@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.
- package/LICENSE +189 -0
- package/README.md +64 -0
- package/dist/index.d.ts +2427 -0
- package/dist/react-datepicker/dist/react-datepicker.min.css.js +3 -0
- package/dist/react-toastify/dist/ReactToastify.min.css.js +3 -0
- package/dist/src/components/ActionBar/index.js +55 -0
- package/dist/src/components/Alert/index.js +144 -0
- package/dist/src/components/Avatar/index.js +90 -0
- package/dist/src/components/Badge/index.js +143 -0
- package/dist/src/components/Banner/index.js +117 -0
- package/dist/src/components/BarChart/Tooltip.js +63 -0
- package/dist/src/components/BarChart/index.js +94 -0
- package/dist/src/components/BarStack/index.js +223 -0
- package/dist/src/components/Breadcrumbs/index.js +89 -0
- package/dist/src/components/Bullet/index.js +137 -0
- package/dist/src/components/Button/index.js +303 -0
- package/dist/src/components/Card/index.js +81 -0
- package/dist/src/components/Carousel/index.js +162 -0
- package/dist/src/components/Checkbox/index.js +338 -0
- package/dist/src/components/CopyButton/index.js +92 -0
- package/dist/src/components/DateInput/index.js +250 -0
- package/dist/src/components/EmptyState/index.js +124 -0
- package/dist/src/components/Expandable/index.js +84 -0
- package/dist/src/components/Icon/index.js +350 -0
- package/dist/src/components/LineChart/CustomLegend.js +147 -0
- package/dist/src/components/LineChart/Tooltip.js +58 -0
- package/dist/src/components/LineChart/helpers.js +75 -0
- package/dist/src/components/LineChart/index.js +139 -0
- package/dist/src/components/Link/index.js +159 -0
- package/dist/src/components/List/Body.js +22 -0
- package/dist/src/components/List/Cell.js +38 -0
- package/dist/src/components/List/HeaderCell.js +118 -0
- package/dist/src/components/List/HeaderRow.js +47 -0
- package/dist/src/components/List/ListContext.js +120 -0
- package/dist/src/components/List/Row.js +211 -0
- package/dist/src/components/List/SelectBar.js +52 -0
- package/dist/src/components/List/SkeletonRows.js +54 -0
- package/dist/src/components/List/constants.js +3 -0
- package/dist/src/components/List/index.js +77 -0
- package/dist/src/components/Loader/index.js +87 -0
- package/dist/src/components/Menu/Item.js +122 -0
- package/dist/src/components/Menu/index.js +143 -0
- package/dist/src/components/Modal/index.js +279 -0
- package/dist/src/components/Notice/index.js +33 -0
- package/dist/src/components/NumberInput/helpers.js +6 -0
- package/dist/src/components/NumberInput/index.js +366 -0
- package/dist/src/components/Pagination/getPageNumbers.js +32 -0
- package/dist/src/components/Pagination/index.js +118 -0
- package/dist/src/components/PasswordCheck/index.js +42 -0
- package/dist/src/components/PasswordStrengthMeter/index.js +116 -0
- package/dist/src/components/PieChart/Legends.js +183 -0
- package/dist/src/components/PieChart/Tooltip.js +64 -0
- package/dist/src/components/PieChart/index.js +133 -0
- package/dist/src/components/PieChart/patterns.js +9 -0
- package/dist/src/components/Popover/index.js +131 -0
- package/dist/src/components/ProgressBar/index.js +72 -0
- package/dist/src/components/Radio/index.js +231 -0
- package/dist/src/components/Row/index.js +43 -0
- package/dist/src/components/SelectInput/index.js +662 -0
- package/dist/src/components/SelectableCard/index.js +154 -0
- package/dist/src/components/Separator/index.js +91 -0
- package/dist/src/components/Skeleton/Block.js +53 -0
- package/dist/src/components/Skeleton/Blocks.js +52 -0
- package/dist/src/components/Skeleton/BoxWithIcon.js +47 -0
- package/dist/src/components/Skeleton/Donut.js +58 -0
- package/dist/src/components/Skeleton/IconSkeleton.js +37 -0
- package/dist/src/components/Skeleton/Line.js +19 -0
- package/dist/src/components/Skeleton/List.js +60 -0
- package/dist/src/components/Skeleton/Slider.js +57 -0
- package/dist/src/components/Skeleton/index.js +85 -0
- package/dist/src/components/Snippet/index.js +250 -0
- package/dist/src/components/Stack/index.js +24 -0
- package/dist/src/components/Status/index.js +101 -0
- package/dist/src/components/StepList/index.js +81 -0
- package/dist/src/components/Stepper/index.js +217 -0
- package/dist/src/components/SwitchButton/FocusOverlay.js +47 -0
- package/dist/src/components/SwitchButton/index.js +131 -0
- package/dist/src/components/Table/Body.js +12 -0
- package/dist/src/components/Table/Cell.js +27 -0
- package/dist/src/components/Table/Header.js +21 -0
- package/dist/src/components/Table/HeaderCell.js +119 -0
- package/dist/src/components/Table/HeaderRow.js +35 -0
- package/dist/src/components/Table/Row.js +70 -0
- package/dist/src/components/Table/SelectBar.js +52 -0
- package/dist/src/components/Table/SkeletonRows.js +52 -0
- package/dist/src/components/Table/TableContext.js +91 -0
- package/dist/src/components/Table/index.js +84 -0
- package/dist/src/components/Tabs/Tab.js +165 -0
- package/dist/src/components/Tabs/TabMenu.js +46 -0
- package/dist/src/components/Tabs/TabMenuItem.js +40 -0
- package/dist/src/components/Tabs/TabsContext.js +6 -0
- package/dist/src/components/Tabs/index.js +117 -0
- package/dist/src/components/Tag/index.js +177 -0
- package/dist/src/components/TagInput/index.js +277 -0
- package/dist/src/components/TagList/index.js +110 -0
- package/dist/src/components/Text/index.js +106 -0
- package/dist/src/components/TextInput/index.js +529 -0
- package/dist/src/components/TimeInput/index.js +38 -0
- package/dist/src/components/Toaster/index.js +116 -0
- package/dist/src/components/Toggle/index.js +192 -0
- package/dist/src/components/Tooltip/helpers.js +131 -0
- package/dist/src/components/Tooltip/index.js +275 -0
- package/dist/src/components/VerificationCode/index.js +203 -0
- package/dist/src/helpers/isJSON.js +11 -0
- package/dist/src/helpers/legend.js +13 -0
- package/dist/src/helpers/recursivelyGetChildrenString.js +12 -0
- package/dist/src/index.js +63 -0
- package/dist/src/theme/index.js +25 -0
- package/dist/src/utils/animations.js +250 -0
- package/dist/src/utils/capitalize.js +4 -0
- package/dist/src/utils/ids.js +12 -0
- package/dist/src/utils/normalize.js +36 -0
- package/dist/src/utils/responsive/Breakpoint.js +12 -0
- package/dist/src/utils/responsive/utilities.js +12 -0
- 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 };
|