@rovula/ui 0.1.3 → 0.1.5
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/dist/cjs/bundle.css +158 -42
- package/dist/cjs/bundle.js +4 -4
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +3 -0
- package/dist/cjs/types/components/InputFilter/InputFilter.stories.d.ts +3 -0
- package/dist/cjs/types/components/MaskedTextInput/MaskedTextInput.d.ts +3 -0
- package/dist/cjs/types/components/MaskedTextInput/MaskedTextInput.stories.d.ts +6 -0
- package/dist/cjs/types/components/PasswordInput/PasswordInput.stories.d.ts +3 -0
- package/dist/cjs/types/components/Search/Search.stories.d.ts +3 -0
- package/dist/cjs/types/components/Switch/Switch.d.ts +3 -1
- package/dist/cjs/types/components/Switch/Switch.stories.d.ts +12 -4
- package/dist/cjs/types/components/Switch/Switch.styles.d.ts +7 -0
- package/dist/cjs/types/components/TextInput/TextInput.d.ts +6 -0
- package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +9 -0
- package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +4 -0
- package/dist/cjs/types/components/Toast/Toast.d.ts +1 -0
- package/dist/cjs/types/components/Toast/Toast.stories.d.ts +14 -0
- package/dist/cjs/types/components/Toast/Toast.styles.d.ts +1 -0
- package/dist/components/PasswordInput/PasswordInput.js +2 -2
- package/dist/components/PasswordInput/PasswordInput.stories.js +1 -1
- package/dist/components/Switch/Switch.js +4 -17
- package/dist/components/Switch/Switch.stories.js +12 -2
- package/dist/components/Switch/Switch.styles.js +39 -0
- package/dist/components/TextInput/TextInput.js +28 -7
- package/dist/components/TextInput/TextInput.stories.js +13 -0
- package/dist/components/TextInput/TextInput.styles.js +26 -4
- package/dist/components/Toast/Toast.js +5 -5
- package/dist/components/Toast/Toast.stories.js +11 -2
- package/dist/components/Toast/Toast.styles.js +38 -6
- package/dist/components/Toast/Toaster.js +17 -1
- package/dist/esm/bundle.css +158 -42
- package/dist/esm/bundle.js +4 -4
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +3 -0
- package/dist/esm/types/components/InputFilter/InputFilter.stories.d.ts +3 -0
- package/dist/esm/types/components/MaskedTextInput/MaskedTextInput.d.ts +3 -0
- package/dist/esm/types/components/MaskedTextInput/MaskedTextInput.stories.d.ts +6 -0
- package/dist/esm/types/components/PasswordInput/PasswordInput.stories.d.ts +3 -0
- package/dist/esm/types/components/Search/Search.stories.d.ts +3 -0
- package/dist/esm/types/components/Switch/Switch.d.ts +3 -1
- package/dist/esm/types/components/Switch/Switch.stories.d.ts +12 -4
- package/dist/esm/types/components/Switch/Switch.styles.d.ts +7 -0
- package/dist/esm/types/components/TextInput/TextInput.d.ts +6 -0
- package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +9 -0
- package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +4 -0
- package/dist/esm/types/components/Toast/Toast.d.ts +1 -0
- package/dist/esm/types/components/Toast/Toast.stories.d.ts +14 -0
- package/dist/esm/types/components/Toast/Toast.styles.d.ts +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/src/theme/global.css +208 -89
- package/package.json +1 -1
- package/src/components/PasswordInput/PasswordInput.stories.tsx +1 -1
- package/src/components/PasswordInput/PasswordInput.tsx +2 -2
- package/src/components/Switch/Switch.stories.tsx +33 -2
- package/src/components/Switch/Switch.styles.ts +48 -0
- package/src/components/Switch/Switch.tsx +68 -45
- package/src/components/TextInput/TextInput.stories.tsx +82 -0
- package/src/components/TextInput/TextInput.styles.ts +36 -17
- package/src/components/TextInput/TextInput.tsx +40 -11
- package/src/components/Toast/Toast.stories.tsx +12 -2
- package/src/components/Toast/Toast.styles.tsx +38 -6
- package/src/components/Toast/Toast.tsx +7 -7
- package/src/components/Toast/Toaster.tsx +26 -4
- package/src/theme/themes/xspector/baseline.css +0 -1
- package/src/theme/tokens/components/switch.css +10 -11
- package/src/theme/themes/xspector/components/switch.css +0 -30
|
@@ -3,58 +3,81 @@
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import * as SwitchPrimitives from "@radix-ui/react-switch";
|
|
5
5
|
import { cn } from "@/utils/cn";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
unchecked:
|
|
12
|
-
"data-[state=unchecked]:bg-[var(--switch-default-color)] hover:data-[state=unchecked]:bg-[var(--switch-hover-color)]",
|
|
13
|
-
checked:
|
|
14
|
-
"data-[state=checked]:bg-[var(--switch-active-color)] hover:data-[state=checked]:bg-[var(--switch-active-hover-color)]",
|
|
15
|
-
disabled:
|
|
16
|
-
"data-[disabled]:cursor-not-allowed data-[disabled]:!bg-[var(--switch-disabled-color)] data-[disabled]:pointer-events-none",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const thumbBaseClasses =
|
|
20
|
-
"block size-4 rounded-full shadow-lg transition-transform";
|
|
21
|
-
const thumbStateClasses = {
|
|
22
|
-
unchecked:
|
|
23
|
-
"data-[state=unchecked]:bg-[var(--switch-thumb-default-color)] data-[state=unchecked]:-translate-x-[2px]",
|
|
24
|
-
checked:
|
|
25
|
-
"data-[state=checked]:bg-[var(--switch-thumb-active-color)] data-[state=checked]:translate-x-4",
|
|
26
|
-
hover:
|
|
27
|
-
"group-hover:ring group-hover:data-[state=checked]:ring-[var(--switch-thumb-active-hover-ring)] group-hover:data-[state=unchecked]:ring-[var(--switch-thumb-hover-ring)]",
|
|
28
|
-
hoverColor:
|
|
29
|
-
"group-hover:data-[state=checked]:bg-[var(--switch-thumb-active-hover-color)] group-hover:data-[state=unchecked]:bg-[var(--switch-thumb-hover-color)]",
|
|
30
|
-
disabled: "group-disabled:!bg-[--switch-thumb-disabled-color]",
|
|
31
|
-
};
|
|
6
|
+
import {
|
|
7
|
+
switchRootVariants,
|
|
8
|
+
switchThumbHaloVariants,
|
|
9
|
+
switchThumbVariants,
|
|
10
|
+
} from "./Switch.styles";
|
|
32
11
|
|
|
33
12
|
const Switch = React.forwardRef<
|
|
34
13
|
React.ElementRef<typeof SwitchPrimitives.Root>,
|
|
35
|
-
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
|
36
|
-
|
|
14
|
+
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> & {
|
|
15
|
+
forceHover?: boolean;
|
|
16
|
+
}
|
|
17
|
+
>(({ className, forceHover = false, ...props }, ref) => (
|
|
37
18
|
<SwitchPrimitives.Root
|
|
38
|
-
className={cn(
|
|
39
|
-
switchBaseClasses,
|
|
40
|
-
switchStateClasses.unchecked,
|
|
41
|
-
switchStateClasses.checked,
|
|
42
|
-
switchStateClasses.disabled,
|
|
43
|
-
className
|
|
44
|
-
)}
|
|
19
|
+
className={cn(switchRootVariants({ forceHover }), className)}
|
|
45
20
|
{...props}
|
|
46
21
|
ref={ref}
|
|
47
22
|
>
|
|
48
|
-
<SwitchPrimitives.Thumb
|
|
49
|
-
className={
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
23
|
+
<SwitchPrimitives.Thumb className={switchThumbVariants({ forceHover })}>
|
|
24
|
+
<span aria-hidden className={switchThumbHaloVariants()}>
|
|
25
|
+
<svg
|
|
26
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
+
width="40"
|
|
28
|
+
height="40"
|
|
29
|
+
viewBox="0 0 40 40"
|
|
30
|
+
fill="none"
|
|
31
|
+
>
|
|
32
|
+
<g filter="url(#switch-hover-halo-shadow)">
|
|
33
|
+
<circle
|
|
34
|
+
cx="20"
|
|
35
|
+
cy="18"
|
|
36
|
+
r="12"
|
|
37
|
+
fill="currentColor"
|
|
38
|
+
shapeRendering="crispEdges"
|
|
39
|
+
/>
|
|
40
|
+
</g>
|
|
41
|
+
<defs>
|
|
42
|
+
<filter
|
|
43
|
+
id="switch-hover-halo-shadow"
|
|
44
|
+
x="0"
|
|
45
|
+
y="0"
|
|
46
|
+
width="40"
|
|
47
|
+
height="40"
|
|
48
|
+
filterUnits="userSpaceOnUse"
|
|
49
|
+
colorInterpolationFilters="sRGB"
|
|
50
|
+
>
|
|
51
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
52
|
+
<feColorMatrix
|
|
53
|
+
in="SourceAlpha"
|
|
54
|
+
type="matrix"
|
|
55
|
+
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
|
56
|
+
result="hardAlpha"
|
|
57
|
+
/>
|
|
58
|
+
<feOffset dy="2" />
|
|
59
|
+
<feGaussianBlur stdDeviation="4" />
|
|
60
|
+
<feComposite in2="hardAlpha" operator="out" />
|
|
61
|
+
<feColorMatrix
|
|
62
|
+
type="matrix"
|
|
63
|
+
values="0 0 0 0 0.568627 0 0 0 0 0.619608 0 0 0 0 0.670588 0 0 0 0.24 0"
|
|
64
|
+
/>
|
|
65
|
+
<feBlend
|
|
66
|
+
mode="normal"
|
|
67
|
+
in2="BackgroundImageFix"
|
|
68
|
+
result="effect1_dropShadow"
|
|
69
|
+
/>
|
|
70
|
+
<feBlend
|
|
71
|
+
mode="normal"
|
|
72
|
+
in="SourceGraphic"
|
|
73
|
+
in2="effect1_dropShadow"
|
|
74
|
+
result="shape"
|
|
75
|
+
/>
|
|
76
|
+
</filter>
|
|
77
|
+
</defs>
|
|
78
|
+
</svg>
|
|
79
|
+
</span>
|
|
80
|
+
</SwitchPrimitives.Thumb>
|
|
58
81
|
</SwitchPrimitives.Root>
|
|
59
82
|
));
|
|
60
83
|
|
|
@@ -265,3 +265,85 @@ export const KeepFooterSpace = {
|
|
|
265
265
|
},
|
|
266
266
|
render: () => <KeepFooterSpaceDemo />,
|
|
267
267
|
} satisfies StoryObj;
|
|
268
|
+
|
|
269
|
+
const FeedbackApiDemo = () => {
|
|
270
|
+
const [legacyError, setLegacyError] = useState(false);
|
|
271
|
+
const [legacyWarning, setLegacyWarning] = useState(false);
|
|
272
|
+
const [useStatusOverride, setUseStatusOverride] = useState(false);
|
|
273
|
+
|
|
274
|
+
return (
|
|
275
|
+
<div className="flex flex-col gap-6 w-full max-w-2xl">
|
|
276
|
+
<div className="flex flex-wrap items-center gap-4 text-sm text-text-grey-dark">
|
|
277
|
+
<label className="flex items-center gap-2 cursor-pointer">
|
|
278
|
+
<input
|
|
279
|
+
type="checkbox"
|
|
280
|
+
checked={legacyError}
|
|
281
|
+
onChange={(e) => setLegacyError(e.target.checked)}
|
|
282
|
+
/>
|
|
283
|
+
legacy error
|
|
284
|
+
</label>
|
|
285
|
+
<label className="flex items-center gap-2 cursor-pointer">
|
|
286
|
+
<input
|
|
287
|
+
type="checkbox"
|
|
288
|
+
checked={legacyWarning}
|
|
289
|
+
onChange={(e) => setLegacyWarning(e.target.checked)}
|
|
290
|
+
/>
|
|
291
|
+
legacy warning
|
|
292
|
+
</label>
|
|
293
|
+
<label className="flex items-center gap-2 cursor-pointer">
|
|
294
|
+
<input
|
|
295
|
+
type="checkbox"
|
|
296
|
+
checked={useStatusOverride}
|
|
297
|
+
onChange={(e) => setUseStatusOverride(e.target.checked)}
|
|
298
|
+
/>
|
|
299
|
+
status override = warning
|
|
300
|
+
</label>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
304
|
+
<div className="flex flex-col gap-2">
|
|
305
|
+
<h4 className="text-sm font-medium text-text-grey-dark">
|
|
306
|
+
Legacy API (error / warning)
|
|
307
|
+
</h4>
|
|
308
|
+
<TextInput
|
|
309
|
+
id="legacy-feedback"
|
|
310
|
+
label="Email"
|
|
311
|
+
helperText="We will never share your email."
|
|
312
|
+
keepFooterSpace
|
|
313
|
+
error={legacyError}
|
|
314
|
+
errorMessage={legacyError ? "Invalid email format." : undefined}
|
|
315
|
+
warning={legacyWarning}
|
|
316
|
+
warningMessage={legacyWarning ? "Please verify this email." : undefined}
|
|
317
|
+
/>
|
|
318
|
+
</div>
|
|
319
|
+
|
|
320
|
+
<div className="flex flex-col gap-2">
|
|
321
|
+
<h4 className="text-sm font-medium text-text-grey-dark">
|
|
322
|
+
New API (status + message)
|
|
323
|
+
</h4>
|
|
324
|
+
<TextInput
|
|
325
|
+
id="status-feedback"
|
|
326
|
+
label="Email"
|
|
327
|
+
helperText="We will never share your email."
|
|
328
|
+
keepFooterSpace
|
|
329
|
+
status={useStatusOverride ? "warning" : "default"}
|
|
330
|
+
error={legacyError}
|
|
331
|
+
errorMessage={legacyError ? "Invalid email format." : undefined}
|
|
332
|
+
warning={legacyWarning}
|
|
333
|
+
warningMessage={
|
|
334
|
+
useStatusOverride
|
|
335
|
+
? "Status explicitly sets warning."
|
|
336
|
+
: legacyWarning
|
|
337
|
+
? "Please verify this email."
|
|
338
|
+
: undefined
|
|
339
|
+
}
|
|
340
|
+
/>
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
export const FeedbackApiCompatibility = {
|
|
348
|
+
render: () => <FeedbackApiDemo />,
|
|
349
|
+
} satisfies StoryObj;
|
|
@@ -41,6 +41,9 @@ export const inputVariant = cva(
|
|
|
41
41
|
error: {
|
|
42
42
|
true: "ring-input-error hover:ring-input-error focus:ring-input-error",
|
|
43
43
|
},
|
|
44
|
+
warning: {
|
|
45
|
+
true: "ring-warning-stroke hover:ring-warning-stroke focus:ring-warning-stroke",
|
|
46
|
+
},
|
|
44
47
|
hasClearIcon: {
|
|
45
48
|
true: "",
|
|
46
49
|
},
|
|
@@ -356,21 +359,25 @@ export const helperTextVariant = cva(
|
|
|
356
359
|
true: "text-input-error",
|
|
357
360
|
false: "text-input-filled-text",
|
|
358
361
|
},
|
|
362
|
+
warning: {
|
|
363
|
+
true: "text-warning",
|
|
364
|
+
},
|
|
359
365
|
},
|
|
360
366
|
defaultVariants: {
|
|
361
367
|
size: "md",
|
|
362
368
|
disabled: false,
|
|
363
369
|
error: false,
|
|
370
|
+
warning: false,
|
|
364
371
|
},
|
|
365
372
|
},
|
|
366
373
|
);
|
|
367
374
|
|
|
368
375
|
const iconInteractiveColorStateClasses = [
|
|
369
376
|
"fill-input-default-text",
|
|
370
|
-
"peer-hover:fill-input-filled-text peer-focus:fill-input-filled-text peer-active:fill-input-filled-text",
|
|
377
|
+
"hover:fill-input-filled-text peer-hover:fill-input-filled-text peer-focus:fill-input-filled-text peer-active:fill-input-filled-text",
|
|
371
378
|
"peer-disabled:fill-input-disable-stroke",
|
|
372
379
|
"[&_svg]:text-input-default-text",
|
|
373
|
-
"peer-hover:[&_svg]:text-input-filled-text peer-focus:[&_svg]:text-input-filled-text peer-active:[&_svg]:text-input-filled-text",
|
|
380
|
+
"hover:[&_svg]:text-input-filled-text peer-hover:[&_svg]:text-input-filled-text peer-focus:[&_svg]:text-input-filled-text peer-active:[&_svg]:text-input-filled-text",
|
|
374
381
|
"peer-disabled:[&_svg]:text-input-disable-stroke",
|
|
375
382
|
];
|
|
376
383
|
|
|
@@ -412,21 +419,18 @@ export const inlineStartIconWrapperVariant = cva(
|
|
|
412
419
|
},
|
|
413
420
|
);
|
|
414
421
|
|
|
415
|
-
export const iconActionVariant = cva(
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
md: "size-4",
|
|
422
|
-
lg: "size-5",
|
|
423
|
-
},
|
|
424
|
-
},
|
|
425
|
-
defaultVariants: {
|
|
426
|
-
size: "md",
|
|
422
|
+
export const iconActionVariant = cva(["cursor-pointer z-50"], {
|
|
423
|
+
variants: {
|
|
424
|
+
size: {
|
|
425
|
+
sm: "size-3",
|
|
426
|
+
md: "size-4",
|
|
427
|
+
lg: "size-5",
|
|
427
428
|
},
|
|
428
429
|
},
|
|
429
|
-
|
|
430
|
+
defaultVariants: {
|
|
431
|
+
size: "md",
|
|
432
|
+
},
|
|
433
|
+
});
|
|
430
434
|
|
|
431
435
|
export const segmentedIconWrapperVariant = cva(
|
|
432
436
|
[
|
|
@@ -449,14 +453,17 @@ export const segmentedIconWrapperVariant = cva(
|
|
|
449
453
|
error: {
|
|
450
454
|
false: "",
|
|
451
455
|
},
|
|
456
|
+
warning: {
|
|
457
|
+
false: "",
|
|
458
|
+
},
|
|
452
459
|
position: {
|
|
453
460
|
start: [
|
|
454
461
|
"inset-y-0 left-0 ",
|
|
455
|
-
"border-r border-r-input-default-stroke peer-hover:border-r-input-active-stroke peer-focus:border-r-input-active-stroke peer-disabled:border-r-input-disable-stroke",
|
|
462
|
+
"border-r border-r-input-default-stroke hover:border-r-input-active-stroke peer-hover:border-r-input-active-stroke peer-focus:border-r-input-active-stroke peer-disabled:border-r-input-disable-stroke",
|
|
456
463
|
],
|
|
457
464
|
end: [
|
|
458
465
|
"inset-y-0 right-0 ",
|
|
459
|
-
"border-l border-l-input-default-stroke peer-hover:border-l-input-active-stroke peer-focus:border-l-input-active-stroke peer-disabled:border-l-input-disable-stroke",
|
|
466
|
+
"border-l border-l-input-default-stroke hover:border-l-input-active-stroke peer-hover:border-l-input-active-stroke peer-focus:border-l-input-active-stroke peer-disabled:border-l-input-disable-stroke",
|
|
460
467
|
],
|
|
461
468
|
},
|
|
462
469
|
},
|
|
@@ -503,11 +510,23 @@ export const segmentedIconWrapperVariant = cva(
|
|
|
503
510
|
error: true,
|
|
504
511
|
className: "border-l-input-error",
|
|
505
512
|
},
|
|
513
|
+
// --- Warning start ---
|
|
514
|
+
{
|
|
515
|
+
position: "start",
|
|
516
|
+
warning: true,
|
|
517
|
+
className: "border-r-warning-stroke",
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
position: "end",
|
|
521
|
+
warning: true,
|
|
522
|
+
className: "border-l-warning-stroke",
|
|
523
|
+
},
|
|
506
524
|
],
|
|
507
525
|
defaultVariants: {
|
|
508
526
|
size: "md",
|
|
509
527
|
rounded: "normal",
|
|
510
528
|
error: false,
|
|
529
|
+
warning: false,
|
|
511
530
|
position: "end",
|
|
512
531
|
},
|
|
513
532
|
},
|
|
@@ -32,9 +32,12 @@ export type InputProps = {
|
|
|
32
32
|
type?: React.HTMLInputTypeAttribute;
|
|
33
33
|
helperText?: string;
|
|
34
34
|
errorMessage?: string;
|
|
35
|
+
warningMessage?: string;
|
|
36
|
+
status?: "default" | "warning" | "error";
|
|
35
37
|
fullwidth?: boolean;
|
|
36
38
|
disabled?: boolean;
|
|
37
39
|
error?: boolean;
|
|
40
|
+
warning?: boolean;
|
|
38
41
|
required?: boolean;
|
|
39
42
|
isFloatingLabel?: boolean;
|
|
40
43
|
keepCloseIconOnValue?: boolean;
|
|
@@ -70,9 +73,12 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
70
73
|
iconMode = "solid",
|
|
71
74
|
helperText,
|
|
72
75
|
errorMessage,
|
|
76
|
+
warningMessage,
|
|
77
|
+
status,
|
|
73
78
|
fullwidth = true,
|
|
74
79
|
disabled = false,
|
|
75
80
|
error = false,
|
|
81
|
+
warning = false,
|
|
76
82
|
required = true,
|
|
77
83
|
isFloatingLabel = true,
|
|
78
84
|
keepCloseIconOnValue = false,
|
|
@@ -95,6 +101,21 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
95
101
|
const _id = id || `${type}-${label}-input`;
|
|
96
102
|
const hasLeftSectionIcon = !!startIcon || !!renderStartIcon;
|
|
97
103
|
const hasRightSectionIcon = !!endIcon || !!renderEndIcon;
|
|
104
|
+
const feedbackStatus =
|
|
105
|
+
status ||
|
|
106
|
+
(error || !!errorMessage
|
|
107
|
+
? "error"
|
|
108
|
+
: warning || !!warningMessage
|
|
109
|
+
? "warning"
|
|
110
|
+
: "default");
|
|
111
|
+
const isError = feedbackStatus === "error";
|
|
112
|
+
const isWarning = feedbackStatus === "warning";
|
|
113
|
+
const feedbackMessage =
|
|
114
|
+
feedbackStatus === "error"
|
|
115
|
+
? errorMessage
|
|
116
|
+
: feedbackStatus === "warning"
|
|
117
|
+
? warningMessage
|
|
118
|
+
: helperText;
|
|
98
119
|
|
|
99
120
|
const inputClassname = inputVariant({
|
|
100
121
|
size,
|
|
@@ -102,7 +123,8 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
102
123
|
variant,
|
|
103
124
|
fullwidth,
|
|
104
125
|
disabled,
|
|
105
|
-
error,
|
|
126
|
+
error: isError,
|
|
127
|
+
warning: isWarning,
|
|
106
128
|
hasSearchIcon:
|
|
107
129
|
(iconMode === "flat" && hasLeftSectionIcon) || hasSearchIcon,
|
|
108
130
|
hasClearIcon:
|
|
@@ -113,7 +135,7 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
113
135
|
const labelClassname = labelVariant({
|
|
114
136
|
size,
|
|
115
137
|
disabled,
|
|
116
|
-
error,
|
|
138
|
+
error: isError,
|
|
117
139
|
hasSearchIcon:
|
|
118
140
|
(iconMode === "flat" && hasLeftSectionIcon) || hasSearchIcon,
|
|
119
141
|
hasLeftSectionIcon: iconMode === "solid" ? hasLeftSectionIcon : false,
|
|
@@ -121,7 +143,8 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
121
143
|
});
|
|
122
144
|
const helperTextClassname = helperTextVariant({
|
|
123
145
|
size,
|
|
124
|
-
error,
|
|
146
|
+
error: isError,
|
|
147
|
+
warning: isWarning,
|
|
125
148
|
disabled,
|
|
126
149
|
});
|
|
127
150
|
const inlineEndIconWrapperClassname = inlineEndIconWrapperVariant({ size });
|
|
@@ -135,13 +158,15 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
135
158
|
const startSegmentIconWrapperClassname = segmentedIconWrapperVariant({
|
|
136
159
|
size,
|
|
137
160
|
rounded,
|
|
138
|
-
error,
|
|
161
|
+
error: isError,
|
|
162
|
+
warning: isWarning,
|
|
139
163
|
position: "start",
|
|
140
164
|
});
|
|
141
165
|
const endSegmentIconWrapperClassname = segmentedIconWrapperVariant({
|
|
142
166
|
size,
|
|
143
167
|
rounded,
|
|
144
|
-
error,
|
|
168
|
+
error: isError,
|
|
169
|
+
warning: isWarning,
|
|
145
170
|
position: "end",
|
|
146
171
|
});
|
|
147
172
|
|
|
@@ -346,24 +371,28 @@ export const TextInput = forwardRef<HTMLInputElement, InputProps>(
|
|
|
346
371
|
)}
|
|
347
372
|
</label>
|
|
348
373
|
</div>
|
|
349
|
-
{(
|
|
374
|
+
{(feedbackMessage || keepFooterSpace) && (
|
|
350
375
|
<span className={helperTextClassname}>
|
|
351
|
-
{
|
|
376
|
+
{feedbackMessage && (
|
|
352
377
|
<span className="h-full shrink-0">
|
|
353
378
|
<CircleAlert
|
|
354
379
|
width={14}
|
|
355
380
|
height={14}
|
|
356
381
|
className={cn(
|
|
357
|
-
"fill-none",
|
|
358
|
-
|
|
382
|
+
"fill-none stroke-current",
|
|
383
|
+
isError
|
|
384
|
+
? "text-input-error"
|
|
385
|
+
: isWarning
|
|
386
|
+
? "text-warning"
|
|
387
|
+
: "text-input-filled-text"
|
|
359
388
|
)}
|
|
360
389
|
/>
|
|
361
390
|
</span>
|
|
362
391
|
)}
|
|
363
|
-
{keepFooterSpace && !
|
|
392
|
+
{keepFooterSpace && !feedbackMessage && (
|
|
364
393
|
<span className="block min-h-[14px]" aria-hidden />
|
|
365
394
|
)}
|
|
366
|
-
{
|
|
395
|
+
{feedbackMessage || ""}
|
|
367
396
|
</span>
|
|
368
397
|
)}
|
|
369
398
|
</div>
|
|
@@ -14,10 +14,14 @@ const meta = {
|
|
|
14
14
|
tags: ["autodocs"],
|
|
15
15
|
parameters: {
|
|
16
16
|
layout: "fullscreen",
|
|
17
|
+
backgrounds: {
|
|
18
|
+
default: "white",
|
|
19
|
+
values: [{ name: "white", value: "#ffffff" }],
|
|
20
|
+
},
|
|
17
21
|
},
|
|
18
22
|
decorators: [
|
|
19
23
|
(Story) => (
|
|
20
|
-
<div className="flex
|
|
24
|
+
<div className="flex max-h-screen w-full bg-white p-4">
|
|
21
25
|
<Story />
|
|
22
26
|
</div>
|
|
23
27
|
),
|
|
@@ -47,11 +51,15 @@ export const Simple = {
|
|
|
47
51
|
"bottom-right",
|
|
48
52
|
],
|
|
49
53
|
},
|
|
54
|
+
showBorder: {
|
|
55
|
+
control: "boolean",
|
|
56
|
+
},
|
|
50
57
|
},
|
|
51
58
|
args: {
|
|
52
59
|
variant: "default",
|
|
53
60
|
contentMode: "horizontal",
|
|
54
61
|
position: "top-center",
|
|
62
|
+
showBorder: false,
|
|
55
63
|
},
|
|
56
64
|
render: (args) => {
|
|
57
65
|
console.log("args ", args);
|
|
@@ -66,11 +74,12 @@ export const Simple = {
|
|
|
66
74
|
useEffect(() => {
|
|
67
75
|
toast({
|
|
68
76
|
variant: props.variant,
|
|
77
|
+
showBorder: props.showBorder,
|
|
69
78
|
title: "Success",
|
|
70
79
|
description: "This is an Info alert — check it out!",
|
|
71
80
|
contentMode: props.contentMode,
|
|
72
81
|
});
|
|
73
|
-
}, [props.variant, props.contentMode]);
|
|
82
|
+
}, [props.variant, props.contentMode, props.showBorder]);
|
|
74
83
|
|
|
75
84
|
return (
|
|
76
85
|
<div className="flex flex-row gap-4 w-full">
|
|
@@ -98,6 +107,7 @@ export const Simple = {
|
|
|
98
107
|
| null
|
|
99
108
|
| undefined;
|
|
100
109
|
contentMode: "horizontal" | "vertical";
|
|
110
|
+
showBorder: boolean;
|
|
101
111
|
position?:
|
|
102
112
|
| "top-center"
|
|
103
113
|
| "top-left"
|
|
@@ -3,22 +3,54 @@ import { cva } from "class-variance-authority";
|
|
|
3
3
|
export const toastVariants = cva(
|
|
4
4
|
[
|
|
5
5
|
"group pointer-events-auto relative flex w-full",
|
|
6
|
-
"rounded-
|
|
6
|
+
"rounded-lg shadow-[0px_8px_16px_0px_rgba(0,0,0,0.12)] px-4 py-3 gap-1",
|
|
7
7
|
"transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
|
8
8
|
"bg-base-popup text-base-popup-foreground",
|
|
9
9
|
],
|
|
10
10
|
{
|
|
11
11
|
variants: {
|
|
12
12
|
variant: {
|
|
13
|
-
default: "
|
|
14
|
-
success: "
|
|
15
|
-
info: "
|
|
16
|
-
warning: "
|
|
17
|
-
error: "
|
|
13
|
+
default: "",
|
|
14
|
+
success: "",
|
|
15
|
+
info: "",
|
|
16
|
+
warning: "",
|
|
17
|
+
error: "",
|
|
18
|
+
},
|
|
19
|
+
showBorder: {
|
|
20
|
+
true: "",
|
|
21
|
+
false: "border-transparent",
|
|
18
22
|
},
|
|
19
23
|
},
|
|
24
|
+
compoundVariants: [
|
|
25
|
+
{
|
|
26
|
+
variant: "default",
|
|
27
|
+
showBorder: true,
|
|
28
|
+
className: "border",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
variant: "success",
|
|
32
|
+
showBorder: true,
|
|
33
|
+
className: "border border-success-stroke",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
variant: "info",
|
|
37
|
+
showBorder: true,
|
|
38
|
+
className: "border border-info-stroke",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
variant: "warning",
|
|
42
|
+
showBorder: true,
|
|
43
|
+
className: "border border-warning-stroke",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
variant: "error",
|
|
47
|
+
showBorder: true,
|
|
48
|
+
className: "border border-error-stroke",
|
|
49
|
+
},
|
|
50
|
+
],
|
|
20
51
|
defaultVariants: {
|
|
21
52
|
variant: "success",
|
|
53
|
+
showBorder: false,
|
|
22
54
|
},
|
|
23
55
|
}
|
|
24
56
|
);
|
|
@@ -15,7 +15,7 @@ const ToastProvider = ToastPrimitives.Provider;
|
|
|
15
15
|
const ToastViewport = React.forwardRef<
|
|
16
16
|
React.ElementRef<typeof ToastPrimitives.Viewport>,
|
|
17
17
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport> &
|
|
18
|
-
|
|
18
|
+
VariantProps<typeof toastViewportVariants>
|
|
19
19
|
>(({ className, position, ...props }, ref) => (
|
|
20
20
|
<ToastPrimitives.Viewport
|
|
21
21
|
ref={ref}
|
|
@@ -28,12 +28,12 @@ ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
|
|
28
28
|
const Toast = React.forwardRef<
|
|
29
29
|
React.ElementRef<typeof ToastPrimitives.Root>,
|
|
30
30
|
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
|
|
31
|
-
|
|
32
|
-
>(({ className, variant, ...props }, ref) => {
|
|
31
|
+
VariantProps<typeof toastVariants>
|
|
32
|
+
>(({ className, variant, showBorder, ...props }, ref) => {
|
|
33
33
|
return (
|
|
34
34
|
<ToastPrimitives.Root
|
|
35
35
|
ref={ref}
|
|
36
|
-
className={cn(toastVariants({ variant }), className)}
|
|
36
|
+
className={cn(toastVariants({ variant, showBorder }), className)}
|
|
37
37
|
{...props}
|
|
38
38
|
/>
|
|
39
39
|
);
|
|
@@ -50,7 +50,7 @@ const ToastAction = React.forwardRef<
|
|
|
50
50
|
{...props}
|
|
51
51
|
asChild
|
|
52
52
|
>
|
|
53
|
-
<Button variant="outline" size="sm">
|
|
53
|
+
<Button variant="outline" color="secondary" size="sm">
|
|
54
54
|
{children}
|
|
55
55
|
</Button>
|
|
56
56
|
</ToastPrimitives.Action>
|
|
@@ -63,7 +63,7 @@ const ToastClose = React.forwardRef<
|
|
|
63
63
|
>(({ className, ...props }, ref) => (
|
|
64
64
|
<ToastPrimitives.Close
|
|
65
65
|
ref={ref}
|
|
66
|
-
className={cn("-mr-2 self-center text-
|
|
66
|
+
className={cn("-mr-2 self-center text-grey-light", className)}
|
|
67
67
|
toast-close=""
|
|
68
68
|
{...props}
|
|
69
69
|
asChild
|
|
@@ -93,7 +93,7 @@ const ToastDescription = React.forwardRef<
|
|
|
93
93
|
>(({ className, ...props }, ref) => (
|
|
94
94
|
<ToastPrimitives.Description
|
|
95
95
|
ref={ref}
|
|
96
|
-
className={cn("typography-
|
|
96
|
+
className={cn("typography-subtitile4 text-grey-light", className)}
|
|
97
97
|
{...props}
|
|
98
98
|
/>
|
|
99
99
|
));
|
|
@@ -47,6 +47,26 @@ export function Toaster({
|
|
|
47
47
|
renderIcon,
|
|
48
48
|
...props
|
|
49
49
|
}) {
|
|
50
|
+
const defaultIconName =
|
|
51
|
+
props.variant === "error"
|
|
52
|
+
? "circle-x"
|
|
53
|
+
: props.variant === "warning"
|
|
54
|
+
? "circle-alert"
|
|
55
|
+
: props.variant === "info"
|
|
56
|
+
? "info"
|
|
57
|
+
: "circle-check";
|
|
58
|
+
|
|
59
|
+
const titleToneClass =
|
|
60
|
+
props.variant === "error"
|
|
61
|
+
? "text-error"
|
|
62
|
+
: props.variant === "warning"
|
|
63
|
+
? "text-warning"
|
|
64
|
+
: props.variant === "info"
|
|
65
|
+
? "text-info"
|
|
66
|
+
: props.variant === "success"
|
|
67
|
+
? "text-success"
|
|
68
|
+
: "text-base-popup-foreground";
|
|
69
|
+
|
|
50
70
|
return (
|
|
51
71
|
<Toast key={id} {...props}>
|
|
52
72
|
<div
|
|
@@ -59,9 +79,9 @@ export function Toaster({
|
|
|
59
79
|
renderIcon?.()
|
|
60
80
|
) : (
|
|
61
81
|
<Icon
|
|
62
|
-
type="
|
|
63
|
-
name=
|
|
64
|
-
className="size-
|
|
82
|
+
type="lucide"
|
|
83
|
+
name={defaultIconName}
|
|
84
|
+
className="size-[22px]"
|
|
65
85
|
{...iconProps}
|
|
66
86
|
/>
|
|
67
87
|
)}
|
|
@@ -73,7 +93,9 @@ export function Toaster({
|
|
|
73
93
|
)}
|
|
74
94
|
>
|
|
75
95
|
{title && (
|
|
76
|
-
<ToastTitle className={titleClassName}>
|
|
96
|
+
<ToastTitle className={cn(titleToneClass, titleClassName)}>
|
|
97
|
+
{title}
|
|
98
|
+
</ToastTitle>
|
|
77
99
|
)}
|
|
78
100
|
{description && (
|
|
79
101
|
<ToastDescription className={descriptionClassName}>
|