infinity-ui-elements 1.3.0 → 1.4.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/README.md +62 -1
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts +49 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox/Checkbox.stories.d.ts +23 -0
- package/dist/components/Checkbox/Checkbox.stories.d.ts.map +1 -0
- package/dist/components/Checkbox/index.d.ts +3 -0
- package/dist/components/Checkbox/index.d.ts.map +1 -0
- package/dist/components/FormFooter/FormFooter.d.ts +38 -0
- package/dist/components/FormFooter/FormFooter.d.ts.map +1 -0
- package/dist/components/FormFooter/FormFooter.stories.d.ts +50 -0
- package/dist/components/FormFooter/FormFooter.stories.d.ts.map +1 -0
- package/dist/components/FormFooter/index.d.ts +3 -0
- package/dist/components/FormFooter/index.d.ts.map +1 -0
- package/dist/components/FormHeader/FormHeader.d.ts +58 -0
- package/dist/components/FormHeader/FormHeader.d.ts.map +1 -0
- package/dist/components/FormHeader/FormHeader.stories.d.ts +65 -0
- package/dist/components/FormHeader/FormHeader.stories.d.ts.map +1 -0
- package/dist/components/FormHeader/index.d.ts +3 -0
- package/dist/components/FormHeader/index.d.ts.map +1 -0
- package/dist/components/Text/Text.d.ts +2 -9
- package/dist/components/Text/Text.d.ts.map +1 -1
- package/dist/components/Text/index.d.ts +1 -1
- package/dist/components/Text/index.d.ts.map +1 -1
- package/dist/components/TextArea/TextArea.d.ts +31 -0
- package/dist/components/TextArea/TextArea.d.ts.map +1 -0
- package/dist/components/TextArea/TextArea.stories.d.ts +27 -0
- package/dist/components/TextArea/TextArea.stories.d.ts.map +1 -0
- package/dist/components/TextArea/index.d.ts +3 -0
- package/dist/components/TextArea/index.d.ts.map +1 -0
- package/dist/components/TextField/TextField.d.ts +4 -0
- package/dist/components/TextField/TextField.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +511 -172
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +520 -172
- package/dist/index.js.map +1 -1
- package/dist/lib/icons.d.ts +96 -0
- package/dist/lib/icons.d.ts.map +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,6 +32,18 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
|
32
32
|
const CUSTOM_CLASS_PATTERNS = [
|
|
33
33
|
// Custom font classes
|
|
34
34
|
/^font-(functional|display)$/,
|
|
35
|
+
// Custom font-size classes
|
|
36
|
+
/^font-size-/,
|
|
37
|
+
// Custom leading (line-height) classes
|
|
38
|
+
/^leading-(00|25|50|75|100|200|300|400|500|600|700|800|900|1000|1100)$/,
|
|
39
|
+
// Custom text utility classes (text-display, text-heading, text-body, text-caption variants)
|
|
40
|
+
/^text-(display|heading|body|caption)(-\w+)?(-\w+)?$/,
|
|
41
|
+
// Text weight classes
|
|
42
|
+
/^text-weight-/,
|
|
43
|
+
// Text color classes
|
|
44
|
+
/^text-color-/,
|
|
45
|
+
/^outline-width-/,
|
|
46
|
+
/^border-width-/,
|
|
35
47
|
// Custom spacing classes (example)
|
|
36
48
|
// /^spacing-(xs|sm|md|lg|xl)$/,
|
|
37
49
|
// Custom color classes (example)
|
|
@@ -54,7 +66,7 @@ function cn(...inputs) {
|
|
|
54
66
|
return clsx.clsx(mergedStandard, customClasses);
|
|
55
67
|
}
|
|
56
68
|
|
|
57
|
-
const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-center whitespace-nowrap
|
|
69
|
+
const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-center whitespace-nowrap ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none", {
|
|
58
70
|
variants: {
|
|
59
71
|
variant: {
|
|
60
72
|
primary: "bg-action-fill-primary-default text-action-ink-on-primary-normal hover:bg-action-fill-primary-hover",
|
|
@@ -70,10 +82,10 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
70
82
|
neutral: "",
|
|
71
83
|
},
|
|
72
84
|
size: {
|
|
73
|
-
xsmall: "md:h-[28px] px-3
|
|
74
|
-
small: "md:h-[32px] px-4
|
|
75
|
-
medium: "md:h-[36px] px-6 py-2 rounded-medium",
|
|
76
|
-
large: "md:h-[44px] px-6
|
|
85
|
+
xsmall: "md:h-[28px] px-3 rounded-medium text-body-small-medium",
|
|
86
|
+
small: "md:h-[32px] px-4 rounded-medium text-body-small-medium",
|
|
87
|
+
medium: "md:h-[36px] px-6 py-2 rounded-medium text-body-medium-medium",
|
|
88
|
+
large: "md:h-[44px] px-6 rounded-xlarge text-body-large-medium",
|
|
77
89
|
},
|
|
78
90
|
isIconOnly: {
|
|
79
91
|
true: "aspect-square p-0",
|
|
@@ -100,7 +112,8 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
100
112
|
class: `bg-action-fill-primary-default text-action-ink-on-primary-normal
|
|
101
113
|
hover:bg-action-fill-primary-hover
|
|
102
114
|
disabled:bg-action-fill-primary-disabled
|
|
103
|
-
disabled:text-action-ink-primary-disabled
|
|
115
|
+
disabled:text-action-ink-primary-disabled,
|
|
116
|
+
active:bg-action-fill-primary-activated
|
|
104
117
|
`,
|
|
105
118
|
},
|
|
106
119
|
{
|
|
@@ -110,6 +123,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
110
123
|
hover:bg-action-fill-positive-hover
|
|
111
124
|
disabled:bg-action-fill-primary-disabled
|
|
112
125
|
disabled:text-action-ink-primary-disabled
|
|
126
|
+
active:bg-action-fill-positive-activated
|
|
113
127
|
`,
|
|
114
128
|
},
|
|
115
129
|
{
|
|
@@ -119,6 +133,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
119
133
|
hover:bg-action-fill-negative-hover
|
|
120
134
|
disabled:bg-action-fill-negative-disabled
|
|
121
135
|
disabled:text-action-ink-negative-disabled
|
|
136
|
+
active:bg-action-fill-negative-activated
|
|
122
137
|
`,
|
|
123
138
|
},
|
|
124
139
|
{
|
|
@@ -128,6 +143,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
128
143
|
hover:bg-action-fill-notice-hover
|
|
129
144
|
disabled:bg-action-fill-notice-disabled
|
|
130
145
|
disabled:text-action-ink-notice-disabled
|
|
146
|
+
active:bg-action-fill-notice-activated
|
|
131
147
|
`,
|
|
132
148
|
},
|
|
133
149
|
{
|
|
@@ -137,6 +153,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
137
153
|
hover:bg-action-fill-info-hover
|
|
138
154
|
disabled:bg-action-fill-info-disabled
|
|
139
155
|
disabled:text-action-ink-info-disabled
|
|
156
|
+
active:bg-action-fill-info-activated
|
|
140
157
|
`,
|
|
141
158
|
},
|
|
142
159
|
{
|
|
@@ -146,42 +163,96 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
146
163
|
hover:bg-action-fill-neutral-hover
|
|
147
164
|
disabled:bg-action-fill-neutral-disabled
|
|
148
165
|
disabled:text-action-ink-neutral-disabled
|
|
166
|
+
active:bg-action-fill-neutral-activated
|
|
149
167
|
`,
|
|
150
168
|
},
|
|
151
169
|
// Secondary variant colors
|
|
152
170
|
{
|
|
153
171
|
variant: "secondary",
|
|
154
172
|
color: "primary",
|
|
155
|
-
class: `
|
|
173
|
+
class: `
|
|
174
|
+
border-action-outline-info-faded
|
|
175
|
+
text-action-ink-primary-normal
|
|
176
|
+
hover:border-action-outline-primary-faded-hover
|
|
177
|
+
hover:bg-action-fill-primary-faded-hover
|
|
156
178
|
disabled:bg-action-outline-info-disabled
|
|
157
179
|
disabled:text-action-ink-primary-disabled
|
|
158
180
|
disabled:border-action-outline-primary-disabled
|
|
181
|
+
active:border-action-outline-primary-faded-activated
|
|
182
|
+
active:bg-action-fill-primary-faded-activated
|
|
159
183
|
`,
|
|
160
184
|
},
|
|
161
185
|
{
|
|
162
186
|
variant: "secondary",
|
|
163
187
|
color: "positive",
|
|
164
|
-
class:
|
|
188
|
+
class: `
|
|
189
|
+
border-action-outline-positive-faded
|
|
190
|
+
text-action-ink-positive-normal
|
|
191
|
+
hover:border-action-outline-positive-faded-hover
|
|
192
|
+
hover:bg-action-fill-positive-faded-hover
|
|
193
|
+
disabled:bg-action-outline-positive-disabled
|
|
194
|
+
disabled:text-action-ink-positive-disabled
|
|
195
|
+
disabled:border-action-outline-positive-disabled
|
|
196
|
+
active:border-action-outline-positive-faded-activated
|
|
197
|
+
active:bg-action-fill-positive-faded-activated
|
|
198
|
+
`,
|
|
165
199
|
},
|
|
166
200
|
{
|
|
167
201
|
variant: "secondary",
|
|
168
202
|
color: "negative",
|
|
169
|
-
class:
|
|
203
|
+
class: `
|
|
204
|
+
border-action-outline-negative-faded
|
|
205
|
+
text-action-ink-negative-normal
|
|
206
|
+
hover:border-action-outline-negative-faded-hover
|
|
207
|
+
hover:bg-action-fill-negative-faded-hover
|
|
208
|
+
disabled:bg-action-outline-negative-disabled
|
|
209
|
+
disabled:text-action-ink-negative-disabled
|
|
210
|
+
disabled:border-action-outline-negative-disabled
|
|
211
|
+
active:border-action-outline-negative-faded-activated
|
|
212
|
+
active:bg-action-fill-negative-faded-activated
|
|
213
|
+
`,
|
|
170
214
|
},
|
|
171
215
|
{
|
|
172
216
|
variant: "secondary",
|
|
173
217
|
color: "notice",
|
|
174
|
-
class:
|
|
218
|
+
class: `
|
|
219
|
+
border-action-outline-notice-faded
|
|
220
|
+
text-action-ink-notice-normal
|
|
221
|
+
hover:border-action-outline-notice-faded-hover
|
|
222
|
+
hover:bg-action-fill-notice-faded-hover
|
|
223
|
+
disabled:bg-action-outline-notice-disabled
|
|
224
|
+
disabled:text-action-ink-notice-disabled
|
|
225
|
+
disabled:border-action-outline-notice-disabled
|
|
226
|
+
active:border-action-outline-notice-faded-activated
|
|
227
|
+
active:bg-action-fill-notice-faded-activated
|
|
228
|
+
`,
|
|
175
229
|
},
|
|
176
230
|
{
|
|
177
231
|
variant: "secondary",
|
|
178
232
|
color: "info",
|
|
179
|
-
class:
|
|
233
|
+
class: `border-action-outline-info-faded
|
|
234
|
+
text-action-ink-info-normal
|
|
235
|
+
hover:border-action-outline-info-faded-hover
|
|
236
|
+
hover:bg-action-fill-info-faded-hover
|
|
237
|
+
disabled:bg-action-outline-info-disabled
|
|
238
|
+
disabled:text-action-ink-info-disabled
|
|
239
|
+
disabled:border-action-outline-info-disabled
|
|
240
|
+
active:border-action-outline-info-faded-activated
|
|
241
|
+
active:bg-action-fill-info-faded-activated
|
|
242
|
+
`,
|
|
180
243
|
},
|
|
181
244
|
{
|
|
182
245
|
variant: "secondary",
|
|
183
246
|
color: "neutral",
|
|
184
|
-
class:
|
|
247
|
+
class: `border-action-outline-neutral-faded
|
|
248
|
+
text-action-ink-neutral-normal
|
|
249
|
+
hover:bg-action-outline-neutral-faded-hover
|
|
250
|
+
hover:bg-action-fill-neutral-faded-hover
|
|
251
|
+
disabled:text-action-ink-neutral-disabled
|
|
252
|
+
disabled:border-action-outline-neutral-disabled
|
|
253
|
+
active:border-action-outline-neutral-faded-activated
|
|
254
|
+
active:bg-action-fill-neutral-faded-activated
|
|
255
|
+
`,
|
|
185
256
|
},
|
|
186
257
|
// Tertiary variant colors
|
|
187
258
|
{
|
|
@@ -190,6 +261,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
190
261
|
class: `text-action-ink-primary-normal
|
|
191
262
|
hover:bg-action-fill-primary-faded
|
|
192
263
|
disabled:text-action-ink-on-primary-muted
|
|
264
|
+
active:bg-action-fill-primary-faded-activated
|
|
193
265
|
`,
|
|
194
266
|
},
|
|
195
267
|
{
|
|
@@ -198,6 +270,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
198
270
|
class: `text-action-ink-positive-normal
|
|
199
271
|
hover:bg-action-fill-positive-faded
|
|
200
272
|
disabled:text-action-ink-on-positive-muted
|
|
273
|
+
active:bg-action-fill-positive-faded-activated
|
|
201
274
|
`,
|
|
202
275
|
},
|
|
203
276
|
{
|
|
@@ -206,6 +279,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
206
279
|
class: `text-action-ink-negative-normal
|
|
207
280
|
hover:bg-action-fill-negative-faded
|
|
208
281
|
disabled:text-action-ink-on-negative-muted
|
|
282
|
+
active:bg-action-fill-negative-faded-activated
|
|
209
283
|
`,
|
|
210
284
|
},
|
|
211
285
|
{
|
|
@@ -214,6 +288,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
214
288
|
class: `text-action-ink-notice-normal
|
|
215
289
|
hover:bg-action-fill-notice-faded
|
|
216
290
|
disabled:text-action-ink-on-notice-muted
|
|
291
|
+
active:bg-action-fill-notice-faded-activated
|
|
217
292
|
`,
|
|
218
293
|
},
|
|
219
294
|
{
|
|
@@ -222,6 +297,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
222
297
|
class: `text-action-ink-info-normal
|
|
223
298
|
hover:bg-action-fill-info-faded
|
|
224
299
|
disabled:text-action-ink-on-notice-muted
|
|
300
|
+
active:bg-action-fill-info-faded-activated
|
|
225
301
|
`,
|
|
226
302
|
},
|
|
227
303
|
{
|
|
@@ -230,6 +306,7 @@ const buttonVariants = classVarianceAuthority.cva("items-center gap-3 justify-ce
|
|
|
230
306
|
class: `text-action-ink-neutral-normal
|
|
231
307
|
hover:bg-action-fill-neutral-faded
|
|
232
308
|
disabled:text-action-ink-on-notice-muted
|
|
309
|
+
active:bg-action-fill-neutral-faded-activated
|
|
233
310
|
`,
|
|
234
311
|
},
|
|
235
312
|
// Icon only sizing
|
|
@@ -279,174 +356,318 @@ const Button = React__namespace.forwardRef(({ className, variant = "primary", co
|
|
|
279
356
|
});
|
|
280
357
|
Button.displayName = "Button";
|
|
281
358
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
h5: "",
|
|
317
|
-
h6: "",
|
|
318
|
-
p: "",
|
|
319
|
-
span: "",
|
|
320
|
-
div: "",
|
|
321
|
-
label: "",
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
compoundVariants: [
|
|
325
|
-
// Display variants use Clash Grotesk with medium weight
|
|
326
|
-
{
|
|
327
|
-
variant: "display",
|
|
328
|
-
weight: "regular",
|
|
329
|
-
class: "font-medium",
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
variant: "display",
|
|
333
|
-
weight: "medium",
|
|
334
|
-
class: "font-medium",
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
variant: "display",
|
|
338
|
-
weight: "semibold",
|
|
339
|
-
class: "font-medium",
|
|
340
|
-
},
|
|
341
|
-
// Caption is always semibold
|
|
342
|
-
{
|
|
343
|
-
variant: "caption",
|
|
344
|
-
weight: "regular",
|
|
345
|
-
class: "font-semibold",
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
variant: "caption",
|
|
349
|
-
weight: "medium",
|
|
350
|
-
class: "font-semibold",
|
|
351
|
-
},
|
|
352
|
-
{
|
|
353
|
-
variant: "caption",
|
|
354
|
-
weight: "semibold",
|
|
355
|
-
class: "font-semibold",
|
|
359
|
+
// Helper function to get the text utility class name
|
|
360
|
+
function getTextClassName(variant = "body", size = "medium", weight = "regular", color = "default") {
|
|
361
|
+
// Build the base class name
|
|
362
|
+
let baseClass = `text-${variant}`;
|
|
363
|
+
// Add size
|
|
364
|
+
if (size) {
|
|
365
|
+
baseClass += `-${size}`;
|
|
366
|
+
}
|
|
367
|
+
// Add weight
|
|
368
|
+
if (weight) {
|
|
369
|
+
baseClass += `-${weight}`;
|
|
370
|
+
}
|
|
371
|
+
// Add color class separately
|
|
372
|
+
const colorClass = `text-color-${color}`;
|
|
373
|
+
return `${baseClass} ${colorClass}`;
|
|
374
|
+
}
|
|
375
|
+
const Text = React__namespace.forwardRef(({ className, variant = "body", size = "medium", weight = "regular", color = "default", as = "p", children, ...props }, ref) => {
|
|
376
|
+
const Component = as;
|
|
377
|
+
const textClass = getTextClassName(variant, size, weight, color);
|
|
378
|
+
return React__namespace.createElement(Component, {
|
|
379
|
+
className: cn(textClass, className),
|
|
380
|
+
ref,
|
|
381
|
+
...props,
|
|
382
|
+
}, children);
|
|
383
|
+
});
|
|
384
|
+
Text.displayName = "Text";
|
|
385
|
+
|
|
386
|
+
const FormFooter = React__namespace.forwardRef(({ helperText, trailingText, validationState = "default", size = "medium", isDisabled = false, className, helperTextClassName, trailingTextClassName, }, ref) => {
|
|
387
|
+
// Size-based configurations
|
|
388
|
+
const sizeConfig = {
|
|
389
|
+
small: {
|
|
390
|
+
textSize: "xsmall",
|
|
391
|
+
iconSize: 12,
|
|
392
|
+
gap: "gap-1",
|
|
356
393
|
},
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
size: "xlarge",
|
|
362
|
-
class: "font-size-1100 leading-1100 tracking-[0%] mb-0",
|
|
394
|
+
medium: {
|
|
395
|
+
textSize: "small",
|
|
396
|
+
iconSize: 14,
|
|
397
|
+
gap: "gap-1",
|
|
363
398
|
},
|
|
364
|
-
{
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
399
|
+
large: {
|
|
400
|
+
textSize: "medium",
|
|
401
|
+
iconSize: 16,
|
|
402
|
+
gap: "gap-1.5",
|
|
368
403
|
},
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
404
|
+
};
|
|
405
|
+
const config = sizeConfig[size];
|
|
406
|
+
// Determine text color based on validation state and disabled state
|
|
407
|
+
const getTextColor = () => {
|
|
408
|
+
if (isDisabled)
|
|
409
|
+
return "disabled";
|
|
410
|
+
if (validationState === "positive")
|
|
411
|
+
return "positive";
|
|
412
|
+
if (validationState === "negative")
|
|
413
|
+
return "negative";
|
|
414
|
+
if (validationState === "default")
|
|
415
|
+
return "default";
|
|
416
|
+
return "default";
|
|
417
|
+
};
|
|
418
|
+
// Don't render anything if there's no content
|
|
419
|
+
if (!helperText && !trailingText) {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("flex items-center justify-between px-1", config.gap, className), children: [helperText && (jsxRuntime.jsxs("div", { className: cn("flex items-center", config.gap), children: [validationState === "positive" && (jsxRuntime.jsx("svg", { width: config.iconSize, height: config.iconSize, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "text-feedback-ink-positive-intense shrink-0", children: jsxRuntime.jsx("path", { d: "M3 7L6 10L11 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })), validationState === "negative" && (jsxRuntime.jsxs("svg", { width: config.iconSize, height: config.iconSize, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "text-feedback-ink-negative-subtle shrink-0", children: [jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "6", stroke: "currentColor", strokeWidth: "1" }), jsxRuntime.jsx("path", { d: "M7 4V7.5M7 10V9.5", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round" })] })), jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "regular", color: getTextColor(), className: cn("italic font-size-100 leading-100", helperTextClassName), children: helperText })] })), trailingText && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "regular", color: isDisabled ? "disabled" : "muted", className: cn("font-size-100 leading-100 shrink-0", trailingTextClassName), children: trailingText }))] }));
|
|
423
|
+
});
|
|
424
|
+
FormFooter.displayName = "FormFooter";
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* ==============================================
|
|
428
|
+
* HOW TO ADD A NEW ICON:
|
|
429
|
+
* ==============================================
|
|
430
|
+
*
|
|
431
|
+
* 1. Add your SVG file to: src/assets/icons/{iconName}.svg
|
|
432
|
+
*
|
|
433
|
+
* 2. Copy the SVG content from the file
|
|
434
|
+
*
|
|
435
|
+
* 3. Add it to the iconRegistry below:
|
|
436
|
+
* iconName: `<svg>...</svg>`,
|
|
437
|
+
*
|
|
438
|
+
* 4. Use it anywhere in your app:
|
|
439
|
+
* <Icon name="iconName" size={24} />
|
|
440
|
+
*
|
|
441
|
+
* The Icon component will automatically:
|
|
442
|
+
* - Replace hardcoded colors with currentColor
|
|
443
|
+
* - Allow you to control color via className or style
|
|
444
|
+
* - Resize based on the size prop
|
|
445
|
+
* ==============================================
|
|
446
|
+
*/
|
|
447
|
+
/**
|
|
448
|
+
* Icon registry - maps icon names to their SVG content
|
|
449
|
+
* Add your icons here by copying the SVG content from your icon files
|
|
450
|
+
*/
|
|
451
|
+
const iconRegistry = {
|
|
452
|
+
// Tick/Check icon
|
|
453
|
+
tick: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
454
|
+
<path d="M10.364 15.1924L19.5564 6L20.9706 7.41421L10.364 18.0208L4 11.6569L5.41422 10.2427L10.364 15.1924Z" fill="#081416"/>
|
|
455
|
+
</svg>`,
|
|
456
|
+
// Alias: check points to the same icon as tick
|
|
457
|
+
check: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
458
|
+
<path d="M10.364 15.1924L19.5564 6L20.9706 7.41421L10.364 18.0208L4 11.6569L5.41422 10.2427L10.364 15.1924Z" fill="#081416"/>
|
|
459
|
+
</svg>`,
|
|
460
|
+
};
|
|
461
|
+
const Icon = ({ name, size = 24, className = "", style = {}, ...props }) => {
|
|
462
|
+
const svgContent = iconRegistry[name];
|
|
463
|
+
if (!svgContent) {
|
|
464
|
+
console.warn(`Icon "${String(name)}" not found in registry.\n` +
|
|
465
|
+
`Available icons: ${Object.keys(iconRegistry).join(", ")}`);
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
// Parse the SVG content
|
|
469
|
+
const parser = new DOMParser();
|
|
470
|
+
const svgDoc = parser.parseFromString(svgContent, "image/svg+xml");
|
|
471
|
+
const svgElement = svgDoc.querySelector("svg");
|
|
472
|
+
if (!svgElement) {
|
|
473
|
+
console.error(`Invalid SVG content for icon "${String(name)}"`);
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
// Extract viewBox attribute
|
|
477
|
+
const viewBox = svgElement.getAttribute("viewBox") || "0 0 24 24";
|
|
478
|
+
let innerHTML = svgElement.innerHTML;
|
|
479
|
+
// Replace hardcoded fill and stroke colors with currentColor
|
|
480
|
+
// This allows the icon color to be controlled via CSS color property
|
|
481
|
+
innerHTML = innerHTML
|
|
482
|
+
.replace(/fill="[^"]*"/g, 'fill="currentColor"')
|
|
483
|
+
.replace(/stroke="[^"]*"/g, 'stroke="currentColor"');
|
|
484
|
+
return (jsxRuntime.jsx("svg", { width: size, height: size, viewBox: viewBox, fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, style: style, ...props, dangerouslySetInnerHTML: { __html: innerHTML } }));
|
|
485
|
+
};
|
|
486
|
+
Icon.displayName = "Icon";
|
|
487
|
+
/**
|
|
488
|
+
* Get all available icon names from the registry
|
|
489
|
+
* @returns Array of registered icon names
|
|
490
|
+
*
|
|
491
|
+
* @example
|
|
492
|
+
* ```tsx
|
|
493
|
+
* const icons = getAvailableIcons();
|
|
494
|
+
* console.log(icons); // ['tick', 'check', ...]
|
|
495
|
+
* ```
|
|
496
|
+
*/
|
|
497
|
+
function getAvailableIcons() {
|
|
498
|
+
return Object.keys(iconRegistry);
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Check if an icon exists in the registry
|
|
502
|
+
* @param name - Icon name to check
|
|
503
|
+
* @returns true if the icon exists
|
|
504
|
+
*
|
|
505
|
+
* @example
|
|
506
|
+
* ```tsx
|
|
507
|
+
* if (hasIcon('tick')) {
|
|
508
|
+
* // Icon exists
|
|
509
|
+
* }
|
|
510
|
+
* ```
|
|
511
|
+
*/
|
|
512
|
+
function hasIcon(name) {
|
|
513
|
+
return name in iconRegistry;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const checkboxVariants = classVarianceAuthority.cva("relative inline-flex items-center justify-center shrink-0 border transition-all cursor-pointer", {
|
|
517
|
+
variants: {
|
|
518
|
+
size: {
|
|
519
|
+
small: "w-[14px] h-[14px] rounded-small border-[1.5px]",
|
|
520
|
+
medium: "w-[16px] h-[16px] rounded-small border-[1.5px]",
|
|
521
|
+
large: "w-[20px] h-[20px] rounded-medium border-[2px]",
|
|
384
522
|
},
|
|
385
|
-
{
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
class: "font-size-600 leading-600 tracking-[0%] mb-0",
|
|
523
|
+
validationState: {
|
|
524
|
+
none: "",
|
|
525
|
+
error: "border-action-outline-negative-default hover:border-action-outline-negative-hover focus:ring-2 ring-action-outline-negative-faded-hover",
|
|
389
526
|
},
|
|
390
|
-
{
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
class: "font-size-500 leading-500 tracking-[0%] mb-0",
|
|
527
|
+
isChecked: {
|
|
528
|
+
true: "",
|
|
529
|
+
false: "",
|
|
394
530
|
},
|
|
395
|
-
{
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
class: "font-size-400 leading-400 tracking-[0%] mb-0",
|
|
531
|
+
isIndeterminate: {
|
|
532
|
+
true: "",
|
|
533
|
+
false: "",
|
|
399
534
|
},
|
|
400
|
-
{
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
class: "font-size-300 leading-300 tracking-[0%] mb-0",
|
|
535
|
+
isDisabled: {
|
|
536
|
+
true: "cursor-not-allowed opacity-60 border-action-outline-neutral-disabled bg-surface-fill-neutral-subtle",
|
|
537
|
+
false: "",
|
|
404
538
|
},
|
|
405
|
-
|
|
539
|
+
},
|
|
540
|
+
compoundVariants: [
|
|
541
|
+
// Unchecked state - none validation
|
|
406
542
|
{
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
543
|
+
isChecked: false,
|
|
544
|
+
validationState: "none",
|
|
545
|
+
isDisabled: false,
|
|
546
|
+
class: "border-action-outline-neutral-faded hover:bg-action-fill-neutral-faded hover:border-action-outline-neutral-faded",
|
|
410
547
|
},
|
|
548
|
+
// Checked state - none validation
|
|
411
549
|
{
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
550
|
+
isChecked: true,
|
|
551
|
+
validationState: "none",
|
|
552
|
+
isDisabled: false,
|
|
553
|
+
class: "bg-action-fill-primary-hover border-surface-outline-neutral-muted",
|
|
415
554
|
},
|
|
555
|
+
// Checked or Indeterminate state - error validation
|
|
416
556
|
{
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
557
|
+
isChecked: true,
|
|
558
|
+
validationState: "error",
|
|
559
|
+
isDisabled: false,
|
|
560
|
+
class: "bg-action-fill-negative-default border-action-fill-negative-default hover:bg-action-fill-negative-hover hover:border-action-fill-negative-hover",
|
|
420
561
|
},
|
|
562
|
+
// Indeterminate state - none validation
|
|
421
563
|
{
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
564
|
+
isIndeterminate: true,
|
|
565
|
+
validationState: "none",
|
|
566
|
+
isDisabled: false,
|
|
567
|
+
class: "bg-action-fill-primary-default border-action-fill-primary-default hover:bg-action-fill-primary-hover hover:border-action-fill-primary-hover",
|
|
425
568
|
},
|
|
426
|
-
//
|
|
569
|
+
// Indeterminate state - error validation (same as checked error)
|
|
427
570
|
{
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
571
|
+
isIndeterminate: true,
|
|
572
|
+
validationState: "error",
|
|
573
|
+
isDisabled: false,
|
|
574
|
+
class: "bg-action-fill-negative-default border-action-fill-negative-default hover:bg-action-fill-negative-hover hover:border-action-fill-negative-hover",
|
|
431
575
|
},
|
|
432
576
|
],
|
|
433
577
|
defaultVariants: {
|
|
434
|
-
variant: "body",
|
|
435
578
|
size: "medium",
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
579
|
+
validationState: "none",
|
|
580
|
+
isChecked: false,
|
|
581
|
+
isIndeterminate: false,
|
|
582
|
+
isDisabled: false,
|
|
439
583
|
},
|
|
440
584
|
});
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
585
|
+
const Checkbox = React__namespace.forwardRef(({ label, errorText, size = "medium", validationState = "none", isDisabled = false, isIndeterminate = false, showErrorText = true, containerClassName, labelClassName, className, checked, onChange, ...props }, ref) => {
|
|
586
|
+
const [internalChecked, setInternalChecked] = React__namespace.useState(false);
|
|
587
|
+
const [showRipple, setShowRipple] = React__namespace.useState(false);
|
|
588
|
+
const inputRef = React__namespace.useRef(null);
|
|
589
|
+
// Use forwarded ref or internal ref
|
|
590
|
+
React__namespace.useImperativeHandle(ref, () => inputRef.current);
|
|
591
|
+
const isChecked = checked !== undefined ? checked : internalChecked;
|
|
592
|
+
// Set indeterminate property on the input element
|
|
593
|
+
React__namespace.useEffect(() => {
|
|
594
|
+
if (inputRef.current) {
|
|
595
|
+
inputRef.current.indeterminate = isIndeterminate;
|
|
596
|
+
}
|
|
597
|
+
}, [isIndeterminate]);
|
|
598
|
+
const handleChange = (e) => {
|
|
599
|
+
if (onChange) {
|
|
600
|
+
onChange(e);
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
setInternalChecked(e.target.checked);
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
const triggerRipple = () => {
|
|
607
|
+
if (!isDisabled) {
|
|
608
|
+
setShowRipple(true);
|
|
609
|
+
setTimeout(() => {
|
|
610
|
+
setShowRipple(false);
|
|
611
|
+
}, 360); // Match animation duration (0.36s)
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
const handleContainerClick = () => {
|
|
615
|
+
if (!isDisabled && inputRef.current) {
|
|
616
|
+
// Only show ripple when checking (not unchecking)
|
|
617
|
+
const willBeChecked = !isChecked && !isIndeterminate;
|
|
618
|
+
if (willBeChecked) {
|
|
619
|
+
triggerRipple();
|
|
620
|
+
}
|
|
621
|
+
inputRef.current.click();
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
const handleKeyDown = (e) => {
|
|
625
|
+
if ((e.key === " " || e.key === "Enter") && !isDisabled) {
|
|
626
|
+
e.preventDefault();
|
|
627
|
+
// Only show ripple when checking (not unchecking)
|
|
628
|
+
const willBeChecked = !isChecked && !isIndeterminate;
|
|
629
|
+
if (willBeChecked) {
|
|
630
|
+
triggerRipple();
|
|
631
|
+
}
|
|
632
|
+
inputRef.current?.click();
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
// Size-based configurations
|
|
636
|
+
const sizeConfig = {
|
|
637
|
+
small: {
|
|
638
|
+
gap: "gap-2",
|
|
639
|
+
labelSize: "text-body-small-regular",
|
|
640
|
+
iconSize: 10,
|
|
641
|
+
},
|
|
642
|
+
medium: {
|
|
643
|
+
gap: "gap-2.5",
|
|
644
|
+
labelSize: "text-body-medium-regular",
|
|
645
|
+
iconSize: 12,
|
|
646
|
+
},
|
|
647
|
+
large: {
|
|
648
|
+
gap: "gap-3",
|
|
649
|
+
labelSize: "text-body-large-regular",
|
|
650
|
+
iconSize: 14,
|
|
651
|
+
},
|
|
652
|
+
};
|
|
653
|
+
const config = sizeConfig[size];
|
|
654
|
+
// Determine if we should show the error text
|
|
655
|
+
const shouldShowError = errorText && showErrorText;
|
|
656
|
+
return (jsxRuntime.jsxs("div", { className: cn("inline-flex flex-col", containerClassName), children: [jsxRuntime.jsxs("div", { className: cn("inline-flex items-center", config.gap, isDisabled ? "cursor-not-allowed" : "cursor-pointer"), onClick: handleContainerClick, onKeyDown: handleKeyDown, role: "checkbox", "aria-checked": isIndeterminate ? "mixed" : isChecked, "aria-disabled": isDisabled, tabIndex: isDisabled ? -1 : 0, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "checkbox", className: "sr-only", checked: isChecked, onChange: handleChange, disabled: isDisabled, ...props }), jsxRuntime.jsxs("div", { className: "relative inline-flex shrink-0", children: [showRipple && (jsxRuntime.jsx("div", { className: cn("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full pointer-events-none w-full h-full", validationState === "error"
|
|
657
|
+
? "bg-action-outline-negative-faded"
|
|
658
|
+
: "bg-action-outline-primary-faded"), style: {
|
|
659
|
+
animation: "var(--animate-checkbox-ripple)",
|
|
660
|
+
} })), jsxRuntime.jsxs("div", { className: cn(checkboxVariants({
|
|
661
|
+
size,
|
|
662
|
+
validationState,
|
|
663
|
+
isChecked: isChecked && !isIndeterminate,
|
|
664
|
+
isIndeterminate,
|
|
665
|
+
isDisabled,
|
|
666
|
+
}), className), children: [isChecked && !isIndeterminate && (jsxRuntime.jsx(Icon, { name: "tick", size: config.iconSize, className: "text-action-ink-on-primary-normal" })), isIndeterminate && (jsxRuntime.jsx("svg", { width: config.iconSize, height: config.iconSize, viewBox: "0 0 12 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "text-action-ink-on-primary-normal", children: jsxRuntime.jsx("path", { d: "M3 6H9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }))] })] }), label && (jsxRuntime.jsx("label", { className: cn(config.labelSize, "select-none inline-flex items-center", isDisabled
|
|
667
|
+
? "text-surface-ink-neutral-disabled"
|
|
668
|
+
: "text-surface-ink-neutral-normal", labelClassName), children: label }))] }), shouldShowError && (jsxRuntime.jsx(FormFooter, { helperText: errorText, validationState: "negative", size: size, isDisabled: isDisabled }))] }));
|
|
448
669
|
});
|
|
449
|
-
|
|
670
|
+
Checkbox.displayName = "Checkbox";
|
|
450
671
|
|
|
451
672
|
const tooltipVariants = classVarianceAuthority.cva("fixed z-50 bg-popup-fill-intense text-action-ink-on-primary-normal rounded-medium border border-popup-outline-subtle flex flex-col p-4 rounded-xlarge min-w-[200px] max-w-[300px] transition-opacity duration-200", {
|
|
452
673
|
variants: {
|
|
@@ -678,6 +899,112 @@ const Tooltip = React__namespace.forwardRef(({ children, heading, description, p
|
|
|
678
899
|
});
|
|
679
900
|
Tooltip.displayName = "Tooltip";
|
|
680
901
|
|
|
902
|
+
const FormHeader = React__namespace.forwardRef(({ label, size = "medium", isOptional = false, isRequired = false, infoHeading, infoDescription, linkText, linkHref, onLinkClick, htmlFor, className, labelClassName, linkClassName, }, ref) => {
|
|
903
|
+
// Size-based configurations
|
|
904
|
+
const sizeConfig = {
|
|
905
|
+
small: {
|
|
906
|
+
textSize: "xsmall",
|
|
907
|
+
iconSize: 12,
|
|
908
|
+
gap: "gap-1.5",
|
|
909
|
+
},
|
|
910
|
+
medium: {
|
|
911
|
+
textSize: "small",
|
|
912
|
+
iconSize: 14,
|
|
913
|
+
gap: "gap-2",
|
|
914
|
+
},
|
|
915
|
+
large: {
|
|
916
|
+
textSize: "medium",
|
|
917
|
+
iconSize: 16,
|
|
918
|
+
gap: "gap-2.5",
|
|
919
|
+
},
|
|
920
|
+
};
|
|
921
|
+
const config = sizeConfig[size];
|
|
922
|
+
return (jsxRuntime.jsxs("div", { ref: ref, className: cn("flex items-center justify-between px-1", config.gap, className), children: [jsxRuntime.jsxs("div", { className: cn("flex items-center", config.gap), children: [jsxRuntime.jsxs("label", { htmlFor: htmlFor, className: cn("flex items-center", labelClassName), children: [jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "semibold", color: "subtle", children: label }), isRequired && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "semibold", className: "text-feedback-ink-negative-subtle ml-0.5", children: "*" })), isOptional && (jsxRuntime.jsx(Text, { as: "span", variant: "body", size: config.textSize, weight: "regular", className: "text-surface-ink-neutral-muted ml-1", children: "(optional)" }))] }), infoDescription && (jsxRuntime.jsx(Tooltip, { description: infoDescription, heading: infoHeading, children: jsxRuntime.jsxs("svg", { width: config.iconSize, height: config.iconSize, viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "text-surface-ink-neutral-muted cursor-help", children: [jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "6", stroke: "currentColor", strokeWidth: "1" }), jsxRuntime.jsx("path", { d: "M7 6V10M7 4.5V4", stroke: "currentColor", strokeWidth: "1", strokeLinecap: "round" })] }) }))] }), linkText && (jsxRuntime.jsx("a", { href: linkHref, onClick: onLinkClick, className: cn("text-surface-ink-primary-normal hover:text-surface-ink-primary-hover transition-colors cursor-pointer font-display font-semibold leading-tight shrink-0", size === "small" && "text-xs", size === "medium" && "text-xs", size === "large" && "text-sm", linkClassName), children: linkText }))] }));
|
|
923
|
+
});
|
|
924
|
+
FormHeader.displayName = "FormHeader";
|
|
925
|
+
|
|
926
|
+
const textAreaVariants = classVarianceAuthority.cva("relative flex flex-col border rounded-medium transition-all font-display font-size-100 leading-100", {
|
|
927
|
+
variants: {
|
|
928
|
+
size: {
|
|
929
|
+
small: "p-3 min-h-[56px] text-xs gap-2",
|
|
930
|
+
medium: "p-4 min-h-[56px] text-sm gap-2",
|
|
931
|
+
large: "p-5 min-h-[64px]text-base gap-3",
|
|
932
|
+
},
|
|
933
|
+
validationState: {
|
|
934
|
+
none: `
|
|
935
|
+
border-action-outline-neutral-default
|
|
936
|
+
hover:border-action-outline-primary-hover
|
|
937
|
+
focus-within:border-action-outline-primary-hover
|
|
938
|
+
focus-within:ring-2
|
|
939
|
+
ring-action-outline-primary-faded-hover`,
|
|
940
|
+
positive: `
|
|
941
|
+
border-action-outline-positive-default
|
|
942
|
+
hover:border-action-outline-positive-hover
|
|
943
|
+
focus-within:border-action-outline-positive-hover
|
|
944
|
+
focus-within:ring-2
|
|
945
|
+
ring-action-outline-positive-faded-hover`,
|
|
946
|
+
negative: `border-action-outline-negative-default
|
|
947
|
+
hover:border-action-outline-negative-hover
|
|
948
|
+
focus-within:border-action-outline-negative-hover
|
|
949
|
+
focus-within:ring-2
|
|
950
|
+
ring-action-outline-negative-faded-hover`,
|
|
951
|
+
},
|
|
952
|
+
isDisabled: {
|
|
953
|
+
true: `
|
|
954
|
+
border-[var(--border-width-thinner)]
|
|
955
|
+
hover:border-action-outline-neutral-disabled
|
|
956
|
+
border-action-outline-neutral-disabled
|
|
957
|
+
bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
|
|
958
|
+
false: "bg-surface-fill-neutral-intense",
|
|
959
|
+
},
|
|
960
|
+
},
|
|
961
|
+
defaultVariants: {
|
|
962
|
+
size: "medium",
|
|
963
|
+
validationState: "none",
|
|
964
|
+
isDisabled: false,
|
|
965
|
+
},
|
|
966
|
+
});
|
|
967
|
+
const TextArea = React__namespace.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isRequired = false, isOptional = false, maxChar, showCharCount = true, infoDescription, infoHeading, linkText, linkHref, onLinkClick, containerClassName, labelClassName, textAreaClassName, className, value, onChange, rows = 4, ...props }, ref) => {
|
|
968
|
+
const [internalValue, setInternalValue] = React__namespace.useState("");
|
|
969
|
+
const textAreaValue = value !== undefined ? value : internalValue;
|
|
970
|
+
const currentLength = String(textAreaValue).length;
|
|
971
|
+
const handleChange = (e) => {
|
|
972
|
+
const newValue = e.target.value;
|
|
973
|
+
// Prevent exceeding maxChar if specified
|
|
974
|
+
if (maxChar && newValue.length > maxChar) {
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
if (onChange) {
|
|
978
|
+
onChange(e);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
setInternalValue(newValue);
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
// Determine which helper text to show
|
|
985
|
+
const displayHelperText = errorText || successText || helperText;
|
|
986
|
+
const currentValidationState = errorText
|
|
987
|
+
? "negative"
|
|
988
|
+
: successText
|
|
989
|
+
? "positive"
|
|
990
|
+
: validationState;
|
|
991
|
+
// Check if we're approaching or at the limit
|
|
992
|
+
const isNearLimit = maxChar && currentLength >= maxChar * 0.9;
|
|
993
|
+
const isAtLimit = maxChar && currentLength >= maxChar;
|
|
994
|
+
return (jsxRuntime.jsxs("div", { className: cn("w-full flex flex-col gap-3", containerClassName), children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsx("div", { className: cn(textAreaVariants({
|
|
995
|
+
size,
|
|
996
|
+
validationState: currentValidationState,
|
|
997
|
+
isDisabled,
|
|
998
|
+
}), className), children: jsxRuntime.jsx("textarea", { ref: ref, value: textAreaValue, onChange: handleChange, disabled: isDisabled, required: isRequired, rows: rows, className: cn("flex-1 bg-transparent border-none outline-none text-surface-ink-neutral-normal placeholder:text-surface-ink-neutral-muted disabled:cursor-not-allowed disabled:text-surface-ink-neutral-disabled font-display resize-none", size === "small" && "text-xs", size === "medium" && "text-sm", size === "large" && "text-base", textAreaClassName), ...props }) }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, trailingText: maxChar && showCharCount ? `${currentLength}/${maxChar}` : undefined, validationState: currentValidationState === "none"
|
|
999
|
+
? "default"
|
|
1000
|
+
: currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1", trailingTextClassName: cn("transition-colors", isAtLimit
|
|
1001
|
+
? "text-feedback-ink-negative-subtle"
|
|
1002
|
+
: isNearLimit
|
|
1003
|
+
? "text-feedback-ink-warning-subtle"
|
|
1004
|
+
: "") })] }));
|
|
1005
|
+
});
|
|
1006
|
+
TextArea.displayName = "TextArea";
|
|
1007
|
+
|
|
681
1008
|
const textFieldVariants = classVarianceAuthority.cva("relative flex items-center gap-2 border rounded-medium transition-all font-display font-size-100 leading-100", {
|
|
682
1009
|
variants: {
|
|
683
1010
|
size: {
|
|
@@ -687,19 +1014,17 @@ const textFieldVariants = classVarianceAuthority.cva("relative flex items-center
|
|
|
687
1014
|
},
|
|
688
1015
|
validationState: {
|
|
689
1016
|
none: `
|
|
690
|
-
border-action-outline-neutral-
|
|
1017
|
+
border-action-outline-neutral-faded
|
|
691
1018
|
hover:border-action-outline-primary-hover
|
|
692
1019
|
focus-within:border-action-outline-primary-hover
|
|
693
1020
|
focus-within:ring-2
|
|
694
1021
|
ring-action-outline-primary-faded-hover`,
|
|
695
1022
|
positive: `
|
|
696
1023
|
border-action-outline-positive-default
|
|
697
|
-
hover:border-action-outline-positive-hover
|
|
698
1024
|
focus-within:border-action-outline-positive-hover
|
|
699
1025
|
focus-within:ring-2
|
|
700
1026
|
ring-action-outline-positive-faded-hover`,
|
|
701
1027
|
negative: `border-action-outline-negative-default
|
|
702
|
-
hover:border-action-outline-negative-hover
|
|
703
1028
|
focus-within:border-action-outline-negative-hover
|
|
704
1029
|
focus-within:ring-2
|
|
705
1030
|
ring-action-outline-negative-faded-hover`,
|
|
@@ -707,6 +1032,7 @@ const textFieldVariants = classVarianceAuthority.cva("relative flex items-center
|
|
|
707
1032
|
isDisabled: {
|
|
708
1033
|
true: `
|
|
709
1034
|
border-[var(--border-width-thinner)]
|
|
1035
|
+
hover:border-action-outline-neutral-disabled
|
|
710
1036
|
border-action-outline-neutral-disabled
|
|
711
1037
|
bg-surface-fill-neutral-intense cursor-not-allowed opacity-60`,
|
|
712
1038
|
false: "bg-surface-fill-neutral-intense",
|
|
@@ -718,7 +1044,7 @@ const textFieldVariants = classVarianceAuthority.cva("relative flex items-center
|
|
|
718
1044
|
isDisabled: false,
|
|
719
1045
|
},
|
|
720
1046
|
});
|
|
721
|
-
const TextField = React__namespace.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isRequired = false, prefix, suffix, showClearButton = false, infoDescription, infoHeading, onClear, containerClassName, labelClassName, inputClassName, className, value, onChange, ...props }, ref) => {
|
|
1047
|
+
const TextField = React__namespace.forwardRef(({ label, helperText, errorText, successText, size = "medium", validationState = "none", isDisabled = false, isRequired = false, isOptional = false, prefix, suffix, showClearButton = false, infoDescription, infoHeading, linkText, linkHref, onLinkClick, onClear, containerClassName, labelClassName, inputClassName, className, value, onChange, ...props }, ref) => {
|
|
722
1048
|
const [internalValue, setInternalValue] = React__namespace.useState("");
|
|
723
1049
|
const inputValue = value !== undefined ? value : internalValue;
|
|
724
1050
|
const hasValue = inputValue && String(inputValue).length > 0;
|
|
@@ -750,33 +1076,55 @@ const TextField = React__namespace.forwardRef(({ label, helperText, errorText, s
|
|
|
750
1076
|
: successText
|
|
751
1077
|
? "positive"
|
|
752
1078
|
: validationState;
|
|
753
|
-
|
|
1079
|
+
const sizeConfig = {
|
|
1080
|
+
small: {
|
|
1081
|
+
gap: "gap-2",
|
|
1082
|
+
},
|
|
1083
|
+
medium: {
|
|
1084
|
+
gap: "gap-2",
|
|
1085
|
+
},
|
|
1086
|
+
large: {
|
|
1087
|
+
gap: "gap-3",
|
|
1088
|
+
},
|
|
1089
|
+
};
|
|
1090
|
+
return (jsxRuntime.jsxs("div", { className: cn("w-full flex flex-col", sizeConfig[size].gap, containerClassName), children: [label && (jsxRuntime.jsx(FormHeader, { label: label, size: size, isRequired: isRequired, isOptional: isOptional, infoHeading: infoHeading, infoDescription: infoDescription, linkText: linkText, linkHref: linkHref, onLinkClick: onLinkClick, htmlFor: props.id, className: "mb-2", labelClassName: labelClassName })), jsxRuntime.jsxs("div", { className: cn(textFieldVariants({
|
|
754
1091
|
size,
|
|
755
1092
|
validationState: currentValidationState,
|
|
756
1093
|
isDisabled,
|
|
757
1094
|
}), className), children: [prefix && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
|
|
758
1095
|
? "text-surface-ink-neutral-disabled"
|
|
759
|
-
:
|
|
1096
|
+
: currentValidationState === "positive"
|
|
1097
|
+
? "text-feedback-ink-positive-intense"
|
|
1098
|
+
: currentValidationState === "negative"
|
|
1099
|
+
? "text-feedback-ink-negative-subtle"
|
|
1100
|
+
: "text-surface-ink-neutral-muted"), children: prefix })), jsxRuntime.jsx("input", { ref: ref, value: inputValue, onChange: handleChange, disabled: isDisabled, required: isRequired, className: cn("flex-1 bg-transparent border-none outline-none text-surface-ink-neutral-normal placeholder:text-surface-ink-neutral-muted disabled:cursor-not-allowed disabled:text-surface-ink-neutral-disabled font-display", inputClassName), ...props }), showClearButton && hasValue && !isDisabled && (jsxRuntime.jsx("button", { type: "button", onClick: handleClear, className: "shrink-0 flex items-center justify-center text-surface-ink-neutral-muted hover:text-surface-ink-neutral-normal transition-colors", tabIndex: -1, children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("path", { d: "M12 4L4 12M4 4L12 12", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })), suffix && (jsxRuntime.jsx("span", { className: cn("shrink-0 flex items-center", isDisabled
|
|
760
1101
|
? "text-surface-ink-neutral-disabled"
|
|
761
|
-
:
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
"text-feedback-ink-positive-intense", currentValidationState === "negative" &&
|
|
769
|
-
"text-feedback-ink-negative-subtle"), children: displayHelperText })] }))] }));
|
|
1102
|
+
: currentValidationState === "positive"
|
|
1103
|
+
? "text-feedback-ink-positive-intense"
|
|
1104
|
+
: currentValidationState === "negative"
|
|
1105
|
+
? "text-feedback-ink-negative-subtle"
|
|
1106
|
+
: "text-surface-ink-neutral-muted"), children: suffix }))] }), jsxRuntime.jsx(FormFooter, { helperText: displayHelperText, validationState: currentValidationState === "none"
|
|
1107
|
+
? "default"
|
|
1108
|
+
: currentValidationState, size: size, isDisabled: isDisabled, className: "mt-1" })] }));
|
|
770
1109
|
});
|
|
771
1110
|
TextField.displayName = "TextField";
|
|
772
1111
|
|
|
773
1112
|
exports.Button = Button;
|
|
1113
|
+
exports.Checkbox = Checkbox;
|
|
1114
|
+
exports.FormFooter = FormFooter;
|
|
1115
|
+
exports.FormHeader = FormHeader;
|
|
1116
|
+
exports.Icon = Icon;
|
|
774
1117
|
exports.Text = Text;
|
|
1118
|
+
exports.TextArea = TextArea;
|
|
775
1119
|
exports.TextField = TextField;
|
|
776
1120
|
exports.Tooltip = Tooltip;
|
|
777
1121
|
exports.buttonVariants = buttonVariants;
|
|
1122
|
+
exports.checkboxVariants = checkboxVariants;
|
|
778
1123
|
exports.cn = cn;
|
|
1124
|
+
exports.getAvailableIcons = getAvailableIcons;
|
|
1125
|
+
exports.hasIcon = hasIcon;
|
|
1126
|
+
exports.iconRegistry = iconRegistry;
|
|
1127
|
+
exports.textAreaVariants = textAreaVariants;
|
|
779
1128
|
exports.textFieldVariants = textFieldVariants;
|
|
780
|
-
exports.textVariants = textVariants;
|
|
781
1129
|
exports.tooltipVariants = tooltipVariants;
|
|
782
1130
|
//# sourceMappingURL=index.js.map
|