@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.
- package/dist/cjs/bundle.css +630 -467
- package/dist/cjs/bundle.js +1545 -1545
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
- package/dist/cjs/types/components/Dialog/Dialog.d.ts +7 -1
- package/dist/cjs/types/components/Dialog/Dialog.stories.d.ts +3 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +2 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
- package/dist/cjs/types/components/Form/Field.d.ts +26 -0
- package/dist/cjs/types/components/Form/FieldMessage.d.ts +7 -0
- package/dist/cjs/types/components/Form/Form.d.ts +49 -11
- package/dist/cjs/types/components/Form/Form.stories.d.ts +23 -0
- package/dist/cjs/types/components/Form/ValidationHintList.d.ts +17 -0
- package/dist/cjs/types/components/Form/ValidationHintList.stories.d.ts +9 -0
- package/dist/cjs/types/components/Form/index.d.ts +10 -0
- package/dist/cjs/types/components/Form/useOptionBridge.d.ts +17 -0
- package/dist/cjs/types/components/OtpInput/OtpInput.d.ts +17 -0
- package/dist/cjs/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
- package/dist/cjs/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
- package/dist/cjs/types/components/OtpInput/index.d.ts +5 -0
- package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +3 -0
- package/dist/cjs/types/index.d.ts +5 -0
- package/dist/cjs/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
- package/dist/cjs/types/utils/colors.d.ts +351 -267
- package/dist/components/ActionButton/ActionButton.stories.js +2 -2
- package/dist/components/ActionButton/ActionButton.styles.js +1 -1
- package/dist/components/AlertDialog/AlertDialog.js +6 -6
- package/dist/components/AlertDialog/AlertDialog.stories.js +3 -0
- package/dist/components/Avatar/Avatar.stories.js +1 -1
- package/dist/components/Avatar/Avatar.styles.js +1 -1
- package/dist/components/Avatar/AvatarBase.js +1 -1
- package/dist/components/Avatar/AvatarGroup.stories.js +1 -1
- package/dist/components/Button/Buttons.stories.js +2 -2
- package/dist/components/Calendar/Calendar.js +1 -1
- package/dist/components/Checkbox/Checkbox.js +1 -1
- package/dist/components/Checkbox/Checkbox.stories.js +17 -7
- package/dist/components/Collapsible/Collapsible.styles.js +1 -1
- package/dist/components/DataTable/DataTable.js +2 -2
- package/dist/components/Dialog/Dialog.js +12 -7
- package/dist/components/Dialog/Dialog.stories.js +90 -2
- package/dist/components/Dropdown/Dropdown.js +2 -2
- package/dist/components/DropdownMenu/DropdownMenu.js +3 -3
- package/dist/components/FocusedScrollView/FocusedScrollView.stories.js +6 -6
- package/dist/components/Form/Field.js +60 -0
- package/dist/components/Form/FieldMessage.js +24 -0
- package/dist/components/Form/Form.js +73 -41
- package/dist/components/Form/Form.stories.js +221 -0
- package/dist/components/Form/ValidationHintList.js +30 -0
- package/dist/components/Form/ValidationHintList.stories.js +50 -0
- package/dist/components/Form/index.js +5 -0
- package/dist/components/Form/useOptionBridge.js +27 -0
- package/dist/components/InputFilter/InputFilter.js +5 -4
- package/dist/components/InputFilter/InputFilter.stories.js +1 -1
- package/dist/components/InputFilter/InputFilter.styles.js +14 -1
- package/dist/components/Label/Label.styles.js +1 -1
- package/dist/components/Menu/Menu.js +2 -2
- package/dist/components/NumberInput/NumberInput.stories.js +1 -1
- package/dist/components/OtpInput/OtpInput.js +118 -0
- package/dist/components/OtpInput/OtpInput.stories.js +60 -0
- package/dist/components/OtpInput/OtpInputGroup.js +23 -0
- package/dist/components/OtpInput/index.js +3 -0
- package/dist/components/PasswordInput/PasswordInput.stories.js +1 -1
- package/dist/components/Popover/Popover.js +1 -1
- package/dist/components/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/RadioGroup/RadioGroup.stories.js +2 -2
- package/dist/components/Search/Search.js +13 -1
- package/dist/components/Search/Search.stories.js +1 -1
- package/dist/components/Slider/Slider.js +1 -1
- package/dist/components/Slider/Slider.stories.js +5 -5
- package/dist/components/Switch/Switch.stories.js +2 -2
- package/dist/components/Switch/Switch.styles.js +1 -1
- package/dist/components/Table/Table.js +5 -5
- package/dist/components/Tabs/Tabs.js +12 -9
- package/dist/components/Tabs/Tabs.stories.js +1 -1
- package/dist/components/Text/Text.js +1 -1
- package/dist/components/Text/Text.stories.js +1 -1
- package/dist/components/TextArea/TextArea.stories.js +1 -1
- package/dist/components/TextArea/TextArea.styles.js +3 -3
- package/dist/components/TextInput/TextInput.js +3 -2
- package/dist/components/TextInput/TextInput.stories.js +3 -3
- package/dist/components/TextInput/TextInput.styles.js +41 -19
- package/dist/components/Toast/Toast.js +4 -2
- package/dist/components/Toast/Toast.stories.js +1 -1
- package/dist/components/Toast/Toast.styles.js +4 -4
- package/dist/components/Toast/Toaster.js +2 -2
- package/dist/components/Tree/Tree.stories.js +1 -1
- package/dist/components/Tree/TreeItem.js +1 -1
- package/dist/esm/bundle.css +630 -467
- package/dist/esm/bundle.js +1545 -1545
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
- package/dist/esm/types/components/Dialog/Dialog.d.ts +7 -1
- package/dist/esm/types/components/Dialog/Dialog.stories.d.ts +3 -0
- package/dist/esm/types/components/Dropdown/Dropdown.d.ts +2 -0
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
- package/dist/esm/types/components/Form/Field.d.ts +26 -0
- package/dist/esm/types/components/Form/FieldMessage.d.ts +7 -0
- package/dist/esm/types/components/Form/Form.d.ts +49 -11
- package/dist/esm/types/components/Form/Form.stories.d.ts +23 -0
- package/dist/esm/types/components/Form/ValidationHintList.d.ts +17 -0
- package/dist/esm/types/components/Form/ValidationHintList.stories.d.ts +9 -0
- package/dist/esm/types/components/Form/index.d.ts +10 -0
- package/dist/esm/types/components/Form/useOptionBridge.d.ts +17 -0
- package/dist/esm/types/components/OtpInput/OtpInput.d.ts +17 -0
- package/dist/esm/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
- package/dist/esm/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
- package/dist/esm/types/components/OtpInput/index.d.ts +5 -0
- package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +3 -0
- package/dist/esm/types/index.d.ts +5 -0
- package/dist/esm/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
- package/dist/esm/types/utils/colors.d.ts +351 -267
- package/dist/index.d.ts +512 -269
- package/dist/index.js +3 -0
- package/dist/src/theme/global.css +2739 -2681
- package/dist/theme/ThemeColorCoverageRuntime.stories.js +91 -0
- package/dist/utils/colors.js +359 -267
- package/package.json +4 -2
- package/src/components/ActionButton/ActionButton.stories.tsx +6 -6
- package/src/components/ActionButton/ActionButton.styles.ts +1 -1
- package/src/components/AlertDialog/AlertDialog.stories.tsx +22 -0
- package/src/components/AlertDialog/AlertDialog.tsx +6 -6
- package/src/components/Avatar/Avatar.stories.tsx +1 -1
- package/src/components/Avatar/Avatar.styles.ts +1 -1
- package/src/components/Avatar/AvatarBase.tsx +1 -1
- package/src/components/Avatar/AvatarGroup.stories.tsx +1 -1
- package/src/components/Button/Buttons.stories.tsx +25 -17
- package/src/components/Calendar/Calendar.tsx +3 -3
- package/src/components/Checkbox/Checkbox.stories.tsx +35 -12
- package/src/components/Checkbox/Checkbox.tsx +7 -5
- package/src/components/Collapsible/Collapsible.styles.ts +1 -1
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/Dialog/Dialog.stories.tsx +173 -0
- package/src/components/Dialog/Dialog.tsx +32 -15
- package/src/components/Dropdown/Dropdown.styles.ts +1 -1
- package/src/components/Dropdown/Dropdown.tsx +16 -14
- package/src/components/DropdownMenu/DropdownMenu.tsx +3 -3
- package/src/components/FocusedScrollView/FocusedScrollView.stories.tsx +10 -10
- package/src/components/Form/Field.tsx +160 -0
- package/src/components/Form/FieldMessage.tsx +38 -0
- package/src/components/Form/Form.docs.mdx +67 -0
- package/src/components/Form/Form.stories.tsx +490 -0
- package/src/components/Form/Form.tsx +185 -87
- package/src/components/Form/README.md +284 -0
- package/src/components/Form/ValidationHintList.stories.tsx +118 -0
- package/src/components/Form/ValidationHintList.tsx +82 -0
- package/src/components/Form/index.ts +28 -0
- package/src/components/Form/useOptionBridge.ts +55 -0
- package/src/components/InputFilter/InputFilter.stories.tsx +1 -1
- package/src/components/InputFilter/InputFilter.styles.ts +14 -1
- package/src/components/InputFilter/InputFilter.tsx +33 -28
- package/src/components/Label/Label.styles.ts +2 -2
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/Menu/Menu.tsx +12 -12
- package/src/components/NumberInput/NumberInput.stories.tsx +1 -1
- package/src/components/OtpInput/OtpInput.stories.tsx +168 -0
- package/src/components/OtpInput/OtpInput.tsx +210 -0
- package/src/components/OtpInput/OtpInputGroup.tsx +74 -0
- package/src/components/OtpInput/index.ts +5 -0
- package/src/components/PasswordInput/PasswordInput.stories.tsx +1 -1
- package/src/components/Popover/Popover.tsx +1 -1
- package/src/components/RadioGroup/RadioGroup.stories.tsx +4 -4
- package/src/components/RadioGroup/RadioGroup.tsx +2 -1
- package/src/components/Search/Search.stories.tsx +1 -1
- package/src/components/Search/Search.tsx +6 -2
- package/src/components/Slider/Slider.stories.tsx +7 -7
- package/src/components/Slider/Slider.tsx +1 -1
- package/src/components/Switch/Switch.stories.tsx +4 -4
- package/src/components/Switch/Switch.styles.ts +1 -1
- package/src/components/Table/Table.tsx +5 -5
- package/src/components/Tabs/Tabs.stories.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +29 -18
- package/src/components/Text/Text.stories.tsx +1 -1
- package/src/components/Text/Text.tsx +1 -1
- package/src/components/TextArea/TextArea.stories.tsx +1 -1
- package/src/components/TextArea/TextArea.styles.ts +3 -3
- package/src/components/TextInput/TextInput.stories.tsx +7 -7
- package/src/components/TextInput/TextInput.styles.ts +42 -19
- package/src/components/TextInput/TextInput.tsx +3 -1
- package/src/components/Toast/Toast.stories.tsx +1 -1
- package/src/components/Toast/Toast.styles.tsx +7 -7
- package/src/components/Toast/Toast.tsx +5 -4
- package/src/components/Toast/Toaster.tsx +17 -20
- package/src/components/Tree/Tree.stories.tsx +1 -1
- package/src/components/Tree/TreeItem.tsx +1 -1
- package/src/index.ts +5 -0
- package/src/theme/THEME_MAPPING.md +36 -37
- package/src/theme/ThemeColorCoverageRuntime.stories.tsx +236 -0
- package/src/theme/direct-token-migration-plan.md +121 -0
- package/src/theme/figma-mcp-check-report.md +225 -0
- package/src/theme/figma-mcp-component-checklist.json +1250 -0
- package/src/theme/global.css +7 -3
- package/src/theme/presets/colors.js +173 -64
- package/src/theme/themes/skyller/baseline.css +0 -4
- package/src/theme/themes/variable-mapping.css +1064 -0
- package/src/theme/themes/variable.css +248 -230
- package/src/theme/themes/xspector/baseline.css +0 -4
- package/src/theme/themes/xspector/components/dropdown-menu.css +4 -4
- package/src/theme/themes/xspector/components/loading.css +2 -2
- package/src/theme/tokens/baseline.css +0 -3
- package/src/theme/tokens/color.css +36 -65
- package/src/theme/tokens/components/action-button.css +6 -6
- package/src/theme/tokens/components/button.css +189 -189
- package/src/theme/tokens/components/dropdown-menu.css +5 -5
- package/src/theme/tokens/components/footer.css +1 -1
- package/src/theme/tokens/components/loading.css +2 -2
- package/src/theme/tokens/components/switch.css +11 -11
- package/src/theme/tokens/typography.css +28 -28
- package/src/theme/tokens_old/baseline.css +13 -0
- package/src/theme/tokens_old/color.css +78 -0
- package/src/theme/tokens_old/components/action-button.css +127 -0
- package/src/theme/tokens_old/components/button.css +512 -0
- package/src/theme/tokens_old/components/dropdown-menu.css +27 -0
- package/src/theme/tokens_old/components/footer.css +9 -0
- package/src/theme/tokens_old/components/loading.css +11 -0
- package/src/theme/tokens_old/components/navbar.css +9 -0
- package/src/theme/tokens_old/components/progress-bar.css +8 -0
- package/src/theme/tokens_old/components/switch.css +29 -0
- package/src/theme/tokens_old/typography.css +199 -0
- package/src/theme/tokens_old/variables.css +28 -0
- package/src/theme/utils.js +172 -33
- package/src/utils/colors.ts +367 -278
- package/src/theme/themes/skyller/color.css +0 -79
- package/src/theme/themes/skyller/palette.css +0 -143
- package/src/theme/themes/skyller/state.css +0 -94
- package/src/theme/themes/skyller/transparent.css +0 -94
- package/src/theme/themes/xspector/color.css +0 -83
- package/src/theme/themes/xspector/palette.css +0 -142
- package/src/theme/themes/xspector/state.css +0 -94
- package/src/theme/themes/xspector/transparent.css +0 -93
- /package/src/theme/{tokens → tokens_old}/palette.css +0 -0
- /package/src/theme/{tokens → tokens_old}/state.css +0 -0
- /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;
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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 =
|
|
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
|
|
74
|
-
"text-
|
|
75
|
-
"text-text-
|
|
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-
|
|
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(
|
|
93
|
-
|
|
94
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
55
|
+
className: "focus:pe-6",
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
hasClearIcon: true,
|
|
59
59
|
size: "md",
|
|
60
|
-
|
|
60
|
+
className: "focus:pe-8",
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
hasClearIcon: true,
|
|
64
64
|
size: "lg",
|
|
65
|
-
|
|
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(
|
|
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-
|
|
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-
|
|
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-
|
|
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."
|