All files / libs/lti/components/src/lib/enrollment/simulation-widget/pagination SimulationWidgetPagination.tsx

0% Statements 0/89
0% Branches 0/1
0% Functions 0/1
0% Lines 0/89

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                                                                                                                                                                   
import { css } from '@emotion/react';
import { IconArrowLeft, IconArrowRight } from '@tabler/icons-react';
import { memo, useCallback, type Dispatch, type SetStateAction } from 'react';
import { useIntl } from 'react-intl';

import { Group, IconButton, UnstyledButton } from '@allshares/studio-design-system';

import { type SimulationWidgetSize } from '../types';

export type SimulationWidgetPaginationProps = {
  readonly page: number;
  readonly pageCount: number;
  readonly size: SimulationWidgetSize;
  readonly onChangePage: Dispatch<SetStateAction<number>>;
};

export const SimulationWidgetPagination = memo(function SimulationWidgetPagination({
  size,
  page,
  pageCount,
  onChangePage,
}: SimulationWidgetPaginationProps) {
  const { formatMessage } = useIntl();

  const handleGoToPreviousPage = useCallback(() => {
    onChangePage((prev) => (prev <= 0 ? pageCount - 1 : prev - 1));
  }, [onChangePage, pageCount]);

  const handleGoToNextPage = useCallback(() => {
    onChangePage((prev) => (prev + 1) % pageCount);
  }, [onChangePage, pageCount]);

  return (
    <Group
      align="center"
      gap={22}
      css={css`
        align-self: center;
        margin-bottom: ${size === 'compact' ? 12 : 16}px;
      `}
    >
      <IconButton
        icon={<IconArrowLeft />}
        label={formatMessage({ defaultMessage: 'Previous' })}
        size={size === 'compact' ? 'small' : 'medium'}
        onClick={handleGoToPreviousPage}
      />

      <Group
        align="center"
        gap={2}
      >
        {Array.from({ length: pageCount }, (_, index) => (
          <UnstyledButton
            key={index}
            css={css`
              flex: none;
              height: 12px;
              width: 12px;
            `}
            onClick={() => onChangePage(index)}
          >
            <div
              css={(theme) => css`
                transition: ${theme.ds.transitions.default('background-color')};
                height: ${size === 'compact' ? '6px' : '8px'};
                width: ${size === 'compact' ? '6px' : '8px'};
                margin: auto;
                border-radius: ${theme.ds.borderRadiuses.round};
                background-color: ${index === page ? theme.ds.colors.gray[800] : theme.ds.colors.gray[200]};

                [data-color-scheme='dark'] & {
                  background-color: ${index === page ? theme.ds.colors.gray[100] : theme.ds.colors.dark[400]};
                }
              `}
            />
          </UnstyledButton>
        ))}
      </Group>

      <IconButton
        icon={<IconArrowRight />}
        label={formatMessage({ defaultMessage: 'Next' })}
        size={size === 'compact' ? 'small' : 'medium'}
        onClick={handleGoToNextPage}
      />
    </Group>
  );
});