uikit-react-public 0.30.1 → 0.32.3

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 (49) hide show
  1. package/dist/components/Heading/Heading.stories.d.ts +5 -7
  2. package/dist/components/MenuNew/Menu.context.d.ts +9 -0
  3. package/dist/components/MenuNew/Menu.d.ts +2 -1
  4. package/dist/components/MenuNew/MenuHeading.d.ts +1 -1
  5. package/dist/components/MenuNew/MenuItemText.d.ts +2 -1
  6. package/dist/components/MenuNew/PrimaryMenuItem.d.ts +1 -1
  7. package/dist/components/Select/Select.types.d.ts +1 -1
  8. package/dist/components/Sidebar/Sidebar.d.ts +12 -0
  9. package/dist/components/Sidebar/Sidebar.stories.d.ts +38 -0
  10. package/dist/components/Sidebar/__tests__/Sidebar.test.d.ts +1 -0
  11. package/dist/components/Sidebar/index.d.ts +2 -0
  12. package/dist/components/Snackbar/Snackbar.d.ts +9 -5
  13. package/dist/components/Snackbar/Snackbar.stories.d.ts +2 -1
  14. package/dist/components/Snackbar/Snackbars.d.ts +19 -0
  15. package/dist/components/Snackbar/Snackbars.stories.d.ts +52 -0
  16. package/dist/components/Snackbar/__tests__/Snackbars.test.d.ts +1 -0
  17. package/dist/components/Snackbar/index.d.ts +2 -0
  18. package/dist/components/index.d.ts +4 -1
  19. package/dist/index.js +5740 -5217
  20. package/lib/components/Dropdown/Dropdown.stories.tsx +69 -74
  21. package/lib/components/Heading/Documentation.mdx +4 -14
  22. package/lib/components/Heading/Heading.stories.tsx +16 -30
  23. package/lib/components/MenuNew/Menu.context.tsx +18 -0
  24. package/lib/components/MenuNew/Menu.tsx +14 -9
  25. package/lib/components/MenuNew/MenuDivider.tsx +12 -1
  26. package/lib/components/MenuNew/MenuHeading.tsx +6 -0
  27. package/lib/components/MenuNew/MenuItemText.tsx +27 -3
  28. package/lib/components/MenuNew/MenuSection.tsx +11 -0
  29. package/lib/components/MenuNew/PrimaryMenuItem.tsx +71 -2
  30. package/lib/components/Select/Select.types.ts +1 -7
  31. package/lib/components/Select/__tests__/Select.test.tsx +112 -0
  32. package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +5 -0
  33. package/lib/components/Select/subcomponents/CustomSelect.tsx +75 -3
  34. package/lib/components/Select/subcomponents/FilterInput.tsx +1 -1
  35. package/lib/components/Sidebar/Sidebar.stories.tsx +94 -0
  36. package/lib/components/Sidebar/Sidebar.tsx +208 -0
  37. package/lib/components/Sidebar/__tests__/Sidebar.test.tsx +96 -0
  38. package/lib/components/Sidebar/__tests__/__snapshots__/Sidebar.test.tsx.snap +272 -0
  39. package/lib/components/Sidebar/index.ts +2 -0
  40. package/lib/components/Snackbar/Snackbar.stories.tsx +11 -0
  41. package/lib/components/Snackbar/Snackbar.tsx +162 -118
  42. package/lib/components/Snackbar/Snackbars.stories.tsx +130 -0
  43. package/lib/components/Snackbar/Snackbars.tsx +377 -0
  44. package/lib/components/Snackbar/__tests__/Snackbar.test.tsx +104 -0
  45. package/lib/components/Snackbar/__tests__/Snackbars.test.tsx +377 -0
  46. package/lib/components/Snackbar/__tests__/__snapshots__/Snackbar.test.tsx.snap +36 -19
  47. package/lib/components/Snackbar/index.ts +6 -0
  48. package/lib/components/index.ts +10 -1
  49. package/package.json +1 -1
@@ -0,0 +1,272 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Sidebar > snapshot: defaultCollapsed prop true 1`] = `
4
+ <aside
5
+ class="ucl-uikit-sidebar css-1r5qfp0"
6
+ data-collapsed="true"
7
+ data-testid="ucl-uikit-sidebar"
8
+ >
9
+ <nav
10
+ class="css-17d0xaj"
11
+ data-testid="ucl-uikit-menu"
12
+ id="_r_1_"
13
+ role="menu"
14
+ >
15
+ <section
16
+ class="ucl-uikit-menu__section css-1lqjxmd"
17
+ data-testid="ucl-uikit-menu__section"
18
+ >
19
+ <div
20
+ aria-current="page"
21
+ class="ucl-uikit-menu__primary-item css-q3xv9x"
22
+ role="button"
23
+ tabindex="0"
24
+ >
25
+ <svg
26
+ class="ucl-uikit-icon css-148hpxb"
27
+ data-testid="ucl-uikit-icon"
28
+ fill="none"
29
+ focusable="false"
30
+ height="24"
31
+ stroke="currentColor"
32
+ stroke-linecap="round"
33
+ stroke-linejoin="round"
34
+ stroke-width="2"
35
+ viewBox="0 0 24 24"
36
+ width="24"
37
+ xmlns="http://www.w3.org/2000/svg"
38
+ >
39
+ <path
40
+ d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
41
+ />
42
+ <path
43
+ d="M9 22V12h6v10"
44
+ />
45
+ </svg>
46
+ <span
47
+ class="css-fsjij5"
48
+ >
49
+ <span
50
+ class="ucl-uikit-text ucl-uikit-menu__item-text css-1p0ghou"
51
+ data-testid="ucl-uikit-text"
52
+ >
53
+ Home
54
+ </span>
55
+ </span>
56
+ </div>
57
+ <div
58
+ class="ucl-uikit-menu__primary-item css-1ukjxb7"
59
+ role="button"
60
+ tabindex="0"
61
+ >
62
+ <svg
63
+ class="ucl-uikit-icon css-148hpxb"
64
+ data-testid="ucl-uikit-icon"
65
+ fill="none"
66
+ focusable="false"
67
+ height="24"
68
+ stroke="currentColor"
69
+ stroke-linecap="round"
70
+ stroke-linejoin="round"
71
+ stroke-width="2"
72
+ viewBox="0 0 24 24"
73
+ width="24"
74
+ xmlns="http://www.w3.org/2000/svg"
75
+ >
76
+ <circle
77
+ cx="11"
78
+ cy="11"
79
+ r="8"
80
+ />
81
+ <path
82
+ d="m21 21-4.35-4.35"
83
+ />
84
+ </svg>
85
+ <span
86
+ class="css-fsjij5"
87
+ >
88
+ <span
89
+ class="ucl-uikit-text ucl-uikit-menu__item-text css-1p0ghou"
90
+ data-testid="ucl-uikit-text"
91
+ >
92
+ Search
93
+ </span>
94
+ </span>
95
+ </div>
96
+ </section>
97
+ </nav>
98
+ <div
99
+ class="css-1uv1uf"
100
+ >
101
+ <button
102
+ aria-controls="_r_1_"
103
+ aria-expanded="false"
104
+ aria-label="Expand sidebar"
105
+ class="ucl-uikit-icon-button css-hfinxr"
106
+ data-testid="ucl-uikit-icon-button"
107
+ type="button"
108
+ >
109
+ <svg
110
+ aria-hidden="true"
111
+ class="ucl-uikit-icon css-148hpxb"
112
+ data-testid="ucl-uikit-icon"
113
+ fill="none"
114
+ focusable="false"
115
+ height="20"
116
+ stroke="currentColor"
117
+ stroke-linecap="round"
118
+ stroke-linejoin="round"
119
+ stroke-width="2"
120
+ viewBox="0 0 24 24"
121
+ width="20"
122
+ xmlns="http://www.w3.org/2000/svg"
123
+ >
124
+ <path
125
+ d="m13 17 5-5-5-5M6 17l5-5-5-5"
126
+ />
127
+ </svg>
128
+ </button>
129
+ </div>
130
+ </aside>
131
+ `;
132
+
133
+ exports[`Sidebar > snapshot: no props 1`] = `
134
+ <aside
135
+ class="ucl-uikit-sidebar css-syj6vq"
136
+ data-collapsed="false"
137
+ data-testid="ucl-uikit-sidebar"
138
+ >
139
+ <nav
140
+ class="css-1ca5xb9"
141
+ data-testid="ucl-uikit-menu"
142
+ id="_r_0_"
143
+ role="menu"
144
+ >
145
+ <section
146
+ class="ucl-uikit-menu__section css-4ikjcu"
147
+ data-testid="ucl-uikit-menu__section"
148
+ >
149
+ <div
150
+ class="ucl-uikit-menu__heading css-zvrw4a"
151
+ data-testid="ucl-uikit-menu__heading"
152
+ >
153
+ <h3
154
+ class="ucl-uikit-heading css-d6quz8"
155
+ data-testid="ucl-uikit-heading"
156
+ >
157
+ Application
158
+ </h3>
159
+ </div>
160
+ <div
161
+ aria-current="page"
162
+ class="ucl-uikit-menu__primary-item css-18nh1y3"
163
+ role="button"
164
+ tabindex="0"
165
+ >
166
+ <svg
167
+ class="ucl-uikit-icon css-148hpxb"
168
+ data-testid="ucl-uikit-icon"
169
+ fill="none"
170
+ focusable="false"
171
+ height="24"
172
+ stroke="currentColor"
173
+ stroke-linecap="round"
174
+ stroke-linejoin="round"
175
+ stroke-width="2"
176
+ viewBox="0 0 24 24"
177
+ width="24"
178
+ xmlns="http://www.w3.org/2000/svg"
179
+ >
180
+ <path
181
+ d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
182
+ />
183
+ <path
184
+ d="M9 22V12h6v10"
185
+ />
186
+ </svg>
187
+ <span
188
+ class="css-fsjij5"
189
+ >
190
+ <span
191
+ class="ucl-uikit-text ucl-uikit-menu__item-text css-9z56wx"
192
+ data-testid="ucl-uikit-text"
193
+ >
194
+ Home
195
+ </span>
196
+ </span>
197
+ </div>
198
+ <div
199
+ class="ucl-uikit-menu__primary-item css-1o5khet"
200
+ role="button"
201
+ tabindex="0"
202
+ >
203
+ <svg
204
+ class="ucl-uikit-icon css-148hpxb"
205
+ data-testid="ucl-uikit-icon"
206
+ fill="none"
207
+ focusable="false"
208
+ height="24"
209
+ stroke="currentColor"
210
+ stroke-linecap="round"
211
+ stroke-linejoin="round"
212
+ stroke-width="2"
213
+ viewBox="0 0 24 24"
214
+ width="24"
215
+ xmlns="http://www.w3.org/2000/svg"
216
+ >
217
+ <circle
218
+ cx="11"
219
+ cy="11"
220
+ r="8"
221
+ />
222
+ <path
223
+ d="m21 21-4.35-4.35"
224
+ />
225
+ </svg>
226
+ <span
227
+ class="css-fsjij5"
228
+ >
229
+ <span
230
+ class="ucl-uikit-text ucl-uikit-menu__item-text css-9z56wx"
231
+ data-testid="ucl-uikit-text"
232
+ >
233
+ Search
234
+ </span>
235
+ </span>
236
+ </div>
237
+ </section>
238
+ </nav>
239
+ <div
240
+ class="css-vzvd2u"
241
+ >
242
+ <button
243
+ aria-controls="_r_0_"
244
+ aria-expanded="true"
245
+ aria-label="Collapse sidebar"
246
+ class="ucl-uikit-icon-button css-hfinxr"
247
+ data-testid="ucl-uikit-icon-button"
248
+ type="button"
249
+ >
250
+ <svg
251
+ aria-hidden="true"
252
+ class="ucl-uikit-icon css-148hpxb"
253
+ data-testid="ucl-uikit-icon"
254
+ fill="none"
255
+ focusable="false"
256
+ height="20"
257
+ stroke="currentColor"
258
+ stroke-linecap="round"
259
+ stroke-linejoin="round"
260
+ stroke-width="2"
261
+ viewBox="0 0 24 24"
262
+ width="20"
263
+ xmlns="http://www.w3.org/2000/svg"
264
+ >
265
+ <path
266
+ d="m11 17-5-5 5-5m7 10-5-5 5-5"
267
+ />
268
+ </svg>
269
+ </button>
270
+ </div>
271
+ </aside>
272
+ `;
@@ -0,0 +1,2 @@
1
+ export { default } from './Sidebar';
2
+ export type { SidebarProps } from './Sidebar';
@@ -38,6 +38,17 @@ export const Undo: Story = {
38
38
  },
39
39
  };
40
40
 
41
+ export const Error: Story = {
42
+ name: 'Variant: Error',
43
+ args: {
44
+ action: 'close',
45
+ children: 'This is an error snackbar',
46
+ size: 'small',
47
+ variant: 'error',
48
+ onClose: () => alert('Close action triggered'),
49
+ },
50
+ };
51
+
41
52
  export const LongText: Story = {
42
53
  name: 'With long text',
43
54
  args: {
@@ -1,136 +1,180 @@
1
- import { memo, forwardRef, OutputHTMLAttributes } from 'react';
1
+ import { memo, HTMLAttributes, Ref } from 'react';
2
2
  import { css, cx } from '@emotion/css';
3
3
  import useTheme from '../../theme/useTheme';
4
- import { IconButton, Icon } from '..';
4
+ import { IconButton, Icon, Text } from '..';
5
5
  import marginsStyle, { MarginProps } from '../common/marginsStyle';
6
6
 
7
7
  export const NAME = 'ucl-uikit-snackbar';
8
8
 
9
- export interface SnackbarBaseProps
10
- extends OutputHTMLAttributes<HTMLOutputElement> {
11
- action: 'close' | 'undo';
9
+ export interface SnackbarBaseProps extends HTMLAttributes<HTMLDivElement> {
10
+ action?: 'close' | 'undo';
11
+ actionDisabled?: boolean;
12
+ closeButtonAriaLabel?: string;
12
13
  onClose?: () => void;
13
14
  onUndo?: () => void;
15
+ size?: 'small' | 'large';
14
16
  testId?: string;
17
+ variant?: 'default' | 'error';
18
+ ref?: Ref<HTMLDivElement>;
15
19
  }
16
20
 
17
21
  export type SnackbarProps = SnackbarBaseProps & MarginProps;
18
22
 
19
- export type Ref = HTMLOutputElement;
20
-
21
- // Should this component be a <div> instead of an <output>?
22
- const Snackbar = forwardRef<Ref, SnackbarProps>(
23
- (
24
- {
25
- action = 'close',
26
- onClose,
27
- onUndo,
28
- children,
29
- testId = NAME,
30
- className,
31
- ...props
32
- },
33
- ref
34
- ) => {
35
- const [theme] = useTheme();
36
-
37
- const baseStyles = css`
38
- display: flex;
39
- justify-content: start;
40
- align-items: center;
41
- gap: 16px;
42
- box-sizing: border-box;
43
- position: fixed;
44
- width: 375px;
45
- height: ${theme.height.h80};
46
- z-index: 9999;
47
- padding-left: ${theme.padding.p24};
48
- padding-right: ${theme.padding.p24};
49
- color: ${theme.color.text.inverted};
50
- background-color: ${theme.color.neutral.grey90};
51
- font-size: ${theme.font.size.f16};
52
- font-family: ${theme.font.family.primary};
53
- font-weight: ${theme.font.weight.regular};
54
- line-height: ${theme.font.lineHeight.h140};
55
- `;
56
-
57
- const style = cx(NAME, baseStyles, marginsStyle(props, theme), className);
58
-
59
- const checkCircleIconStyle = css`
60
- min-width: 24px;
61
- min-height: 24px;
62
- `;
63
-
64
- const actionButtonStyle = css`
65
- margin-left: auto;
66
- `;
67
-
68
- const undoButtonStyle = css`
69
- padding: ${theme.padding.p4};
70
- border: none;
71
- background-color: transparent;
72
- color: ${theme.color.text.inverted};
73
- font-size: ${theme.font.size.f16};
74
- font-family: ${theme.font.family.primary};
75
- font-weight: 700;
76
- cursor: pointer;
77
-
78
- &:hover {
79
- color: ${theme.color.neutral.grey20}; // This is a guess
80
- }
81
-
82
- &:focus-visible {
83
- outline: none;
84
- box-shadow: ${theme.boxShadow.focus};
85
- }
86
- `;
87
-
88
- return (
89
- <output
90
- ref={ref}
91
- className={style}
92
- data-testid={testId}
93
- {...props}
23
+ const Snackbar = ({
24
+ action = 'close',
25
+ actionDisabled = false,
26
+ closeButtonAriaLabel = 'Dismiss notification',
27
+ onClose,
28
+ onUndo,
29
+ children,
30
+ size = 'large',
31
+ testId = NAME,
32
+ className,
33
+ variant = 'default',
34
+ ref,
35
+ ...props
36
+ }: SnackbarProps) => {
37
+ const [theme] = useTheme();
38
+ const IconComponent =
39
+ variant === 'error' ? Icon.AlertTriangle : Icon.CheckCircle;
40
+ const role = variant === 'error' ? 'alert' : 'status';
41
+ const iconSize = size === 'small' ? 20 : 32;
42
+ const padding = size === 'small' ? theme.padding.p16 : theme.padding.p24;
43
+ const textLevel = size === 'small' ? 'md' : 'lg-medium';
44
+ const minHeight = size === 'small' ? '56px' : theme.height.h80;
45
+
46
+ const baseStyles = css`
47
+ display: flex;
48
+ justify-content: start;
49
+ align-items: center;
50
+ gap: ${theme.margin.m8};
51
+ box-sizing: border-box;
52
+ position: fixed;
53
+ width: 375px;
54
+ max-width: calc(100vw - ${theme.margin.m48});
55
+ min-height: ${minHeight};
56
+ z-index: 9999;
57
+ padding: ${padding};
58
+ color: ${theme.colour.text.inverse};
59
+ background-color: ${
60
+ variant === 'error'
61
+ ? theme.primitiveColour.red['10'].$value.hex
62
+ : theme.colour.bg.inversePrimary
63
+ };
64
+ `;
65
+
66
+ const style = cx(NAME, baseStyles, marginsStyle(props, theme), className);
67
+
68
+ const iconStyle = css`
69
+ min-width: ${iconSize}px;
70
+ min-height: ${iconSize}px;
71
+ flex-shrink: 0;
72
+ `;
73
+
74
+ const messageStyle = css`
75
+ flex: 1;
76
+ min-width: 0;
77
+ color: inherit;
78
+ overflow-wrap: anywhere;
79
+ `;
80
+
81
+ const actionButtonStyle = css`
82
+ margin-left: auto;
83
+ flex-shrink: 0;
84
+ `;
85
+
86
+ const closeButtonStyle = css`
87
+ &:hover {
88
+ color: ${theme.colour.icon.inverseHover};
89
+ }
90
+ `;
91
+
92
+ const undoButtonStyle = css`
93
+ padding: ${theme.padding.p4};
94
+ border: none;
95
+ background-color: transparent;
96
+ color: ${theme.colour.text.inverse};
97
+ cursor: pointer;
98
+
99
+ &:hover {
100
+ color: ${theme.colour.icon.inverseHover};
101
+ }
102
+
103
+ &:focus-visible {
104
+ outline: none;
105
+ box-shadow: ${theme.boxShadow.focus};
106
+ }
107
+ `;
108
+
109
+ const undoButtonTextStyle = css`
110
+ color: inherit;
111
+ `;
112
+
113
+ return (
114
+ <div
115
+ ref={ref}
116
+ className={style}
117
+ data-testid={testId}
118
+ {...props}
119
+ >
120
+ <IconComponent
121
+ aria-hidden='true'
122
+ className={iconStyle}
123
+ size={iconSize}
124
+ />
125
+
126
+ <Text
127
+ level={textLevel}
128
+ className={messageStyle}
129
+ role={role}
94
130
  >
95
- <Icon.CheckCircle className={checkCircleIconStyle} />
96
-
97
- <span>{children}</span>
98
-
99
- <span className={actionButtonStyle}>
100
- {action === 'close' && (
101
- <IconButton
102
- onClick={
103
- onClose ??
104
- (() =>
105
- console.warn(
106
- '<Snackbar> close action triggered but unassigned'
107
- ))
108
- }
109
- data-testid={`${testId}-close-button`}
110
- >
111
- <Icon.X size={24} />
112
- </IconButton>
113
- )}
114
-
115
- {action === 'undo' && (
116
- <button
117
- onClick={
118
- onUndo ??
119
- (() =>
120
- console.warn(
121
- '<Snackbar> undo action triggered but unassigned'
122
- ))
123
- }
124
- className={undoButtonStyle}
125
- data-testid={`${testId}-undo-button`}
131
+ {children}
132
+ </Text>
133
+
134
+ <span className={actionButtonStyle}>
135
+ {action === 'close' && (
136
+ <IconButton
137
+ aria-label={closeButtonAriaLabel}
138
+ onClick={
139
+ onClose ??
140
+ (() =>
141
+ console.warn(
142
+ '<Snackbar> close action triggered but unassigned'
143
+ ))
144
+ }
145
+ data-testid={`${testId}-close-button`}
146
+ className={closeButtonStyle}
147
+ disabled={actionDisabled}
148
+ >
149
+ <Icon.X
150
+ aria-hidden='true'
151
+ size={24}
152
+ />
153
+ </IconButton>
154
+ )}
155
+
156
+ {action === 'undo' && (
157
+ <button
158
+ onClick={
159
+ onUndo ??
160
+ (() =>
161
+ console.warn('<Snackbar> undo action triggered but unassigned'))
162
+ }
163
+ className={undoButtonStyle}
164
+ data-testid={`${testId}-undo-button`}
165
+ disabled={actionDisabled}
166
+ >
167
+ <Text
168
+ level='lg-semibold'
169
+ className={undoButtonTextStyle}
126
170
  >
127
171
  UNDO
128
- </button>
129
- )}
130
- </span>
131
- </output>
132
- );
133
- }
134
- );
172
+ </Text>
173
+ </button>
174
+ )}
175
+ </span>
176
+ </div>
177
+ );
178
+ };
135
179
 
136
180
  export default memo(Snackbar);