@ssa-ui-kit/widgets 0.0.5-alpha → 0.0.6-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssa-ui-kit/widgets",
3
- "version": "0.0.5-alpha",
3
+ "version": "0.0.6-alpha",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "private": false,
@@ -29,9 +29,9 @@
29
29
  "js-tokens": "^4.0.0",
30
30
  "loose-envify": "^1.4.0",
31
31
  "scheduler": "^0.23.0",
32
- "@ssa-ui-kit/core": "^0.0.4-alpha",
33
- "@ssa-ui-kit/utils": "^0.0.1-alpha",
34
- "@ssa-ui-kit/hooks": "^0.0.1-alpha"
32
+ "@ssa-ui-kit/core": "^0.0.5-alpha",
33
+ "@ssa-ui-kit/hooks": "^0.0.1-alpha",
34
+ "@ssa-ui-kit/utils": "^0.0.1-alpha"
35
35
  },
36
36
  "browserslist": [
37
37
  ">0.1%",
@@ -1,3 +1,4 @@
1
+ import { createRef } from 'react';
1
2
  import userEvent from '@testing-library/user-event';
2
3
  import { Button } from '@ssa-ui-kit/core';
3
4
  import { NotificationCard } from './NotificationCard';
@@ -87,4 +88,26 @@ describe('NotificationCard', () => {
87
88
 
88
89
  expect(mockOnClick).toBeCalledTimes(1);
89
90
  });
91
+
92
+ it('Renders with ref', () => {
93
+ const ref = createRef<HTMLDivElement>();
94
+ render(<NotificationCard {...commonProps} isRead={false} ref={ref} />);
95
+
96
+ expect(ref.current?.querySelector('h6')?.textContent).toBe('Title');
97
+ });
98
+
99
+ it('Renders with custom styles', () => {
100
+ const { getByTestId } = render(
101
+ <NotificationCard
102
+ {...commonProps}
103
+ isRead={false}
104
+ css={{
105
+ backgroundColor: 'blue',
106
+ }}
107
+ />,
108
+ );
109
+
110
+ const notification = getByTestId('notification');
111
+ expect(notification).toHaveStyleRule('background-color', 'blue');
112
+ });
90
113
  });
@@ -1,3 +1,4 @@
1
+ import { forwardRef } from 'react';
1
2
  import { useTheme } from '@emotion/react';
2
3
  import { dateFormatters } from '@ssa-ui-kit/utils';
3
4
  import {
@@ -33,22 +34,22 @@ export const notificationTypes: Record<string, { [key: string]: string }> = {
33
34
  },
34
35
  };
35
36
 
36
- export const NotificationCard = ({
37
- title,
38
- children,
39
- text,
40
- isRead,
41
- type,
42
- time,
43
- onClick,
44
- }: NotificationCardProps) => {
37
+ export const NotificationCard = forwardRef<
38
+ HTMLDivElement,
39
+ NotificationCardProps
40
+ >(function NotificationCard(
41
+ { title, children, text, isRead, type, time, onClick, className },
42
+ ref,
43
+ ) {
45
44
  const theme = useTheme();
46
45
  const { getTimeAgo } = dateFormatters;
47
46
 
48
47
  return (
49
48
  <CardBase
49
+ ref={ref}
50
50
  data-testid="notification"
51
51
  css={notifyCard}
52
+ className={className}
52
53
  noShadow
53
54
  onClick={() => {
54
55
  if (typeof onClick === 'function') {
@@ -91,4 +92,4 @@ export const NotificationCard = ({
91
92
  </Typography>
92
93
  </CardBase>
93
94
  );
94
- };
95
+ });
@@ -1,9 +1,12 @@
1
+ export type NotificationType = 'Informational' | 'Warning' | 'Error';
2
+
1
3
  export interface NotificationCardProps {
2
4
  title: string;
3
5
  text: string;
4
6
  isRead: boolean;
5
- type: 'Informational' | 'Warning' | 'Error';
7
+ type: NotificationType;
6
8
  time: string | number;
7
9
  children?: React.ReactNode;
8
10
  onClick?: () => void;
11
+ className?: string;
9
12
  }
@@ -3,36 +3,49 @@ import { SCREEN_SIZES } from '../../consts';
3
3
 
4
4
  const WIDGETS_CUSTOM_SHOTS_PATH = './custom-shots/';
5
5
 
6
- test('Widgets: Pagination hover', async ({ page }) => {
7
- // Hover a selected page
8
- await page.setViewportSize(SCREEN_SIZES[1920]);
9
- await page.goto(
10
- 'http://localhost:6007/iframe.html?args=&id=widgets-pagination--page-selected&viewMode=story',
11
- );
12
- await page.getByRole('button', { name: 'Current page 5' }).hover();
13
-
14
- await page.screenshot({
15
- path: `${WIDGETS_CUSTOM_SHOTS_PATH}widgets-pagination--selected-hover__[w1920px].png`,
6
+ const TEST_CASES = [
7
+ {
8
+ url: 'http://localhost:6007/iframe.html?args=&id=widgets-pagination--page-selected&viewMode=story',
9
+ testTitle: 'Widgets: Pagination hover',
10
+ screenshotPrefix: 'widgets-pagination--',
11
+ },
12
+ {
13
+ url: 'http://localhost:6007/iframe.html?args=&id=widgets-pagination--disabled&viewMode=story',
14
+ testTitle: 'Widgets: Disabled pagination hover',
15
+ screenshotPrefix: 'widgets-pagination-disabled--',
16
+ },
17
+ ];
18
+
19
+ for (const { url, testTitle, screenshotPrefix } of TEST_CASES) {
20
+ test(testTitle, async ({ page }) => {
21
+ // Hover a selected page
22
+ await page.setViewportSize(SCREEN_SIZES[1920]);
23
+ await page.goto(url);
24
+ await page.getByRole('button', { name: 'Current page 5' }).hover();
25
+
26
+ await page.screenshot({
27
+ path: `${WIDGETS_CUSTOM_SHOTS_PATH}${screenshotPrefix}selected-hover__[w1920px].png`,
28
+ });
29
+
30
+ // Hover a NOT selected page
31
+ await page.getByRole('button', { name: 'Go to page 4' }).hover();
32
+
33
+ await page.screenshot({
34
+ path: `${WIDGETS_CUSTOM_SHOTS_PATH}${screenshotPrefix}not-selected-hover__[w1920px].png`,
35
+ });
36
+
37
+ // Hover the previous page arrow
38
+ await page.getByRole('button', { name: 'Go to previous page' }).hover();
39
+
40
+ await page.screenshot({
41
+ path: `${WIDGETS_CUSTOM_SHOTS_PATH}${screenshotPrefix}previous-hover__[w1920px].png`,
42
+ });
43
+
44
+ // Hover the next page arrow
45
+ await page.getByRole('button', { name: 'Go to next page' }).hover();
46
+
47
+ await page.screenshot({
48
+ path: `${WIDGETS_CUSTOM_SHOTS_PATH}${screenshotPrefix}next-hover__[w1920px].png`,
49
+ });
16
50
  });
17
-
18
- // Hover a NOT selected page
19
- await page.getByRole('button', { name: 'Go to page 4' }).hover();
20
-
21
- await page.screenshot({
22
- path: `${WIDGETS_CUSTOM_SHOTS_PATH}widgets-pagination--not-selected-hover__[w1920px].png`,
23
- });
24
-
25
- // Hover the previous page arrow
26
- await page.getByRole('button', { name: 'Go to previous page' }).hover();
27
-
28
- await page.screenshot({
29
- path: `${WIDGETS_CUSTOM_SHOTS_PATH}widgets-pagination--previous-hover__[w1920px].png`,
30
- });
31
-
32
- // Hover the next page arrow
33
- await page.getByRole('button', { name: 'Go to next page' }).hover();
34
-
35
- await page.screenshot({
36
- path: `${WIDGETS_CUSTOM_SHOTS_PATH}widgets-pagination--next-hover__[w1920px].png`,
37
- });
38
- });
51
+ }
@@ -215,4 +215,14 @@ describe('Pagination', () => {
215
215
  expect(document.body.children.length).toBe(1);
216
216
  expect(document.body.children[0]?.tagName).toBe('DIV');
217
217
  });
218
+
219
+ it('Renders in a disabled state', () => {
220
+ setup(<Pagination pagesCount={3} isDisabled={true} />, 2);
221
+
222
+ const buttonEls = screen.getAllByRole('button');
223
+ expect(buttonEls.length).toBe(5); // "previous" "1" "2" "3" "next"
224
+ for (const btnEl of buttonEls) {
225
+ expect(btnEl).toBeDisabled();
226
+ }
227
+ });
218
228
  });
@@ -48,3 +48,13 @@ export const LastPageSelected = {
48
48
  selectedPage: 10,
49
49
  },
50
50
  };
51
+
52
+ export const Disabled = {
53
+ args: {
54
+ pagesCount: 10,
55
+ isDisabled: true,
56
+ },
57
+ parameters: {
58
+ selectedPage: 5,
59
+ },
60
+ };
@@ -14,6 +14,7 @@ const Pagination = ({
14
14
  className,
15
15
  as,
16
16
  ariaLabel,
17
+ isDisabled,
17
18
  }: IPaginationProps) => {
18
19
  const { page, setPage } = usePaginationContext();
19
20
  const range = usePaginationRange({ pagesCount, selectedPage: page });
@@ -28,11 +29,20 @@ const Pagination = ({
28
29
  }
29
30
  }}
30
31
  isDisabled={
31
- pagesCount == null || pagesCount <= 1 || page == null || page === 1
32
+ isDisabled ||
33
+ pagesCount == null ||
34
+ pagesCount <= 1 ||
35
+ page == null ||
36
+ page === 1
32
37
  }
33
38
  css={{ marginRight: '12px' }}
34
39
  />
35
- <PaginationButtons range={range} selectedPage={page} onClick={setPage} />
40
+ <PaginationButtons
41
+ range={range}
42
+ selectedPage={page}
43
+ onClick={setPage}
44
+ isDisabled={isDisabled}
45
+ />
36
46
  <ArrowButton
37
47
  direction="right"
38
48
  onClick={() => {
@@ -41,6 +51,7 @@ const Pagination = ({
41
51
  }
42
52
  }}
43
53
  isDisabled={
54
+ isDisabled ||
44
55
  pagesCount == null ||
45
56
  pagesCount <= 1 ||
46
57
  page == null ||
@@ -7,7 +7,12 @@ import { IPaginationButtonsProps, IPageButtonProps } from './types';
7
7
 
8
8
  const Break = () => <span css={{ cursor: 'default' }}>...</span>;
9
9
 
10
- const PageButton = ({ onClick, isSelected, page }: IPageButtonProps) => {
10
+ const PageButton = ({
11
+ onClick,
12
+ isSelected,
13
+ page,
14
+ isDisabled,
15
+ }: IPageButtonProps) => {
11
16
  const theme = useTheme();
12
17
  const styles = useMemo(() => {
13
18
  return isSelected ? selectedPageBtnStyles(theme) : pageBtnStyles(theme);
@@ -17,6 +22,7 @@ const PageButton = ({ onClick, isSelected, page }: IPageButtonProps) => {
17
22
  <Button
18
23
  size="small"
19
24
  variant="secondary"
25
+ isDisabled={isDisabled}
20
26
  onClick={
21
27
  isSelected
22
28
  ? () => {
@@ -36,6 +42,7 @@ export const PaginationButtons = ({
36
42
  range,
37
43
  selectedPage,
38
44
  onClick,
45
+ isDisabled,
39
46
  }: IPaginationButtonsProps) => {
40
47
  return (
41
48
  Array.isArray(range) &&
@@ -48,6 +55,7 @@ export const PaginationButtons = ({
48
55
  page={page}
49
56
  isSelected={page === selectedPage}
50
57
  onClick={() => onClick(page)}
58
+ isDisabled={isDisabled}
51
59
  />
52
60
  );
53
61
  })
@@ -7,6 +7,10 @@ const baseBtnStyles = (theme: Theme) => css`
7
7
  ${theme.mediaQueries.md} {
8
8
  height: 25px;
9
9
  }
10
+
11
+ &:disabled {
12
+ cursor: default;
13
+ }
10
14
  `;
11
15
 
12
16
  export const pageBtnStyles = (theme: Theme) => css`
@@ -21,9 +25,14 @@ export const pageBtnStyles = (theme: Theme) => css`
21
25
  padding: 0 9px;
22
26
  }
23
27
 
24
- &:hover,
25
- &:active,
26
- &:focus {
28
+ &:disabled {
29
+ background: unset;
30
+ box-shadow: unset;
31
+ }
32
+
33
+ &:not(:disabled):hover,
34
+ &:not(:disabled):active,
35
+ &:not(:disabled):focus {
27
36
  background: #eef1f7;
28
37
  box-shadow: unset;
29
38
  }
@@ -36,6 +45,15 @@ const selectedBtnBg = (theme: Theme) => css`
36
45
  ${theme.colors.blueDark},
37
46
  ${theme.colors.blueLightDarker}
38
47
  );
48
+
49
+ &:disabled {
50
+ background: ${theme.colors.blueLightDarker};
51
+ background: linear-gradient(
52
+ 247.37deg,
53
+ ${theme.colors.blueDark},
54
+ ${theme.colors.blueLightDarker}
55
+ );
56
+ }
39
57
  `;
40
58
 
41
59
  export const selectedPageBtnStyles = (theme: Theme) => css`
@@ -51,16 +69,16 @@ export const selectedPageBtnStyles = (theme: Theme) => css`
51
69
  padding: 0 10px;
52
70
  }
53
71
 
54
- &:hover {
55
- box-shadow: 0 5px 5px -1px rgba(0, 0, 0, 0.3);
56
- cursor: default;
57
- }
58
-
59
72
  &:hover,
60
73
  &:active,
61
74
  &:focus {
62
75
  ${selectedBtnBg(theme)}
63
76
  }
77
+
78
+ &:not(:disabled):hover {
79
+ box-shadow: 0 5px 5px -1px rgba(0, 0, 0, 0.3);
80
+ cursor: default;
81
+ }
64
82
  `;
65
83
 
66
84
  export const arrowBtnStyles = (theme: Theme) => css`
@@ -70,7 +88,6 @@ export const arrowBtnStyles = (theme: Theme) => css`
70
88
  background: ${theme.colors.white};
71
89
 
72
90
  &:disabled {
73
- cursor: default;
74
91
  background: unset;
75
92
  }
76
93
 
@@ -3,12 +3,14 @@ import { CommonProps } from '@ssa-ui-kit/core';
3
3
  export interface IPaginationProps extends CommonProps {
4
4
  pagesCount: number;
5
5
  ariaLabel?: string;
6
+ isDisabled?: boolean;
6
7
  }
7
8
 
8
9
  export interface IPaginationButtonsProps {
9
10
  range: number[];
10
11
  selectedPage?: number;
11
12
  onClick: (page: number) => void;
13
+ isDisabled?: boolean;
12
14
  }
13
15
 
14
16
  export interface IArrowButtonProps {
@@ -22,6 +24,7 @@ export interface IPageButtonProps {
22
24
  onClick: () => void;
23
25
  page: number | string;
24
26
  isSelected: boolean;
27
+ isDisabled?: boolean;
25
28
  }
26
29
 
27
30
  export interface IPaginationContext {
@@ -3,7 +3,6 @@ import { Input } from '@ssa-ui-kit/core';
3
3
 
4
4
  export const SearchBoxInput = styled(Input)`
5
5
  height: 40px;
6
- line-height: 40px;
7
6
  border-radius: 5px;
8
7
  background-color: ${({ theme }) => theme.colors.greyLighter};
9
8
  border: 1px solid #dee0e8;