@rovula/ui 0.1.6 → 0.1.8

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 (232) hide show
  1. package/dist/cjs/bundle.css +630 -467
  2. package/dist/cjs/bundle.js +1545 -1545
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
  5. package/dist/cjs/types/components/Dialog/Dialog.d.ts +7 -1
  6. package/dist/cjs/types/components/Dialog/Dialog.stories.d.ts +3 -0
  7. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +2 -0
  8. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
  9. package/dist/cjs/types/components/Form/Field.d.ts +26 -0
  10. package/dist/cjs/types/components/Form/FieldMessage.d.ts +7 -0
  11. package/dist/cjs/types/components/Form/Form.d.ts +49 -11
  12. package/dist/cjs/types/components/Form/Form.stories.d.ts +23 -0
  13. package/dist/cjs/types/components/Form/ValidationHintList.d.ts +17 -0
  14. package/dist/cjs/types/components/Form/ValidationHintList.stories.d.ts +9 -0
  15. package/dist/cjs/types/components/Form/index.d.ts +10 -0
  16. package/dist/cjs/types/components/Form/useOptionBridge.d.ts +17 -0
  17. package/dist/cjs/types/components/OtpInput/OtpInput.d.ts +17 -0
  18. package/dist/cjs/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
  19. package/dist/cjs/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
  20. package/dist/cjs/types/components/OtpInput/index.d.ts +5 -0
  21. package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +3 -0
  22. package/dist/cjs/types/index.d.ts +5 -0
  23. package/dist/cjs/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
  24. package/dist/cjs/types/utils/colors.d.ts +351 -267
  25. package/dist/components/ActionButton/ActionButton.stories.js +2 -2
  26. package/dist/components/ActionButton/ActionButton.styles.js +1 -1
  27. package/dist/components/AlertDialog/AlertDialog.js +6 -6
  28. package/dist/components/AlertDialog/AlertDialog.stories.js +3 -0
  29. package/dist/components/Avatar/Avatar.stories.js +1 -1
  30. package/dist/components/Avatar/Avatar.styles.js +1 -1
  31. package/dist/components/Avatar/AvatarBase.js +1 -1
  32. package/dist/components/Avatar/AvatarGroup.stories.js +1 -1
  33. package/dist/components/Button/Buttons.stories.js +2 -2
  34. package/dist/components/Calendar/Calendar.js +1 -1
  35. package/dist/components/Checkbox/Checkbox.js +1 -1
  36. package/dist/components/Checkbox/Checkbox.stories.js +17 -7
  37. package/dist/components/Collapsible/Collapsible.styles.js +1 -1
  38. package/dist/components/DataTable/DataTable.js +2 -2
  39. package/dist/components/Dialog/Dialog.js +12 -7
  40. package/dist/components/Dialog/Dialog.stories.js +90 -2
  41. package/dist/components/Dropdown/Dropdown.js +2 -2
  42. package/dist/components/DropdownMenu/DropdownMenu.js +3 -3
  43. package/dist/components/FocusedScrollView/FocusedScrollView.stories.js +6 -6
  44. package/dist/components/Form/Field.js +60 -0
  45. package/dist/components/Form/FieldMessage.js +24 -0
  46. package/dist/components/Form/Form.js +73 -41
  47. package/dist/components/Form/Form.stories.js +221 -0
  48. package/dist/components/Form/ValidationHintList.js +30 -0
  49. package/dist/components/Form/ValidationHintList.stories.js +50 -0
  50. package/dist/components/Form/index.js +5 -0
  51. package/dist/components/Form/useOptionBridge.js +27 -0
  52. package/dist/components/InputFilter/InputFilter.js +5 -4
  53. package/dist/components/InputFilter/InputFilter.stories.js +1 -1
  54. package/dist/components/InputFilter/InputFilter.styles.js +14 -1
  55. package/dist/components/Label/Label.styles.js +1 -1
  56. package/dist/components/Menu/Menu.js +2 -2
  57. package/dist/components/NumberInput/NumberInput.stories.js +1 -1
  58. package/dist/components/OtpInput/OtpInput.js +118 -0
  59. package/dist/components/OtpInput/OtpInput.stories.js +60 -0
  60. package/dist/components/OtpInput/OtpInputGroup.js +23 -0
  61. package/dist/components/OtpInput/index.js +3 -0
  62. package/dist/components/PasswordInput/PasswordInput.stories.js +1 -1
  63. package/dist/components/Popover/Popover.js +1 -1
  64. package/dist/components/RadioGroup/RadioGroup.js +1 -1
  65. package/dist/components/RadioGroup/RadioGroup.stories.js +2 -2
  66. package/dist/components/Search/Search.js +13 -1
  67. package/dist/components/Search/Search.stories.js +1 -1
  68. package/dist/components/Slider/Slider.js +1 -1
  69. package/dist/components/Slider/Slider.stories.js +5 -5
  70. package/dist/components/Switch/Switch.stories.js +2 -2
  71. package/dist/components/Switch/Switch.styles.js +1 -1
  72. package/dist/components/Table/Table.js +5 -5
  73. package/dist/components/Tabs/Tabs.js +12 -9
  74. package/dist/components/Tabs/Tabs.stories.js +1 -1
  75. package/dist/components/Text/Text.js +1 -1
  76. package/dist/components/Text/Text.stories.js +1 -1
  77. package/dist/components/TextArea/TextArea.stories.js +1 -1
  78. package/dist/components/TextArea/TextArea.styles.js +3 -3
  79. package/dist/components/TextInput/TextInput.js +3 -2
  80. package/dist/components/TextInput/TextInput.stories.js +3 -3
  81. package/dist/components/TextInput/TextInput.styles.js +41 -19
  82. package/dist/components/Toast/Toast.js +4 -2
  83. package/dist/components/Toast/Toast.stories.js +1 -1
  84. package/dist/components/Toast/Toast.styles.js +4 -4
  85. package/dist/components/Toast/Toaster.js +2 -2
  86. package/dist/components/Tree/Tree.stories.js +1 -1
  87. package/dist/components/Tree/TreeItem.js +1 -1
  88. package/dist/esm/bundle.css +630 -467
  89. package/dist/esm/bundle.js +1545 -1545
  90. package/dist/esm/bundle.js.map +1 -1
  91. package/dist/esm/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
  92. package/dist/esm/types/components/Dialog/Dialog.d.ts +7 -1
  93. package/dist/esm/types/components/Dialog/Dialog.stories.d.ts +3 -0
  94. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +2 -0
  95. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
  96. package/dist/esm/types/components/Form/Field.d.ts +26 -0
  97. package/dist/esm/types/components/Form/FieldMessage.d.ts +7 -0
  98. package/dist/esm/types/components/Form/Form.d.ts +49 -11
  99. package/dist/esm/types/components/Form/Form.stories.d.ts +23 -0
  100. package/dist/esm/types/components/Form/ValidationHintList.d.ts +17 -0
  101. package/dist/esm/types/components/Form/ValidationHintList.stories.d.ts +9 -0
  102. package/dist/esm/types/components/Form/index.d.ts +10 -0
  103. package/dist/esm/types/components/Form/useOptionBridge.d.ts +17 -0
  104. package/dist/esm/types/components/OtpInput/OtpInput.d.ts +17 -0
  105. package/dist/esm/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
  106. package/dist/esm/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
  107. package/dist/esm/types/components/OtpInput/index.d.ts +5 -0
  108. package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +3 -0
  109. package/dist/esm/types/index.d.ts +5 -0
  110. package/dist/esm/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
  111. package/dist/esm/types/utils/colors.d.ts +351 -267
  112. package/dist/index.d.ts +512 -269
  113. package/dist/index.js +3 -0
  114. package/dist/src/theme/global.css +2739 -2681
  115. package/dist/theme/ThemeColorCoverageRuntime.stories.js +91 -0
  116. package/dist/utils/colors.js +359 -267
  117. package/package.json +4 -2
  118. package/src/components/ActionButton/ActionButton.stories.tsx +6 -6
  119. package/src/components/ActionButton/ActionButton.styles.ts +1 -1
  120. package/src/components/AlertDialog/AlertDialog.stories.tsx +22 -0
  121. package/src/components/AlertDialog/AlertDialog.tsx +6 -6
  122. package/src/components/Avatar/Avatar.stories.tsx +1 -1
  123. package/src/components/Avatar/Avatar.styles.ts +1 -1
  124. package/src/components/Avatar/AvatarBase.tsx +1 -1
  125. package/src/components/Avatar/AvatarGroup.stories.tsx +1 -1
  126. package/src/components/Button/Buttons.stories.tsx +25 -17
  127. package/src/components/Calendar/Calendar.tsx +3 -3
  128. package/src/components/Checkbox/Checkbox.stories.tsx +35 -12
  129. package/src/components/Checkbox/Checkbox.tsx +7 -5
  130. package/src/components/Collapsible/Collapsible.styles.ts +1 -1
  131. package/src/components/DataTable/DataTable.tsx +2 -2
  132. package/src/components/Dialog/Dialog.stories.tsx +173 -0
  133. package/src/components/Dialog/Dialog.tsx +32 -15
  134. package/src/components/Dropdown/Dropdown.styles.ts +1 -1
  135. package/src/components/Dropdown/Dropdown.tsx +16 -14
  136. package/src/components/DropdownMenu/DropdownMenu.tsx +3 -3
  137. package/src/components/FocusedScrollView/FocusedScrollView.stories.tsx +10 -10
  138. package/src/components/Form/Field.tsx +160 -0
  139. package/src/components/Form/FieldMessage.tsx +38 -0
  140. package/src/components/Form/Form.docs.mdx +67 -0
  141. package/src/components/Form/Form.stories.tsx +490 -0
  142. package/src/components/Form/Form.tsx +185 -87
  143. package/src/components/Form/README.md +284 -0
  144. package/src/components/Form/ValidationHintList.stories.tsx +118 -0
  145. package/src/components/Form/ValidationHintList.tsx +82 -0
  146. package/src/components/Form/index.ts +28 -0
  147. package/src/components/Form/useOptionBridge.ts +55 -0
  148. package/src/components/InputFilter/InputFilter.stories.tsx +1 -1
  149. package/src/components/InputFilter/InputFilter.styles.ts +14 -1
  150. package/src/components/InputFilter/InputFilter.tsx +33 -28
  151. package/src/components/Label/Label.styles.ts +2 -2
  152. package/src/components/Label/Label.tsx +1 -1
  153. package/src/components/Menu/Menu.tsx +12 -12
  154. package/src/components/NumberInput/NumberInput.stories.tsx +1 -1
  155. package/src/components/OtpInput/OtpInput.stories.tsx +168 -0
  156. package/src/components/OtpInput/OtpInput.tsx +210 -0
  157. package/src/components/OtpInput/OtpInputGroup.tsx +74 -0
  158. package/src/components/OtpInput/index.ts +5 -0
  159. package/src/components/PasswordInput/PasswordInput.stories.tsx +1 -1
  160. package/src/components/Popover/Popover.tsx +1 -1
  161. package/src/components/RadioGroup/RadioGroup.stories.tsx +4 -4
  162. package/src/components/RadioGroup/RadioGroup.tsx +2 -1
  163. package/src/components/Search/Search.stories.tsx +1 -1
  164. package/src/components/Search/Search.tsx +6 -2
  165. package/src/components/Slider/Slider.stories.tsx +7 -7
  166. package/src/components/Slider/Slider.tsx +1 -1
  167. package/src/components/Switch/Switch.stories.tsx +4 -4
  168. package/src/components/Switch/Switch.styles.ts +1 -1
  169. package/src/components/Table/Table.tsx +5 -5
  170. package/src/components/Tabs/Tabs.stories.tsx +1 -1
  171. package/src/components/Tabs/Tabs.tsx +29 -18
  172. package/src/components/Text/Text.stories.tsx +1 -1
  173. package/src/components/Text/Text.tsx +1 -1
  174. package/src/components/TextArea/TextArea.stories.tsx +1 -1
  175. package/src/components/TextArea/TextArea.styles.ts +3 -3
  176. package/src/components/TextInput/TextInput.stories.tsx +7 -7
  177. package/src/components/TextInput/TextInput.styles.ts +42 -19
  178. package/src/components/TextInput/TextInput.tsx +3 -1
  179. package/src/components/Toast/Toast.stories.tsx +1 -1
  180. package/src/components/Toast/Toast.styles.tsx +7 -7
  181. package/src/components/Toast/Toast.tsx +5 -4
  182. package/src/components/Toast/Toaster.tsx +17 -20
  183. package/src/components/Tree/Tree.stories.tsx +1 -1
  184. package/src/components/Tree/TreeItem.tsx +1 -1
  185. package/src/index.ts +5 -0
  186. package/src/theme/THEME_MAPPING.md +36 -37
  187. package/src/theme/ThemeColorCoverageRuntime.stories.tsx +236 -0
  188. package/src/theme/direct-token-migration-plan.md +121 -0
  189. package/src/theme/figma-mcp-check-report.md +225 -0
  190. package/src/theme/figma-mcp-component-checklist.json +1250 -0
  191. package/src/theme/global.css +7 -3
  192. package/src/theme/presets/colors.js +173 -64
  193. package/src/theme/themes/skyller/baseline.css +0 -4
  194. package/src/theme/themes/variable-mapping.css +1064 -0
  195. package/src/theme/themes/variable.css +248 -230
  196. package/src/theme/themes/xspector/baseline.css +0 -4
  197. package/src/theme/themes/xspector/components/dropdown-menu.css +4 -4
  198. package/src/theme/themes/xspector/components/loading.css +2 -2
  199. package/src/theme/tokens/baseline.css +0 -3
  200. package/src/theme/tokens/color.css +36 -65
  201. package/src/theme/tokens/components/action-button.css +6 -6
  202. package/src/theme/tokens/components/button.css +189 -189
  203. package/src/theme/tokens/components/dropdown-menu.css +5 -5
  204. package/src/theme/tokens/components/footer.css +1 -1
  205. package/src/theme/tokens/components/loading.css +2 -2
  206. package/src/theme/tokens/components/switch.css +11 -11
  207. package/src/theme/tokens/typography.css +28 -28
  208. package/src/theme/tokens_old/baseline.css +13 -0
  209. package/src/theme/tokens_old/color.css +78 -0
  210. package/src/theme/tokens_old/components/action-button.css +127 -0
  211. package/src/theme/tokens_old/components/button.css +512 -0
  212. package/src/theme/tokens_old/components/dropdown-menu.css +27 -0
  213. package/src/theme/tokens_old/components/footer.css +9 -0
  214. package/src/theme/tokens_old/components/loading.css +11 -0
  215. package/src/theme/tokens_old/components/navbar.css +9 -0
  216. package/src/theme/tokens_old/components/progress-bar.css +8 -0
  217. package/src/theme/tokens_old/components/switch.css +29 -0
  218. package/src/theme/tokens_old/typography.css +199 -0
  219. package/src/theme/tokens_old/variables.css +28 -0
  220. package/src/theme/utils.js +172 -33
  221. package/src/utils/colors.ts +367 -278
  222. package/src/theme/themes/skyller/color.css +0 -79
  223. package/src/theme/themes/skyller/palette.css +0 -143
  224. package/src/theme/themes/skyller/state.css +0 -94
  225. package/src/theme/themes/skyller/transparent.css +0 -94
  226. package/src/theme/themes/xspector/color.css +0 -83
  227. package/src/theme/themes/xspector/palette.css +0 -142
  228. package/src/theme/themes/xspector/state.css +0 -94
  229. package/src/theme/themes/xspector/transparent.css +0 -93
  230. /package/src/theme/{tokens → tokens_old}/palette.css +0 -0
  231. /package/src/theme/{tokens → tokens_old}/state.css +0 -0
  232. /package/src/theme/{tokens → tokens_old}/transparent.css +0 -0
@@ -0,0 +1,118 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useImperativeHandle, useMemo, useRef, } from "react";
3
+ import { cn } from "@/utils/cn";
4
+ const sanitizeChars = (raw, charPattern, maxLength) => {
5
+ const chars = Array.from(raw).filter((char) => charPattern.test(char));
6
+ return chars.slice(0, maxLength);
7
+ };
8
+ export const OtpInput = forwardRef(({ value, onChange, onBlur, onComplete, length = 6, disabled = false, invalid = false, autoFocus = false, inputMode = "numeric", charPattern = /^\d$/, className, inputClassName, }, ref) => {
9
+ const inputRefs = useRef([]);
10
+ const containerRef = useRef(null);
11
+ const slots = useMemo(() => {
12
+ const normalizedValue = value || "";
13
+ return Array.from({ length }, (_, index) => normalizedValue[index] || "");
14
+ }, [length, value]);
15
+ useImperativeHandle(ref, () => inputRefs.current[0], []);
16
+ const setCode = (nextSlots) => {
17
+ const nextValue = nextSlots.join("");
18
+ onChange(nextValue);
19
+ if (onComplete && nextSlots.every((slot) => slot !== "")) {
20
+ onComplete(nextValue);
21
+ }
22
+ };
23
+ const focusInput = (index) => {
24
+ var _a, _b;
25
+ const clamped = Math.max(0, Math.min(length - 1, index));
26
+ (_a = inputRefs.current[clamped]) === null || _a === void 0 ? void 0 : _a.focus();
27
+ (_b = inputRefs.current[clamped]) === null || _b === void 0 ? void 0 : _b.select();
28
+ };
29
+ const handleInputChange = (index, rawValue) => {
30
+ if (disabled)
31
+ return;
32
+ if (!rawValue) {
33
+ const nextSlots = [...slots];
34
+ nextSlots[index] = "";
35
+ setCode(nextSlots);
36
+ return;
37
+ }
38
+ const incomingChars = sanitizeChars(rawValue, charPattern, length);
39
+ if (!incomingChars.length)
40
+ return;
41
+ const nextSlots = [...slots];
42
+ let cursor = index;
43
+ incomingChars.forEach((char) => {
44
+ if (cursor < length) {
45
+ nextSlots[cursor] = char;
46
+ cursor += 1;
47
+ }
48
+ });
49
+ setCode(nextSlots);
50
+ if (cursor < length) {
51
+ focusInput(cursor);
52
+ }
53
+ else {
54
+ focusInput(length - 1);
55
+ }
56
+ };
57
+ const handlePaste = (index, event) => {
58
+ event.preventDefault();
59
+ if (disabled)
60
+ return;
61
+ const pasted = event.clipboardData.getData("text");
62
+ const incomingChars = sanitizeChars(pasted, charPattern, length - index);
63
+ if (!incomingChars.length)
64
+ return;
65
+ const nextSlots = [...slots];
66
+ incomingChars.forEach((char, offset) => {
67
+ nextSlots[index + offset] = char;
68
+ });
69
+ setCode(nextSlots);
70
+ const nextFocusIndex = Math.min(index + incomingChars.length, length - 1);
71
+ focusInput(nextFocusIndex);
72
+ };
73
+ const handleKeyDown = (index, event) => {
74
+ if (disabled)
75
+ return;
76
+ if (event.key === "ArrowLeft") {
77
+ event.preventDefault();
78
+ focusInput(index - 1);
79
+ return;
80
+ }
81
+ if (event.key === "ArrowRight") {
82
+ event.preventDefault();
83
+ focusInput(index + 1);
84
+ return;
85
+ }
86
+ if (event.key !== "Backspace")
87
+ return;
88
+ if (slots[index]) {
89
+ event.preventDefault();
90
+ const nextSlots = [...slots];
91
+ nextSlots[index] = "";
92
+ setCode(nextSlots);
93
+ return;
94
+ }
95
+ if (index > 0) {
96
+ event.preventDefault();
97
+ const nextSlots = [...slots];
98
+ nextSlots[index - 1] = "";
99
+ setCode(nextSlots);
100
+ focusInput(index - 1);
101
+ }
102
+ };
103
+ return (_jsx("div", { className: cn("flex items-center gap-3", className), ref: containerRef, children: slots.map((slot, index) => (_jsx("input", { ref: (element) => {
104
+ inputRefs.current[index] = element;
105
+ }, type: "text", inputMode: inputMode, autoComplete: index === 0 ? "one-time-code" : "off", value: slot, maxLength: 1, disabled: disabled, autoFocus: autoFocus && index === 0, "aria-invalid": invalid || undefined, className: cn("h-14 w-[46px] rounded-[8px] border bg-transparent text-center text-2xl font-semibold text-text-white outline-none transition-all duration-200", "border-input-default-stroke focus:border-input-active-stroke", "disabled:cursor-not-allowed disabled:opacity-50", invalid && "border-input-error focus:border-input-error", inputClassName), onFocus: (event) => {
106
+ event.target.select();
107
+ }, onBlur: (event) => {
108
+ var _a;
109
+ const nextFocused = event.relatedTarget;
110
+ const stillInside = nextFocused && ((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.contains(nextFocused));
111
+ // Notify RHF only when focus leaves the whole OTP control.
112
+ if (!stillInside) {
113
+ onBlur === null || onBlur === void 0 ? void 0 : onBlur();
114
+ }
115
+ }, onChange: (event) => handleInputChange(index, event.target.value), onPaste: (event) => handlePaste(index, event), onKeyDown: (event) => handleKeyDown(index, event) }, index))) }));
116
+ });
117
+ OtpInput.displayName = "OtpInput";
118
+ export default OtpInput;
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import * as yup from "yup";
4
+ import Button from "@/components/Button/Button";
5
+ import { Field } from "@/components/Form/Field";
6
+ import { Form } from "@/components/Form/Form";
7
+ import OtpInput from "./OtpInput";
8
+ import { OtpInputGroup } from "./OtpInputGroup";
9
+ const meta = {
10
+ title: "Components/OtpInput",
11
+ tags: ["autodocs"],
12
+ parameters: {
13
+ layout: "centered",
14
+ },
15
+ };
16
+ export default meta;
17
+ export const Basic = {
18
+ render: () => {
19
+ const [value, setValue] = useState("");
20
+ const [completed, setCompleted] = useState("-");
21
+ return (_jsx("div", { className: "w-[420px] max-w-full rounded-md bg-bg-bg2 p-4", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(OtpInput, { value: value, onChange: setValue, onComplete: (code) => setCompleted(code) }), _jsxs("div", { className: "text-xs text-text-g-contrast-medium", children: ["Value: ", value || "-"] }), _jsxs("div", { className: "text-xs text-text-g-contrast-medium", children: ["Last completed: ", completed] })] }) }));
22
+ },
23
+ };
24
+ const otpSchema = yup.object({
25
+ otp: yup
26
+ .string()
27
+ .required("OTP is required")
28
+ .length(6, "OTP must be 6 digits"),
29
+ });
30
+ export const WithFormField = {
31
+ render: () => {
32
+ return (_jsx("div", { className: "w-[420px] max-w-full rounded-md bg-bg-bg2 p-4", children: _jsx(Form, { defaultValues: { otp: "" }, validationSchema: otpSchema, mode: "onTouched", className: "flex flex-col gap-3", onSubmit: (values) => {
33
+ // eslint-disable-next-line no-console
34
+ console.log("OTP submit:", values);
35
+ }, children: ({ formState }) => (_jsxs(_Fragment, { children: [_jsx(Field, { name: "otp", component: OtpInput, componentProps: {
36
+ autoFocus: true,
37
+ }, invalidPropName: "invalid" }), _jsx(Button, { type: "submit", disabled: !formState.isValid || formState.isSubmitting, isLoading: formState.isSubmitting, children: "Verify OTP" })] })) }) }));
38
+ },
39
+ };
40
+ export const GroupWithLabelAndError = {
41
+ render: () => {
42
+ const [value, setValue] = useState("");
43
+ const isInvalid = value.length > 0 && value.length < 6;
44
+ return (_jsx("div", { className: "w-[420px] max-w-full rounded-md bg-bg-bg2 p-4", children: _jsx(OtpInputGroup, { id: "otp-group", label: "Verification code", required: true, value: value, onChange: setValue, helperText: "Enter the 6-digit code from your authenticator app", error: isInvalid, errorMessage: isInvalid ? "OTP must be 6 digits" : undefined, autoFocus: true }) }));
45
+ },
46
+ };
47
+ export const GroupWithFormField = {
48
+ render: () => {
49
+ return (_jsx("div", { className: "w-[420px] max-w-full rounded-md bg-bg-bg2 p-4", children: _jsx(Form, { defaultValues: { otp: "" }, validationSchema: otpSchema, mode: "onTouched", className: "flex flex-col gap-3", onSubmit: (values) => {
50
+ // eslint-disable-next-line no-console
51
+ console.log("OTP group submit:", values);
52
+ }, children: ({ formState }) => (_jsxs(_Fragment, { children: [_jsx(Field, { name: "otp", component: OtpInputGroup, componentProps: {
53
+ id: "otp-field-group",
54
+ label: "Verification code",
55
+ helperText: "Paste is supported",
56
+ required: true,
57
+ autoFocus: true,
58
+ }, invalidPropName: "error" }), _jsx(Button, { type: "submit", disabled: !formState.isValid || formState.isSubmitting, isLoading: formState.isSubmitting, children: "Verify OTP" })] })) }) }));
59
+ },
60
+ };
@@ -0,0 +1,23 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import React from "react";
14
+ import { cn } from "@/utils/cn";
15
+ import { OtpInput } from "./OtpInput";
16
+ export const OtpInputGroup = React.forwardRef((_a, ref) => {
17
+ var { id, label, required = false, helperText, error = false, errorMessage, keepFooterSpace = true, labelClassName, messageClassName, className } = _a, otpProps = __rest(_a, ["id", "label", "required", "helperText", "error", "errorMessage", "keepFooterSpace", "labelClassName", "messageClassName", "className"]);
18
+ const isInvalid = Boolean(error || errorMessage);
19
+ const message = isInvalid ? errorMessage : helperText;
20
+ return (_jsxs("div", { className: cn("inline-flex w-full flex-col gap-2", className), children: [label && (_jsxs("label", { htmlFor: id, className: cn("typography-overline text-input-default-text", isInvalid && "text-input-error", labelClassName), children: [label, required && _jsx("span", { className: "ml-1 text-input-error", children: "*" })] })), _jsx(OtpInput, Object.assign({}, otpProps, { ref: ref, invalid: isInvalid })), (message || keepFooterSpace) && (_jsx("div", { className: cn("typography-small2 min-h-[18px]", isInvalid ? "text-input-error" : "text-text-g-contrast-medium", messageClassName), role: isInvalid ? "alert" : undefined, children: message || " " }))] }));
21
+ });
22
+ OtpInputGroup.displayName = "OtpInputGroup";
23
+ export default OtpInputGroup;
@@ -0,0 +1,3 @@
1
+ export { OtpInput } from "./OtpInput";
2
+ export { OtpInputGroup } from "./OtpInputGroup";
3
+ export { default } from "./OtpInput";
@@ -8,7 +8,7 @@ const meta = {
8
8
  layout: "fullscreen",
9
9
  },
10
10
  decorators: [
11
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
11
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg2", children: _jsx(Story, {}) })),
12
12
  ],
13
13
  };
14
14
  export default meta;
@@ -18,7 +18,7 @@ const Popover = PopoverPrimitive.Root;
18
18
  const PopoverTrigger = PopoverPrimitive.Trigger;
19
19
  const PopoverContent = React.forwardRef((_a, ref) => {
20
20
  var { className, align = "center", sideOffset = 4 } = _a, props = __rest(_a, ["className", "align", "sideOffset"]);
21
- return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, Object.assign({ ref: ref, align: align, sideOffset: sideOffset, className: cn("z-50 min-w-72 rounded-md border bg-surface border-none overflow-hidden p-0 text-surface-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className) }, props)) }));
21
+ return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, Object.assign({ ref: ref, align: align, sideOffset: sideOffset, className: cn("z-50 min-w-72 rounded-md border bg-bg-bg1 border-none overflow-hidden p-0 text-common-black shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className) }, props)) }));
22
22
  });
23
23
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
24
24
  export { Popover, PopoverTrigger, PopoverContent };
@@ -22,7 +22,7 @@ const RadioGroupItem = React.forwardRef((_a, ref) => {
22
22
  var { className } = _a, props = __rest(_a, ["className"]);
23
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
- "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",
25
+ "data-[disabled]:!border-state-disable-outline data-[disabled]:!fill-state-disable-outline data-[disabled]:!cursor-not-allowed data-[disabled]:!pointer-events-none data-[disabled]:!text-state-disable-outline", "[&[data-disabled][data-state=checked]]:!border-state-disable-solid [&[data-disabled][data-state=checked]]:!text-state-disable-solid",
26
26
  // Checked state styles
27
27
  "data-[state=checked]:border-function-active-solid data-[state=checked]:text-function-active-solid", "hover:data-[state=checked]:border-function-active-hover hover:data-[state=checked]:text-function-active-hover", className) }, props, { children: _jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "fill-current text-current", children: _jsx("circle", { cx: "5", cy: "5", r: "5", fill: "current" }) }) }) })));
28
28
  });
@@ -9,7 +9,7 @@ const meta = {
9
9
  layout: "fullscreen",
10
10
  },
11
11
  decorators: [
12
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
12
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg2", children: _jsx(Story, {}) })),
13
13
  ],
14
14
  };
15
15
  export default meta;
@@ -53,5 +53,5 @@ const radioPreviewRows = [
53
53
  { label: "Checked - Disable", checked: true, disabled: true },
54
54
  ];
55
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))) }) })),
56
+ render: () => (_jsx("div", { className: "bg-bg-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-bg-stroke1 bg-bg-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-contrast-max", children: row.label }), _jsx(RadioGroup, { defaultValue: row.checked ? "option" : undefined, disabled: row.disabled, children: _jsx(RadioGroupItem, { value: "option", className: row.className }) })] }, row.label))) }) })),
57
57
  };
@@ -1,7 +1,19 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { jsx as _jsx } from "react/jsx-runtime";
2
13
  import { forwardRef } from "react";
3
14
  import Dropdown from "../Dropdown/Dropdown";
4
15
  const Search = forwardRef((props, ref) => {
5
- return (_jsx(Dropdown, Object.assign({ label: "Search" }, props, { ref: ref, keepCloseIconOnValue: true, hasClearIcon: true, hasSearchIcon: true, endIcon: null, filterMode: true, isFloatingLabel: false })));
16
+ const { label = "Search", required = false } = props, restProps = __rest(props, ["label", "required"]);
17
+ return (_jsx(Dropdown, Object.assign({ label: label, required: required }, restProps, { ref: ref, keepCloseIconOnValue: true, hasClearIcon: true, hasSearchIcon: true, endIcon: null, filterMode: true, isFloatingLabel: false, segmentedInput: false })));
6
18
  });
7
19
  export { Search };
@@ -8,7 +8,7 @@ const meta = {
8
8
  layout: "fullscreen",
9
9
  },
10
10
  decorators: [
11
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
11
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg2", children: _jsx(Story, {}) })),
12
12
  ],
13
13
  };
14
14
  export default meta;
@@ -16,7 +16,7 @@ import * as SliderPrimitive from "@radix-ui/react-slider";
16
16
  import { cn } from "@/utils/cn";
17
17
  const Slider = React.forwardRef((_a, ref) => {
18
18
  var { className, trackClassName, rangeClassName, thumbClassName, thumbStyle, trackStyle, rangeStyle } = _a, props = __rest(_a, ["className", "trackClassName", "rangeClassName", "thumbClassName", "thumbStyle", "trackStyle", "rangeStyle"]);
19
- return (_jsxs(SliderPrimitive.Root, Object.assign({ ref: ref, className: cn("relative flex w-full touch-none select-none items-center", className) }, props, { children: [_jsx(SliderPrimitive.Track, { className: cn("relative h-2 w-full grow overflow-hidden rounded-full bg-grey-50", trackClassName), style: trackStyle, children: _jsx(SliderPrimitive.Range, { className: cn("absolute h-full bg-primary", rangeClassName), style: rangeStyle }) }), _jsx(SliderPrimitive.Thumb, { className: cn("block h-5 w-5 cursor-pointer rounded-full border-[3px] border-primary bg-background outline-none ring-0 transition-colors disabled:pointer-events-none disabled:opacity-50", thumbClassName), style: thumbStyle })] })));
19
+ return (_jsxs(SliderPrimitive.Root, Object.assign({ ref: ref, className: cn("relative flex w-full touch-none select-none items-center", className) }, props, { children: [_jsx(SliderPrimitive.Track, { className: cn("relative h-2 w-full grow overflow-hidden rounded-full bg-grey-50", trackClassName), style: trackStyle, children: _jsx(SliderPrimitive.Range, { className: cn("absolute h-full bg-primary", rangeClassName), style: rangeStyle }) }), _jsx(SliderPrimitive.Thumb, { className: cn("block h-5 w-5 cursor-pointer rounded-full border-[3px] border-primary bg-bg-bg1 outline-none ring-0 transition-colors disabled:pointer-events-none disabled:opacity-50", thumbClassName), style: thumbStyle })] })));
20
20
  });
21
21
  Slider.displayName = SliderPrimitive.Root.displayName;
22
22
  export { Slider };
@@ -11,7 +11,7 @@ const meta = {
11
11
  layout: "fullscreen",
12
12
  },
13
13
  decorators: [
14
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-background", children: _jsx(Story, {}) })),
14
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg1", children: _jsx(Story, {}) })),
15
15
  ],
16
16
  };
17
17
  export default meta;
@@ -38,15 +38,15 @@ export const GradientColor = {
38
38
  const [empty, setEmpty] = useState([50]);
39
39
  const [rainbow, setRainbow] = useState([50]);
40
40
  const [darkRed, setDarkRed] = useState([50]);
41
- return (_jsxs("div", { className: "w-[400px] p-6 space-y-8 rounded-md shadow-lg bg-surface", children: [_jsx(Slider, { value: exposure, onValueChange: setExposure, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24 bg-gradient-to-r from-black to-white", rangeClassName: "bg-unset", thumbClassName: "bg-white border border-white shadow", thumbStyle: {
41
+ return (_jsxs("div", { className: "w-[400px] p-6 space-y-8 rounded-md shadow-lg bg-bg-bg1", children: [_jsx(Slider, { value: exposure, onValueChange: setExposure, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24 bg-gradient-to-r from-common-black to-common-white", rangeClassName: "bg-unset", thumbClassName: "bg-common-white border border-common-white shadow", thumbStyle: {
42
42
  filter: "drop-shadow(0px 6px 12px rgba(0, 0, 0, 0.12))",
43
- }, min: 0, max: 100, step: 1 }), _jsx(Slider, { value: empty, onValueChange: setEmpty, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24", rangeClassName: "bg-unset", thumbClassName: "bg-white border border-white shadow", thumbStyle: {
43
+ }, min: 0, max: 100, step: 1 }), _jsx(Slider, { value: empty, onValueChange: setEmpty, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24", rangeClassName: "bg-unset", thumbClassName: "bg-common-white border border-common-white shadow", thumbStyle: {
44
44
  filter: "drop-shadow(0px 6px 12px rgba(0, 0, 0, 0.12))",
45
45
  }, min: 0, max: 100, step: 1 }), _jsx(Slider, { value: rainbow, onValueChange: setRainbow, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24", trackStyle: {
46
46
  backgroundImage: "linear-gradient(90deg, #F00 0%, #FF8502 11.54%, #F2FF05 23.08%, #06F90F 35.58%, #00E6FF 48.56%, #0404FF 61.54%, #AB02FF 74.52%, #FF069E 87.5%, #FF0408 100%)",
47
- }, rangeClassName: "bg-unset", thumbClassName: "bg-white border border-white shadow", thumbStyle: {
47
+ }, rangeClassName: "bg-unset", thumbClassName: "bg-common-white border border-common-white shadow", thumbStyle: {
48
48
  filter: "drop-shadow(0px 6px 12px rgba(0, 0, 0, 0.12))",
49
- }, min: 0, max: 100, step: 1 }), _jsx(Slider, { value: darkRed, onValueChange: setDarkRed, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24 bg-gradient-to-r from-[#848484] to-[#A00202]", rangeClassName: "bg-unset", thumbClassName: "bg-white border border-white shadow", thumbStyle: {
49
+ }, min: 0, max: 100, step: 1 }), _jsx(Slider, { value: darkRed, onValueChange: setDarkRed, className: "bg-grey-transparent-24", trackClassName: "h-1 rounded-full bg-grey-transparent-24 bg-gradient-to-r from-[#848484] to-[#A00202]", rangeClassName: "bg-unset", thumbClassName: "bg-common-white border border-common-white shadow", thumbStyle: {
50
50
  filter: "drop-shadow(0px 6px 12px rgba(0, 0, 0, 0.12))",
51
51
  }, min: 0, max: 100, step: 1 })] }));
52
52
  },
@@ -10,7 +10,7 @@ const meta = {
10
10
  layout: "fullscreen",
11
11
  },
12
12
  decorators: [
13
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
13
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg2", children: _jsx(Story, {}) })),
14
14
  ],
15
15
  };
16
16
  export default meta;
@@ -33,5 +33,5 @@ const switchPreviewRows = [
33
33
  { label: "Off - Disable", checked: false, disabled: true },
34
34
  ];
35
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))) }) })),
36
+ render: () => (_jsx("div", { className: "bg-bg-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-bg-stroke1 bg-bg-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-contrast-max", children: row.label }), _jsx(Switch, { checked: row.checked, disabled: row.disabled, forceHover: row.forceHover })] }, row.label))) }) })),
37
37
  };
@@ -20,7 +20,7 @@ export const switchThumbVariants = cva([
20
20
  "relative isolate block size-4 rounded-full [filter:var(--switch-thumb-filter)] transition-[transform,background-color,color,filter]",
21
21
  "data-[state=unchecked]:bg-[var(--switch-thumb-default-color)] data-[state=unchecked]:translate-x-0",
22
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)]",
23
+ "data-[state=unchecked]:text-[var(--state-tertiary-hover-bg)] data-[state=checked]:text-[var(--state-primary-hover-bg)]",
24
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
25
  "group-disabled:!bg-[var(--switch-thumb-disabled-color)] group-disabled:[&_.switch-thumb-halo]:opacity-0",
26
26
  ], {
@@ -29,27 +29,27 @@ const TableBody = React.forwardRef((_a, ref) => {
29
29
  TableBody.displayName = "TableBody";
30
30
  const TableFooter = React.forwardRef((_a, ref) => {
31
31
  var { className } = _a, props = __rest(_a, ["className"]);
32
- return (_jsx("tfoot", Object.assign({ ref: ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className) }, props)));
32
+ return (_jsx("tfoot", Object.assign({ ref: ref, className: cn("border-t bg-transparent-grey2-8 font-medium [&>tr]:last:border-b-0", className) }, props)));
33
33
  });
34
34
  TableFooter.displayName = "TableFooter";
35
35
  const TableRow = React.forwardRef((_a, ref) => {
36
36
  var { className } = _a, props = __rest(_a, ["className"]);
37
- return (_jsx("tr", Object.assign({ ref: ref, className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-grey-20", className) }, props)));
37
+ return (_jsx("tr", Object.assign({ ref: ref, className: cn("border-b transition-colors hover:bg-transparent-grey2-8 data-[state=selected]:bg-grey-20", className) }, props)));
38
38
  });
39
39
  TableRow.displayName = "TableRow";
40
40
  const TableHead = React.forwardRef((_a, ref) => {
41
41
  var { className } = _a, props = __rest(_a, ["className"]);
42
- return (_jsx("th", Object.assign({ ref: ref, className: cn(" h-12 py-3 px-6 text-left align-middle typography-body2 text-text-grey-dark [&:has([role=checkbox])]:pr-4 [&:has([role=checkbox])]:w-4", className) }, props)));
42
+ return (_jsx("th", Object.assign({ ref: ref, className: cn(" h-12 py-3 px-6 text-left align-middle typography-body2 text-text-g-contrast-low [&:has([role=checkbox])]:pr-4 [&:has([role=checkbox])]:w-4", className) }, props)));
43
43
  });
44
44
  TableHead.displayName = "TableHead";
45
45
  const TableCell = React.forwardRef((_a, ref) => {
46
46
  var { className } = _a, props = __rest(_a, ["className"]);
47
- return (_jsx("td", Object.assign({ ref: ref, className: cn(" py-3 px-6 text-left align-middle typography-body3 text-text-grey-dark [&:has([role=checkbox])]:pr-4 [&:has([role=checkbox])]:w-4", className) }, props)));
47
+ return (_jsx("td", Object.assign({ ref: ref, className: cn(" py-3 px-6 text-left align-middle typography-body3 text-text-g-contrast-low [&:has([role=checkbox])]:pr-4 [&:has([role=checkbox])]:w-4", className) }, props)));
48
48
  });
49
49
  TableCell.displayName = "TableCell";
50
50
  const TableCaption = React.forwardRef((_a, ref) => {
51
51
  var { className } = _a, props = __rest(_a, ["className"]);
52
- return (_jsx("caption", Object.assign({ ref: ref, className: cn("mt-4 text-sm text-muted-foreground", className) }, props)));
52
+ return (_jsx("caption", Object.assign({ ref: ref, className: cn("mt-4 text-sm text-text-g-contrast-medium", className) }, props)));
53
53
  });
54
54
  TableCaption.displayName = "TableCaption";
55
55
  export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, };
@@ -5,8 +5,10 @@ import "./Tabs.css";
5
5
  import ActionButton from "../ActionButton/ActionButton";
6
6
  import Icon from "../Icon/Icon";
7
7
  import { Loading } from "@/index";
8
- const Tabs = ({ tabs = [], value, initialTab = 0, tabBarSize = 38, enableBorderLine = true, enableAddTabButton = false, keepIconSpace = true, disabled = false, keepMounted = false, tabMode = "start", className, tabBarClassName, tabBarContainerClassName, tabBarWrapperClassName, tabButtonClassName, tabButtonActiveClassName, tabButtonActiveDisableClassName, tabButtonDisableClassName, tabContentClassName, addTabButtonWrapperClassName, borderSliderClassName, leftAction, rightAction, onAddTab, onTabChange, }) => {
8
+ const Tabs = ({ tabs = [], value, initialTab = 0, tabBarSize = 38, enableBorderLine = true, enableAddTabButton = false, keepIconSpace = false, disabled = false, keepMounted = false, tabMode = "start", className, tabBarClassName, tabBarContainerClassName, tabBarWrapperClassName, tabButtonClassName, tabButtonActiveClassName, tabButtonActiveDisableClassName, tabButtonDisableClassName, tabContentClassName, addTabButtonWrapperClassName, borderSliderClassName, leftAction, rightAction, onAddTab, onTabChange, }) => {
9
+ var _a;
9
10
  const [activeTab, setActiveTab] = useState(initialTab);
11
+ const [hoveredTab, setHoveredTab] = useState(null);
10
12
  const [sliderStyle, setSliderStyle] = useState({
11
13
  width: "0px",
12
14
  transform: "translateX(0px)",
@@ -70,11 +72,11 @@ const Tabs = ({ tabs = [], value, initialTab = 0, tabBarSize = 38, enableBorderL
70
72
  justifyContent: tabMode === "justify" ? "stretch" : tabMode,
71
73
  }, role: "tablist", children: [tabs.map((tab, index) => {
72
74
  var _a, _b, _c, _d, _e, _f, _g, _h;
73
- return (_jsxs("button", { ref: (el) => (tabRefs.current[index] = el), role: "tab", "aria-selected": index === activeTab, "aria-controls": `tab-content-${index}`, disabled: disabled || tab.disabled, id: `tab-${index}`, className: cn("flex justify-center flex-row items-center py-3 cursor-pointer transition-colors duration-300 box-border gap-1 flex-shrink-0 typography-subtitle6", {
74
- "text-foreground": index === activeTab,
75
- "text-text-grey-medium hover:text-text-grey-dark active:text-text-dark": index !== activeTab,
75
+ return (_jsxs("button", { ref: (el) => (tabRefs.current[index] = el), role: "tab", "aria-selected": index === activeTab, "aria-controls": `tab-content-${index}`, disabled: disabled || tab.disabled, id: `tab-${index}`, className: cn("group relative flex justify-center flex-row items-center py-3 cursor-pointer transition-colors duration-300 box-border gap-1 flex-shrink-0 typography-subtitle6", {
76
+ "text-text-contrast-max": index === activeTab,
77
+ "text-text-g-contrast-medium": index !== activeTab,
76
78
  // -- disabled
77
- "text-state-disable-solid pointer-events-none": disabled || tab.disabled,
79
+ "text-state-disable-outline pointer-events-none": disabled || tab.disabled,
78
80
  [(_b = (_a = tab.disableClassName) !== null && _a !== void 0 ? _a : tabButtonDisableClassName) !== null && _b !== void 0 ? _b : ""]: disabled || tab.disabled,
79
81
  // --
80
82
  "text-state-disable-outline": index === activeTab && (disabled || tab.disabled),
@@ -88,10 +90,11 @@ const Tabs = ({ tabs = [], value, initialTab = 0, tabBarSize = 38, enableBorderL
88
90
  }), onClick: () => {
89
91
  setActiveTab(index);
90
92
  onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange(index);
91
- }, children: [(keepIconSpace || tab.startTabContent) && (_jsx("div", { className: "h-full w-3 flex items-center justify-center", children: tab.isLoading ? _jsx(Loading, {}) : tab.startTabContent })), tab.label, (keepIconSpace || tab.endTabContent) && (_jsx("div", { className: "h-full w-3 flex items-center justify-center", children: tab.endTabContent }))] }, index));
92
- }), _jsx("div", { className: cn(`absolute left-0 bottom-0 h-[2px] rounded-full bg-foreground transition-all duration-300 ease-in-out`, {
93
- "bg-state-disable-solid": disabled,
94
- }, borderSliderClassName), style: sliderStyle })] }) }), enableAddTabButton && (_jsx("div", { className: cn("sticky right-0 flex content-center items-center mx-4", addTabButtonWrapperClassName), children: _jsx(ActionButton, { variant: "outline", size: "sm", onClick: () => onAddTab === null || onAddTab === void 0 ? void 0 : onAddTab(), disabled: disabled, children: _jsx(Icon, { name: "plus" }) }) })), rightAction] }), _jsx("div", { className: cn("mt-4 text-foreground", tabContentClassName), role: "tabpanel", id: `tab-content-${activeTab}`, "aria-labelledby": `tab-${activeTab}`, children: tabs.map((tab, idx) => {
93
+ }, onMouseEnter: () => setHoveredTab(index), onMouseLeave: () => setHoveredTab(null), children: [(keepIconSpace || tab.startTabContent) && (_jsx("div", { className: "h-full w-3 flex items-center justify-center [&_svg]:size-3 [&_svg]:stroke-current [&_svg]:text-current", children: tab.isLoading ? (_jsx(Loading, { size: 12 })) : (tab.startTabContent) })), tab.label, (keepIconSpace || tab.endTabContent) && (_jsx("div", { className: "h-full w-3 flex items-center justify-center [&_svg]:size-3 [&_svg]:stroke-current [&_svg]:text-current", children: tab.endTabContent })), !disabled && !tab.disabled && index !== activeTab && (_jsx("div", { className: "absolute bottom-0 left-0 right-0 h-[2px] rounded-[1px] bg-function-default-hover opacity-0 transition-opacity duration-150 group-hover:opacity-100" }))] }, index));
94
+ }), _jsx("div", { className: cn("absolute left-0 bottom-0 h-[2px] rounded-[1px] bg-function-active-solid transition-all duration-300 ease-in-out", {
95
+ hidden: disabled || ((_a = tabs[activeTab]) === null || _a === void 0 ? void 0 : _a.disabled),
96
+ "bg-function-active-hover": hoveredTab === activeTab && !disabled,
97
+ }, borderSliderClassName), style: sliderStyle })] }) }), enableAddTabButton && (_jsx("div", { className: cn("sticky right-0 flex content-center items-center mx-4", addTabButtonWrapperClassName), children: _jsx(ActionButton, { variant: "outline", size: "sm", onClick: () => onAddTab === null || onAddTab === void 0 ? void 0 : onAddTab(), disabled: disabled, children: _jsx(Icon, { name: "plus" }) }) })), rightAction] }), _jsx("div", { className: cn("mt-4 text-text-g-contrast-high", tabContentClassName), role: "tabpanel", id: `tab-content-${activeTab}`, "aria-labelledby": `tab-${activeTab}`, children: tabs.map((tab, idx) => {
95
98
  var _a;
96
99
  if (!keepMounted && activeTab !== idx) {
97
100
  return null;
@@ -15,7 +15,7 @@ const meta = {
15
15
  layout: "fullscreen",
16
16
  },
17
17
  decorators: [
18
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
18
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg2", children: _jsx(Story, {}) })),
19
19
  ],
20
20
  };
21
21
  export default meta;
@@ -13,7 +13,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { cn } from "@/utils/cn";
14
14
  import { forwardRef } from "react";
15
15
  import { cva } from "class-variance-authority";
16
- const textVariants = cva(["text-foreground"], {
16
+ const textVariants = cva(["text-common-black"], {
17
17
  variants: {
18
18
  color: {
19
19
  primary: "text-primary",
@@ -10,7 +10,7 @@ const meta = {
10
10
  layout: "fullscreen",
11
11
  },
12
12
  decorators: [
13
- (Story) => (_jsx("div", { className: "p-5 flex w-full bg-base-bg2", children: _jsx(Story, {}) })),
13
+ (Story) => (_jsx("div", { className: "p-5 flex w-full bg-bg-bg2", children: _jsx(Story, {}) })),
14
14
  ],
15
15
  };
16
16
  export default meta;
@@ -8,7 +8,7 @@ const meta = {
8
8
  },
9
9
  tags: ["autodocs"],
10
10
  decorators: [
11
- (Story) => (_jsx("div", { className: "p-5 flex h-screen w-full bg-base-bg2", children: _jsx(Story, {}) })),
11
+ (Story) => (_jsx("div", { className: "p-5 flex h-screen w-full bg-bg-bg2", children: _jsx(Story, {}) })),
12
12
  ],
13
13
  argTypes: {
14
14
  size: {
@@ -52,17 +52,17 @@ export const textareaVariant = cva([
52
52
  {
53
53
  hasClearIcon: true,
54
54
  size: "sm",
55
- class: "focus:pe-6",
55
+ className: "focus:pe-6",
56
56
  },
57
57
  {
58
58
  hasClearIcon: true,
59
59
  size: "md",
60
- class: "focus:pe-8",
60
+ className: "focus:pe-8",
61
61
  },
62
62
  {
63
63
  hasClearIcon: true,
64
64
  size: "lg",
65
- class: "focus:pe-10",
65
+ className: "focus:pe-10",
66
66
  },
67
67
  ],
68
68
  defaultVariants: {
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
11
11
  };
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, } from "react";
14
- import { helperTextVariant, iconActionVariant, inlineEndIconWrapperVariant, inlineStartIconWrapperVariant, inputVariant, labelVariant, segmentedIconWrapperVariant, } from "./TextInput.styles";
14
+ import { helperTextVariant, iconActionVariant, inlineEndIconWrapperVariant, inlineStartIconWrapperVariant, inputVariant, labelVariant, searchIconVariant, segmentedIconWrapperVariant, } from "./TextInput.styles";
15
15
  import { CircleAlert, CircleX, Search, } from "lucide-react";
16
16
  import { cn } from "@/utils/cn";
17
17
  export const TextInput = forwardRef((_a, ref) => {
@@ -65,6 +65,7 @@ export const TextInput = forwardRef((_a, ref) => {
65
65
  size,
66
66
  });
67
67
  const iconActionClassname = iconActionVariant({ size });
68
+ const searchIconClassname = searchIconVariant({ size });
68
69
  // TODO wait for clearify aboutm start,end, search and clearIcon with iconMode
69
70
  const startSegmentIconWrapperClassname = segmentedIconWrapperVariant({
70
71
  size,
@@ -146,7 +147,7 @@ export const TextInput = forwardRef((_a, ref) => {
146
147
  renderEndIcon,
147
148
  handleOnClickRightSectionIcon,
148
149
  ]);
149
- return (_jsxs("div", { className: `inline-flex flex-col ${fullwidth ? "w-full" : ""}`, children: [_jsxs("div", { className: "relative", children: [_jsx("input", Object.assign({}, props, { placeholder: " ", ref: inputRef, type: type, id: _id, disabled: disabled, className: cn(inputClassname, props.className) })), hasSearchIcon && !hasLeftSectionIcon && (_jsx("div", { className: cn(inlineStartIconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconSearchWrapper), children: _jsx(Search, { className: cn(iconActionClassname, classes === null || classes === void 0 ? void 0 : classes.icon) }) })), startIconElement, hasClearIcon && !hasRightSectionIcon && (_jsx("div", { className: cn(inlineEndIconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconWrapper), style: {
150
+ return (_jsxs("div", { className: `inline-flex flex-col ${fullwidth ? "w-full" : ""}`, children: [_jsxs("div", { className: "relative", children: [_jsx("input", Object.assign({}, props, { placeholder: " ", ref: inputRef, type: type, id: _id, disabled: disabled, className: cn(inputClassname, props.className) })), hasSearchIcon && !hasLeftSectionIcon && (_jsx("div", { className: cn(inlineStartIconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconSearchWrapper), children: _jsx(Search, { className: cn(searchIconClassname, classes === null || classes === void 0 ? void 0 : classes.icon) }) })), startIconElement, hasClearIcon && !hasRightSectionIcon && (_jsx("div", { className: cn(inlineEndIconWrapperClassname, classes === null || classes === void 0 ? void 0 : classes.iconWrapper), style: {
150
151
  display: keepCloseIconOnValue && props.value ? "flex" : undefined,
151
152
  }, children: _jsx(CircleX, { className: cn(iconActionClassname,
152
153
  // 'fill-none stroke-current',
@@ -13,7 +13,7 @@ const meta = {
13
13
  layout: "fullscreen",
14
14
  },
15
15
  decorators: [
16
- (Story) => (_jsx("div", { className: "p-5 flex h-full w-full bg-[var(--base-color-popup)] ", children: _jsx(Story, {}) })),
16
+ (Story) => (_jsx("div", { className: "p-5 flex h-full w-full bg-modal-surface", children: _jsx(Story, {}) })),
17
17
  ],
18
18
  };
19
19
  export default meta;
@@ -78,7 +78,7 @@ export const CustomIcon = {
78
78
  };
79
79
  const KeepFooterSpaceDemo = () => {
80
80
  const [hasError, setHasError] = useState(false);
81
- return (_jsxs("div", { className: "flex flex-col gap-8 w-full max-w-md", children: [_jsxs("p", { className: "text-sm text-text-grey-dark", children: ["Use ", _jsx("code", { children: "keepFooterSpace" }), " to always reserve space for the footer/helper area, preventing layout shift when an error or helper text is shown or hidden."] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: hasError, onChange: (e) => setHasError(e.target.checked) }), "Show error message"] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { children: [_jsx("h4", { className: "text-sm font-medium mb-2 text-text-grey-dark", children: "With keepFooterSpace (layout stays stable)" }), _jsx(TextInput, { id: "with-keep", label: "Email", keepFooterSpace: true, size: "lg", error: hasError, errorMessage: hasError ? "Please enter a valid email address" : undefined })] }), _jsxs("div", { children: [_jsx("h4", { className: "text-sm font-medium mb-2 text-text-grey-dark", children: "Without keepFooterSpace (layout shifts when error appears)" }), _jsx(TextInput, { id: "no-keep", label: "Email", size: "lg", error: hasError, errorMessage: hasError ? "Please enter a valid email address" : undefined })] }), _jsx("div", {})] })] })] }));
81
+ return (_jsxs("div", { className: "flex flex-col gap-8 w-full max-w-md", children: [_jsxs("p", { className: "text-sm text-text-g-contrast-low", children: ["Use ", _jsx("code", { children: "keepFooterSpace" }), " to always reserve space for the footer/helper area, preventing layout shift when an error or helper text is shown or hidden."] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: hasError, onChange: (e) => setHasError(e.target.checked) }), "Show error message"] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { children: [_jsx("h4", { className: "text-sm font-medium mb-2 text-text-g-contrast-low", children: "With keepFooterSpace (layout stays stable)" }), _jsx(TextInput, { id: "with-keep", label: "Email", keepFooterSpace: true, size: "lg", error: hasError, errorMessage: hasError ? "Please enter a valid email address" : undefined })] }), _jsxs("div", { children: [_jsx("h4", { className: "text-sm font-medium mb-2 text-text-g-contrast-low", children: "Without keepFooterSpace (layout shifts when error appears)" }), _jsx(TextInput, { id: "no-keep", label: "Email", size: "lg", error: hasError, errorMessage: hasError ? "Please enter a valid email address" : undefined })] }), _jsx("div", {})] })] })] }));
82
82
  };
83
83
  export const KeepFooterSpace = {
84
84
  args: {
@@ -92,7 +92,7 @@ const FeedbackApiDemo = () => {
92
92
  const [legacyError, setLegacyError] = useState(false);
93
93
  const [legacyWarning, setLegacyWarning] = useState(false);
94
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
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-g-contrast-low", 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-g-contrast-low", 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-g-contrast-low", 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
96
  ? "Status explicitly sets warning."
97
97
  : legacyWarning
98
98
  ? "Please verify this email."