@ultraviolet/ui 1.30.0 → 1.31.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.
@@ -0,0 +1,282 @@
1
+ import _styled from '@emotion/styled/base';
2
+ import { Icon } from '@ultraviolet/icons';
3
+ import { forwardRef, useId, useState, useMemo } from 'react';
4
+ import { Button } from '../Button/index.js';
5
+ import { Loader } from '../Loader/index.js';
6
+ import { Stack } from '../Stack/index.js';
7
+ import { Text } from '../Text/index.js';
8
+ import { Tooltip } from '../Tooltip/index.js';
9
+ import { jsxs, jsx } from '@emotion/react/jsx-runtime';
10
+
11
+ const TEXTINPUT_SIZE_HEIGHT = {
12
+ large: 48,
13
+ medium: 40,
14
+ small: 32
15
+ };
16
+ const BasicPrefixStack = /*#__PURE__*/_styled(Stack, {
17
+ target: "e7tir8v5"
18
+ })("padding:", ({
19
+ theme
20
+ }) => theme.space['2'], ";border-right:1px solid;border-color:inherit;");
21
+ const StateStack = /*#__PURE__*/_styled(Stack, {
22
+ target: "e7tir8v4"
23
+ })("padding:", ({
24
+ theme
25
+ }) => `0 ${theme.space['2']}`, ";");
26
+ const BasicSuffixStack = /*#__PURE__*/_styled(Stack, {
27
+ target: "e7tir8v3"
28
+ })("padding:", ({
29
+ theme
30
+ }) => `0 ${theme.space['2']}`, ";border-left:1px solid;border-color:inherit;");
31
+ const CTASuffixStack = /*#__PURE__*/_styled(Stack, {
32
+ target: "e7tir8v2"
33
+ })("padding:", ({
34
+ theme
35
+ }) => `0 ${theme.space['1']}`, ";border-left:1px solid;border-color:inherit;");
36
+ const StyledInput = /*#__PURE__*/_styled('input', {
37
+ shouldForwardProp: prop => !['isSuccess', 'isError', 'isClearable'].includes(prop),
38
+ target: "e7tir8v1"
39
+ })("flex:1;border:none;outline:none;height:100%;padding-left:", ({
40
+ theme
41
+ }) => theme.space['2'], ";background:transparent;");
42
+ const StyledInputWrapper = /*#__PURE__*/_styled('div', {
43
+ shouldForwardProp: prop => !['hasFocus', 'size'].includes(prop),
44
+ target: "e7tir8v0"
45
+ })("display:flex;flex-direction:row;height:", ({
46
+ size
47
+ }) => TEXTINPUT_SIZE_HEIGHT[size], "px;background:", ({
48
+ theme
49
+ }) => theme.colors.neutral.background, ";border:1px solid ", ({
50
+ theme
51
+ }) => theme.colors.neutral.border, ";border-radius:", ({
52
+ theme
53
+ }) => theme.radii.default, ";&>", StyledInput, "{color:", ({
54
+ theme
55
+ }) => theme.colors.neutral.text, ";&::placeholder{color:", ({
56
+ theme
57
+ }) => theme.colors.neutral.textWeak, ";}}&[data-success='true']{border-color:", ({
58
+ theme
59
+ }) => theme.colors.success.border, ";}&[data-error='true']{border-color:", ({
60
+ theme
61
+ }) => theme.colors.danger.border, ";}&[data-readOnly='true']{background:", ({
62
+ theme
63
+ }) => theme.colors.neutral.backgroundWeak, ";border-color:", ({
64
+ theme
65
+ }) => theme.colors.neutral.border, ";}&[data-disabled='true']{background:", ({
66
+ theme
67
+ }) => theme.colors.neutral.backgroundDisabled, ";border-color:", ({
68
+ theme
69
+ }) => theme.colors.neutral.borderDisabled, ";&>", StyledInput, "{color:", ({
70
+ theme
71
+ }) => theme.colors.neutral.textDisabled, ";&::placeholder{color:", ({
72
+ theme
73
+ }) => theme.colors.neutral.textWeakDisabled, ";}}}&:not([data-disabled='true']):not([data-readOnly]):hover{border-color:", ({
74
+ theme
75
+ }) => theme.colors.primary.border, ";}", ({
76
+ theme,
77
+ hasFocus
78
+ }) => hasFocus ? `
79
+ box-shadow: ${theme.shadows.focusPrimary};
80
+ border: 1px solid ${theme.colors.primary.border};
81
+ ` : null, ";");
82
+ /**
83
+ * This component offers an extended input HTML
84
+ */
85
+ const TextInput = /*#__PURE__*/forwardRef(({
86
+ id,
87
+ className,
88
+ tabIndex,
89
+ value,
90
+ onChange,
91
+ placeholder,
92
+ disabled = false,
93
+ readOnly = false,
94
+ success,
95
+ error,
96
+ helper,
97
+ tooltip,
98
+ label,
99
+ autoFocus,
100
+ required = false,
101
+ 'data-testid': dataTestId,
102
+ name,
103
+ onFocus,
104
+ onBlur,
105
+ clearable = false,
106
+ labelDescription,
107
+ type = 'text',
108
+ prefix,
109
+ suffix,
110
+ iconName,
111
+ size = 'large',
112
+ loading,
113
+ onRandomize,
114
+ minLength,
115
+ maxLength
116
+ }, ref) => {
117
+ const localId = useId();
118
+ const [hasFocus, setHasFocus] = useState(false);
119
+ const [isPasswordVisible, setIsPasswordVisible] = useState(false);
120
+ const computedType = type === 'password' && isPasswordVisible ? 'text' : type;
121
+ const sentiment = useMemo(() => {
122
+ if (error) {
123
+ return 'danger';
124
+ }
125
+ if (success) {
126
+ return 'success';
127
+ }
128
+ return 'neutral';
129
+ }, [error, success]);
130
+ const computedClearable = clearable && !!value;
131
+ return jsxs(Stack, {
132
+ gap: 0.5,
133
+ className: className,
134
+ children: [jsxs(Stack, {
135
+ direction: "row",
136
+ gap: "1",
137
+ alignItems: "center",
138
+ children: [jsxs(Stack, {
139
+ direction: "row",
140
+ gap: "0.5",
141
+ alignItems: "start",
142
+ children: [jsx(Text, {
143
+ as: "label",
144
+ variant: "bodySmallStrong",
145
+ sentiment: "neutral",
146
+ htmlFor: id ?? localId,
147
+ children: label
148
+ }), required ? jsx(Icon, {
149
+ name: "asterisk",
150
+ color: "danger",
151
+ size: 8
152
+ }) : null]
153
+ }), labelDescription ?? null]
154
+ }), jsx(Tooltip, {
155
+ text: tooltip,
156
+ children: jsxs(StyledInputWrapper, {
157
+ hasFocus: hasFocus,
158
+ "data-disabled": disabled,
159
+ "data-readOnly": readOnly,
160
+ "data-success": !!success,
161
+ "data-error": !!error,
162
+ size: size,
163
+ children: [prefix ? jsx(BasicPrefixStack, {
164
+ direction: "row",
165
+ alignItems: "center",
166
+ children: jsx(Text, {
167
+ as: "span",
168
+ sentiment: "neutral",
169
+ variant: "bodySmall",
170
+ disabled: disabled,
171
+ children: prefix
172
+ })
173
+ }) : null, iconName ? jsx(Icon, {
174
+ name: iconName,
175
+ size: 16
176
+ }) : null, jsx(StyledInput, {
177
+ type: computedType,
178
+ "aria-invalid": !!error,
179
+ id: id ?? localId,
180
+ tabIndex: tabIndex,
181
+ autoFocus: autoFocus,
182
+ disabled: disabled,
183
+ ref: ref,
184
+ value: value,
185
+ onChange: event => {
186
+ onChange(event.currentTarget.value);
187
+ },
188
+ isSuccess: !!success,
189
+ isError: !!error,
190
+ isClearable: !!computedClearable,
191
+ placeholder: placeholder,
192
+ "data-testid": dataTestId,
193
+ name: name,
194
+ onFocus: event => {
195
+ setHasFocus(true);
196
+ onFocus?.(event);
197
+ },
198
+ onBlur: event => {
199
+ setHasFocus(false);
200
+ onBlur?.(event);
201
+ },
202
+ readOnly: readOnly,
203
+ minLength: minLength,
204
+ maxLength: maxLength
205
+ }), success || error || loading || computedClearable ? jsxs(StateStack, {
206
+ direction: "row",
207
+ gap: 1,
208
+ alignItems: "center",
209
+ children: [computedClearable ? jsx(Button, {
210
+ "aria-label": "clear value",
211
+ disabled: disabled || !value,
212
+ variant: "ghost",
213
+ size: size === 'small' ? 'xsmall' : 'small',
214
+ icon: "close",
215
+ onClick: () => {
216
+ onChange('');
217
+ },
218
+ sentiment: "neutral"
219
+ }) : null, success ? jsx(Icon, {
220
+ name: "checkbox-circle-outline",
221
+ color: "success",
222
+ size: 16,
223
+ disabled: disabled
224
+ }) : null, error ? jsx(Icon, {
225
+ name: "alert",
226
+ color: "danger",
227
+ size: 16,
228
+ disabled: disabled
229
+ }) : null, loading && !disabled ? jsx(Loader, {
230
+ active: true,
231
+ size: 16
232
+ }) : null]
233
+ }) : null, suffix ? jsx(BasicSuffixStack, {
234
+ direction: "row",
235
+ alignItems: "center",
236
+ children: jsx(Text, {
237
+ as: "span",
238
+ sentiment: "neutral",
239
+ variant: "bodySmall",
240
+ disabled: disabled,
241
+ children: suffix
242
+ })
243
+ }) : null, type === 'password' ? jsx(CTASuffixStack, {
244
+ direction: "row",
245
+ alignItems: "center",
246
+ children: jsx(Button, {
247
+ disabled: disabled,
248
+ "data-testid": dataTestId ? `${dataTestId}-visibility-button` : undefined,
249
+ "aria-label": isPasswordVisible ? 'hide' : 'show',
250
+ onClick: () => {
251
+ setIsPasswordVisible(!isPasswordVisible);
252
+ },
253
+ variant: "ghost",
254
+ sentiment: "neutral",
255
+ icon: isPasswordVisible ? 'eye-off' : 'eye',
256
+ size: size === 'small' ? 'xsmall' : 'small'
257
+ })
258
+ }) : null, onRandomize ? jsx(CTASuffixStack, {
259
+ direction: "row",
260
+ alignItems: "center",
261
+ children: jsx(Button, {
262
+ disabled: disabled,
263
+ icon: "auto-fix",
264
+ size: size === 'small' ? 'xsmall' : 'small',
265
+ variant: "ghost",
266
+ sentiment: "neutral",
267
+ onClick: onRandomize
268
+ })
269
+ }) : null]
270
+ })
271
+ }), error || success || typeof helper === 'string' ? jsx(Text, {
272
+ as: "p",
273
+ variant: "caption",
274
+ sentiment: sentiment,
275
+ prominence: !error && !success ? 'weak' : 'default',
276
+ disabled: disabled,
277
+ children: error || success || helper
278
+ }) : null, !error && !success && typeof helper !== 'string' && helper ? helper : null]
279
+ });
280
+ });
281
+
282
+ export { TEXTINPUT_SIZE_HEIGHT, TextInput };
@@ -6,6 +6,5 @@ const isJSONString = str => {
6
6
  }
7
7
  return true;
8
8
  };
9
- var isJSONString$1 = isJSONString;
10
9
 
11
- export { isJSONString$1 as default };
10
+ export { isJSONString as default };
@@ -7,6 +7,5 @@ const recursivelyGetChildrenString = children => {
7
7
  }
8
8
  return '';
9
9
  };
10
- var recursivelyGetChildrenString$1 = recursivelyGetChildrenString;
11
10
 
12
- export { recursivelyGetChildrenString$1 as default };
11
+ export { recursivelyGetChildrenString as default };
package/dist/src/index.js CHANGED
@@ -32,6 +32,7 @@ export { Modal } from './components/Modal/index.js';
32
32
  export { Notice } from './components/Notice/index.js';
33
33
  export { CheckboxGroup, CheckboxGroupCheckbox } from './components/CheckboxGroup/index.js';
34
34
  export { NumberInput } from './components/NumberInput/index.js';
35
+ export { NumberInputV2 } from './components/NumberInputV2/index.js';
35
36
  export { Pagination } from './components/Pagination/index.js';
36
37
  export { PasswordCheck } from './components/PasswordCheck/index.js';
37
38
  export { PasswordStrengthMeter } from './components/PasswordStrengthMeter/index.js';
@@ -59,6 +60,7 @@ export { TagList } from './components/TagList/index.js';
59
60
  export { Text } from './components/Text/index.js';
60
61
  export { TextArea } from './components/TextArea/index.js';
61
62
  export { TextInput } from './components/TextInput/index.js';
63
+ export { TextInput as TextInputV2 } from './components/TextInputV2/index.js';
62
64
  export { TimeInput } from './components/TimeInput/index.js';
63
65
  export { ToastContainer, toast } from './components/Toaster/index.js';
64
66
  export { Toggle } from './components/Toggle/index.js';
@@ -1,4 +1,3 @@
1
1
  const capitalize = value => value.charAt(0).toUpperCase() + value.slice(1);
2
- var capitalize$1 = capitalize;
3
2
 
4
- export { capitalize$1 as default };
3
+ export { capitalize as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultraviolet/ui",
3
- "version": "1.30.0",
3
+ "version": "1.31.0",
4
4
  "description": "Ultraviolet UI",
5
5
  "homepage": "https://github.com/scaleway/ultraviolet#readme",
6
6
  "repository": {
@@ -67,7 +67,7 @@
67
67
  "react-use-clipboard": "1.0.9",
68
68
  "reakit": "1.3.11",
69
69
  "@ultraviolet/themes": "1.7.0",
70
- "@ultraviolet/icons": "2.7.6"
70
+ "@ultraviolet/icons": "2.7.7"
71
71
  },
72
72
  "scripts": {
73
73
  "build": "rollup -c ../../rollup.config.mjs",