@rovula/ui 0.1.2 → 0.1.4

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 (105) hide show
  1. package/dist/cjs/bundle.css +436 -111
  2. package/dist/cjs/bundle.js +4 -4
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/ActionButton/ActionButton.d.ts +4 -2
  5. package/dist/cjs/types/components/ActionButton/ActionButton.stories.d.ts +30 -8
  6. package/dist/cjs/types/components/ActionButton/ActionButton.styles.d.ts +2 -1
  7. package/dist/cjs/types/components/Avatar/Avatar.styles.d.ts +1 -1
  8. package/dist/cjs/types/components/Button/Button.d.ts +4 -2
  9. package/dist/cjs/types/components/Button/Button.styles.d.ts +2 -1
  10. package/dist/cjs/types/components/Button/Buttons.stories.d.ts +71 -6
  11. package/dist/cjs/types/components/Checkbox/Checkbox.stories.d.ts +13 -9
  12. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +3 -0
  13. package/dist/cjs/types/components/InputFilter/InputFilter.stories.d.ts +3 -0
  14. package/dist/cjs/types/components/MaskedTextInput/MaskedTextInput.d.ts +3 -0
  15. package/dist/cjs/types/components/MaskedTextInput/MaskedTextInput.stories.d.ts +6 -0
  16. package/dist/cjs/types/components/PasswordInput/PasswordInput.stories.d.ts +3 -0
  17. package/dist/cjs/types/components/RadioGroup/RadioGroup.stories.d.ts +10 -7
  18. package/dist/cjs/types/components/Search/Search.stories.d.ts +3 -0
  19. package/dist/cjs/types/components/Switch/Switch.d.ts +3 -1
  20. package/dist/cjs/types/components/Switch/Switch.stories.d.ts +12 -4
  21. package/dist/cjs/types/components/Switch/Switch.styles.d.ts +7 -0
  22. package/dist/cjs/types/components/TextInput/TextInput.d.ts +6 -0
  23. package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +9 -0
  24. package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +4 -0
  25. package/dist/cjs/types/components/Toast/Toast.d.ts +1 -0
  26. package/dist/cjs/types/components/Toast/Toast.stories.d.ts +14 -0
  27. package/dist/cjs/types/components/Toast/Toast.styles.d.ts +1 -0
  28. package/dist/components/ActionButton/ActionButton.js +2 -1
  29. package/dist/components/ActionButton/ActionButton.stories.js +40 -7
  30. package/dist/components/ActionButton/ActionButton.styles.js +77 -17
  31. package/dist/components/Button/Button.js +9 -2
  32. package/dist/components/Button/Button.styles.js +51 -14
  33. package/dist/components/Button/Buttons.stories.js +55 -0
  34. package/dist/components/Checkbox/Checkbox.js +6 -7
  35. package/dist/components/Checkbox/Checkbox.stories.js +23 -1
  36. package/dist/components/InputFilter/InputFilter.js +1 -1
  37. package/dist/components/InputFilter/InputFilter.styles.js +1 -1
  38. package/dist/components/RadioGroup/RadioGroup.js +1 -1
  39. package/dist/components/RadioGroup/RadioGroup.stories.js +16 -1
  40. package/dist/components/Switch/Switch.js +4 -17
  41. package/dist/components/Switch/Switch.stories.js +12 -2
  42. package/dist/components/Switch/Switch.styles.js +39 -0
  43. package/dist/components/TextInput/TextInput.js +28 -7
  44. package/dist/components/TextInput/TextInput.stories.js +13 -0
  45. package/dist/components/TextInput/TextInput.styles.js +22 -0
  46. package/dist/components/Toast/Toast.js +5 -5
  47. package/dist/components/Toast/Toast.stories.js +11 -2
  48. package/dist/components/Toast/Toast.styles.js +38 -6
  49. package/dist/components/Toast/Toaster.js +17 -1
  50. package/dist/esm/bundle.css +436 -111
  51. package/dist/esm/bundle.js +115 -115
  52. package/dist/esm/bundle.js.map +1 -1
  53. package/dist/esm/types/components/ActionButton/ActionButton.d.ts +4 -2
  54. package/dist/esm/types/components/ActionButton/ActionButton.stories.d.ts +30 -8
  55. package/dist/esm/types/components/ActionButton/ActionButton.styles.d.ts +2 -1
  56. package/dist/esm/types/components/Avatar/Avatar.styles.d.ts +1 -1
  57. package/dist/esm/types/components/Button/Button.d.ts +4 -2
  58. package/dist/esm/types/components/Button/Button.styles.d.ts +2 -1
  59. package/dist/esm/types/components/Button/Buttons.stories.d.ts +71 -6
  60. package/dist/esm/types/components/Checkbox/Checkbox.stories.d.ts +13 -9
  61. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +3 -0
  62. package/dist/esm/types/components/InputFilter/InputFilter.stories.d.ts +3 -0
  63. package/dist/esm/types/components/MaskedTextInput/MaskedTextInput.d.ts +3 -0
  64. package/dist/esm/types/components/MaskedTextInput/MaskedTextInput.stories.d.ts +6 -0
  65. package/dist/esm/types/components/PasswordInput/PasswordInput.stories.d.ts +3 -0
  66. package/dist/esm/types/components/RadioGroup/RadioGroup.stories.d.ts +10 -7
  67. package/dist/esm/types/components/Search/Search.stories.d.ts +3 -0
  68. package/dist/esm/types/components/Switch/Switch.d.ts +3 -1
  69. package/dist/esm/types/components/Switch/Switch.stories.d.ts +12 -4
  70. package/dist/esm/types/components/Switch/Switch.styles.d.ts +7 -0
  71. package/dist/esm/types/components/TextInput/TextInput.d.ts +6 -0
  72. package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +9 -0
  73. package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +4 -0
  74. package/dist/esm/types/components/Toast/Toast.d.ts +1 -0
  75. package/dist/esm/types/components/Toast/Toast.stories.d.ts +14 -0
  76. package/dist/esm/types/components/Toast/Toast.styles.d.ts +1 -0
  77. package/dist/index.d.ts +19 -4
  78. package/dist/src/theme/global.css +557 -167
  79. package/package.json +1 -1
  80. package/src/components/ActionButton/ActionButton.stories.tsx +105 -149
  81. package/src/components/ActionButton/ActionButton.styles.ts +78 -18
  82. package/src/components/ActionButton/ActionButton.tsx +7 -2
  83. package/src/components/Button/Button.styles.ts +51 -14
  84. package/src/components/Button/Button.tsx +11 -2
  85. package/src/components/Button/Buttons.stories.tsx +235 -0
  86. package/src/components/Checkbox/Checkbox.stories.tsx +50 -4
  87. package/src/components/Checkbox/Checkbox.tsx +12 -8
  88. package/src/components/InputFilter/InputFilter.styles.ts +2 -2
  89. package/src/components/InputFilter/InputFilter.tsx +21 -24
  90. package/src/components/RadioGroup/RadioGroup.stories.tsx +43 -4
  91. package/src/components/RadioGroup/RadioGroup.tsx +1 -1
  92. package/src/components/Switch/Switch.stories.tsx +33 -2
  93. package/src/components/Switch/Switch.styles.ts +48 -0
  94. package/src/components/Switch/Switch.tsx +68 -45
  95. package/src/components/TextInput/TextInput.stories.tsx +82 -0
  96. package/src/components/TextInput/TextInput.styles.ts +22 -0
  97. package/src/components/TextInput/TextInput.tsx +40 -11
  98. package/src/components/Toast/Toast.stories.tsx +12 -2
  99. package/src/components/Toast/Toast.styles.tsx +38 -6
  100. package/src/components/Toast/Toast.tsx +7 -7
  101. package/src/components/Toast/Toaster.tsx +26 -4
  102. package/src/theme/themes/variable.css +1 -1
  103. package/src/theme/themes/xspector/baseline.css +0 -1
  104. package/src/theme/tokens/components/switch.css +10 -11
  105. package/src/theme/themes/xspector/components/switch.css +0 -30
@@ -29,10 +29,32 @@ export const WithText = {
29
29
  return (_jsxs("div", { className: "items-top flex space-x-2", children: [_jsx(Checkbox, { id: "terms1" }), _jsxs("div", { className: "grid gap-1.5 leading-none", children: [_jsx("label", { htmlFor: "terms1", className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: "Accept terms and conditions" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "You agree to our Terms of Service and Privacy Policy." })] })] }));
30
30
  },
31
31
  };
32
- export const Diabled = {
32
+ export const Disabled = {
33
33
  args: {},
34
34
  render: (args) => {
35
35
  const props = Object.assign({}, args);
36
36
  return (_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Checkbox, { id: "terms2", disabled: true }), _jsx("label", { htmlFor: "terms2", className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", children: "Accept terms and conditions" })] }));
37
37
  },
38
38
  };
39
+ const checkboxPreviewRows = [
40
+ { label: "Default", checked: false },
41
+ { label: "Hover", checked: false, className: "!border-function-default-hover" },
42
+ { label: "Disable", checked: false, disabled: true },
43
+ { label: "Checked", checked: true },
44
+ {
45
+ label: "Checked - Hover",
46
+ checked: true,
47
+ className: "!data-[state=checked]:border-function-active-hover !data-[state=checked]:bg-function-active-hover",
48
+ },
49
+ { label: "Checked - Disable", checked: true, disabled: true },
50
+ { label: "Indeterminate", checked: "indeterminate" },
51
+ {
52
+ label: "Indeterminate - Hover",
53
+ checked: "indeterminate",
54
+ className: "!data-[state=indeterminate]:border-function-active-hover !data-[state=indeterminate]:bg-function-active-hover",
55
+ },
56
+ { label: "Indeterminate - Disable", checked: "indeterminate", disabled: true },
57
+ ];
58
+ export const FigmaPreview = {
59
+ render: () => (_jsx("div", { className: "bg-base-bg2 p-8 min-h-screen", children: _jsx("div", { className: "mx-auto flex w-full max-w-[360px] flex-col gap-4 rounded-lg border border-base-bg-stroke1 bg-base-bg1 p-6", children: checkboxPreviewRows.map((row) => (_jsxs("div", { className: "grid grid-cols-[160px_16px] items-center gap-4", children: [_jsx("span", { className: "text-sm font-medium text-text-white", children: row.label }), _jsx(Checkbox, { checked: row.checked, disabled: row.disabled, className: row.className })] }, row.label))) }) })),
60
+ };
@@ -119,6 +119,6 @@ const InputFilter = forwardRef((_a, ref) => {
119
119
  active: !!values.length,
120
120
  disabled,
121
121
  });
122
- return (_jsxs("div", { ref: containerRef, className: `relative ${fullwidth ? "w-full" : ""}`, children: [_jsx(TextInput, Object.assign({ hasClearIcon: false, endIcon: _jsx("div", { className: filterIconClassName, children: _jsx(Icon, { type: "heroicons", name: "adjustments-horizontal", variant: "outline", color: "inherit", stroke: "inherit", fill: "transparent" }) }) }, props, { ref: ref, readOnly: !filterMode, value: textValue, onChange: handleOnChangeText, label: label, placeholder: " ", type: "text", rounded: rounded, variant: variant, helperText: helperText, errorMessage: errorMessage, fullwidth: fullwidth, error: error, required: required, id: _id, disabled: disabled, size: size, className: customInputVariant({ size }), onFocus: handleOnFocus, onKeyDown: handleOnKeyDown })), isFocused && renderOptions()] }));
122
+ return (_jsxs("div", { ref: containerRef, className: `relative ${fullwidth ? "w-full" : ""}`, children: [_jsx(TextInput, Object.assign({ hasClearIcon: false, endIcon: _jsx(Icon, { type: "heroicons", name: "adjustments-horizontal", variant: "outline", color: "inherit", stroke: "inherit", fill: "transparent" }), classes: { endIconWrapper: filterIconClassName } }, props, { ref: ref, readOnly: !filterMode, value: textValue, onChange: handleOnChangeText, label: label, placeholder: " ", type: "text", rounded: rounded, variant: variant, helperText: helperText, errorMessage: errorMessage, fullwidth: fullwidth, error: error, required: required, id: _id, disabled: disabled, size: size, className: customInputVariant({ size }), onFocus: handleOnFocus, onKeyDown: handleOnKeyDown })), isFocused && renderOptions()] }));
123
123
  });
124
124
  export { InputFilter };
@@ -1,7 +1,7 @@
1
1
  import { cva } from "class-variance-authority";
2
2
  export const filterIconVariant = cva([
3
3
  // Base styles
4
- "absolute contents items-center justify-center cursor-pointer",
4
+ "absolute flex items-center justify-center cursor-pointer",
5
5
  // Border styles
6
6
  "border-l border-l-input-default-stroke",
7
7
  "peer-hover:border-l-input-active-stroke",
@@ -20,7 +20,7 @@ const RadioGroup = React.forwardRef((_a, ref) => {
20
20
  RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
21
21
  const RadioGroupItem = React.forwardRef((_a, ref) => {
22
22
  var { className } = _a, props = __rest(_a, ["className"]);
23
- return (_jsx(RadioGroupPrimitive.Item, Object.assign({ ref: ref, className: cn("aspect-square box-border size-4 rounded-full border border-function-default-solid text-function-default-solid", "hover:border-function-default-hover", "focus:outline-none",
23
+ return (_jsx(RadioGroupPrimitive.Item, Object.assign({ ref: ref, className: cn("aspect-square box-border size-4 cursor-pointer rounded-full border border-function-default-solid text-function-default-solid", "hover:border-function-default-hover", "focus:outline-none",
24
24
  // Disabled state styles
25
25
  "data-[disabled]:!border-state-disable-solid data-[disabled]:!fill-state-disable-solid data-[disabled]:!cursor-not-allowed data-[disabled]:!pointer-events-none data-[disabled]:!text-state-disable-solid",
26
26
  // Checked state styles
@@ -22,7 +22,7 @@ export const Default = {
22
22
  return (_jsx("div", { className: "flex flex-row gap-4 w-full", children: _jsxs(RadioGroup, Object.assign({ defaultValue: "option-one" }, props, { children: [_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(RadioGroupItem, { value: "option-one", id: "option-one" }), _jsx(Label, { htmlFor: "option-one", children: "Option One" })] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(RadioGroupItem, { value: "option-two", id: "option-two" }), _jsx(Label, { htmlFor: "option-two", children: "Option Two" })] })] })) }));
23
23
  },
24
24
  };
25
- export const Diabled = {
25
+ export const Disabled = {
26
26
  args: {
27
27
  disabled: true,
28
28
  },
@@ -40,3 +40,18 @@ export const Horizontal = {
40
40
  return (_jsxs(RadioGroup, { defaultValue: "option1", className: "flex flex-row space-x-4", children: [_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(RadioGroupItem, { value: "option1", id: "option1" }), _jsx(Label, { htmlFor: "option1", children: "Option 1" })] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(RadioGroupItem, { value: "option2", id: "option2" }), _jsx(Label, { htmlFor: "option2", children: "Option 2" })] }), _jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(RadioGroupItem, { value: "option3", id: "option3" }), _jsx(Label, { htmlFor: "option3", children: "Option 3" })] })] }));
41
41
  },
42
42
  };
43
+ const radioPreviewRows = [
44
+ { label: "Default", checked: false },
45
+ { label: "Hover", checked: false, className: "!border-function-default-hover" },
46
+ { label: "Disable", checked: false, disabled: true },
47
+ { label: "Checked", checked: true },
48
+ {
49
+ label: "Checked - Hover",
50
+ checked: true,
51
+ className: "!data-[state=checked]:border-function-active-hover !data-[state=checked]:text-function-active-hover",
52
+ },
53
+ { label: "Checked - Disable", checked: true, disabled: true },
54
+ ];
55
+ export const FigmaPreview = {
56
+ render: () => (_jsx("div", { className: "bg-base-bg2 p-8 min-h-screen", children: _jsx("div", { className: "mx-auto flex w-full max-w-[360px] flex-col gap-4 rounded-lg border border-base-bg-stroke1 bg-base-bg1 p-6", children: radioPreviewRows.map((row) => (_jsxs("div", { className: "grid grid-cols-[160px_16px] items-center gap-4", children: [_jsx("span", { className: "text-sm font-medium text-text-white", children: row.label }), _jsx(RadioGroup, { defaultValue: row.checked ? "option" : undefined, disabled: row.disabled, children: _jsx(RadioGroupItem, { value: "option", className: row.className }) })] }, row.label))) }) })),
57
+ };
@@ -10,27 +10,14 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  }
11
11
  return t;
12
12
  };
13
- import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import * as React from "react";
15
15
  import * as SwitchPrimitives from "@radix-ui/react-switch";
16
16
  import { cn } from "@/utils/cn";
17
- const switchBaseClasses = "group inline-flex h-3 w-[32px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors";
18
- const switchStateClasses = {
19
- unchecked: "data-[state=unchecked]:bg-[var(--switch-default-color)] hover:data-[state=unchecked]:bg-[var(--switch-hover-color)]",
20
- checked: "data-[state=checked]:bg-[var(--switch-active-color)] hover:data-[state=checked]:bg-[var(--switch-active-hover-color)]",
21
- disabled: "data-[disabled]:cursor-not-allowed data-[disabled]:!bg-[var(--switch-disabled-color)] data-[disabled]:pointer-events-none",
22
- };
23
- const thumbBaseClasses = "block size-4 rounded-full shadow-lg transition-transform";
24
- const thumbStateClasses = {
25
- unchecked: "data-[state=unchecked]:bg-[var(--switch-thumb-default-color)] data-[state=unchecked]:-translate-x-[2px]",
26
- checked: "data-[state=checked]:bg-[var(--switch-thumb-active-color)] data-[state=checked]:translate-x-4",
27
- hover: "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: "group-hover:data-[state=checked]:bg-[var(--switch-thumb-active-hover-color)] group-hover:data-[state=unchecked]:bg-[var(--switch-thumb-hover-color)]",
29
- disabled: "group-disabled:!bg-[--switch-thumb-disabled-color]",
30
- };
17
+ import { switchRootVariants, switchThumbHaloVariants, switchThumbVariants, } from "./Switch.styles";
31
18
  const Switch = React.forwardRef((_a, ref) => {
32
- var { className } = _a, props = __rest(_a, ["className"]);
33
- return (_jsx(SwitchPrimitives.Root, Object.assign({ className: cn(switchBaseClasses, switchStateClasses.unchecked, switchStateClasses.checked, switchStateClasses.disabled, className) }, props, { ref: ref, children: _jsx(SwitchPrimitives.Thumb, { className: cn(thumbBaseClasses, thumbStateClasses.unchecked, thumbStateClasses.checked, thumbStateClasses.hover, thumbStateClasses.hoverColor, thumbStateClasses.disabled) }) })));
19
+ var { className, forceHover = false } = _a, props = __rest(_a, ["className", "forceHover"]);
20
+ return (_jsx(SwitchPrimitives.Root, Object.assign({ className: cn(switchRootVariants({ forceHover }), className) }, props, { ref: ref, children: _jsx(SwitchPrimitives.Thumb, { className: switchThumbVariants({ forceHover }), children: _jsx("span", { "aria-hidden": true, className: switchThumbHaloVariants(), children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "40", height: "40", viewBox: "0 0 40 40", fill: "none", children: [_jsx("g", { filter: "url(#switch-hover-halo-shadow)", children: _jsx("circle", { cx: "20", cy: "18", r: "12", fill: "currentColor", shapeRendering: "crispEdges" }) }), _jsx("defs", { children: _jsxs("filter", { id: "switch-hover-halo-shadow", x: "0", y: "0", width: "40", height: "40", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [_jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }), _jsx("feColorMatrix", { in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), _jsx("feOffset", { dy: "2" }), _jsx("feGaussianBlur", { stdDeviation: "4" }), _jsx("feComposite", { in2: "hardAlpha", operator: "out" }), _jsx("feColorMatrix", { type: "matrix", 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" }), _jsx("feBlend", { mode: "normal", in2: "BackgroundImageFix", result: "effect1_dropShadow" }), _jsx("feBlend", { mode: "normal", in: "SourceGraphic", in2: "effect1_dropShadow", result: "shape" })] }) })] }) }) }) })));
34
21
  });
35
22
  Switch.displayName = SwitchPrimitives.Root.displayName;
36
23
  export { Switch };
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Switch } from "./Switch";
3
3
  // More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
4
4
  const meta = {
@@ -20,8 +20,18 @@ export const Default = {
20
20
  disabled: false,
21
21
  },
22
22
  render: (args) => {
23
- console.log("args ", args);
24
23
  const props = Object.assign({}, args);
25
24
  return (_jsx("div", { className: "flex flex-row gap-4 w-full", children: _jsx(Switch, Object.assign({}, props)) }));
26
25
  },
27
26
  };
27
+ const switchPreviewRows = [
28
+ { label: "On - Default", checked: true },
29
+ { label: "On - Hover", checked: true, forceHover: true },
30
+ { label: "On - Disable", checked: true, disabled: true },
31
+ { label: "Off - Default", checked: false },
32
+ { label: "Off - Hover", checked: false, forceHover: true },
33
+ { label: "Off - Disable", checked: false, disabled: true },
34
+ ];
35
+ export const FigmaPreview = {
36
+ render: () => (_jsx("div", { className: "bg-base-bg2 p-8 min-h-screen", children: _jsx("div", { className: "mx-auto flex w-full max-w-[300px] flex-col gap-4 rounded-lg border border-base-bg-stroke1 bg-base-bg1 p-6", children: switchPreviewRows.map((row) => (_jsxs("div", { className: "grid grid-cols-[1fr_40px] items-center gap-6", children: [_jsx("span", { className: "text-sm font-medium text-text-white", children: row.label }), _jsx(Switch, { checked: row.checked, disabled: row.disabled, forceHover: row.forceHover })] }, row.label))) }) })),
37
+ };
@@ -0,0 +1,39 @@
1
+ import { cva } from "class-variance-authority";
2
+ export const switchRootVariants = cva([
3
+ "group relative inline-flex h-6 w-10 shrink-0 cursor-pointer items-center overflow-visible px-1",
4
+ "before:pointer-events-none before:absolute before:left-1 before:top-1/2 before:h-3 before:w-8 before:-translate-y-1/2 before:rounded-full before:transition-colors",
5
+ "data-[state=unchecked]:before:bg-[var(--switch-default-color)] hover:data-[state=unchecked]:before:bg-[var(--switch-hover-color)]",
6
+ "data-[state=checked]:before:bg-[var(--switch-active-color)] hover:data-[state=checked]:before:bg-[var(--switch-active-hover-color)]",
7
+ "data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none data-[disabled]:before:!bg-[var(--switch-disabled-color)]",
8
+ ], {
9
+ variants: {
10
+ forceHover: {
11
+ true: "data-[state=unchecked]:before:bg-[var(--switch-hover-color)] data-[state=checked]:before:bg-[var(--switch-active-hover-color)]",
12
+ false: "",
13
+ },
14
+ },
15
+ defaultVariants: {
16
+ forceHover: false,
17
+ },
18
+ });
19
+ export const switchThumbVariants = cva([
20
+ "relative isolate block size-4 rounded-full [filter:var(--switch-thumb-filter)] transition-[transform,background-color,color,filter]",
21
+ "data-[state=unchecked]:bg-[var(--switch-thumb-default-color)] data-[state=unchecked]:translate-x-0",
22
+ "data-[state=checked]:bg-[var(--switch-thumb-active-color)] data-[state=checked]:translate-x-4",
23
+ "data-[state=unchecked]:text-[var(--state-color-tertiary-hover-bg)] data-[state=checked]:text-[var(--state-color-primary-hover-bg)]",
24
+ "group-hover:[&_.switch-thumb-halo]:opacity-100 group-hover:data-[state=checked]:bg-[var(--switch-thumb-active-hover-color)] group-hover:data-[state=unchecked]:bg-[var(--switch-thumb-hover-color)]",
25
+ "group-disabled:!bg-[var(--switch-thumb-disabled-color)] group-disabled:[&_.switch-thumb-halo]:opacity-0",
26
+ ], {
27
+ variants: {
28
+ forceHover: {
29
+ true: "[&_.switch-thumb-halo]:opacity-100 data-[state=unchecked]:bg-[var(--switch-thumb-hover-color)] data-[state=checked]:bg-[var(--switch-thumb-active-hover-color)]",
30
+ false: "",
31
+ },
32
+ },
33
+ defaultVariants: {
34
+ forceHover: false,
35
+ },
36
+ });
37
+ export const switchThumbHaloVariants = cva([
38
+ "switch-thumb-halo pointer-events-none absolute left-0 top-0.5 -z-10 block size-6 -translate-x-1/2 -translate-y-1/2 opacity-0 transition-opacity",
39
+ ]);
@@ -15,18 +15,32 @@ import { helperTextVariant, iconActionVariant, inlineEndIconWrapperVariant, inli
15
15
  import { CircleAlert, CircleX, Search, } from "lucide-react";
16
16
  import { cn } from "@/utils/cn";
17
17
  export const TextInput = forwardRef((_a, ref) => {
18
- var { id, label, size = "md", rounded = "normal", variant = "outline", type = "text", iconMode = "solid", helperText, errorMessage, fullwidth = true, disabled = false, error = false, required = true, isFloatingLabel = true, keepCloseIconOnValue = false, keepFooterSpace = true, hasClearIcon = true, hasSearchIcon = false, startIcon, endIcon, labelClassName, onClickStartIcon, onClickEndIcon, renderStartIcon, renderEndIcon, classes } = _a, props = __rest(_a, ["id", "label", "size", "rounded", "variant", "type", "iconMode", "helperText", "errorMessage", "fullwidth", "disabled", "error", "required", "isFloatingLabel", "keepCloseIconOnValue", "keepFooterSpace", "hasClearIcon", "hasSearchIcon", "startIcon", "endIcon", "labelClassName", "onClickStartIcon", "onClickEndIcon", "renderStartIcon", "renderEndIcon", "classes"]);
18
+ var { id, label, size = "md", rounded = "normal", variant = "outline", type = "text", iconMode = "solid", helperText, errorMessage, warningMessage, status, fullwidth = true, disabled = false, error = false, warning = false, required = true, isFloatingLabel = true, keepCloseIconOnValue = false, keepFooterSpace = true, hasClearIcon = true, hasSearchIcon = false, startIcon, endIcon, labelClassName, onClickStartIcon, onClickEndIcon, renderStartIcon, renderEndIcon, classes } = _a, props = __rest(_a, ["id", "label", "size", "rounded", "variant", "type", "iconMode", "helperText", "errorMessage", "warningMessage", "status", "fullwidth", "disabled", "error", "warning", "required", "isFloatingLabel", "keepCloseIconOnValue", "keepFooterSpace", "hasClearIcon", "hasSearchIcon", "startIcon", "endIcon", "labelClassName", "onClickStartIcon", "onClickEndIcon", "renderStartIcon", "renderEndIcon", "classes"]);
19
19
  const inputRef = useRef(null);
20
20
  const _id = id || `${type}-${label}-input`;
21
21
  const hasLeftSectionIcon = !!startIcon || !!renderStartIcon;
22
22
  const hasRightSectionIcon = !!endIcon || !!renderEndIcon;
23
+ const feedbackStatus = status ||
24
+ (error || !!errorMessage
25
+ ? "error"
26
+ : warning || !!warningMessage
27
+ ? "warning"
28
+ : "default");
29
+ const isError = feedbackStatus === "error";
30
+ const isWarning = feedbackStatus === "warning";
31
+ const feedbackMessage = feedbackStatus === "error"
32
+ ? errorMessage
33
+ : feedbackStatus === "warning"
34
+ ? warningMessage
35
+ : helperText;
23
36
  const inputClassname = inputVariant({
24
37
  size,
25
38
  rounded,
26
39
  variant,
27
40
  fullwidth,
28
41
  disabled,
29
- error,
42
+ error: isError,
43
+ warning: isWarning,
30
44
  hasSearchIcon: (iconMode === "flat" && hasLeftSectionIcon) || hasSearchIcon,
31
45
  hasClearIcon: (iconMode === "flat" && hasRightSectionIcon) || hasClearIcon,
32
46
  leftSectionIcon: iconMode === "solid" ? hasLeftSectionIcon : false,
@@ -35,14 +49,15 @@ export const TextInput = forwardRef((_a, ref) => {
35
49
  const labelClassname = labelVariant({
36
50
  size,
37
51
  disabled,
38
- error,
52
+ error: isError,
39
53
  hasSearchIcon: (iconMode === "flat" && hasLeftSectionIcon) || hasSearchIcon,
40
54
  hasLeftSectionIcon: iconMode === "solid" ? hasLeftSectionIcon : false,
41
55
  isFloatingLabel,
42
56
  });
43
57
  const helperTextClassname = helperTextVariant({
44
58
  size,
45
- error,
59
+ error: isError,
60
+ warning: isWarning,
46
61
  disabled,
47
62
  });
48
63
  const inlineEndIconWrapperClassname = inlineEndIconWrapperVariant({ size });
@@ -54,13 +69,15 @@ export const TextInput = forwardRef((_a, ref) => {
54
69
  const startSegmentIconWrapperClassname = segmentedIconWrapperVariant({
55
70
  size,
56
71
  rounded,
57
- error,
72
+ error: isError,
73
+ warning: isWarning,
58
74
  position: "start",
59
75
  });
60
76
  const endSegmentIconWrapperClassname = segmentedIconWrapperVariant({
61
77
  size,
62
78
  rounded,
63
- error,
79
+ error: isError,
80
+ warning: isWarning,
64
81
  position: "end",
65
82
  });
66
83
  useImperativeHandle(ref, () => inputRef === null || inputRef === void 0 ? void 0 : inputRef.current);
@@ -136,6 +153,10 @@ export const TextInput = forwardRef((_a, ref) => {
136
153
  // "fill-none stroke-input-default-text hover:stroke-input-filled-text active:stroke-input-filled-text",
137
154
  classes === null || classes === void 0 ? void 0 : classes.icon), onMouseDown: handleClearInput }) })), endIconElement, _jsxs("label", { htmlFor: _id, className: cn(labelClassname), children: [label, " ", required && (_jsx("span", { className: cn("text-input-error", {
138
155
  "text-input-disable-text": disabled,
139
- }), children: "*" }))] })] }), (errorMessage || helperText || keepFooterSpace) && (_jsxs("span", { className: helperTextClassname, children: [(errorMessage || helperText) && (_jsx("span", { className: "h-full shrink-0", children: _jsx(CircleAlert, { width: 14, height: 14, className: cn("fill-none", error ? "stroke-input-error" : "stroke-input-filled-text") }) })), keepFooterSpace && !error && !helperText && (_jsx("span", { className: "block min-h-[14px]", "aria-hidden": true })), (error ? errorMessage : helperText) || ''] }))] }));
156
+ }), children: "*" }))] })] }), (feedbackMessage || keepFooterSpace) && (_jsxs("span", { className: helperTextClassname, children: [feedbackMessage && (_jsx("span", { className: "h-full shrink-0", children: _jsx(CircleAlert, { width: 14, height: 14, className: cn("fill-none stroke-current", isError
157
+ ? "text-input-error"
158
+ : isWarning
159
+ ? "text-warning"
160
+ : "text-input-filled-text") }) })), keepFooterSpace && !feedbackMessage && (_jsx("span", { className: "block min-h-[14px]", "aria-hidden": true })), feedbackMessage || ""] }))] }));
140
161
  });
141
162
  export default TextInput;
@@ -88,3 +88,16 @@ export const KeepFooterSpace = {
88
88
  },
89
89
  render: () => _jsx(KeepFooterSpaceDemo, {}),
90
90
  };
91
+ const FeedbackApiDemo = () => {
92
+ const [legacyError, setLegacyError] = useState(false);
93
+ const [legacyWarning, setLegacyWarning] = useState(false);
94
+ const [useStatusOverride, setUseStatusOverride] = useState(false);
95
+ return (_jsxs("div", { className: "flex flex-col gap-6 w-full max-w-2xl", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-text-grey-dark", children: [_jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: legacyError, onChange: (e) => setLegacyError(e.target.checked) }), "legacy error"] }), _jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: legacyWarning, onChange: (e) => setLegacyWarning(e.target.checked) }), "legacy warning"] }), _jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: useStatusOverride, onChange: (e) => setUseStatusOverride(e.target.checked) }), "status override = warning"] })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h4", { className: "text-sm font-medium text-text-grey-dark", children: "Legacy API (error / warning)" }), _jsx(TextInput, { id: "legacy-feedback", label: "Email", helperText: "We will never share your email.", keepFooterSpace: true, error: legacyError, errorMessage: legacyError ? "Invalid email format." : undefined, warning: legacyWarning, warningMessage: legacyWarning ? "Please verify this email." : undefined })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h4", { className: "text-sm font-medium text-text-grey-dark", children: "New API (status + message)" }), _jsx(TextInput, { id: "status-feedback", label: "Email", helperText: "We will never share your email.", keepFooterSpace: true, status: useStatusOverride ? "warning" : "default", error: legacyError, errorMessage: legacyError ? "Invalid email format." : undefined, warning: legacyWarning, warningMessage: useStatusOverride
96
+ ? "Status explicitly sets warning."
97
+ : legacyWarning
98
+ ? "Please verify this email."
99
+ : undefined })] })] })] }));
100
+ };
101
+ export const FeedbackApiCompatibility = {
102
+ render: () => _jsx(FeedbackApiDemo, {}),
103
+ };
@@ -37,6 +37,9 @@ export const inputVariant = cva([
37
37
  error: {
38
38
  true: "ring-input-error hover:ring-input-error focus:ring-input-error",
39
39
  },
40
+ warning: {
41
+ true: "ring-warning-stroke hover:ring-warning-stroke focus:ring-warning-stroke",
42
+ },
40
43
  hasClearIcon: {
41
44
  true: "",
42
45
  },
@@ -343,11 +346,15 @@ export const helperTextVariant = cva(["typography-small1 flex flex-row items-cen
343
346
  true: "text-input-error",
344
347
  false: "text-input-filled-text",
345
348
  },
349
+ warning: {
350
+ true: "text-warning",
351
+ },
346
352
  },
347
353
  defaultVariants: {
348
354
  size: "md",
349
355
  disabled: false,
350
356
  error: false,
357
+ warning: false,
351
358
  },
352
359
  });
353
360
  const iconInteractiveColorStateClasses = [
@@ -419,6 +426,9 @@ export const segmentedIconWrapperVariant = cva([
419
426
  error: {
420
427
  false: "",
421
428
  },
429
+ warning: {
430
+ false: "",
431
+ },
422
432
  position: {
423
433
  start: [
424
434
  "inset-y-0 left-0 ",
@@ -473,11 +483,23 @@ export const segmentedIconWrapperVariant = cva([
473
483
  error: true,
474
484
  className: "border-l-input-error",
475
485
  },
486
+ // --- Warning start ---
487
+ {
488
+ position: "start",
489
+ warning: true,
490
+ className: "border-r-warning-stroke",
491
+ },
492
+ {
493
+ position: "end",
494
+ warning: true,
495
+ className: "border-l-warning-stroke",
496
+ },
476
497
  ],
477
498
  defaultVariants: {
478
499
  size: "md",
479
500
  rounded: "normal",
480
501
  error: false,
502
+ warning: false,
481
503
  position: "end",
482
504
  },
483
505
  });
@@ -25,18 +25,18 @@ const ToastViewport = React.forwardRef((_a, ref) => {
25
25
  });
26
26
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
27
27
  const Toast = React.forwardRef((_a, ref) => {
28
- var { className, variant } = _a, props = __rest(_a, ["className", "variant"]);
29
- return (_jsx(ToastPrimitives.Root, Object.assign({ ref: ref, className: cn(toastVariants({ variant }), className) }, props)));
28
+ var { className, variant, showBorder } = _a, props = __rest(_a, ["className", "variant", "showBorder"]);
29
+ return (_jsx(ToastPrimitives.Root, Object.assign({ ref: ref, className: cn(toastVariants({ variant, showBorder }), className) }, props)));
30
30
  });
31
31
  Toast.displayName = ToastPrimitives.Root.displayName;
32
32
  const ToastAction = React.forwardRef((_a, ref) => {
33
33
  var { className, children } = _a, props = __rest(_a, ["className", "children"]);
34
- return (_jsx(ToastPrimitives.Action, Object.assign({ ref: ref, className: cn("", className) }, props, { asChild: true, children: _jsx(Button, { variant: "outline", size: "sm", children: children }) })));
34
+ return (_jsx(ToastPrimitives.Action, Object.assign({ ref: ref, className: cn("", className) }, props, { asChild: true, children: _jsx(Button, { variant: "outline", color: "secondary", size: "sm", children: children }) })));
35
35
  });
36
36
  ToastAction.displayName = ToastPrimitives.Action.displayName;
37
37
  const ToastClose = React.forwardRef((_a, ref) => {
38
38
  var { className } = _a, props = __rest(_a, ["className"]);
39
- return (_jsx(ToastPrimitives.Close, Object.assign({ ref: ref, className: cn("-mr-2 self-center text-input-default-text", className), "toast-close": "" }, props, { asChild: true, children: _jsx(ActionButton, { variant: "icon", size: "sm", children: _jsx(Icon, { type: "heroicons", name: "xmark" }) }) })));
39
+ return (_jsx(ToastPrimitives.Close, Object.assign({ ref: ref, className: cn("-mr-2 self-center text-grey-light", className), "toast-close": "" }, props, { asChild: true, children: _jsx(ActionButton, { variant: "icon", size: "sm", children: _jsx(Icon, { type: "heroicons", name: "xmark" }) }) })));
40
40
  });
41
41
  ToastClose.displayName = ToastPrimitives.Close.displayName;
42
42
  const ToastTitle = React.forwardRef((_a, ref) => {
@@ -46,7 +46,7 @@ const ToastTitle = React.forwardRef((_a, ref) => {
46
46
  ToastTitle.displayName = ToastPrimitives.Title.displayName;
47
47
  const ToastDescription = React.forwardRef((_a, ref) => {
48
48
  var { className } = _a, props = __rest(_a, ["className"]);
49
- return (_jsx(ToastPrimitives.Description, Object.assign({ ref: ref, className: cn("typography-subtitile5 text-input-default-text", className) }, props)));
49
+ return (_jsx(ToastPrimitives.Description, Object.assign({ ref: ref, className: cn("typography-subtitile4 text-grey-light", className) }, props)));
50
50
  });
51
51
  ToastDescription.displayName = ToastPrimitives.Description.displayName;
52
52
  export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction, };
@@ -11,9 +11,13 @@ const meta = {
11
11
  tags: ["autodocs"],
12
12
  parameters: {
13
13
  layout: "fullscreen",
14
+ backgrounds: {
15
+ default: "white",
16
+ values: [{ name: "white", value: "#ffffff" }],
17
+ },
14
18
  },
15
19
  decorators: [
16
- (Story) => (_jsx("div", { className: "flex max-h-screen w-full", children: _jsx(Story, {}) })),
20
+ (Story) => (_jsx("div", { className: "flex max-h-screen w-full bg-white p-4", children: _jsx(Story, {}) })),
17
21
  ],
18
22
  };
19
23
  export default meta;
@@ -38,11 +42,15 @@ export const Simple = {
38
42
  "bottom-right",
39
43
  ],
40
44
  },
45
+ showBorder: {
46
+ control: "boolean",
47
+ },
41
48
  },
42
49
  args: {
43
50
  variant: "default",
44
51
  contentMode: "horizontal",
45
52
  position: "top-center",
53
+ showBorder: false,
46
54
  },
47
55
  render: (args) => {
48
56
  console.log("args ", args);
@@ -53,11 +61,12 @@ export const Simple = {
53
61
  useEffect(() => {
54
62
  toast({
55
63
  variant: props.variant,
64
+ showBorder: props.showBorder,
56
65
  title: "Success",
57
66
  description: "This is an Info alert — check it out!",
58
67
  contentMode: props.contentMode,
59
68
  });
60
- }, [props.variant, props.contentMode]);
69
+ }, [props.variant, props.contentMode, props.showBorder]);
61
70
  return (_jsxs("div", { className: "flex flex-row gap-4 w-full", children: [_jsx(Toaster, {}), _jsx(Button, { onClick: () => {
62
71
  toast({
63
72
  title: "Scheduled: Catch up",
@@ -1,21 +1,53 @@
1
1
  import { cva } from "class-variance-authority";
2
2
  export const toastVariants = cva([
3
3
  "group pointer-events-auto relative flex w-full",
4
- "rounded-md shadow-lg px-4 py-3 gap-1",
4
+ "rounded-lg shadow-[0px_8px_16px_0px_rgba(0,0,0,0.12)] px-4 py-3 gap-1",
5
5
  "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",
6
6
  "bg-base-popup text-base-popup-foreground",
7
7
  ], {
8
8
  variants: {
9
9
  variant: {
10
- default: "border",
11
- success: "border border-success-stroke",
12
- info: "border border-info-stroke",
13
- warning: "border border-warning-stroke",
14
- error: "border border-error-stroke",
10
+ default: "",
11
+ success: "",
12
+ info: "",
13
+ warning: "",
14
+ error: "",
15
+ },
16
+ showBorder: {
17
+ true: "",
18
+ false: "border-transparent",
15
19
  },
16
20
  },
21
+ compoundVariants: [
22
+ {
23
+ variant: "default",
24
+ showBorder: true,
25
+ className: "border",
26
+ },
27
+ {
28
+ variant: "success",
29
+ showBorder: true,
30
+ className: "border border-success-stroke",
31
+ },
32
+ {
33
+ variant: "info",
34
+ showBorder: true,
35
+ className: "border border-info-stroke",
36
+ },
37
+ {
38
+ variant: "warning",
39
+ showBorder: true,
40
+ className: "border border-warning-stroke",
41
+ },
42
+ {
43
+ variant: "error",
44
+ showBorder: true,
45
+ className: "border border-error-stroke",
46
+ },
47
+ ],
17
48
  defaultVariants: {
18
49
  variant: "success",
50
+ showBorder: false,
19
51
  },
20
52
  });
21
53
  export const toastViewportVariants = cva(["fixed z-[1000] flex w-auto flex-col-reverse px-4"], {
@@ -21,6 +21,22 @@ export function Toaster(_a) {
21
21
  const { toasts, position } = useToast();
22
22
  return (_jsxs(ToastProvider, Object.assign({}, toastProviderProps, { children: [toasts.map(function (_a) {
23
23
  var { id, title, description, action, contentMode = "horizontal", iconProps, renderIcon } = _a, props = __rest(_a, ["id", "title", "description", "action", "contentMode", "iconProps", "renderIcon"]);
24
- return (_jsxs(Toast, Object.assign({}, props, { children: [_jsx("div", { className: cn(toastIconVariants({ variant: props.variant }), iconWrapperClassName), children: renderIcon ? (renderIcon === null || renderIcon === void 0 ? void 0 : renderIcon()) : (_jsx(Icon, Object.assign({ type: "heroicons", name: "check-circle", className: "size-6" }, iconProps))) }), _jsxs("div", { className: cn(toastContentVariants({ contentMode }), contentClassName), children: [title && (_jsx(ToastTitle, { className: titleClassName, children: title })), description && (_jsx(ToastDescription, { className: descriptionClassName, children: description }))] }), _jsx("div", { className: cn("self-center ml-[var(--spacing-spacing-xl)]", actionWrapperClassName), children: action }), _jsx(ToastClose, {})] }), id));
24
+ const defaultIconName = props.variant === "error"
25
+ ? "circle-x"
26
+ : props.variant === "warning"
27
+ ? "circle-alert"
28
+ : props.variant === "info"
29
+ ? "info"
30
+ : "circle-check";
31
+ const titleToneClass = props.variant === "error"
32
+ ? "text-error"
33
+ : props.variant === "warning"
34
+ ? "text-warning"
35
+ : props.variant === "info"
36
+ ? "text-info"
37
+ : props.variant === "success"
38
+ ? "text-success"
39
+ : "text-base-popup-foreground";
40
+ return (_jsxs(Toast, Object.assign({}, props, { children: [_jsx("div", { className: cn(toastIconVariants({ variant: props.variant }), iconWrapperClassName), children: renderIcon ? (renderIcon === null || renderIcon === void 0 ? void 0 : renderIcon()) : (_jsx(Icon, Object.assign({ type: "lucide", name: defaultIconName, className: "size-[22px]" }, iconProps))) }), _jsxs("div", { className: cn(toastContentVariants({ contentMode }), contentClassName), children: [title && (_jsx(ToastTitle, { className: cn(titleToneClass, titleClassName), children: title })), description && (_jsx(ToastDescription, { className: descriptionClassName, children: description }))] }), _jsx("div", { className: cn("self-center ml-[var(--spacing-spacing-xl)]", actionWrapperClassName), children: action }), _jsx(ToastClose, {})] }), id));
25
41
  }), _jsx(ToastViewport, { position: position, className: viewportClassName })] })));
26
42
  }