@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,177 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import useClipboard from 'react-use-clipboard';
3
+ import { Button } from '../Button/index.js';
4
+ import { Icon } from '../Icon/index.js';
5
+ import { Loader } from '../Loader/index.js';
6
+ import { Tooltip } from '../Tooltip/index.js';
7
+ import { jsx, jsxs, Fragment } from '@emotion/react/jsx-runtime';
8
+
9
+ 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)."; }
10
+ const COPY_DURATION = 2500;
11
+ const StyledContainer = /*#__PURE__*/_styled('span', {
12
+ shouldForwardProp: prop => !['sentiment', 'copiable'].includes(prop),
13
+ target: "el6733p2"
14
+ })("display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;border-radius:", _ref => {
15
+ let {
16
+ theme
17
+ } = _ref;
18
+ return theme.radii.default;
19
+ }, ";padding:0 ", _ref2 => {
20
+ let {
21
+ theme
22
+ } = _ref2;
23
+ return theme.space['1'];
24
+ }, ";gap:", _ref3 => {
25
+ let {
26
+ theme
27
+ } = _ref3;
28
+ return theme.space['1'];
29
+ }, ";width:fit-content;height:24px;", _ref4 => {
30
+ let {
31
+ copiable,
32
+ theme
33
+ } = _ref4;
34
+ return copiable && `
35
+ &:hover, &:active {
36
+ cursor: pointer;
37
+ background: ${theme.colors.neutral.backgroundWeakHover};
38
+ border-color: ${theme.colors.neutral.borderStrongHover};
39
+ }
40
+
41
+ &:active {
42
+ box-shadow: ${theme.shadows.focusNeutral};
43
+ }
44
+ `;
45
+ }, " ", _ref5 => {
46
+ let {
47
+ sentiment,
48
+ theme
49
+ } = _ref5;
50
+ if (sentiment === 'disabled') {
51
+ return `
52
+ color: ${theme.colors.neutral.textDisabled};
53
+ background: ${theme.colors.neutral.backgroundDisabled};
54
+ border: solid 1px ${theme.colors.neutral.borderDisabled};
55
+ cursor: not-allowed
56
+
57
+ `;
58
+ }
59
+ if (sentiment === 'neutral') {
60
+ return `
61
+ color: ${theme.colors.neutral.text};
62
+ background: ${theme.colors.neutral.background};
63
+ border: solid 1px ${theme.colors.neutral.border};
64
+ `;
65
+ }
66
+ return `
67
+ color: ${theme.colors[sentiment].text};
68
+ background: ${theme.colors[sentiment].background};
69
+ border: solid 1px ${theme.colors[sentiment].background};
70
+ `;
71
+ }, ";");
72
+ const StyledTag = /*#__PURE__*/_styled("span", {
73
+ target: "el6733p1"
74
+ })(process.env.NODE_ENV === "production" ? {
75
+ name: "td7tdt",
76
+ styles: "font-size:12px;font-weight:500;color:inherit;max-width:232px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis"
77
+ } : {
78
+ name: "td7tdt",
79
+ styles: "font-size:12px;font-weight:500;color:inherit;max-width:232px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis",
80
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
81
+ });
82
+ const StyledCloseButton = /*#__PURE__*/_styled(Button, {
83
+ target: "el6733p0"
84
+ })(process.env.NODE_ENV === "production" ? {
85
+ name: "1z1k76",
86
+ styles: "width:fit-content;height:fit-content;padding:2px"
87
+ } : {
88
+ name: "1z1k76",
89
+ styles: "width:fit-content;height:fit-content;padding:2px",
90
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
91
+ });
92
+ const TagInner = _ref6 => {
93
+ let {
94
+ children,
95
+ isLoading = false,
96
+ onClose,
97
+ icon,
98
+ disabled = false
99
+ } = _ref6;
100
+ return jsxs(Fragment, {
101
+ children: [icon ? jsx(Icon, {
102
+ name: icon,
103
+ size: 16
104
+ }) : null, jsx(StyledTag, {
105
+ "aria-disabled": disabled,
106
+ children: children
107
+ }), onClose && !isLoading ? jsx(StyledCloseButton, {
108
+ onClick: onClose,
109
+ disabled: disabled,
110
+ "aria-label": "Close tag",
111
+ "data-testid": "close-tag",
112
+ variant: "ghost",
113
+ sentiment: "neutral",
114
+ icon: "close",
115
+ size: "small"
116
+ }) : null, isLoading ? jsx(Loader, {
117
+ active: true,
118
+ size: 16
119
+ }) : null]
120
+ });
121
+ };
122
+ const Tag = _ref7 => {
123
+ let {
124
+ children,
125
+ isLoading,
126
+ onClose,
127
+ icon,
128
+ copiable = false,
129
+ copyText = 'Copy',
130
+ copiedText = 'Copied!',
131
+ disabled,
132
+ sentiment = 'neutral',
133
+ className,
134
+ 'data-testid': dataTestId
135
+ } = _ref7;
136
+ const [isCopied, setCopied] = useClipboard(typeof children === 'string' ? children : '', {
137
+ successDuration: COPY_DURATION
138
+ });
139
+ if (copiable && !disabled) {
140
+ const Container = StyledContainer.withComponent('button', {
141
+ target: "el6733p3"
142
+ });
143
+ return jsx(Tooltip, {
144
+ text: isCopied ? copiedText : copyText,
145
+ children: jsx(Container
146
+ // @note: sending disabled as a special sentiment is a bit weird
147
+ , {
148
+ sentiment: disabled ? 'disabled' : sentiment,
149
+ copiable: true,
150
+ onClick: setCopied,
151
+ className: className,
152
+ "data-testid": dataTestId,
153
+ children: jsx(TagInner, {
154
+ isLoading: isLoading,
155
+ onClose: onClose,
156
+ icon: icon,
157
+ disabled: disabled,
158
+ children: children
159
+ })
160
+ })
161
+ });
162
+ }
163
+ return jsx(StyledContainer, {
164
+ sentiment: disabled ? 'disabled' : sentiment,
165
+ className: className,
166
+ "data-testid": dataTestId,
167
+ children: jsx(TagInner, {
168
+ isLoading: isLoading,
169
+ onClose: onClose,
170
+ icon: icon,
171
+ disabled: disabled,
172
+ children: children
173
+ })
174
+ });
175
+ };
176
+
177
+ export { Tag };
@@ -0,0 +1,277 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useState, useEffect, useRef } from 'react';
3
+ import { Tag } from '../Tag/index.js';
4
+ import { jsxs, jsx } from '@emotion/react/jsx-runtime';
5
+ import { getUUID } from '../../utils/ids.js';
6
+
7
+ const STATUS = {
8
+ IDLE: 'idle',
9
+ LOADING: 'loading'
10
+ };
11
+ const variants = {
12
+ base: _ref => {
13
+ let {
14
+ theme: {
15
+ colors,
16
+ shadows,
17
+ radii
18
+ }
19
+ } = _ref;
20
+ return `
21
+ padding: 8px;
22
+ cursor: text;
23
+ border-radius: ${radii.default};
24
+ border: 1px solid ${colors.neutral.borderWeak};
25
+ &:focus-within {
26
+ border: 1px solid ${colors.primary.borderWeak};
27
+ box-shadow: ${shadows.focusPrimary};
28
+ }
29
+
30
+ &:hover {
31
+ border: 1px solid ${colors.primary.borderWeak};
32
+ }
33
+
34
+ & > * {
35
+ margin: 6px;
36
+ }
37
+ `;
38
+ },
39
+ bordered: _ref2 => {
40
+ let {
41
+ theme: {
42
+ shadows
43
+ }
44
+ } = _ref2;
45
+ return `
46
+ margin-top: 0;
47
+ padding: 8px 0;
48
+
49
+ > input:focus {
50
+ box-shadow: ${shadows.focusPrimary};
51
+ }
52
+
53
+ > * {
54
+ margin-bottom: 6px;
55
+ &:not(:last-child) {
56
+ margin-right: 6px;
57
+ }
58
+ }
59
+ `;
60
+ },
61
+ 'no-border': _ref3 => {
62
+ let {
63
+ theme: {
64
+ shadows
65
+ }
66
+ } = _ref3;
67
+ return `
68
+ &:focus-within {
69
+ box-shadow: ${shadows.focusPrimary};
70
+ }
71
+
72
+ > * {
73
+ margin-right: 6px;
74
+ margin-bottom: 6px;
75
+ }
76
+ `;
77
+ }
78
+ };
79
+ const TagInputContainer = /*#__PURE__*/_styled('div', {
80
+ shouldForwardProp: prop => !['variant'].includes(prop),
81
+ target: "ea7vc6o1"
82
+ })("display:flex;flex-wrap:wrap;background-color:", _ref4 => {
83
+ let {
84
+ theme: {
85
+ colors
86
+ }
87
+ } = _ref4;
88
+ return colors.neutral.backgroundWeak;
89
+ }, ";", _ref5 => {
90
+ let {
91
+ variant,
92
+ theme
93
+ } = _ref5;
94
+ return variants[variant] ? variants[variant]({
95
+ theme
96
+ }) : variants.base({
97
+ theme
98
+ });
99
+ }, ";");
100
+ const StyledInput = /*#__PURE__*/_styled("input", {
101
+ target: "ea7vc6o0"
102
+ })("font-size:16px;color:", _ref6 => {
103
+ let {
104
+ theme: {
105
+ colors
106
+ }
107
+ } = _ref6;
108
+ return colors.neutral.text;
109
+ }, ";border:none;outline:none;background-color:", _ref7 => {
110
+ let {
111
+ theme: {
112
+ colors
113
+ }
114
+ } = _ref7;
115
+ return colors.neutral.backgroundWeak;
116
+ }, ";&::placeholder{color:", _ref8 => {
117
+ let {
118
+ theme: {
119
+ colors
120
+ }
121
+ } = _ref8;
122
+ return colors.neutral.textWeak;
123
+ }, ";}");
124
+ const convertTagArrayToTagStateArray = tags => (tags || [])?.map((tag, index) => typeof tag === 'object' ? {
125
+ ...tag,
126
+ index: getUUID(`tag-${index}`)
127
+ } : {
128
+ index: getUUID(`tag-${index}`),
129
+ label: tag
130
+ });
131
+ /**
132
+ * @experimental This component is experimental and may be subject to breaking changes in the future.
133
+ */
134
+ const TagInput = _ref9 => {
135
+ let {
136
+ disabled = false,
137
+ id,
138
+ manualInput = true,
139
+ name,
140
+ onChange,
141
+ onChangeError,
142
+ placeholder,
143
+ tags,
144
+ variant = 'base',
145
+ className,
146
+ 'data-testid': dataTestId
147
+ } = _ref9;
148
+ const [tagInputState, setTagInput] = useState(convertTagArrayToTagStateArray(tags ?? []));
149
+ const [input, setInput] = useState('');
150
+ const [status, setStatus] = useState({});
151
+ useEffect(() => {
152
+ setTagInput(convertTagArrayToTagStateArray(tags));
153
+ }, [tags, setTagInput]);
154
+ const inputRef = useRef(null);
155
+ const dispatchOnChange = newState => {
156
+ const changes = newState.map(tag => typeof tag === 'object' ? tag?.label : tag);
157
+ onChange?.(changes);
158
+ };
159
+ const handleContainerClick = () => {
160
+ if (inputRef.current) {
161
+ inputRef?.current?.focus();
162
+ }
163
+ };
164
+ const onInputChange = e => setInput(e.target.value);
165
+ const addTag = () => {
166
+ const newTagInput = input ? [...tagInputState, {
167
+ index: getUUID('tag'),
168
+ label: input
169
+ }] : tagInputState;
170
+ setInput('');
171
+ setTagInput(newTagInput);
172
+ if (newTagInput.length !== tagInputState.length) {
173
+ setStatus({
174
+ [newTagInput[newTagInput.length - 1].index]: STATUS.LOADING
175
+ });
176
+ }
177
+ try {
178
+ dispatchOnChange(newTagInput);
179
+ setStatus({
180
+ [newTagInput[newTagInput.length - 1].index]: STATUS.IDLE
181
+ });
182
+ } catch (error) {
183
+ onChangeError?.(error);
184
+ setTagInput(tagInputState);
185
+ }
186
+ };
187
+ const deleteTag = tagIndex => {
188
+ setStatus({
189
+ [tagIndex]: STATUS.LOADING
190
+ });
191
+ const findIndex = tagInputState.findIndex(_ref10 => {
192
+ let {
193
+ index
194
+ } = _ref10;
195
+ return index === tagIndex;
196
+ });
197
+ const newTagInput = [...tagInputState];
198
+ newTagInput.splice(findIndex, 1);
199
+ try {
200
+ dispatchOnChange(newTagInput);
201
+ setTagInput(newTagInput);
202
+ setStatus({
203
+ [tagIndex]: STATUS.IDLE
204
+ });
205
+ } catch (error) {
206
+ onChangeError?.(error);
207
+ setTagInput(tagInputState);
208
+ }
209
+ };
210
+ const handleInputKeydown = e => {
211
+ // 32 = Space | 13 = Enter | 8 = Backspace
212
+ // https://www.w3.org/TR/uievents-key/#control
213
+ const key = e.key || e.keyCode;
214
+ const space = [' ', 32];
215
+ const enter = ['Enter', 13];
216
+ const tab = ['Tab', 9];
217
+ const backspace = ['Backspace', 8];
218
+ if (space.includes(key) || enter.includes(key) || tab.includes(key)) {
219
+ addTag();
220
+ e.preventDefault();
221
+ }
222
+ if (backspace.includes(key) && inputRef?.current?.selectionStart === 0 && tagInputState.length) {
223
+ e.preventDefault();
224
+ deleteTag(tagInputState[tagInputState.length - 1].index);
225
+ }
226
+ };
227
+ const handlePaste = e => {
228
+ e.preventDefault();
229
+ const newTagInput = [...tagInputState, {
230
+ index: getUUID('tag'),
231
+ label: e?.clipboardData?.getData('Text')
232
+ }];
233
+ setTagInput(newTagInput);
234
+ setStatus({
235
+ [newTagInput.length - 1]: STATUS.LOADING
236
+ });
237
+ try {
238
+ dispatchOnChange(newTagInput);
239
+ setStatus({
240
+ [newTagInput.length - 1]: STATUS.IDLE
241
+ });
242
+ } catch (error) {
243
+ onChangeError?.(error);
244
+ setTagInput(tagInputState);
245
+ }
246
+ };
247
+ return jsxs(TagInputContainer, {
248
+ onClick: handleContainerClick,
249
+ variant: variant,
250
+ onBlur: addTag,
251
+ className: className,
252
+ "data-testid": dataTestId,
253
+ children: [tagInputState.map(tag => jsx(Tag, {
254
+ sentiment: "neutral",
255
+ disabled: disabled,
256
+ isLoading: status[tag.index] === STATUS.LOADING,
257
+ onClose: e => {
258
+ e.stopPropagation();
259
+ deleteTag(tag.index);
260
+ },
261
+ children: tag.label
262
+ }, tag.index)), !disabled && manualInput ? jsx(StyledInput, {
263
+ id: id,
264
+ name: name,
265
+ "aria-label": name,
266
+ type: "text",
267
+ placeholder: !tagInputState.length ? placeholder : '',
268
+ value: input,
269
+ onChange: onInputChange,
270
+ onKeyDown: handleInputKeydown,
271
+ onPaste: handlePaste,
272
+ ref: inputRef
273
+ }) : null]
274
+ });
275
+ };
276
+
277
+ export { TagInput };
@@ -0,0 +1,110 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useState } from 'react';
3
+ import { Popover } from '../Popover/index.js';
4
+ import { Tag } from '../Tag/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 StyledContainer = /*#__PURE__*/_styled("div", {
9
+ target: "eb6op482"
10
+ })(process.env.NODE_ENV === "production" ? {
11
+ name: "zjik7",
12
+ styles: "display:flex"
13
+ } : {
14
+ name: "zjik7",
15
+ styles: "display:flex",
16
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__
17
+ });
18
+ const TagsWrapper = /*#__PURE__*/_styled("span", {
19
+ target: "eb6op481"
20
+ })("cursor:pointer;color:", _ref => {
21
+ let {
22
+ theme
23
+ } = _ref;
24
+ return theme.colors.primary.text;
25
+ }, ";border:none;font-size:14px;align-self:center;max-width:350px;overflow:hidden;white-space:pre;text-overflow:ellipsis;background-color:transparent;padding-left:8px;padding-right:8px;");
26
+ const StyledTagContainer = /*#__PURE__*/_styled("div", {
27
+ target: "eb6op480"
28
+ })("display:flex;align-items:center;color:", _ref2 => {
29
+ let {
30
+ theme
31
+ } = _ref2;
32
+ return theme.colors.neutral.text;
33
+ }, ";gap:", _ref3 => {
34
+ let {
35
+ theme
36
+ } = _ref3;
37
+ return theme.space['1'];
38
+ }, ";", _ref4 => {
39
+ let {
40
+ multiline
41
+ } = _ref4;
42
+ return multiline && `flex-wrap: wrap;`;
43
+ }, ";");
44
+ const DEFAULT_TAGS = [];
45
+ const TagList = _ref5 => {
46
+ let {
47
+ maxLength = 600,
48
+ tags = DEFAULT_TAGS,
49
+ threshold = 1,
50
+ multiline = false,
51
+ popoverTitle,
52
+ copiable,
53
+ copyText,
54
+ copiedText,
55
+ className,
56
+ 'data-testid': dataTestId
57
+ } = _ref5;
58
+ let tmpThreshold = threshold;
59
+ if (tags.length > 0 && tags.slice(0, tmpThreshold).reduce((_, tag) => _ + tag).length > maxLength) {
60
+ // If total tags length in characters is above maxLength,
61
+ // threshold is decremented in order to prevent too many long tags displayed.
62
+ tmpThreshold -= 1;
63
+ }
64
+ const hasManyTags = tags.length > tmpThreshold || false;
65
+ const visibleTagsCount = hasManyTags ? tmpThreshold : tags.length;
66
+ const [isVisible, setIsVisible] = useState(false);
67
+ if (!tags.length) {
68
+ return null;
69
+ }
70
+ return jsxs(StyledContainer, {
71
+ className: className,
72
+ "data-testid": dataTestId,
73
+ children: [jsx(StyledTagContainer, {
74
+ multiline: multiline,
75
+ children: tags.slice(0, visibleTagsCount).map((tag, index) => jsx(Tag
76
+ // useful when two tags are identical `${tag}-${index}`
77
+ // eslint-disable-next-line react/no-array-index-key
78
+ , {
79
+ copiable: copiable,
80
+ copyText: copyText,
81
+ copiedText: copiedText,
82
+ children: tag
83
+ }, `${tag}-${index}`))
84
+ }), hasManyTags && jsx(Popover, {
85
+ title: popoverTitle,
86
+ visible: isVisible,
87
+ size: "small",
88
+ onClose: () => setIsVisible(false),
89
+ content: jsx(StyledTagContainer, {
90
+ multiline: true,
91
+ children: tags.slice(visibleTagsCount).map((tag, index) => jsx(Tag
92
+ // useful when two tags are identical `${tag}-${index}`
93
+ // eslint-disable-next-line react/no-array-index-key
94
+ , {
95
+ copiable: copiable,
96
+ copyText: copyText,
97
+ copiedText: copiedText,
98
+ children: tag
99
+ }, `${tag}-${index}`))
100
+ }),
101
+ children: jsxs(TagsWrapper, {
102
+ "data-testid": `${dataTestId ?? 'taglist'}-open`,
103
+ onClick: () => setIsVisible(true),
104
+ children: ["+", tags.length - tmpThreshold]
105
+ })
106
+ })]
107
+ });
108
+ };
109
+
110
+ export { TagList };
@@ -0,0 +1,106 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { useState, useRef, useEffect } from 'react';
3
+ import recursivelyGetChildrenString from '../../helpers/recursivelyGetChildrenString.js';
4
+ import capitalize from '../../utils/capitalize.js';
5
+ import { Tooltip } from '../Tooltip/index.js';
6
+ import { jsx } from '@emotion/react/jsx-runtime';
7
+
8
+ const PROMINENCES = {
9
+ default: '',
10
+ strong: 'strong',
11
+ stronger: 'stronger',
12
+ weak: 'weak'
13
+ };
14
+
15
+ /**
16
+ * Generate all styles available for text based on prominence and variants
17
+ */
18
+ const generateStyles = _ref => {
19
+ let {
20
+ prominence,
21
+ color,
22
+ variant,
23
+ theme,
24
+ oneLine,
25
+ disabled,
26
+ italic,
27
+ underline
28
+ } = _ref;
29
+ // stronger is available only for neutral color
30
+ const definedProminence = color !== 'neutral' && prominence === 'stronger' ? capitalize(PROMINENCES.default) : capitalize(PROMINENCES[prominence]);
31
+ theme.colors[color];
32
+ const text = `text${definedProminence}${disabled ? 'Disabled' : ''}`;
33
+ return `
34
+ color: ${theme.colors[color][text]};
35
+
36
+ font-size: ${theme.typography[variant].fontSize};
37
+ font-family: ${theme.typography[variant].fontFamily};
38
+ font-weight: ${theme.typography[variant].weight};
39
+ letter-spacing: ${theme.typography[variant].letterSpacing};
40
+ line-height: ${theme.typography[variant].lineHeight};
41
+ text-transform: ${theme.typography[variant].textCase};
42
+ text-decoration: ${theme.typography[variant].textDecoration};
43
+
44
+ ${oneLine ? `white-space: nowrap;
45
+ text-overflow: ellipsis;
46
+ overflow: hidden;` : ''}
47
+ ${italic ? `font-style: italic;` : ''}
48
+ ${underline ? `text-decoration: underline;` : ''}
49
+ `;
50
+ };
51
+ const StyledText = /*#__PURE__*/_styled('div', {
52
+ shouldForwardProp: prop => !['as', 'variant', 'color', 'prominence', 'oneLine', 'disabled', 'italic', 'underline'].includes(prop),
53
+ target: "e13y3mga0"
54
+ })(generateStyles);
55
+ const Text = _ref2 => {
56
+ let {
57
+ variant,
58
+ children,
59
+ as,
60
+ color = 'neutral',
61
+ oneLine = false,
62
+ prominence = 'default',
63
+ className,
64
+ disabled = false,
65
+ italic = false,
66
+ underline = false,
67
+ id,
68
+ dir,
69
+ htmlFor,
70
+ 'data-testid': dataTestId
71
+ } = _ref2;
72
+ const [isTruncated, setIsTruncated] = useState(false);
73
+ const elementRef = useRef(null);
74
+ const finalStringChildren = recursivelyGetChildrenString(children);
75
+ useEffect(() => {
76
+ if (oneLine && elementRef && elementRef.current) {
77
+ const {
78
+ offsetWidth,
79
+ scrollWidth
80
+ } = elementRef.current;
81
+ setIsTruncated(offsetWidth < scrollWidth);
82
+ }
83
+ }, [oneLine]);
84
+ return jsx(Tooltip, {
85
+ text: oneLine && isTruncated ? finalStringChildren : '',
86
+ children: jsx(StyledText, {
87
+ ref: elementRef,
88
+ as: as,
89
+ prominence: prominence,
90
+ color: color,
91
+ variant: variant,
92
+ oneLine: oneLine,
93
+ className: className,
94
+ disabled: disabled,
95
+ italic: italic,
96
+ underline: underline,
97
+ id: id,
98
+ dir: dir,
99
+ htmlFor: htmlFor,
100
+ "data-testid": dataTestId,
101
+ children: children
102
+ })
103
+ });
104
+ };
105
+
106
+ export { Text };