aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/layout/widget.test.tsx
blob: af561eaa704cc3eca3000a5b11834f992552544a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { render, screen } from '@test-utils';
import Widget from './widget';

const children = 'Widget body';
const title = 'Widget title';
const titleLevel = 2;

describe('Widget', () => {
  it('renders the widget title', () => {
    render(
      <Widget expanded={true} title={title} level={titleLevel}>
        {children}
      </Widget>
    );
    expect(
      screen.getByRole('heading', { level: titleLevel })
    ).toHaveTextContent(title);
  });
});
ghlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
import SingleComment, {
  type CommentProps,
} from '@components/organisms/layout/comment';
import { FC } from 'react';
import styles from './comments-list.module.scss';

export type Comment = Omit<CommentProps, 'canReply' | 'saveComment'> & {
  child?: Comment[];
};

export type CommentsListProps = {
  /**
   * An array of comments.
   */
  comments: Comment[];
  /**
   * The maximum depth. Use `0` to not display nested comments.
   */
  depth: 0 | 1 | 2 | 3 | 4;
  /**
   * A callback function to save comment form data.
   */
  saveComment: CommentProps['saveComment'];
};

/**
 * CommentsList component
 *
 * Render a comments list.
 */
const CommentsList: FC<CommentsListProps> = ({
  comments,
  depth,
  saveComment,
}) => {
  /**
   * Get each comment wrapped in a list item.
   *
   * @param {Comment[]} commentsList - An array of comments.
   * @returns {JSX.Element[]} The list items.
   */
  const getItems = (
    commentsList: Comment[],
    startLevel: number
  ): JSX.Element[] => {
    const isLastLevel = startLevel === depth;

    return commentsList.map(({ child, ...comment }) => (
      <li key={comment.id} className={styles.item}>
        <SingleComment
          saveComment={saveComment}
          canReply={!isLastLevel}
          {...comment}
        />
        {child && !isLastLevel && (
          <ol className={styles.list}>{getItems(child, startLevel + 1)}</ol>
        )}
      </li>
    ));
  };

  return <ol className={styles.list}>{getItems(comments, 0)}</ol>;
};

export default CommentsList;