@ultraviolet/ui 1.0.0

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 (115) hide show
  1. package/LICENSE +189 -0
  2. package/README.md +64 -0
  3. package/dist/index.d.ts +2427 -0
  4. package/dist/react-datepicker/dist/react-datepicker.min.css.js +3 -0
  5. package/dist/react-toastify/dist/ReactToastify.min.css.js +3 -0
  6. package/dist/src/components/ActionBar/index.js +55 -0
  7. package/dist/src/components/Alert/index.js +144 -0
  8. package/dist/src/components/Avatar/index.js +90 -0
  9. package/dist/src/components/Badge/index.js +143 -0
  10. package/dist/src/components/Banner/index.js +117 -0
  11. package/dist/src/components/BarChart/Tooltip.js +63 -0
  12. package/dist/src/components/BarChart/index.js +94 -0
  13. package/dist/src/components/BarStack/index.js +223 -0
  14. package/dist/src/components/Breadcrumbs/index.js +89 -0
  15. package/dist/src/components/Bullet/index.js +137 -0
  16. package/dist/src/components/Button/index.js +303 -0
  17. package/dist/src/components/Card/index.js +81 -0
  18. package/dist/src/components/Carousel/index.js +162 -0
  19. package/dist/src/components/Checkbox/index.js +338 -0
  20. package/dist/src/components/CopyButton/index.js +92 -0
  21. package/dist/src/components/DateInput/index.js +250 -0
  22. package/dist/src/components/EmptyState/index.js +124 -0
  23. package/dist/src/components/Expandable/index.js +84 -0
  24. package/dist/src/components/Icon/index.js +350 -0
  25. package/dist/src/components/LineChart/CustomLegend.js +147 -0
  26. package/dist/src/components/LineChart/Tooltip.js +58 -0
  27. package/dist/src/components/LineChart/helpers.js +75 -0
  28. package/dist/src/components/LineChart/index.js +139 -0
  29. package/dist/src/components/Link/index.js +159 -0
  30. package/dist/src/components/List/Body.js +22 -0
  31. package/dist/src/components/List/Cell.js +38 -0
  32. package/dist/src/components/List/HeaderCell.js +118 -0
  33. package/dist/src/components/List/HeaderRow.js +47 -0
  34. package/dist/src/components/List/ListContext.js +120 -0
  35. package/dist/src/components/List/Row.js +211 -0
  36. package/dist/src/components/List/SelectBar.js +52 -0
  37. package/dist/src/components/List/SkeletonRows.js +54 -0
  38. package/dist/src/components/List/constants.js +3 -0
  39. package/dist/src/components/List/index.js +77 -0
  40. package/dist/src/components/Loader/index.js +87 -0
  41. package/dist/src/components/Menu/Item.js +122 -0
  42. package/dist/src/components/Menu/index.js +143 -0
  43. package/dist/src/components/Modal/index.js +279 -0
  44. package/dist/src/components/Notice/index.js +33 -0
  45. package/dist/src/components/NumberInput/helpers.js +6 -0
  46. package/dist/src/components/NumberInput/index.js +366 -0
  47. package/dist/src/components/Pagination/getPageNumbers.js +32 -0
  48. package/dist/src/components/Pagination/index.js +118 -0
  49. package/dist/src/components/PasswordCheck/index.js +42 -0
  50. package/dist/src/components/PasswordStrengthMeter/index.js +116 -0
  51. package/dist/src/components/PieChart/Legends.js +183 -0
  52. package/dist/src/components/PieChart/Tooltip.js +64 -0
  53. package/dist/src/components/PieChart/index.js +133 -0
  54. package/dist/src/components/PieChart/patterns.js +9 -0
  55. package/dist/src/components/Popover/index.js +131 -0
  56. package/dist/src/components/ProgressBar/index.js +72 -0
  57. package/dist/src/components/Radio/index.js +231 -0
  58. package/dist/src/components/Row/index.js +43 -0
  59. package/dist/src/components/SelectInput/index.js +662 -0
  60. package/dist/src/components/SelectableCard/index.js +154 -0
  61. package/dist/src/components/Separator/index.js +91 -0
  62. package/dist/src/components/Skeleton/Block.js +53 -0
  63. package/dist/src/components/Skeleton/Blocks.js +52 -0
  64. package/dist/src/components/Skeleton/BoxWithIcon.js +47 -0
  65. package/dist/src/components/Skeleton/Donut.js +58 -0
  66. package/dist/src/components/Skeleton/IconSkeleton.js +37 -0
  67. package/dist/src/components/Skeleton/Line.js +19 -0
  68. package/dist/src/components/Skeleton/List.js +60 -0
  69. package/dist/src/components/Skeleton/Slider.js +57 -0
  70. package/dist/src/components/Skeleton/index.js +85 -0
  71. package/dist/src/components/Snippet/index.js +250 -0
  72. package/dist/src/components/Stack/index.js +24 -0
  73. package/dist/src/components/Status/index.js +101 -0
  74. package/dist/src/components/StepList/index.js +81 -0
  75. package/dist/src/components/Stepper/index.js +217 -0
  76. package/dist/src/components/SwitchButton/FocusOverlay.js +47 -0
  77. package/dist/src/components/SwitchButton/index.js +131 -0
  78. package/dist/src/components/Table/Body.js +12 -0
  79. package/dist/src/components/Table/Cell.js +27 -0
  80. package/dist/src/components/Table/Header.js +21 -0
  81. package/dist/src/components/Table/HeaderCell.js +119 -0
  82. package/dist/src/components/Table/HeaderRow.js +35 -0
  83. package/dist/src/components/Table/Row.js +70 -0
  84. package/dist/src/components/Table/SelectBar.js +52 -0
  85. package/dist/src/components/Table/SkeletonRows.js +52 -0
  86. package/dist/src/components/Table/TableContext.js +91 -0
  87. package/dist/src/components/Table/index.js +84 -0
  88. package/dist/src/components/Tabs/Tab.js +165 -0
  89. package/dist/src/components/Tabs/TabMenu.js +46 -0
  90. package/dist/src/components/Tabs/TabMenuItem.js +40 -0
  91. package/dist/src/components/Tabs/TabsContext.js +6 -0
  92. package/dist/src/components/Tabs/index.js +117 -0
  93. package/dist/src/components/Tag/index.js +177 -0
  94. package/dist/src/components/TagInput/index.js +277 -0
  95. package/dist/src/components/TagList/index.js +110 -0
  96. package/dist/src/components/Text/index.js +106 -0
  97. package/dist/src/components/TextInput/index.js +529 -0
  98. package/dist/src/components/TimeInput/index.js +38 -0
  99. package/dist/src/components/Toaster/index.js +116 -0
  100. package/dist/src/components/Toggle/index.js +192 -0
  101. package/dist/src/components/Tooltip/helpers.js +131 -0
  102. package/dist/src/components/Tooltip/index.js +275 -0
  103. package/dist/src/components/VerificationCode/index.js +203 -0
  104. package/dist/src/helpers/isJSON.js +11 -0
  105. package/dist/src/helpers/legend.js +13 -0
  106. package/dist/src/helpers/recursivelyGetChildrenString.js +12 -0
  107. package/dist/src/index.js +63 -0
  108. package/dist/src/theme/index.js +25 -0
  109. package/dist/src/utils/animations.js +250 -0
  110. package/dist/src/utils/capitalize.js +4 -0
  111. package/dist/src/utils/ids.js +12 -0
  112. package/dist/src/utils/normalize.js +36 -0
  113. package/dist/src/utils/responsive/Breakpoint.js +12 -0
  114. package/dist/src/utils/responsive/utilities.js +12 -0
  115. package/package.json +70 -0
@@ -0,0 +1,366 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useRef, useId, useState, useMemo } from 'react';
3
+ import { Button } from '../Button/index.js';
4
+ import { Icon } from '../Icon/index.js';
5
+ import { Stack } from '../Stack/index.js';
6
+ import { Text } from '../Text/index.js';
7
+ import { Tooltip } from '../Tooltip/index.js';
8
+ import { getMinusRoundedValue, getPlusRoundedValue, roundStep, bounded } from './helpers.js';
9
+ import { jsxs, jsx } from '@emotion/react/jsx-runtime';
10
+
11
+ const containerSizes = {
12
+ large: 48,
13
+ medium: 40,
14
+ small: 32
15
+ };
16
+ const iconSizes = {
17
+ large: 26,
18
+ medium: 24,
19
+ small: 22
20
+ };
21
+ const BASE_INPUT_WIDTH = 34;
22
+ const StyledSelectButton = /*#__PURE__*/_styled(Button, {
23
+ target: "exvap484"
24
+ })("margin:0 ", _ref => {
25
+ let {
26
+ theme
27
+ } = _ref;
28
+ return theme.space['1'];
29
+ }, ";width:32px;height:32px;");
30
+ const StyledCenterBox = /*#__PURE__*/_styled('div', {
31
+ shouldForwardProp: prop => !['size'].includes(prop),
32
+ target: "exvap483"
33
+ })("display:flex;flex:1;flex-direction:row;height:", _ref2 => {
34
+ let {
35
+ size
36
+ } = _ref2;
37
+ return size === 'small' ? '24px' : '32px';
38
+ }, ";align-items:center;outline:none;justify-content:center;border-radius:", _ref3 => {
39
+ let {
40
+ theme
41
+ } = _ref3;
42
+ return theme.radii.default;
43
+ }, ";border:1px solid transparent;max-width:100%;");
44
+ const StyledInput = /*#__PURE__*/_styled("input", {
45
+ target: "exvap482"
46
+ })("color:", _ref4 => {
47
+ let {
48
+ theme
49
+ } = _ref4;
50
+ return theme.colors.neutral.text;
51
+ }, ";background-color:transparent;font-size:", _ref5 => {
52
+ let {
53
+ theme
54
+ } = _ref5;
55
+ return theme.typography.bodyStrong.fontSize;
56
+ }, ";border:none;outline:none;position:relative;margin-right:", _ref6 => {
57
+ let {
58
+ theme
59
+ } = _ref6;
60
+ return theme.space['0.5'];
61
+ }, ";max-width:100%;font-weight:", _ref7 => {
62
+ let {
63
+ theme
64
+ } = _ref7;
65
+ return theme.typography.bodyStrong.weight;
66
+ }, ";text-align:center;&::-webkit-outer-spin-button,&::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}::placeholder{color:", _ref8 => {
67
+ let {
68
+ theme
69
+ } = _ref8;
70
+ return theme.colors.neutral.textWeak;
71
+ }, ";}-moz-appearance:textfield;&[disabled]{color:", _ref9 => {
72
+ let {
73
+ theme
74
+ } = _ref9;
75
+ return theme.colors.neutral.textDisabled;
76
+ }, ";cursor:not-allowed;}");
77
+ const StyledText = /*#__PURE__*/_styled('span', {
78
+ shouldForwardProp: prop => !['disabled'].includes(prop),
79
+ target: "exvap481"
80
+ })("color:", _ref10 => {
81
+ let {
82
+ theme,
83
+ disabled
84
+ } = _ref10;
85
+ return disabled ? theme.colors.neutral.textDisabled : theme.colors.neutral.text;
86
+ }, ";user-select:none;margin-right:", _ref11 => {
87
+ let {
88
+ theme
89
+ } = _ref11;
90
+ return theme.space['1'];
91
+ }, ";");
92
+ const StyledContainer = /*#__PURE__*/_styled('div', {
93
+ shouldForwardProp: prop => !['size'].includes(prop),
94
+ target: "exvap480"
95
+ })("background-color:", _ref12 => {
96
+ let {
97
+ theme
98
+ } = _ref12;
99
+ return theme.colors.neutral.backgroundWeak;
100
+ }, ";display:flex;flex-direction:row;align-items:center;align-self:stretch;font-weight:500;height:", _ref13 => {
101
+ let {
102
+ size
103
+ } = _ref13;
104
+ return containerSizes[size];
105
+ }, "px;border:1px solid ", _ref14 => {
106
+ let {
107
+ theme
108
+ } = _ref14;
109
+ return theme.colors.neutral.borderWeak;
110
+ }, ";border-radius:", _ref15 => {
111
+ let {
112
+ theme
113
+ } = _ref15;
114
+ return theme.radii.default;
115
+ }, ";&[data-error='true']{border:1px solid ", _ref16 => {
116
+ let {
117
+ theme
118
+ } = _ref16;
119
+ return theme.colors.danger.borderWeak;
120
+ }, ";}&[aria-disabled='true']{background:", _ref17 => {
121
+ let {
122
+ theme
123
+ } = _ref17;
124
+ return theme.colors.neutral.backgroundDisabled;
125
+ }, ";cursor:not-allowed;}&:not([aria-disabled='true']){", StyledCenterBox, ":hover,", StyledCenterBox, ":focus{border:1px solid ", _ref18 => {
126
+ let {
127
+ theme
128
+ } = _ref18;
129
+ return theme.colors.primary.borderWeakHover;
130
+ }, ";}", StyledCenterBox, ":focus-within{box-shadow:", _ref19 => {
131
+ let {
132
+ theme
133
+ } = _ref19;
134
+ return theme.shadows.focusPrimary;
135
+ }, ";border:1px solid ", _ref20 => {
136
+ let {
137
+ theme
138
+ } = _ref20;
139
+ return theme.colors.primary.borderWeakHover;
140
+ }, ";}}");
141
+ const NumberInput = _ref21 => {
142
+ let {
143
+ disabled = false,
144
+ maxValue,
145
+ minValue = 0,
146
+ name = 'numberinput',
147
+ onChange,
148
+ onFocus,
149
+ onBlur,
150
+ onMaxCrossed,
151
+ onMinCrossed,
152
+ size = 'large',
153
+ step = 1,
154
+ text,
155
+ defaultValue,
156
+ value,
157
+ disabledTooltip,
158
+ className,
159
+ label,
160
+ id,
161
+ placeholder,
162
+ error,
163
+ 'aria-label': ariaLabel,
164
+ 'aria-describedby': ariaDescribedBy,
165
+ 'data-testid': dataTestId
166
+ } = _ref21;
167
+ const inputRef = useRef();
168
+ const uniqueId = useId();
169
+
170
+ // local state used if component is not controlled (no value prop provided)
171
+ const [inputValue, setInputValue] = useState(() => {
172
+ if (defaultValue && minValue && defaultValue < minValue) {
173
+ return minValue;
174
+ }
175
+ if (defaultValue && maxValue && defaultValue > maxValue) {
176
+ return maxValue;
177
+ }
178
+ return defaultValue;
179
+ });
180
+ const currentValue = value !== undefined ? value : inputValue;
181
+ const setValue = function (newValue,
182
+ /**
183
+ * If true, will check if newValue is between minValue and maxValue and set it to minValue or maxValue if it's not.
184
+ */
185
+ hasMinMaxVerification) {
186
+ if (hasMinMaxVerification === void 0) {
187
+ hasMinMaxVerification = true;
188
+ }
189
+ if (value === undefined) {
190
+ if (hasMinMaxVerification) {
191
+ if (newValue !== undefined && newValue < minValue) {
192
+ setInputValue(minValue);
193
+ return;
194
+ }
195
+ if (newValue !== undefined && maxValue !== undefined && newValue > maxValue) {
196
+ setInputValue(maxValue);
197
+ return;
198
+ }
199
+ }
200
+ setInputValue(newValue);
201
+ }
202
+ onChange?.(newValue);
203
+ };
204
+ const offsetFn = direction => () => {
205
+ const localValue = currentValue ?? 0;
206
+ const newValue = localValue % step === 0 ? localValue + step * direction : localValue;
207
+ const roundedValue = roundStep(newValue, step, direction);
208
+ setValue(roundedValue);
209
+ };
210
+ const handleChange = event => {
211
+ setValue(event.currentTarget.value ? Number(event.currentTarget.value) : undefined, false);
212
+ };
213
+ const handleOnFocus = event => {
214
+ if (onFocus) onFocus(event);
215
+ };
216
+ const handleOnBlur = event => {
217
+ if (currentValue) {
218
+ const boundedValue = bounded(currentValue, minValue ?? currentValue, maxValue ?? currentValue);
219
+ if (maxValue && currentValue > maxValue) onMaxCrossed?.();
220
+ if (minValue && currentValue < minValue) onMinCrossed?.();
221
+ setValue(boundedValue);
222
+ onBlur?.(event);
223
+ }
224
+ };
225
+ const onKeyDown = event => {
226
+ if (event.key === 'ArrowUp') {
227
+ event.stopPropagation();
228
+ event.preventDefault();
229
+ const direction = 1;
230
+ const localValue = currentValue ?? 0;
231
+ const newValue = localValue % step === 0 ? localValue + step * direction : localValue;
232
+ const roundedValue = roundStep(newValue, step, direction);
233
+ if (maxValue === undefined) {
234
+ setValue(roundedValue);
235
+ return;
236
+ }
237
+ setValue(Math.min(roundedValue, maxValue));
238
+ }
239
+ if (event.key === 'ArrowDown') {
240
+ event.stopPropagation();
241
+ event.preventDefault();
242
+ const direction = -1;
243
+ const localValue = currentValue ?? 0;
244
+ const newValue = localValue % step === 0 ? localValue + step * direction : localValue;
245
+ const roundedValue = roundStep(newValue, step, direction);
246
+ setValue(Math.max(roundedValue, minValue));
247
+ }
248
+ };
249
+ const isMinusDisabled = useMemo(() => {
250
+ if (disabled) return true;
251
+ if (currentValue === undefined) return false;
252
+ if (getMinusRoundedValue(currentValue, step) < minValue) {
253
+ return true;
254
+ }
255
+ return disabled;
256
+ }, [currentValue, disabled, minValue, step]);
257
+ const isPlusDisabled = useMemo(() => {
258
+ if (disabled) return true;
259
+ if (currentValue === undefined) return false;
260
+ if (maxValue && getPlusRoundedValue(currentValue, step) > maxValue) {
261
+ return true;
262
+ }
263
+ return disabled;
264
+ }, [currentValue, disabled, maxValue, step]);
265
+ const inputWidth = useMemo(() => {
266
+ if (placeholder && currentValue === undefined) {
267
+ return placeholder.length * 12;
268
+ }
269
+ if (currentValue !== undefined) {
270
+ return currentValue.toString().length * 16;
271
+ }
272
+ return BASE_INPUT_WIDTH;
273
+ }, [currentValue, placeholder]);
274
+ return jsxs(Stack, {
275
+ gap: 1,
276
+ children: [label ? jsx(Text, {
277
+ variant: "bodyStrong",
278
+ as: "label",
279
+ htmlFor: id || uniqueId,
280
+ children: label
281
+ }) : null, jsxs(Stack, {
282
+ gap: 0.5,
283
+ children: [jsxs(StyledContainer, {
284
+ "aria-disabled": disabled,
285
+ "data-error": !!error,
286
+ size: size,
287
+ className: className,
288
+ "data-testid": dataTestId,
289
+ children: [jsx(Tooltip, {
290
+ text: isMinusDisabled && disabledTooltip,
291
+ children: jsx(StyledSelectButton, {
292
+ onClick: offsetFn(-1),
293
+ disabled: isMinusDisabled,
294
+ "aria-label": "Minus",
295
+ type: "button",
296
+ variant: "ghost",
297
+ sentiment: "primary",
298
+ size: "small",
299
+ children: jsx(Icon, {
300
+ name: "minus",
301
+ size: iconSizes[size],
302
+ color: "primary",
303
+ disabled: isMinusDisabled
304
+ })
305
+ })
306
+ }), jsxs(StyledCenterBox, {
307
+ size: size,
308
+ onClick: () => {
309
+ if (inputRef?.current) {
310
+ inputRef.current.focus();
311
+ }
312
+ },
313
+ "aria-live": "assertive",
314
+ role: "status",
315
+ children: [jsx(StyledInput, {
316
+ disabled: disabled,
317
+ name: name,
318
+ onBlur: handleOnBlur,
319
+ onChange: handleChange,
320
+ onFocus: handleOnFocus,
321
+ onKeyDown: onKeyDown,
322
+ ref: inputRef,
323
+ style: {
324
+ width: inputWidth
325
+ },
326
+ value: currentValue !== undefined ? currentValue.toString() : undefined // A dom element can only have string attributes.
327
+ ,
328
+ type: "number",
329
+ id: id || uniqueId,
330
+ "aria-label": !label && !ariaLabel ? 'Number Input' : ariaLabel,
331
+ "aria-describedby": ariaDescribedBy,
332
+ placeholder: placeholder
333
+ }), currentValue !== undefined ? jsx(StyledText, {
334
+ disabled: disabled,
335
+ children: text
336
+ }) : null]
337
+ }), jsx(Tooltip, {
338
+ text: isPlusDisabled && disabledTooltip,
339
+ children: jsx(StyledSelectButton, {
340
+ onClick: offsetFn(1),
341
+ disabled: isPlusDisabled,
342
+ "aria-label": "Plus",
343
+ type: "button",
344
+ variant: "ghost",
345
+ sentiment: "primary",
346
+ size: "small",
347
+ children: jsx(Icon, {
348
+ name: "plus",
349
+ size: iconSizes[size],
350
+ color: "primary",
351
+ disabled: isPlusDisabled
352
+ })
353
+ })
354
+ })]
355
+ }), typeof error === 'string' ? jsx(Text, {
356
+ as: "span",
357
+ variant: "bodySmall",
358
+ color: "danger",
359
+ prominence: "weak",
360
+ children: error
361
+ }) : null]
362
+ })]
363
+ });
364
+ };
365
+
366
+ export { NumberInput };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Return a list of page numbers around the currentPage
3
+ * @param currentPage The current page
4
+ * @param pageCount The last page number
5
+ * @param range The number of pages wanted
6
+ * @returns List of page numbers around currentPage
7
+ */
8
+ const getPageNumbers = function (currentPage, pageCount, range) {
9
+ if (range === void 0) {
10
+ range = 5;
11
+ }
12
+ const gap = Math.floor(range / 2);
13
+ let end = currentPage + gap;
14
+ let remaining = 0;
15
+ if (end > pageCount) {
16
+ remaining = end - pageCount;
17
+ end = pageCount;
18
+ }
19
+ let start = currentPage - gap - remaining;
20
+ if (start < 1) {
21
+ remaining = Math.abs(start - 1);
22
+ start = 1;
23
+ }
24
+ if (end < pageCount) {
25
+ end = Math.min(end + remaining, pageCount);
26
+ }
27
+ return Array.from({
28
+ length: end - start + 1
29
+ }, (_, index) => start + index);
30
+ };
31
+
32
+ export { getPageNumbers };
@@ -0,0 +1,118 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useCallback, useMemo } from 'react';
3
+ import { Button } from '../Button/index.js';
4
+ import { getPageNumbers } from './getPageNumbers.js';
5
+ import { jsxs, jsx } from '@emotion/react/jsx-runtime';
6
+
7
+ function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
8
+ const PageNumbersContainer = /*#__PURE__*/_styled("div", {
9
+ target: "e5s692s2"
10
+ })("display:flex;gap:", _ref => {
11
+ let {
12
+ theme
13
+ } = _ref;
14
+ return theme.space['2'];
15
+ }, ";margin:0 ", _ref2 => {
16
+ let {
17
+ theme
18
+ } = _ref2;
19
+ return theme.space['2'];
20
+ }, ";");
21
+ const PageSwitchContainer = /*#__PURE__*/_styled("div", {
22
+ target: "e5s692s1"
23
+ })("display:flex;gap:", _ref3 => {
24
+ let {
25
+ theme
26
+ } = _ref3;
27
+ return theme.space['1'];
28
+ }, ";");
29
+ const StyledContainer = /*#__PURE__*/_styled("div", {
30
+ target: "e5s692s0"
31
+ })(process.env.NODE_ENV === "production" ? {
32
+ name: "zjik7",
33
+ styles: "display:flex"
34
+ } : {
35
+ name: "zjik7",
36
+ styles: "display:flex",
37
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
38
+ });
39
+ /**
40
+ * Display multiple buttons to allow navigation between a paginated resource
41
+ */
42
+ const Pagination = _ref4 => {
43
+ let {
44
+ disabled = false,
45
+ page,
46
+ pageCount,
47
+ onChange,
48
+ pageTabCount = 5,
49
+ className,
50
+ 'data-testid': dataTestId
51
+ } = _ref4;
52
+ const goToFirstPage = useCallback(() => {
53
+ onChange(1);
54
+ }, [onChange]);
55
+ const goToLastPage = useCallback(() => {
56
+ onChange(pageCount);
57
+ }, [onChange, pageCount]);
58
+ const goToNextPage = useCallback(() => {
59
+ onChange(page + 1);
60
+ }, [onChange, page]);
61
+ const goToPreviousPage = useCallback(() => {
62
+ onChange(page - 1);
63
+ }, [onChange, page]);
64
+ const pageNumbersToDisplay = useMemo(() => pageCount > 1 ? getPageNumbers(page, pageCount, pageTabCount) : [1], [page, pageCount, pageTabCount]);
65
+ const handlePageClick = useCallback(pageNumber => () => {
66
+ onChange(pageNumber);
67
+ }, [onChange]);
68
+ return jsxs(StyledContainer, {
69
+ className: className,
70
+ "data-testid": dataTestId,
71
+ children: [jsxs(PageSwitchContainer, {
72
+ children: [jsx(Button, {
73
+ "aria-label": "First",
74
+ disabled: page <= 1 || disabled,
75
+ variant: "outlined",
76
+ sentiment: "primary",
77
+ onClick: goToFirstPage,
78
+ icon: "arrow-left-double"
79
+ }), jsx(Button, {
80
+ "aria-label": "Back",
81
+ disabled: page <= 1 || disabled,
82
+ variant: "outlined",
83
+ sentiment: "primary",
84
+ onClick: goToPreviousPage,
85
+ icon: "arrow-left"
86
+ })]
87
+ }), jsx(PageNumbersContainer, {
88
+ children: pageNumbersToDisplay.map(pageNumber => jsx(Button, {
89
+ "aria-label": `Page ${pageNumber}`,
90
+ "aria-current": pageNumber === page,
91
+ disabled: disabled,
92
+ variant: "outlined",
93
+ sentiment: pageNumber === page ? 'primary' : 'neutral',
94
+ onClick: handlePageClick(pageNumber),
95
+ type: "button",
96
+ children: pageNumber
97
+ }, `pagination-page-${pageNumber}`))
98
+ }), jsxs(PageSwitchContainer, {
99
+ children: [jsx(Button, {
100
+ "aria-label": "Next",
101
+ disabled: page >= pageCount || disabled,
102
+ variant: "outlined",
103
+ sentiment: "primary",
104
+ onClick: goToNextPage,
105
+ icon: "arrow-right"
106
+ }), jsx(Button, {
107
+ "aria-label": "Last",
108
+ disabled: page >= pageCount || disabled,
109
+ variant: "outlined",
110
+ sentiment: "primary",
111
+ onClick: goToLastPage,
112
+ icon: "arrow-right-double"
113
+ })]
114
+ })]
115
+ });
116
+ };
117
+
118
+ export { Pagination };
@@ -0,0 +1,42 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Icon } from '../Icon/index.js';
3
+ import { Stack } from '../Stack/index.js';
4
+ import { Text } from '../Text/index.js';
5
+ import { jsx, jsxs } from '@emotion/react/jsx-runtime';
6
+
7
+ const PasswordCheckContainer = /*#__PURE__*/_styled("div", {
8
+ target: "eunxap90"
9
+ })("display:grid;grid-template-columns:repeat(2, 1fr);gap:", _ref => {
10
+ let {
11
+ theme
12
+ } = _ref;
13
+ return theme.space['1'];
14
+ }, ";");
15
+ const PasswordCheck = _ref2 => {
16
+ let {
17
+ rules,
18
+ className,
19
+ 'data-testid': dataTestId
20
+ } = _ref2;
21
+ return jsx(PasswordCheckContainer, {
22
+ className: className,
23
+ "data-testid": dataTestId,
24
+ children: rules.map(rule => jsxs(Stack, {
25
+ direction: "row",
26
+ gap: 1,
27
+ alignItems: "center",
28
+ children: [jsx(Icon, {
29
+ name: rule.valid ? 'checkbox-circle-outline' : 'close-circle-outline',
30
+ color: rule.valid ? 'success' : 'neutral',
31
+ prominence: "weak",
32
+ size: 20
33
+ }), jsx(Text, {
34
+ as: "p",
35
+ variant: "bodySmall",
36
+ children: rule.text
37
+ })]
38
+ }, rule.name))
39
+ });
40
+ };
41
+
42
+ export { PasswordCheck };
@@ -0,0 +1,116 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useTheme } from '@emotion/react';
3
+ import { useState, useCallback, useEffect } from 'react';
4
+ import { Text } from '../Text/index.js';
5
+ import { jsxs, jsx } from '@emotion/react/jsx-runtime';
6
+
7
+ function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
8
+ const StyledTitle = /*#__PURE__*/_styled(Text, {
9
+ target: "e1uv9umu3"
10
+ })(process.env.NODE_ENV === "production" ? {
11
+ name: "1gbhlwb",
12
+ styles: "display:inline-block;vertical-align:top;line-height:22px"
13
+ } : {
14
+ name: "1gbhlwb",
15
+ styles: "display:inline-block;vertical-align:top;line-height:22px",
16
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
17
+ });
18
+ const StyledStrength = /*#__PURE__*/_styled(Text, {
19
+ target: "e1uv9umu2"
20
+ })("float:right;vertical-align:top;color:", _ref => {
21
+ let {
22
+ strength
23
+ } = _ref;
24
+ return strength.color;
25
+ }, ";");
26
+ const StyledWrapper = /*#__PURE__*/_styled("div", {
27
+ target: "e1uv9umu1"
28
+ })("background-color:", _ref2 => {
29
+ let {
30
+ theme
31
+ } = _ref2;
32
+ return theme.colors.neutral.backgroundDisabled;
33
+ }, ";border-radius:", _ref3 => {
34
+ let {
35
+ theme
36
+ } = _ref3;
37
+ return theme.radii.default;
38
+ }, ";height:8px;margin-top:", _ref4 => {
39
+ let {
40
+ theme
41
+ } = _ref4;
42
+ return theme.space['1'];
43
+ }, ";margin-bottom:", _ref5 => {
44
+ let {
45
+ theme
46
+ } = _ref5;
47
+ return theme.space['2'];
48
+ }, ";");
49
+ const StyledMeter = /*#__PURE__*/_styled("div", {
50
+ target: "e1uv9umu0"
51
+ })("border-radius:", _ref6 => {
52
+ let {
53
+ theme
54
+ } = _ref6;
55
+ return theme.radii.default;
56
+ }, ";height:100%;transition:all 0.5s;");
57
+ const DEFAULT_ESTIMATE = () => ({
58
+ score: 0
59
+ });
60
+ const DEFAULT_FORBIDDEN_WORDS = [];
61
+ const PasswordStrengthMeter = _ref7 => {
62
+ let {
63
+ password = '',
64
+ onChange,
65
+ strength,
66
+ title,
67
+ estimate = DEFAULT_ESTIMATE,
68
+ forbiddenInputs = DEFAULT_FORBIDDEN_WORDS,
69
+ className,
70
+ 'data-testid': dataTestId
71
+ } = _ref7;
72
+ const [score, setScore] = useState(0);
73
+ const theme = useTheme();
74
+ const [backgroundColor, setBackgroundColor] = useState(strength[0]?.color || theme.colors.success.backgroundStrong);
75
+ const [width, setWidth] = useState(0);
76
+ const getScore = useCallback(async passwordToTest => {
77
+ const {
78
+ score: internalScore = 0
79
+ } = await estimate(passwordToTest || '', forbiddenInputs);
80
+ return internalScore;
81
+ }, [estimate, forbiddenInputs]);
82
+ const handleChange = useCallback(e => onChange?.(e), [onChange]);
83
+ useEffect(() => {
84
+ setBackgroundColor(strength[score].color);
85
+ handleChange(score);
86
+ getScore(password).then(s => setScore(s)).catch(null);
87
+ const toValue = (score + 1) / strength.length * 100;
88
+ setWidth(`${toValue}%`);
89
+ }, [getScore, handleChange, password, score, strength]);
90
+ return jsxs("div", {
91
+ title: title,
92
+ role: "alert",
93
+ "aria-live": "polite",
94
+ className: className,
95
+ "data-testid": dataTestId,
96
+ children: [jsx(StyledTitle, {
97
+ variant: "bodySmallStrong",
98
+ as: "p",
99
+ children: title
100
+ }), jsx(StyledStrength, {
101
+ as: "span",
102
+ variant: "bodySmallStrong",
103
+ strength: strength[score],
104
+ children: strength[score]?.t
105
+ }), jsx(StyledWrapper, {
106
+ children: jsx(StyledMeter, {
107
+ style: {
108
+ backgroundColor,
109
+ width
110
+ }
111
+ })
112
+ })]
113
+ });
114
+ };
115
+
116
+ export { PasswordStrengthMeter };