@indico-data/design-system 1.0.47 → 1.0.49

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.
Files changed (182) hide show
  1. package/README.md +5 -0
  2. package/jest.config.js +15 -0
  3. package/lib/components/Accordion/Accordion.d.ts +1 -1
  4. package/lib/components/Accordion/Accordion.stories.d.ts +2 -2
  5. package/lib/components/Accordion/Accordion.styles.d.ts +1 -275
  6. package/lib/components/Icon/Icon.stories.d.ts +3 -4
  7. package/lib/components/Icon/indicons.d.ts +143 -125
  8. package/lib/components/Icon/storyHelpers.d.ts +3 -813
  9. package/lib/components/ListTable/Header/Header.d.ts +1 -1
  10. package/lib/components/ListTable/Header/Header.styles.d.ts +1 -272
  11. package/lib/components/ListTable/ListTable.d.ts +1 -1
  12. package/lib/components/ListTable/ListTable.stories.d.ts +1 -1
  13. package/lib/components/ListTable/ListTable.styles.d.ts +1 -272
  14. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.d.ts +15 -0
  15. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.stories.d.ts +22 -0
  16. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.styles.d.ts +3 -0
  17. package/lib/components/LoadingAwareContainer/index.d.ts +1 -0
  18. package/lib/components/Navigation/Drawer/Drawer.d.ts +15 -0
  19. package/lib/components/Navigation/Drawer/Drawer.stories.d.ts +6 -0
  20. package/lib/components/Navigation/Drawer/Drawer.styles.d.ts +7 -0
  21. package/lib/components/Navigation/Drawer/DrawerLinkList.d.ts +9 -0
  22. package/lib/components/Navigation/Drawer/DrawerLinkList.styles.d.ts +2 -0
  23. package/lib/components/Navigation/Drawer/__mocks__/mocks.d.ts +3 -0
  24. package/lib/components/Navigation/Drawer/__tests__/Drawer.test.d.ts +1 -0
  25. package/lib/components/Navigation/Drawer/__tests__/DrawerLinkList.test.d.ts +1 -0
  26. package/lib/components/Navigation/Drawer/index.d.ts +1 -0
  27. package/lib/components/Navigation/Drawer/types.d.ts +7 -0
  28. package/lib/components/Navigation/index.d.ts +1 -0
  29. package/lib/components/Pagination/Pagination.d.ts +1 -2
  30. package/lib/components/Pagination/Pagination.styles.d.ts +1 -272
  31. package/lib/components/Wizard/Wizard.d.ts +48 -0
  32. package/lib/components/Wizard/Wizard.stories.d.ts +29 -0
  33. package/lib/components/Wizard/Wizard.styles.d.ts +4 -0
  34. package/lib/components/Wizard/index.d.ts +2 -0
  35. package/lib/components/WizardWithSidebar/WizardWithSidebar.d.ts +58 -0
  36. package/lib/components/WizardWithSidebar/WizardWithSidebar.stories.d.ts +46 -0
  37. package/lib/components/WizardWithSidebar/WizardWithSidebar.styles.d.ts +9 -0
  38. package/lib/components/WizardWithSidebar/index.d.ts +2 -0
  39. package/lib/components/basic-section/Section/Section.d.ts +1 -1
  40. package/lib/components/basic-section/Section/Section.stories.d.ts +1 -1
  41. package/lib/components/basic-section/Section/Section.styles.d.ts +1 -272
  42. package/lib/components/basic-section/SectionBlock/SectionBlock.d.ts +1 -1
  43. package/lib/components/basic-section/SectionBlock/SectionBlock.styles.d.ts +1 -272
  44. package/lib/components/basic-section/SectionBody/SectionBody.d.ts +1 -1
  45. package/lib/components/basic-section/SectionBody/SectionBody.stories.d.ts +1 -2
  46. package/lib/components/basic-section/SectionBody/SectionBody.styles.d.ts +1 -272
  47. package/lib/components/basic-section/SectionHeader/SectionHeader.d.ts +1 -1
  48. package/lib/components/basic-section/SectionHeader/SectionHeader.stories.d.ts +1 -1
  49. package/lib/components/basic-section/SectionHeader/SectionHeader.styles.d.ts +1 -272
  50. package/lib/components/basic-section/SectionTable/SectionTable.d.ts +1 -2
  51. package/lib/components/basic-section/SectionTable/SectionTable.styles.d.ts +1 -272
  52. package/lib/components/buttons/Button/Button.styles.d.ts +1 -282
  53. package/lib/components/buttons/IconButton/IconButton.d.ts +4 -5
  54. package/lib/components/buttons/IconButton/IconButton.stories.d.ts +3 -3
  55. package/lib/components/buttons/IconButton/IconButton.styles.d.ts +2 -567
  56. package/lib/components/buttons/types.d.ts +2 -1
  57. package/lib/components/dropdowns/BorderSelect/BorderSelect.d.ts +1 -1
  58. package/lib/components/dropdowns/BorderSelect/BorderSelect.stories.d.ts +1 -1
  59. package/lib/components/dropdowns/BorderSelect/BorderSelect.styles.d.ts +2 -543
  60. package/lib/components/dropdowns/MultiCombobox/MultiCombobox.styles.d.ts +1 -84
  61. package/lib/components/dropdowns/Select/Select.d.ts +1 -1
  62. package/lib/components/dropdowns/Select/Select.stories.d.ts +1 -1
  63. package/lib/components/dropdowns/Select/Select.styles.d.ts +1 -272
  64. package/lib/components/dropdowns/SingleCombobox/SingleCombobox.styles.d.ts +1 -84
  65. package/lib/components/dropdowns/utils.d.ts +1 -2
  66. package/lib/components/index.d.ts +7 -2
  67. package/lib/components/inputs/EditableInput/EditableInput.d.ts +1 -1
  68. package/lib/components/inputs/EditableInput/EditableInput.stories.d.ts +1 -2
  69. package/lib/components/inputs/EditableInput/EditableInput.styles.d.ts +1 -272
  70. package/lib/components/inputs/NumberInput/NumberInput.styles.d.ts +1 -272
  71. package/lib/components/inputs/RadioButtons/RadioButtons.d.ts +24 -0
  72. package/lib/components/inputs/RadioButtons/RadioButtons.stories.d.ts +15 -0
  73. package/lib/components/inputs/RadioButtons/RadioButtons.styles.d.ts +14 -0
  74. package/lib/components/inputs/RadioButtons/index.d.ts +1 -0
  75. package/lib/components/inputs/RadioGroup/RadioGroup.d.ts +27 -0
  76. package/lib/components/inputs/RadioGroup/RadioGroup.stories.d.ts +16 -0
  77. package/lib/components/inputs/RadioGroup/RadioGroup.styles.d.ts +2 -0
  78. package/lib/components/inputs/RadioGroup/index.d.ts +1 -0
  79. package/lib/components/inputs/SearchInput/SearchInput.d.ts +1 -1
  80. package/lib/components/inputs/SearchInput/SearchInput.stories.d.ts +1 -1
  81. package/lib/components/inputs/SearchInput/SearchInput.styles.d.ts +1 -5
  82. package/lib/components/inputs/TextInput/TextInput.styles.d.ts +2 -543
  83. package/lib/components/inputs/index.d.ts +2 -0
  84. package/lib/components/loading-indicators/BarSpinner/BarSpinner.styles.d.ts +1 -272
  85. package/lib/components/loading-indicators/CirclePulse/CirclePulse.styles.d.ts +3 -3
  86. package/lib/components/loading-indicators/LoadingIndicator/LoadingIndicator.d.ts +10 -0
  87. package/lib/components/loading-indicators/LoadingIndicator/LoadingIndicator.stories.d.ts +11 -0
  88. package/lib/components/loading-indicators/LoadingIndicator/LoadingIndicator.styles.d.ts +8 -0
  89. package/lib/components/loading-indicators/LoadingIndicator/index.d.ts +1 -0
  90. package/lib/components/loading-indicators/LoadingList/LoadingList.d.ts +1 -2
  91. package/lib/components/loading-indicators/LoadingList/LoadingList.stories.d.ts +1 -2
  92. package/lib/components/loading-indicators/LoadingList/LoadingList.styles.d.ts +1 -272
  93. package/lib/components/loading-indicators/PercentageRing/PercentageRing.d.ts +1 -2
  94. package/lib/components/loading-indicators/PercentageRing/PercentageRing.styles.d.ts +1 -272
  95. package/lib/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.d.ts +1 -2
  96. package/lib/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.stories.d.ts +1 -2
  97. package/lib/components/loading-indicators/index.d.ts +1 -0
  98. package/lib/components/modals/ConfirmModal/ConfirmModal.d.ts +17 -0
  99. package/lib/components/modals/ConfirmModal/ConfirmModal.stories.d.ts +44 -0
  100. package/lib/components/modals/ConfirmModal/ConfirmModal.styles.d.ts +2 -0
  101. package/lib/components/modals/ConfirmModal/index.d.ts +1 -0
  102. package/lib/components/modals/ModalBase/ModalBase.d.ts +27 -0
  103. package/lib/components/modals/ModalBase/ModalBase.stories.d.ts +9 -0
  104. package/lib/components/modals/ModalBase/ModalBase.styles.d.ts +4 -0
  105. package/lib/components/modals/ModalBase/index.d.ts +2 -0
  106. package/lib/components/modals/index.d.ts +2 -0
  107. package/lib/components/user-feedback/Shrug/Shrug.stories.d.ts +1 -1
  108. package/lib/components/user-feedback/Shrug/Shrug.styles.d.ts +1 -272
  109. package/lib/index.d.ts +531 -270
  110. package/lib/index.esm.js +5722 -824
  111. package/lib/index.esm.js.map +1 -1
  112. package/lib/index.js +5779 -867
  113. package/lib/index.js.map +1 -1
  114. package/lib/setupTests.d.ts +1 -0
  115. package/lib/styles/globals/index.d.ts +1 -2
  116. package/lib/tokens/colors.d.ts +9 -0
  117. package/lib/tokens/typography.d.ts +12 -0
  118. package/lib/types.d.ts +147 -125
  119. package/package.json +60 -42
  120. package/src/components/Icon/Icon.tsx +1 -0
  121. package/src/components/Icon/indicons.tsx +138 -15
  122. package/src/components/ListTable/ListTable.stories.tsx +1 -1
  123. package/src/components/LoadingAwareContainer/LoadingAwareContainer.stories.tsx +45 -0
  124. package/src/components/LoadingAwareContainer/LoadingAwareContainer.styles.ts +16 -0
  125. package/src/components/LoadingAwareContainer/LoadingAwareContainer.tsx +36 -0
  126. package/src/components/LoadingAwareContainer/index.ts +1 -0
  127. package/src/components/Navigation/Drawer/Drawer.stories.tsx +44 -0
  128. package/src/components/Navigation/Drawer/Drawer.styles.ts +75 -0
  129. package/src/components/Navigation/Drawer/Drawer.tsx +108 -0
  130. package/src/components/Navigation/Drawer/DrawerLinkList.styles.ts +66 -0
  131. package/src/components/Navigation/Drawer/DrawerLinkList.tsx +64 -0
  132. package/src/components/Navigation/Drawer/__mocks__/mocks.ts +49 -0
  133. package/src/components/Navigation/Drawer/__tests__/Drawer.test.tsx +175 -0
  134. package/src/components/Navigation/Drawer/__tests__/DrawerLinkList.test.tsx +66 -0
  135. package/src/components/Navigation/Drawer/index.ts +1 -0
  136. package/src/components/Navigation/Drawer/types.ts +8 -0
  137. package/src/components/Navigation/index.ts +1 -0
  138. package/src/components/Wizard/Wizard.stories.tsx +180 -0
  139. package/src/components/Wizard/Wizard.styles.ts +72 -0
  140. package/src/components/Wizard/Wizard.tsx +211 -0
  141. package/src/components/Wizard/index.ts +2 -0
  142. package/src/components/WizardWithSidebar/WizardWithSidebar.stories.tsx +143 -0
  143. package/src/components/WizardWithSidebar/WizardWithSidebar.styles.ts +123 -0
  144. package/src/components/WizardWithSidebar/WizardWithSidebar.tsx +262 -0
  145. package/src/components/WizardWithSidebar/index.ts +2 -0
  146. package/src/components/buttons/IconButton/IconButton.styles.ts +31 -0
  147. package/src/components/buttons/IconButton/IconButton.tsx +8 -6
  148. package/src/components/buttons/types.ts +2 -1
  149. package/src/components/index.ts +16 -1
  150. package/src/components/inputs/RadioButtons/RadioButtons.stories.tsx +84 -0
  151. package/src/components/inputs/RadioButtons/RadioButtons.styles.ts +82 -0
  152. package/src/components/inputs/RadioButtons/RadioButtons.tsx +61 -0
  153. package/src/components/inputs/RadioButtons/index.tsx +1 -0
  154. package/src/components/inputs/RadioGroup/RadioGroup.stories.tsx +66 -0
  155. package/src/components/inputs/RadioGroup/RadioGroup.styles.ts +11 -0
  156. package/src/components/inputs/RadioGroup/RadioGroup.tsx +120 -0
  157. package/src/components/inputs/RadioGroup/index.ts +1 -0
  158. package/src/components/inputs/SearchInput/SearchInput.styles.ts +28 -42
  159. package/src/components/inputs/SearchInput/SearchInput.tsx +6 -4
  160. package/src/components/inputs/index.ts +2 -0
  161. package/src/components/loading-indicators/CirclePulse/CirclePulse.styles.ts +7 -7
  162. package/src/components/loading-indicators/CirclePulse/CirclePulse.tsx +3 -3
  163. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.stories.tsx +22 -0
  164. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.styles.ts +81 -0
  165. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.tsx +61 -0
  166. package/src/components/loading-indicators/LoadingIndicator/index.ts +1 -0
  167. package/src/components/loading-indicators/index.ts +1 -0
  168. package/src/components/modals/ConfirmModal/ConfirmModal.stories.tsx +76 -0
  169. package/src/components/modals/ConfirmModal/ConfirmModal.styles.ts +30 -0
  170. package/src/components/modals/ConfirmModal/ConfirmModal.tsx +84 -0
  171. package/src/components/modals/ConfirmModal/index.ts +1 -0
  172. package/src/components/modals/ModalBase/ModalBase.stories.tsx +47 -0
  173. package/src/components/modals/ModalBase/ModalBase.styles.tsx +73 -0
  174. package/src/components/modals/ModalBase/ModalBase.tsx +72 -0
  175. package/src/components/modals/ModalBase/index.ts +2 -0
  176. package/src/components/modals/index.ts +2 -0
  177. package/src/index.ts +13 -0
  178. package/src/setupTests.ts +4 -0
  179. package/src/tokens/colors.ts +9 -0
  180. package/src/tokens/typography.ts +7 -1
  181. package/src/types.ts +8 -0
  182. package/tsconfig.json +1 -1
@@ -0,0 +1,66 @@
1
+ import styled from 'styled-components';
2
+ import { TYPOGRAPHY } from '@/tokens';
3
+
4
+ export const StyledDrawerLinkList = styled.div`
5
+ .drawer__list {
6
+ white-space: nowrap;
7
+
8
+ .drawer__list__item {
9
+ box-sizing: border-box;
10
+ margin-bottom: 10px;
11
+ font-weight: ${TYPOGRAPHY.weight.semibold};
12
+ font-size: ${TYPOGRAPHY.fontSize.subheadSmall};
13
+ display: flex;
14
+ align-items: center;
15
+ padding-top: 12px;
16
+ padding-bottom: 10px;
17
+
18
+ &:last-child {
19
+ margin-bottom: 0;
20
+ }
21
+
22
+ &:hover {
23
+ color: #6833d0;
24
+ background-color: #efebf7;
25
+
26
+ a,
27
+ &:active {
28
+ color: #6833d0;
29
+ }
30
+ }
31
+
32
+ &--active {
33
+ color: white;
34
+ background-color: #6833d0;
35
+ border-radius: 4px;
36
+
37
+ a,
38
+ &:active {
39
+ color: white;
40
+ }
41
+ }
42
+
43
+ .drawer__list__item__link {
44
+ font-size: ${TYPOGRAPHY.fontSize.subheadSmall};
45
+ display: flex;
46
+ align-items: center;
47
+
48
+ .drawer__list__item__icon {
49
+ width: 22px;
50
+ height: 22px;
51
+ margin-right: 12px;
52
+ margin-left: 10px;
53
+ }
54
+
55
+ .drawer__list__item__label {
56
+ opacity: 1;
57
+ }
58
+
59
+ .drawer__list__item__label--hidden {
60
+ opacity: 0;
61
+ transition: all 0.3s ease-out;
62
+ }
63
+ }
64
+ }
65
+ }
66
+ `;
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import classNames from 'classnames';
3
+ import { PermafrostComponent } from '@/types';
4
+ import { StyledDrawerLinkList } from './DrawerLinkList.styles';
5
+ import { Icon } from '../../Icon';
6
+ import { ListItem } from './types';
7
+ import { NavLink } from 'react-router-dom';
8
+
9
+ type Props = PermafrostComponent & {
10
+ style?: object;
11
+ listItems?: ListItem[];
12
+ isOpen: boolean;
13
+ };
14
+
15
+ export const DrawerLinkList = (props: Props) => {
16
+ const { className, style = {}, id, listItems, isOpen, ...restOfProps } = props;
17
+
18
+ return (
19
+ <StyledDrawerLinkList
20
+ id={id}
21
+ data-cy={props['data-cy']}
22
+ data-testid={props['data-testid']}
23
+ style={style}
24
+ {...restOfProps}
25
+ className={classNames('drawer__content__list', className)}
26
+ >
27
+ {listItems && (
28
+ <ul className="drawer__list">
29
+ {listItems.map((item) => (
30
+ <NavLink
31
+ key={item.id}
32
+ to={item.path}
33
+ className={({ isActive, isPending }) => {
34
+ return classNames(
35
+ 'drawer__list__item',
36
+ { 'drawer__list__item--active': isActive },
37
+ { 'drawer__list__item--pending': isPending },
38
+ );
39
+ }}
40
+ role="link"
41
+ aria-label={item.label}
42
+ data-testid={`link-list-item-${item.label}`}
43
+ >
44
+ <li className="drawer__list__item__link">
45
+ <span className={`drawer__list__item__icon`}>
46
+ <Icon size={[22]} name={item.icon} ariaLabel={`${item.label} icon`} />
47
+ </span>
48
+ <span
49
+ className={`drawer__list__item__label ${
50
+ !isOpen ? 'drawer__list__item__label--hidden' : ''
51
+ }`}
52
+ aria-hidden={!isOpen}
53
+ data-testid="list-item-label"
54
+ >
55
+ {item.label}
56
+ </span>
57
+ </li>
58
+ </NavLink>
59
+ ))}
60
+ </ul>
61
+ )}
62
+ </StyledDrawerLinkList>
63
+ );
64
+ };
@@ -0,0 +1,49 @@
1
+ import { ListItem } from '../types';
2
+
3
+ export const navigationItems: ListItem[] = [
4
+ {
5
+ id: '1',
6
+ icon: 'search-thin',
7
+ label: 'Search',
8
+ path: '/iframe.html',
9
+ },
10
+ {
11
+ id: '4',
12
+ icon: 'libraries',
13
+ label: 'Libraries',
14
+ path: '/',
15
+ },
16
+ {
17
+ id: '2',
18
+ icon: 'collection',
19
+ label: 'Collections',
20
+ path: '/profile',
21
+ },
22
+ {
23
+ id: '3',
24
+ icon: 'compare',
25
+ label: 'Compare',
26
+ path: '/settings',
27
+ },
28
+ ];
29
+
30
+ export const footerItems: ListItem[] = [
31
+ {
32
+ id: 'foter-1',
33
+ icon: 'circle-help',
34
+ label: 'Help',
35
+ path: '/search',
36
+ },
37
+ {
38
+ id: '4f',
39
+ icon: 'cog',
40
+ label: 'Settings',
41
+ path: '/',
42
+ },
43
+ {
44
+ id: '42',
45
+ icon: 'logout',
46
+ label: 'Sign Out',
47
+ path: '/profile',
48
+ },
49
+ ];
@@ -0,0 +1,175 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { Drawer } from '../Drawer';
5
+ import { navigationItems, footerItems } from '../__mocks__/mocks';
6
+ import { MemoryRouter } from 'react-router-dom';
7
+
8
+ let navDrawer: HTMLElement;
9
+
10
+ describe('Drawer', () => {
11
+ describe('expanded interactions', () => {
12
+ beforeEach(() => {
13
+ render(
14
+ <MemoryRouter>
15
+ <Drawer
16
+ logoIcon={'indico-o'}
17
+ logoText={'INDICO INSIGHTS'}
18
+ navigationItems={navigationItems}
19
+ footerItems={footerItems}
20
+ $expandedWidth="300"
21
+ $collapsedWidth="45"
22
+ data-testid="navigation__drawer"
23
+ />
24
+ ,
25
+ </MemoryRouter>,
26
+ );
27
+ navDrawer = screen.getByTestId('navigation__drawer');
28
+ });
29
+
30
+ it('opens the drawer when the mouse is over the drawer', async () => {
31
+ expect(navDrawer).toHaveAttribute('aria-expanded', 'false');
32
+
33
+ await userEvent.hover(navDrawer);
34
+ expect(navDrawer).toHaveAttribute('aria-expanded', 'true');
35
+ });
36
+
37
+ it('closes the drawer when the mouse is over the drawer and then leaves the drawer', async () => {
38
+ expect(navDrawer).toHaveAttribute('aria-expanded', 'false');
39
+ await userEvent.hover(navDrawer);
40
+
41
+ expect(navDrawer).toHaveAttribute('aria-expanded', 'true');
42
+ await userEvent.unhover(navDrawer);
43
+ expect(navDrawer).toHaveAttribute('aria-expanded', 'false');
44
+ });
45
+ });
46
+
47
+ describe('styling', () => {
48
+ beforeEach(() => {
49
+ render(
50
+ <MemoryRouter>
51
+ <Drawer
52
+ logoIcon={'indico-o'}
53
+ logoText={'INDICO INSIGHTS'}
54
+ navigationItems={navigationItems}
55
+ footerItems={footerItems}
56
+ $expandedWidth="400"
57
+ $collapsedWidth="45"
58
+ data-testid="navigation__drawer"
59
+ />
60
+ ,
61
+ </MemoryRouter>,
62
+ );
63
+ navDrawer = screen.getByTestId('navigation__drawer');
64
+ });
65
+
66
+ it('applies the drawer--open class to the component when the drawer is open', async () => {
67
+ expect(navDrawer).toHaveClass('drawer--closed');
68
+ await userEvent.hover(navDrawer);
69
+
70
+ expect(navDrawer).toHaveAttribute('aria-expanded', 'true');
71
+ expect(navDrawer).toHaveClass('drawer--open');
72
+ });
73
+
74
+ it('applies the drawer--closed class to the component when the drawer is closed', async () => {
75
+ expect(navDrawer).toHaveClass('drawer--closed');
76
+ await userEvent.hover(navDrawer);
77
+
78
+ expect(navDrawer).toHaveClass('drawer--open');
79
+ await userEvent.unhover(navDrawer);
80
+ expect(navDrawer).toHaveClass('drawer--closed');
81
+ });
82
+
83
+ it('sets the drawer width to the min width value passed in as a prop when drawer is closed', () => {
84
+ expect(navDrawer).toHaveClass('drawer--closed');
85
+ expect(navDrawer).toHaveStyle({ width: '45px' });
86
+ });
87
+
88
+ it('sets the drawer width to the max width value passed in as a prop when drawer is open', async () => {
89
+ await userEvent.hover(navDrawer);
90
+
91
+ expect(navDrawer).toHaveClass('drawer--open');
92
+ expect(navDrawer).toHaveStyle({ width: '400px' });
93
+ });
94
+ });
95
+
96
+ describe('Logo and Header Display', () => {
97
+ it('displays the header component when one is provided', () => {
98
+ render(
99
+ <MemoryRouter>
100
+ <Drawer
101
+ navigationItems={navigationItems}
102
+ footerItems={footerItems}
103
+ data-testid="navigation__drawer"
104
+ $expandedWidth="400"
105
+ $collapsedWidth="45"
106
+ headerComponent={<div>Header Component</div>}
107
+ />
108
+ ,
109
+ </MemoryRouter>,
110
+ );
111
+
112
+ navDrawer = screen.getByTestId('navigation__drawer');
113
+
114
+ expect(screen.getByText('Header Component')).toBeInTheDocument();
115
+ });
116
+ it('displays the logo icon and text when no header component is provided', async () => {
117
+ render(
118
+ <MemoryRouter>
119
+ <Drawer
120
+ logoIcon={'indico-o'}
121
+ logoText={'INDICO INSIGHTS'}
122
+ navigationItems={navigationItems}
123
+ footerItems={footerItems}
124
+ data-testid="navigation__drawer"
125
+ />
126
+ ,
127
+ </MemoryRouter>,
128
+ );
129
+ navDrawer = screen.getByTestId('navigation__drawer');
130
+
131
+ await userEvent.hover(navDrawer);
132
+ const logoIcon = screen.getByTestId('logo-icon');
133
+ const logoText = screen.getByText('INDICO INSIGHTS');
134
+
135
+ expect(logoIcon).toBeInTheDocument();
136
+ expect(logoText).toBeInTheDocument();
137
+ expect(logoText).toHaveAttribute('aria-hidden', 'false');
138
+ expect(logoText).toBeVisible();
139
+ expect(logoIcon).toBeVisible();
140
+ });
141
+ });
142
+ describe('Conditional Rendering Of Lists', () => {
143
+ it('does not display nav or footer lists if props are empty', () => {
144
+ render(
145
+ <MemoryRouter>
146
+ <Drawer navigationItems={[]} footerItems={[]} data-testid="navigation__drawer" />,
147
+ </MemoryRouter>,
148
+ );
149
+
150
+ const nav = screen.queryByTestId('drawer-navigation');
151
+ const footer = screen.queryByTestId('drawer-footer');
152
+
153
+ expect(nav).not.toBeInTheDocument();
154
+ expect(footer).not.toBeInTheDocument();
155
+ });
156
+ it('displays nav and footer lists if props are not empty', () => {
157
+ render(
158
+ <MemoryRouter>
159
+ <Drawer
160
+ navigationItems={navigationItems}
161
+ footerItems={footerItems}
162
+ data-testid="navigation__drawer"
163
+ />
164
+ ,
165
+ </MemoryRouter>,
166
+ );
167
+
168
+ const nav = screen.getByTestId('drawer-navigation');
169
+ const footer = screen.getByTestId('drawer-footer');
170
+
171
+ expect(nav).toBeInTheDocument();
172
+ expect(footer).toBeInTheDocument();
173
+ });
174
+ });
175
+ });
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { DrawerLinkList } from '../DrawerLinkList';
4
+ import { navigationItems } from '../__mocks__/mocks';
5
+ import { MemoryRouter } from 'react-router-dom';
6
+
7
+ describe('DrawerLinkList', () => {
8
+ describe('expanded interactions', () => {
9
+ it('it renders the correct number of items in the list', () => {
10
+ render(
11
+ <MemoryRouter>
12
+ <DrawerLinkList isOpen={true} listItems={navigationItems} />
13
+ </MemoryRouter>,
14
+ );
15
+
16
+ const list = screen.getAllByRole('listitem');
17
+ expect(list).toHaveLength(navigationItems.length);
18
+ });
19
+
20
+ // NOTE, the default path for the purpose of this test is `/` which matches the prop value.
21
+ it('hides the label when isOpen is false', () => {
22
+ render(
23
+ <MemoryRouter>
24
+ <DrawerLinkList isOpen={false} listItems={navigationItems} />
25
+ </MemoryRouter>,
26
+ );
27
+
28
+ const items = screen.queryAllByTestId('list-item-label');
29
+ items.map((item) => {
30
+ expect(item).not.toBeVisible();
31
+ });
32
+ });
33
+ it('shows the label when isOpen is true', () => {
34
+ render(
35
+ <MemoryRouter>
36
+ <DrawerLinkList isOpen={true} listItems={navigationItems} />
37
+ </MemoryRouter>,
38
+ );
39
+
40
+ const items = screen.queryAllByTestId('list-item-label');
41
+ items.map((item) => {
42
+ expect(item).toBeVisible();
43
+ });
44
+ });
45
+ it('sets active class on handleActiveLink match', () => {
46
+ render(
47
+ <MemoryRouter>
48
+ <DrawerLinkList isOpen={true} listItems={navigationItems} />
49
+ </MemoryRouter>,
50
+ );
51
+
52
+ const lineItem = screen.getByTestId('link-list-item-Libraries');
53
+ expect(lineItem).toHaveClass('drawer__list__item--active');
54
+ });
55
+ it('does not render a list when no items are passed to the component', () => {
56
+ render(
57
+ <MemoryRouter>
58
+ <DrawerLinkList isOpen={true} listItems={[]} />
59
+ </MemoryRouter>,
60
+ );
61
+
62
+ const list = screen.queryAllByRole('listitem');
63
+ expect(list).toHaveLength(0);
64
+ });
65
+ });
66
+ });
@@ -0,0 +1 @@
1
+ export { Drawer } from './Drawer';
@@ -0,0 +1,8 @@
1
+ import { IconName } from '@/types';
2
+
3
+ export type ListItem = {
4
+ id: string;
5
+ icon: IconName;
6
+ label: string;
7
+ path: string;
8
+ };
@@ -0,0 +1 @@
1
+ export { Drawer } from './Drawer';
@@ -0,0 +1,180 @@
1
+ import React, { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+
4
+ import { Wizard } from './Wizard';
5
+ import { WizardCard, WizardSection } from './Wizard.styles';
6
+
7
+ const meta = {
8
+ component: Wizard,
9
+ title: 'wizards/Wizard',
10
+ args: {
11
+ steps: ['Task Details', 'Labels and Keywords', 'Labelers'],
12
+ onCancel: () => console.info('cancelling'),
13
+ onSubmit: () => console.info('submitting'),
14
+ wizardTitle: 'New Teach Task',
15
+ confirmCancel: {
16
+ title: 'Are you sure you want to stop creating this Task?',
17
+ message: 'Your Task will not be saved, nor available to be labeled.',
18
+ confirmText: 'Yes, go ahead',
19
+ rejectText: 'No, go back',
20
+ },
21
+ submitButtonLabel: 'Add Teach Task',
22
+ // Evidently, we need to add this prop or its corresponding logic within the component evaluates to false in storybook.
23
+ // Was not happening in earlier version, so was not necessary.
24
+ onNextPress: () => true,
25
+ },
26
+ } satisfies Meta<typeof Wizard>;
27
+
28
+ export default meta;
29
+ type Story = StoryObj<typeof Wizard>;
30
+
31
+ function StoryRender(props: any) {
32
+ const [currentStep, setCurrentStep] = useState('');
33
+
34
+ const currentStepContent = () => {
35
+ if (currentStep === 'Task Details') {
36
+ return (
37
+ <WizardCard>
38
+ <WizardSection>
39
+ <h2 className="section-heading">Task Name</h2>
40
+
41
+ <div className="section-content">hello yes this is dog</div>
42
+ </WizardSection>
43
+
44
+ <WizardSection>
45
+ <h2 className="section-heading">Dataset</h2>
46
+
47
+ <div className="section-content" />
48
+ </WizardSection>
49
+
50
+ <WizardSection>
51
+ <h2 className="section-heading">
52
+ Processors and Branches <span className="supporting-text">(Optional)</span>
53
+ </h2>
54
+
55
+ <div className="section-content" />
56
+ </WizardSection>
57
+ </WizardCard>
58
+ );
59
+ }
60
+
61
+ if (currentStep === 'Labels and Keywords') {
62
+ return (
63
+ <WizardCard>
64
+ <WizardSection>
65
+ <h2 className="section-heading">Labels</h2>
66
+
67
+ <div className="section-content" />
68
+ </WizardSection>
69
+
70
+ <WizardSection>
71
+ <h2 className="section-heading">Label Predictions</h2>
72
+
73
+ <div className="section-content" />
74
+ </WizardSection>
75
+
76
+ <WizardSection>
77
+ <h2 className="section-heading">
78
+ Keywords <span className="supporting-text">(Optional)</span>
79
+ </h2>
80
+
81
+ <div className="section-content" />
82
+ </WizardSection>
83
+ </WizardCard>
84
+ );
85
+ }
86
+
87
+ if (currentStep === 'Labelers') {
88
+ return (
89
+ <WizardCard>
90
+ <WizardSection>
91
+ <h2 className="section-heading">Labelers Required Per Example</h2>
92
+
93
+ <div className="section-content" />
94
+ </WizardSection>
95
+
96
+ <WizardSection>
97
+ <h2 className="section-heading">
98
+ Team{' '}
99
+ <span className="supporting-text" style={{ marginLeft: '0.25em' }}>
100
+ 1
101
+ </span>
102
+ </h2>
103
+
104
+ <div className="section-content" />
105
+ </WizardSection>
106
+ </WizardCard>
107
+ );
108
+ }
109
+ };
110
+
111
+ return (
112
+ <Wizard {...props} onStepChange={(step) => setCurrentStep(step)}>
113
+ {currentStepContent()}
114
+ </Wizard>
115
+ );
116
+ }
117
+
118
+ export const Normal: Story = {
119
+ args: {
120
+ startingStep: 'Labels and Keywords',
121
+ },
122
+ render: (args) => {
123
+ return <StoryRender {...args} />;
124
+ },
125
+ };
126
+
127
+ export const FirstStep: Story = {
128
+ // args: {},
129
+ render: (args) => {
130
+ return <StoryRender {...args} />;
131
+ },
132
+ };
133
+
134
+ export const LastStep: Story = {
135
+ args: {
136
+ startingStep: 'Labelers',
137
+ },
138
+ render: (args) => {
139
+ return <StoryRender {...args} />;
140
+ },
141
+ };
142
+
143
+ export const DisabledNextStep: Story = {
144
+ args: {
145
+ disableNextStep: true,
146
+ },
147
+ render: (args) => {
148
+ return <StoryRender {...args} />;
149
+ },
150
+ };
151
+
152
+ export const DisabledPreviousStep: Story = {
153
+ args: {
154
+ startingStep: 'Labels and Keywords',
155
+ disablePrevStep: true,
156
+ },
157
+ render: (args) => {
158
+ return <StoryRender {...args} />;
159
+ },
160
+ };
161
+
162
+ export const SubmitProcessing: Story = {
163
+ args: {
164
+ submitProcessing: 'Adding Teach Task',
165
+ startingStep: 'Labelers',
166
+ },
167
+ render: (args) => {
168
+ return <StoryRender {...args} />;
169
+ },
170
+ };
171
+
172
+ export const LastStepOverride: Story = {
173
+ args: {
174
+ startingStep: 'Labelers',
175
+ isLastStep: false,
176
+ },
177
+ render: (args) => {
178
+ return <StoryRender {...args} />;
179
+ },
180
+ };
@@ -0,0 +1,72 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { COLORS, TYPOGRAPHY } from '@/tokens';
4
+
5
+ export const StyledWizard = styled.div`
6
+ nav {
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: space-between;
10
+
11
+ margin-bottom: 24px;
12
+
13
+ // override for some styling in AppChrome IPA component
14
+ padding-left: 0 !important;
15
+ padding-right: 0 !important;
16
+ }
17
+
18
+ h1 {
19
+ margin-bottom: 0;
20
+ }
21
+
22
+ .wizard-buttons {
23
+ display: flex;
24
+ align-items: center;
25
+
26
+ font-size: ${TYPOGRAPHY.fontSize.subheadLarge};
27
+
28
+ button.link-style {
29
+ font-size: inherit;
30
+ margin-right: 1em;
31
+ }
32
+ }
33
+ `;
34
+
35
+ const commonPadding = '20px';
36
+
37
+ // todo: permafrost: move into css fragment at top level
38
+ export const WizardCard = styled.div`
39
+ width: 100%;
40
+ padding: 14px ${commonPadding};
41
+
42
+ background-color: ${COLORS.clay};
43
+ border: 1px solid ${COLORS.oxfordBlue};
44
+ border-radius: 4px;
45
+ box-shadow: 1px 1px 1px 0 ${COLORS.ebony};
46
+ `;
47
+
48
+ export const WizardSection = styled.div`
49
+ .section-heading {
50
+ margin-bottom: 0;
51
+ // todo: store value elsewhere
52
+ font-size: 22px;
53
+ color: ${COLORS.lightFontColor};
54
+
55
+ .supporting-text {
56
+ font-size: ${TYPOGRAPHY.fontSize.subheadLarge};
57
+ color: ${COLORS.defaultFontColor};
58
+ }
59
+ }
60
+
61
+ .section-content {
62
+ padding: ${commonPadding};
63
+ }
64
+
65
+ :not(:last-of-type) {
66
+ margin-bottom: ${commonPadding};
67
+
68
+ .section-content {
69
+ border-bottom: 1px solid ${COLORS.ebony};
70
+ }
71
+ }
72
+ `;