@k8o/arte-odyssey 8.0.3 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/buttons/button/button.d.mts +1 -1
- package/dist/components/buttons/button/button.mjs +1 -1
- package/dist/components/buttons/icon-button/icon-button.d.mts +1 -1
- package/dist/components/buttons/icon-button/icon-button.mjs +5 -16
- package/dist/components/data-display/accordion/accordion-button.mjs +2 -2
- package/dist/components/data-display/accordion/accordion-item.mjs +4 -1
- package/dist/components/data-display/accordion/accordion.mjs +1 -1
- package/dist/components/data-display/accordion/context.d.mts +1 -1
- package/dist/components/data-display/accordion/context.mjs +3 -12
- package/dist/components/data-display/avatar/avatar.d.mts +1 -1
- package/dist/components/data-display/avatar/avatar.mjs +2 -2
- package/dist/components/data-display/badge/badge.d.mts +1 -1
- package/dist/components/data-display/badge/badge.mjs +3 -3
- package/dist/components/data-display/card/card.mjs +2 -2
- package/dist/components/data-display/card/interactive-card.mjs +2 -2
- package/dist/components/data-display/card/type.d.mts +1 -1
- package/dist/components/data-display/code/code.d.mts +1 -1
- package/dist/components/data-display/code/code.mjs +4 -5
- package/dist/{helpers/color → components/data-display/code}/find-all-colors.d.mts +1 -1
- package/dist/{helpers/color → components/data-display/code}/find-all-colors.mjs +1 -1
- package/dist/components/data-display/heading/heading.d.mts +1 -1
- package/dist/components/data-display/heading/heading.mjs +7 -7
- package/dist/components/data-display/table/table.d.mts +12 -17
- package/dist/components/data-display/table/table.mjs +23 -21
- package/dist/components/feedback/alert/alert.d.mts +1 -1
- package/dist/components/feedback/alert/alert.mjs +2 -2
- package/dist/components/feedback/progress/progress.d.mts +1 -1
- package/dist/components/feedback/progress/progress.mjs +6 -7
- package/dist/components/feedback/skeleton/skeleton.d.mts +1 -1
- package/dist/components/feedback/skeleton/skeleton.mjs +2 -2
- package/dist/components/feedback/spinner/spinner.d.mts +1 -1
- package/dist/components/feedback/spinner/spinner.mjs +2 -2
- package/dist/components/feedback/toast/context.d.mts +2 -2
- package/dist/components/feedback/toast/context.mjs +6 -7
- package/dist/components/feedback/toast/provider.mjs +1 -1
- package/dist/components/form/autocomplete/autocomplete.d.mts +1 -1
- package/dist/components/form/autocomplete/autocomplete.mjs +75 -51
- package/dist/components/form/checkbox/checkbox.d.mts +1 -1
- package/dist/components/form/checkbox/checkbox.mjs +7 -4
- package/dist/components/form/checkbox-card/checkbox-card.d.mts +1 -1
- package/dist/components/form/checkbox-card/checkbox-card.mjs +10 -9
- package/dist/components/form/checkbox-group/checkbox-group.d.mts +1 -1
- package/dist/components/form/checkbox-group/index.d.mts +3 -3
- package/dist/components/form/file-field/file-field.d.mts +1 -1
- package/dist/components/form/file-field/file-field.mjs +4 -10
- package/dist/components/form/form/form.d.mts +1 -1
- package/dist/components/form/form/form.mjs +2 -3
- package/dist/{helpers/number → components/form/number-field}/cast.d.mts +1 -1
- package/dist/{helpers/number → components/form/number-field}/cast.mjs +2 -2
- package/dist/components/form/number-field/number-field.d.mts +1 -1
- package/dist/components/form/number-field/number-field.mjs +25 -24
- package/dist/components/form/password-input/password-input.d.mts +1 -1
- package/dist/components/form/password-input/password-input.mjs +3 -3
- package/dist/components/form/radio/radio.d.mts +1 -1
- package/dist/components/form/radio/radio.mjs +6 -4
- package/dist/components/form/radio-card/radio-card.d.mts +1 -1
- package/dist/components/form/radio-card/radio-card.mjs +11 -8
- package/dist/components/form/select/select.d.mts +1 -1
- package/dist/components/form/select/select.mjs +5 -4
- package/dist/components/form/slider/slider.d.mts +1 -1
- package/dist/components/form/slider/slider.mjs +15 -8
- package/dist/components/form/switch/switch.d.mts +1 -1
- package/dist/components/form/switch/switch.mjs +9 -6
- package/dist/components/form/text-field/text-field.d.mts +1 -1
- package/dist/components/form/text-field/text-field.mjs +1 -1
- package/dist/components/form/textarea/textarea.d.mts +1 -1
- package/dist/components/form/textarea/textarea.mjs +1 -1
- package/dist/components/icons/index.d.mts +3 -2
- package/dist/components/icons/index.mjs +3 -2
- package/dist/components/icons/logo.mjs +3 -3
- package/dist/components/icons/lucide.d.mts +2 -1
- package/dist/components/icons/lucide.mjs +6 -2
- package/dist/components/icons/qiita.mjs +4 -4
- package/dist/components/icons/twitter.mjs +1 -1
- package/dist/components/icons/vertical-writing.d.mts +7 -0
- package/dist/components/icons/vertical-writing.mjs +25 -0
- package/dist/components/index.d.mts +3 -2
- package/dist/components/index.mjs +3 -2
- package/dist/components/layout/separator/separator.d.mts +1 -1
- package/dist/components/layout/separator/separator.mjs +2 -5
- package/dist/components/navigation/anchor/anchor.d.mts +1 -1
- package/dist/components/navigation/anchor/anchor.mjs +1 -2
- package/dist/components/navigation/breadcrumb/breadcrumb.mjs +1 -1
- package/dist/components/navigation/pagination/pagination.mjs +12 -6
- package/dist/components/navigation/tabs/tabs.mjs +25 -25
- package/dist/components/overlays/dialog/dialog.mjs +3 -7
- package/dist/components/overlays/drawer/drawer.mjs +1 -1
- package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +1 -1
- package/dist/components/overlays/dropdown-menu/hooks.d.mts +2 -3
- package/dist/components/overlays/dropdown-menu/hooks.mjs +4 -9
- package/dist/components/overlays/list-box/hooks.d.mts +0 -1
- package/dist/components/overlays/list-box/hooks.mjs +3 -8
- package/dist/components/overlays/list-box/list-box.mjs +1 -1
- package/dist/components/overlays/modal/modal.mjs +9 -5
- package/dist/components/overlays/popover/hooks.d.mts +1 -3
- package/dist/components/overlays/popover/hooks.mjs +3 -8
- package/dist/components/overlays/popover/popover.mjs +8 -2
- package/dist/components/overlays/tooltip/tooltip.mjs +19 -6
- package/dist/helpers/chain.d.mts +5 -0
- package/dist/helpers/chain.mjs +29 -0
- package/dist/helpers/create-safe-context.d.mts +7 -0
- package/dist/helpers/create-safe-context.mjs +13 -0
- package/dist/helpers/index.d.mts +5 -8
- package/dist/helpers/index.mjs +5 -8
- package/dist/helpers/merge-props.d.mts +6 -0
- package/dist/helpers/merge-props.mjs +56 -0
- package/dist/hooks/click-away/index.mjs +1 -1
- package/dist/hooks/index.d.mts +2 -1
- package/dist/hooks/index.mjs +2 -1
- package/dist/hooks/writing-mode/index.d.mts +7 -0
- package/dist/hooks/writing-mode/index.mjs +22 -0
- package/dist/index.d.mts +8 -9
- package/dist/index.mjs +8 -9
- package/dist/internal/clamp.d.mts +4 -0
- package/dist/internal/clamp.mjs +15 -0
- package/dist/{helpers/number → internal}/to-precision.d.mts +1 -1
- package/dist/{helpers/number → internal}/to-precision.mjs +1 -1
- package/dist/styles/index.css +37 -0
- package/dist/styles/tokens.d.mts +12 -1
- package/dist/styles/tokens.mjs +25 -1
- package/docs/references/typography.md +29 -0
- package/package.json +2 -2
- package/dist/helpers/is-internal-route.d.mts +0 -4
- package/dist/helpers/is-internal-route.mjs +0 -12
- package/dist/helpers/number/between.d.mts +0 -4
- package/dist/helpers/number/between.mjs +0 -15
- package/dist/helpers/number/commalize.d.mts +0 -4
- package/dist/helpers/number/commalize.mjs +0 -20
- package/dist/helpers/number/index.d.mts +0 -5
- package/dist/helpers/number/index.mjs +0 -5
- package/dist/helpers/uuid-v4.d.mts +0 -4
- package/dist/helpers/uuid-v4.mjs +0 -28
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { createSafeContext } from "../../../helpers/create-safe-context.mjs";
|
|
3
|
+
import { useCallback } from "react";
|
|
4
4
|
//#region src/components/feedback/toast/context.ts
|
|
5
5
|
const MAX_TOAST_COUNT = 5;
|
|
6
|
-
const SetToastContext =
|
|
6
|
+
const [SetToastContext, useSetToast] = createSafeContext("useToast must be used within a ToastProvider");
|
|
7
7
|
const useToast = () => {
|
|
8
|
-
const setToasts =
|
|
9
|
-
if (!setToasts) throw new Error("useToast must be used within a ToastProvider");
|
|
8
|
+
const setToasts = useSetToast();
|
|
10
9
|
return {
|
|
11
10
|
onOpen: useCallback((status, message) => {
|
|
12
11
|
setToasts((prev) => {
|
|
13
12
|
return [...prev, {
|
|
14
|
-
id:
|
|
13
|
+
id: crypto.randomUUID(),
|
|
15
14
|
status,
|
|
16
15
|
message
|
|
17
16
|
}].slice(-MAX_TOAST_COUNT);
|
|
@@ -26,4 +25,4 @@ const useToast = () => {
|
|
|
26
25
|
};
|
|
27
26
|
};
|
|
28
27
|
//#endregion
|
|
29
|
-
export { SetToastContext, useToast };
|
|
28
|
+
export { SetToastContext, useSetToast, useToast };
|
|
@@ -54,7 +54,7 @@ const ToastProvider = ({ children, portalRef = null, position = "fixed" }) => {
|
|
|
54
54
|
children: [children, container ? createPortal(/* @__PURE__ */ jsx("section", {
|
|
55
55
|
"aria-label": "通知",
|
|
56
56
|
"aria-live": "polite",
|
|
57
|
-
className: cn("absolute bottom-3 z-
|
|
57
|
+
className: cn("absolute bottom-3 z-toast flex w-full flex-col items-center justify-center gap-4", position === "fixed" && "fixed", position === "absolute" && "absolute"),
|
|
58
58
|
children: /* @__PURE__ */ jsx(AnimatePresence, {
|
|
59
59
|
initial: false,
|
|
60
60
|
children: toasts.map((toast) => /* @__PURE__ */ jsx(motion$1.div, {
|
|
@@ -6,7 +6,7 @@ type BaseProps = {
|
|
|
6
6
|
id: string;
|
|
7
7
|
invalid?: boolean;
|
|
8
8
|
options: readonly Option[];
|
|
9
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'role' | 'className' | 'value' | 'onChange' | 'defaultValue' | 'children' | 'id' | 'autoComplete' | 'aria-autocomplete' | 'aria-controls' | 'aria-expanded'>;
|
|
9
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'role' | 'className' | 'style' | 'value' | 'onChange' | 'defaultValue' | 'children' | 'id' | 'autoComplete' | 'aria-autocomplete' | 'aria-controls' | 'aria-expanded'>;
|
|
10
10
|
type ControlledProps = {
|
|
11
11
|
value: string[];
|
|
12
12
|
onChange: (value: string[]) => void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../../helpers/cn.mjs";
|
|
3
|
+
import { useDisclosure } from "../../../hooks/disclosure/index.mjs";
|
|
3
4
|
import { CloseIcon } from "../../icons/lucide.mjs";
|
|
4
5
|
import { IconButton } from "../../buttons/icon-button/icon-button.mjs";
|
|
5
6
|
import { useControllableState } from "../../../hooks/controllable-state/index.mjs";
|
|
@@ -7,6 +8,7 @@ import { useDeferredDebounce } from "../../../hooks/deferred-debounce/index.mjs"
|
|
|
7
8
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
8
9
|
import { useFormStatus } from "react-dom";
|
|
9
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { autoUpdate, flip, offset, size, useFloating } from "@floating-ui/react";
|
|
10
12
|
//#region src/components/form/autocomplete/autocomplete.tsx
|
|
11
13
|
const Autocomplete = ({ id, name, invalid = false, disabled = false, required = false, options, value, defaultValue, onChange, ...rest }) => {
|
|
12
14
|
const [currentValue, handleChange] = useControllableState({
|
|
@@ -15,18 +17,37 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
15
17
|
onChange
|
|
16
18
|
});
|
|
17
19
|
const ref = useRef(null);
|
|
18
|
-
const
|
|
20
|
+
const { isOpen, open, close } = useDisclosure();
|
|
19
21
|
const [text, setText] = useState("");
|
|
20
22
|
const [selectIndex, setSelectIndex] = useState();
|
|
23
|
+
const { refs, floatingStyles } = useFloating({
|
|
24
|
+
strategy: "fixed",
|
|
25
|
+
placement: "bottom-start",
|
|
26
|
+
open: isOpen,
|
|
27
|
+
whileElementsMounted: autoUpdate,
|
|
28
|
+
middleware: [
|
|
29
|
+
offset(4),
|
|
30
|
+
flip({
|
|
31
|
+
fallbackAxisSideDirection: "end",
|
|
32
|
+
padding: 8
|
|
33
|
+
}),
|
|
34
|
+
size({ apply: ({ rects, elements }) => {
|
|
35
|
+
const referenceEl = elements.reference instanceof HTMLElement ? elements.reference : null;
|
|
36
|
+
const isVertical = referenceEl !== null && getComputedStyle(referenceEl).writingMode.startsWith("vertical");
|
|
37
|
+
Object.assign(elements.floating.style, { inlineSize: `${isVertical ? rects.reference.height : rects.reference.width}px` });
|
|
38
|
+
} })
|
|
39
|
+
],
|
|
40
|
+
transform: false
|
|
41
|
+
});
|
|
21
42
|
const [deferredText, isPending] = useDeferredDebounce(text);
|
|
22
43
|
const filteredOptions = options.filter((option) => option.label.includes(deferredText));
|
|
23
44
|
const { pending: formPending } = useFormStatus();
|
|
24
45
|
const disabledResolved = disabled || formPending;
|
|
25
46
|
const reset = useCallback(() => {
|
|
26
47
|
setText("");
|
|
27
|
-
|
|
48
|
+
close();
|
|
28
49
|
setSelectIndex(void 0);
|
|
29
|
-
}, []);
|
|
50
|
+
}, [close]);
|
|
30
51
|
useEffect(() => {
|
|
31
52
|
const handleClick = (e) => {
|
|
32
53
|
if (e.target instanceof Node && ref.current?.contains(e.target) === true) return;
|
|
@@ -37,9 +58,13 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
37
58
|
document.removeEventListener("click", handleClick);
|
|
38
59
|
};
|
|
39
60
|
}, [reset]);
|
|
61
|
+
const setReferenceRef = (node) => {
|
|
62
|
+
ref.current = node;
|
|
63
|
+
refs.setReference(node);
|
|
64
|
+
};
|
|
40
65
|
return /* @__PURE__ */ jsxs("div", {
|
|
41
|
-
className: cn("relative
|
|
42
|
-
ref,
|
|
66
|
+
className: cn("relative rounded-xl border border-border-base bg-bg-base inline-full", "focus-within:border-transparent focus-within:outline-hidden focus-within:ring-2 focus-within:ring-border-info", "has-aria-invalid:border-border-error", "has-disabled:cursor-not-allowed has-disabled:border-border-mute has-disabled:bg-bg-mute hover:has-disabled:has-hover:bg-bg-mute"),
|
|
67
|
+
ref: setReferenceRef,
|
|
43
68
|
children: [
|
|
44
69
|
name !== void 0 && name !== "" ? currentValue.map((selectedValue) => /* @__PURE__ */ jsx("input", {
|
|
45
70
|
name,
|
|
@@ -69,8 +94,8 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
69
94
|
}), /* @__PURE__ */ jsx("input", {
|
|
70
95
|
...rest,
|
|
71
96
|
"aria-autocomplete": "list",
|
|
72
|
-
"aria-controls":
|
|
73
|
-
"aria-expanded":
|
|
97
|
+
"aria-controls": isOpen ? `${id}_listbox` : void 0,
|
|
98
|
+
"aria-expanded": isOpen,
|
|
74
99
|
"aria-invalid": invalid,
|
|
75
100
|
"aria-required": required,
|
|
76
101
|
autoComplete: "off",
|
|
@@ -79,19 +104,19 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
79
104
|
id,
|
|
80
105
|
onBlur: (e) => {
|
|
81
106
|
if (e.relatedTarget?.id.startsWith(`${id}_option_`) === true) return;
|
|
82
|
-
|
|
107
|
+
close();
|
|
83
108
|
},
|
|
84
109
|
onChange: (e) => {
|
|
85
|
-
|
|
110
|
+
open();
|
|
86
111
|
setText(e.target.value);
|
|
87
112
|
setSelectIndex(void 0);
|
|
88
113
|
},
|
|
89
114
|
onClick: () => {
|
|
90
|
-
if (
|
|
91
|
-
|
|
115
|
+
if (isOpen && text.length === 0) {
|
|
116
|
+
close();
|
|
92
117
|
return;
|
|
93
118
|
}
|
|
94
|
-
|
|
119
|
+
open();
|
|
95
120
|
setSelectIndex(void 0);
|
|
96
121
|
},
|
|
97
122
|
onKeyDown: (e) => {
|
|
@@ -101,7 +126,7 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
101
126
|
return;
|
|
102
127
|
}
|
|
103
128
|
if (e.key === "ArrowDown") {
|
|
104
|
-
|
|
129
|
+
open();
|
|
105
130
|
setSelectIndex((prev) => {
|
|
106
131
|
if (prev === void 0) return 0;
|
|
107
132
|
return Math.min(prev + 1, options.length - 1);
|
|
@@ -109,7 +134,7 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
109
134
|
return;
|
|
110
135
|
}
|
|
111
136
|
if (e.key === "ArrowUp") {
|
|
112
|
-
|
|
137
|
+
open();
|
|
113
138
|
setSelectIndex((prev) => {
|
|
114
139
|
if (prev === void 0) return 0;
|
|
115
140
|
return Math.max(prev - 1, 0);
|
|
@@ -147,43 +172,42 @@ const Autocomplete = ({ id, name, invalid = false, disabled = false, required =
|
|
|
147
172
|
children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" })
|
|
148
173
|
})]
|
|
149
174
|
}),
|
|
150
|
-
/* @__PURE__ */ jsx("div", {
|
|
151
|
-
className: "
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
})
|
|
175
|
+
isOpen && /* @__PURE__ */ jsx("div", {
|
|
176
|
+
className: "bg-bg-raised z-10 rounded-xl shadow-md",
|
|
177
|
+
ref: refs.setFloating,
|
|
178
|
+
role: "presentation",
|
|
179
|
+
style: floatingStyles,
|
|
180
|
+
children: /* @__PURE__ */ jsxs("ul", {
|
|
181
|
+
"aria-busy": isPending || void 0,
|
|
182
|
+
className: cn("max-h-96 py-2 transition-opacity vertical:max-h-none vertical:max-w-96", isPending && "opacity-60"),
|
|
183
|
+
id: `${id}_listbox`,
|
|
184
|
+
children: [filteredOptions.length === 0 && /* @__PURE__ */ jsx("li", {
|
|
185
|
+
className: "text-fg-mute px-3 py-2",
|
|
186
|
+
children: "該当なし"
|
|
187
|
+
}), filteredOptions.map((option, idx) => {
|
|
188
|
+
const selected = currentValue.includes(option.value);
|
|
189
|
+
return /* @__PURE__ */ jsx("li", {
|
|
190
|
+
className: cn("cursor-pointer px-3 py-2 transition-colors", selected && "bg-primary-bg-subtle text-primary-fg", selectIndex === idx && !selected && "bg-bg-subtle", selectIndex === idx && selected && "bg-primary-bg-mute text-primary-fg"),
|
|
191
|
+
id: `${id}_option_${option.value}`,
|
|
192
|
+
onClick: (e) => {
|
|
193
|
+
e.stopPropagation();
|
|
194
|
+
reset();
|
|
195
|
+
if (selected) {
|
|
196
|
+
handleChange(currentValue.filter((v) => v !== option.value));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
handleChange([...currentValue, option.value]);
|
|
200
|
+
},
|
|
201
|
+
onKeyDown: (e) => {
|
|
202
|
+
e.preventDefault();
|
|
203
|
+
},
|
|
204
|
+
onMouseEnter: () => {
|
|
205
|
+
setSelectIndex(idx);
|
|
206
|
+
},
|
|
207
|
+
tabIndex: -1,
|
|
208
|
+
children: option.label
|
|
209
|
+
}, option.value);
|
|
210
|
+
})]
|
|
187
211
|
})
|
|
188
212
|
})
|
|
189
213
|
]
|
|
@@ -4,7 +4,7 @@ import { ChangeEventHandler, FC, InputHTMLAttributes } from "react";
|
|
|
4
4
|
type BaseProps = {
|
|
5
5
|
itemValue?: string;
|
|
6
6
|
label: string;
|
|
7
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'className' | 'value' | 'onChange' | 'defaultChecked' | 'checked' | 'children'>;
|
|
7
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'className' | 'style' | 'value' | 'onChange' | 'defaultChecked' | 'checked' | 'children'>;
|
|
8
8
|
type ControlledProps = {
|
|
9
9
|
value: boolean;
|
|
10
10
|
onChange: ChangeEventHandler<HTMLInputElement>;
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../../helpers/cn.mjs";
|
|
3
3
|
import { CheckIcon } from "../../icons/lucide.mjs";
|
|
4
|
+
import { useControllableState } from "../../../hooks/controllable-state/index.mjs";
|
|
4
5
|
import { useCheckboxGroupContext } from "../checkbox-group/checkbox-group.mjs";
|
|
5
|
-
import { useState } from "react";
|
|
6
6
|
import { useFormStatus } from "react-dom";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/form/checkbox/checkbox.tsx
|
|
9
9
|
const Checkbox = ({ name, itemValue, disabled = false, label, value, defaultChecked, onChange, ...rest }) => {
|
|
10
10
|
const groupContext = useCheckboxGroupContext();
|
|
11
11
|
const { pending } = useFormStatus();
|
|
12
|
-
const [internalChecked, setInternalChecked] =
|
|
12
|
+
const [internalChecked, setInternalChecked] = useControllableState({
|
|
13
|
+
value,
|
|
14
|
+
defaultValue: defaultChecked ?? false
|
|
15
|
+
});
|
|
13
16
|
const groupItemValue = itemValue ?? "";
|
|
14
17
|
if (groupContext && (itemValue === void 0 || itemValue === "")) throw new Error("Checkbox inside CheckboxGroup requires itemValue");
|
|
15
18
|
const isControlled = value !== void 0;
|
|
16
19
|
const disabledResolved = disabled || groupContext?.disabled === true || pending;
|
|
17
|
-
const checked = groupContext ? groupContext.currentValue.includes(groupItemValue) :
|
|
20
|
+
const checked = groupContext ? groupContext.currentValue.includes(groupItemValue) : internalChecked;
|
|
18
21
|
const setChecked = (nextChecked) => {
|
|
19
|
-
|
|
22
|
+
setInternalChecked(nextChecked);
|
|
20
23
|
onChange?.({ target: { checked: nextChecked } });
|
|
21
24
|
};
|
|
22
25
|
return /* @__PURE__ */ jsxs("label", {
|
|
@@ -11,7 +11,7 @@ type CheckboxCardOption = Readonly<{
|
|
|
11
11
|
type BaseProps = {
|
|
12
12
|
invalid?: boolean;
|
|
13
13
|
options: readonly CheckboxCardOption[];
|
|
14
|
-
} & Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'className' | 'children' | 'onChange' | 'defaultValue'>;
|
|
14
|
+
} & Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'className' | 'style' | 'children' | 'onChange' | 'defaultValue'>;
|
|
15
15
|
type ControlledProps = {
|
|
16
16
|
value: string[];
|
|
17
17
|
onChange: (value: string[]) => void;
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../../helpers/cn.mjs";
|
|
3
3
|
import { CheckIcon } from "../../icons/lucide.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { useControllableState } from "../../../hooks/controllable-state/index.mjs";
|
|
5
|
+
import { useId } from "react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
//#region src/components/form/checkbox-card/checkbox-card.tsx
|
|
7
8
|
const CheckboxCard = ({ name, disabled = false, invalid = false, options, value, defaultValue, onChange, ...rest }) => {
|
|
8
9
|
const groupId = useId();
|
|
9
|
-
const [
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const [selectedValues, setSelectedValues] = useControllableState({
|
|
11
|
+
value,
|
|
12
|
+
defaultValue: defaultValue ?? [],
|
|
13
|
+
onChange
|
|
14
|
+
});
|
|
12
15
|
const handleToggle = (nextValue, checked) => {
|
|
13
|
-
|
|
14
|
-
if (!isControlled) setInternalValue(nextValues);
|
|
15
|
-
onChange?.(nextValues);
|
|
16
|
+
setSelectedValues(checked ? [...selectedValues, nextValue] : selectedValues.filter((item) => item !== nextValue));
|
|
16
17
|
};
|
|
17
18
|
return /* @__PURE__ */ jsx("fieldset", {
|
|
18
19
|
...rest,
|
|
19
|
-
className: cn("m-0
|
|
20
|
+
className: cn("m-0 min-w-0 border-0 p-0 inline-full", "grid gap-3", disabled && "opacity-70"),
|
|
20
21
|
children: options.map((option) => {
|
|
21
22
|
const checked = selectedValues.includes(option.value);
|
|
22
23
|
const optionDisabled = disabled || option.disabled === true;
|
|
@@ -24,7 +25,7 @@ const CheckboxCard = ({ name, disabled = false, invalid = false, options, value,
|
|
|
24
25
|
const hasVisual = option.visual !== void 0 && option.visual !== null;
|
|
25
26
|
const optionId = `${groupId}-${option.value}`;
|
|
26
27
|
return /* @__PURE__ */ jsxs("label", {
|
|
27
|
-
className: cn("flex
|
|
28
|
+
className: cn("flex min-w-0 rounded-xl border bg-bg-base p-4 text-left transition-colors inline-full", "has-[input:focus-visible]:outline-hidden has-[input:focus-visible]:ring-2 has-[input:focus-visible]:ring-border-info", checked && "border-primary-border bg-primary-bg-subtle hover:bg-primary-bg-mute", invalid ? "border-border-error" : !checked && "border-border-mute hover:bg-bg-subtle", optionDisabled && "cursor-not-allowed border-border-mute bg-bg-subtle text-fg-mute"),
|
|
28
29
|
id: optionId,
|
|
29
30
|
children: [
|
|
30
31
|
/* @__PURE__ */ jsx("input", {
|
|
@@ -12,7 +12,7 @@ type RootBaseProps = PropsWithChildren<{
|
|
|
12
12
|
invalid?: boolean;
|
|
13
13
|
required?: boolean;
|
|
14
14
|
name: string;
|
|
15
|
-
} & Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'className' | 'onChange' | 'defaultValue' | 'name'>>;
|
|
15
|
+
} & Omit<FieldsetHTMLAttributes<HTMLFieldSetElement>, 'className' | 'style' | 'onChange' | 'defaultValue' | 'name'>>;
|
|
16
16
|
type RootControlledProps = {
|
|
17
17
|
value: string[];
|
|
18
18
|
onChange: (value: string[]) => void;
|
|
@@ -5,7 +5,7 @@ declare const CheckboxGroup: _$react.FC<{
|
|
|
5
5
|
invalid?: boolean;
|
|
6
6
|
required?: boolean;
|
|
7
7
|
name: string;
|
|
8
|
-
} & Omit<_$react.FieldsetHTMLAttributes<HTMLFieldSetElement>, "
|
|
8
|
+
} & Omit<_$react.FieldsetHTMLAttributes<HTMLFieldSetElement>, "defaultValue" | "onChange" | "className" | "style" | "name"> & {
|
|
9
9
|
children?: _$react.ReactNode | undefined;
|
|
10
10
|
} & ({
|
|
11
11
|
value: string[];
|
|
@@ -20,7 +20,7 @@ declare const CheckboxGroup: _$react.FC<{
|
|
|
20
20
|
invalid?: boolean;
|
|
21
21
|
required?: boolean;
|
|
22
22
|
name: string;
|
|
23
|
-
} & Omit<_$react.FieldsetHTMLAttributes<HTMLFieldSetElement>, "
|
|
23
|
+
} & Omit<_$react.FieldsetHTMLAttributes<HTMLFieldSetElement>, "defaultValue" | "onChange" | "className" | "style" | "name"> & {
|
|
24
24
|
children?: _$react.ReactNode | undefined;
|
|
25
25
|
} & ({
|
|
26
26
|
value: string[];
|
|
@@ -35,7 +35,7 @@ declare const CheckboxGroup: _$react.FC<{
|
|
|
35
35
|
Item: _$react.FC<{
|
|
36
36
|
itemValue?: string;
|
|
37
37
|
label: string;
|
|
38
|
-
} & Omit<_$react.InputHTMLAttributes<HTMLInputElement>, "
|
|
38
|
+
} & Omit<_$react.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "type" | "className" | "style" | "checked" | "defaultChecked" | "children"> & ({
|
|
39
39
|
value: boolean;
|
|
40
40
|
onChange: _$react.ChangeEventHandler<HTMLInputElement>;
|
|
41
41
|
defaultChecked?: never;
|
|
@@ -8,7 +8,7 @@ type RootProps = PropsWithChildren<{
|
|
|
8
8
|
defaultValue?: File[];
|
|
9
9
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
10
10
|
webkitDirectory?: boolean;
|
|
11
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'className' | 'onChange' | 'defaultValue' | 'value' | 'children'>>;
|
|
11
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'className' | 'style' | 'onChange' | 'defaultValue' | 'value' | 'children'>>;
|
|
12
12
|
declare const FileField: {
|
|
13
13
|
readonly Root: ({
|
|
14
14
|
children,
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { createSafeContext } from "../../../helpers/create-safe-context.mjs";
|
|
3
3
|
import { CloseIcon } from "../../icons/lucide.mjs";
|
|
4
4
|
import { IconButton } from "../../buttons/icon-button/icon-button.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { useCallback, useId, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { useFormStatus } from "react-dom";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/form/file-field/file-field.tsx
|
|
9
|
-
const
|
|
10
|
-
const FileFieldProvider = FileFieldContext;
|
|
11
|
-
const useFileFieldContext = () => {
|
|
12
|
-
const fileField = use(FileFieldContext);
|
|
13
|
-
if (!fileField) throw new Error("useFileFieldContext must be used within a FileField.Root");
|
|
14
|
-
return fileField;
|
|
15
|
-
};
|
|
9
|
+
const [FileFieldProvider, useFileFieldContext] = createSafeContext("useFileFieldContext must be used within a FileField.Root");
|
|
16
10
|
const Root = ({ children, disabled = false, invalid = false, required = false, multiple = false, maxFiles, onChange, webkitDirectory = false, ...rest }) => {
|
|
17
11
|
const generatedId = useId();
|
|
18
12
|
const inputRef = useRef(null);
|
|
@@ -23,7 +17,7 @@ const Root = ({ children, disabled = false, invalid = false, required = false, m
|
|
|
23
17
|
onChange?.(event);
|
|
24
18
|
const newFiles = Array.from(event.target.files ?? []).map((file) => ({
|
|
25
19
|
file,
|
|
26
|
-
id:
|
|
20
|
+
id: crypto.randomUUID()
|
|
27
21
|
}));
|
|
28
22
|
setAcceptedFiles(multiple || webkitDirectory ? [...acceptedFiles, ...newFiles].slice(0, maxFiles ?? Number.POSITIVE_INFINITY) : newFiles.slice(0, 1));
|
|
29
23
|
}, [
|
|
@@ -4,7 +4,7 @@ import { FC, FormHTMLAttributes, ReactNode } from "react";
|
|
|
4
4
|
type Props = {
|
|
5
5
|
action?: ((formData: FormData) => void | Promise<void>) | string;
|
|
6
6
|
children: ReactNode;
|
|
7
|
-
} & Omit<FormHTMLAttributes<HTMLFormElement>, 'action' | 'children'>;
|
|
7
|
+
} & Omit<FormHTMLAttributes<HTMLFormElement>, 'action' | 'children' | 'className' | 'style'>;
|
|
8
8
|
declare const Form: FC<Props>;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { Form };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../../../helpers/cn.mjs";
|
|
3
2
|
import { jsx } from "react/jsx-runtime";
|
|
4
3
|
//#region src/components/form/form/form.tsx
|
|
5
|
-
const Form = ({ action,
|
|
4
|
+
const Form = ({ action, children, ...rest }) => /* @__PURE__ */ jsx("form", {
|
|
6
5
|
action,
|
|
7
|
-
className:
|
|
6
|
+
className: "flex flex-col gap-6",
|
|
8
7
|
...rest,
|
|
9
8
|
children
|
|
10
9
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { toPrecision } from "
|
|
2
|
-
//#region src/
|
|
1
|
+
import { toPrecision } from "../../../internal/to-precision.mjs";
|
|
2
|
+
//#region src/components/form/number-field/cast.ts
|
|
3
3
|
const FLOATING_POINT_REGEX = /^[Ee0-9+\-.]$/;
|
|
4
4
|
const isInvalidCharacter = (value) => FLOATING_POINT_REGEX.test(value);
|
|
5
5
|
const sanitize = (value) => value.split("").filter((char) => isInvalidCharacter(char)).join("");
|
|
@@ -4,7 +4,7 @@ import { FC, InputHTMLAttributes } from "react";
|
|
|
4
4
|
type BaseProps = {
|
|
5
5
|
invalid?: boolean;
|
|
6
6
|
precision?: number;
|
|
7
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'role' | 'className' | 'value' | 'onChange' | 'defaultValue' | 'children' | 'step' | 'min' | 'max'> & {
|
|
7
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'role' | 'className' | 'style' | 'value' | 'onChange' | 'defaultValue' | 'children' | 'step' | 'min' | 'max'> & {
|
|
8
8
|
step?: number;
|
|
9
9
|
min?: number;
|
|
10
10
|
max?: number;
|
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../../helpers/cn.mjs";
|
|
3
3
|
import { ChevronIcon } from "../../icons/lucide.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { toPrecision } from "../../../internal/to-precision.mjs";
|
|
5
|
+
import { useControllableState } from "../../../hooks/controllable-state/index.mjs";
|
|
6
|
+
import { clamp } from "../../../internal/clamp.mjs";
|
|
7
|
+
import { cast } from "./cast.mjs";
|
|
7
8
|
import { useState } from "react";
|
|
8
9
|
import { useFormStatus } from "react-dom";
|
|
9
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
11
|
//#region src/components/form/number-field/number-field.tsx
|
|
11
12
|
const NumberField = ({ invalid = false, disabled = false, required = false, value, defaultValue, onChange, step = 1, precision = 0, max = 9007199254740991, min = -9007199254740991, ...rest }) => {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const [currentValue, setCurrentValue] = useControllableState({
|
|
14
|
+
value,
|
|
15
|
+
defaultValue: defaultValue ?? 0,
|
|
16
|
+
onChange
|
|
17
|
+
});
|
|
18
|
+
const [displayValue, setDisplayValue] = useState(() => currentValue.toFixed(precision));
|
|
19
|
+
const [prevValue, setPrevValue] = useState(currentValue);
|
|
17
20
|
const { pending } = useFormStatus();
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
setPrevValue(value);
|
|
21
|
+
if (currentValue !== prevValue) {
|
|
22
|
+
setDisplayValue(currentValue.toFixed(precision));
|
|
23
|
+
setPrevValue(currentValue);
|
|
22
24
|
}
|
|
23
25
|
const handleChange = (newValue) => {
|
|
24
|
-
|
|
25
|
-
onChange?.(newValue);
|
|
26
|
+
setCurrentValue(newValue);
|
|
26
27
|
};
|
|
27
28
|
return /* @__PURE__ */ jsxs("div", {
|
|
28
|
-
className: cn("relative flex h-12 w-full items-center justify-between gap-2 rounded-xl border border-border-base bg-bg-base", "focus-within:border-transparent focus-within:outline-hidden focus-within:ring-2 focus-within:ring-border-info", "has-aria-invalid:border-border-error", "has-disabled:cursor-not-allowed has-disabled:border-border-mute has-disabled:bg-bg-mute hover:has-disabled:has-hover:bg-bg-mute"),
|
|
29
|
+
className: cn("relative flex h-12 w-full items-center justify-between gap-2 rounded-xl border border-border-base bg-bg-base vertical:h-auto vertical:w-12", "focus-within:border-transparent focus-within:outline-hidden focus-within:ring-2 focus-within:ring-border-info", "has-aria-invalid:border-border-error", "has-disabled:cursor-not-allowed has-disabled:border-border-mute has-disabled:bg-bg-mute hover:has-disabled:has-hover:bg-bg-mute"),
|
|
29
30
|
children: [/* @__PURE__ */ jsx("input", {
|
|
30
31
|
autoComplete: "off",
|
|
31
32
|
autoCorrect: "off",
|
|
@@ -36,11 +37,11 @@ const NumberField = ({ invalid = false, disabled = false, required = false, valu
|
|
|
36
37
|
"aria-valuemax": max,
|
|
37
38
|
"aria-valuemin": min,
|
|
38
39
|
"aria-valuenow": currentValue,
|
|
39
|
-
className: cn("grow bg-transparent
|
|
40
|
+
className: cn("grow bg-transparent pe-8 ps-3 focus-visible:outline-hidden size-full", "disabled:cursor-not-allowed", "read-only:cursor-not-allowed"),
|
|
40
41
|
disabled,
|
|
41
42
|
readOnly: pending || void 0,
|
|
42
43
|
onBlur: () => {
|
|
43
|
-
const newValue =
|
|
44
|
+
const newValue = clamp(cast(displayValue, precision), min, max);
|
|
44
45
|
handleChange(newValue);
|
|
45
46
|
setDisplayValue(newValue.toFixed(precision));
|
|
46
47
|
},
|
|
@@ -50,12 +51,12 @@ const NumberField = ({ invalid = false, disabled = false, required = false, valu
|
|
|
50
51
|
},
|
|
51
52
|
onKeyDown: (e) => {
|
|
52
53
|
if (e.key === "ArrowUp") {
|
|
53
|
-
const newValue =
|
|
54
|
+
const newValue = clamp(toPrecision(cast(displayValue, precision) + step, precision), min, max);
|
|
54
55
|
handleChange(newValue);
|
|
55
56
|
setDisplayValue(newValue.toFixed(precision));
|
|
56
57
|
}
|
|
57
58
|
if (e.key === "ArrowDown") {
|
|
58
|
-
const newValue =
|
|
59
|
+
const newValue = clamp(toPrecision(cast(displayValue, precision) - step, precision), min, max);
|
|
59
60
|
handleChange(newValue);
|
|
60
61
|
setDisplayValue(newValue.toFixed(precision));
|
|
61
62
|
}
|
|
@@ -66,12 +67,12 @@ const NumberField = ({ invalid = false, disabled = false, required = false, valu
|
|
|
66
67
|
value: displayValue
|
|
67
68
|
}), /* @__PURE__ */ jsxs("div", {
|
|
68
69
|
"aria-hidden": "true",
|
|
69
|
-
className: "absolute
|
|
70
|
+
className: "vertical:inset-e-auto vertical:bottom-1 vertical:h-auto vertical:w-full vertical:flex-row vertical:px-1 vertical:py-0 absolute end-1 flex h-full flex-col py-1",
|
|
70
71
|
children: [/* @__PURE__ */ jsxs("button", {
|
|
71
|
-
className: cn("flex w-6 grow items-center justify-center rounded-md text-fg-mute transition-colors", "hover:bg-bg-mute hover:text-fg-base", "disabled:cursor-not-allowed disabled:text-fg-mute hover:disabled:bg-transparent"),
|
|
72
|
+
className: cn("flex w-6 grow items-center justify-center rounded-md text-fg-mute transition-colors vertical:h-6 vertical:w-auto", "hover:bg-bg-mute hover:text-fg-base", "disabled:cursor-not-allowed disabled:text-fg-mute hover:disabled:bg-transparent"),
|
|
72
73
|
disabled: disabled || pending,
|
|
73
74
|
onClick: () => {
|
|
74
|
-
const newValue =
|
|
75
|
+
const newValue = clamp(toPrecision(cast(displayValue, precision) + step, precision), min, max);
|
|
75
76
|
handleChange(newValue);
|
|
76
77
|
setDisplayValue(newValue.toFixed(precision));
|
|
77
78
|
},
|
|
@@ -85,10 +86,10 @@ const NumberField = ({ invalid = false, disabled = false, required = false, valu
|
|
|
85
86
|
size: "sm"
|
|
86
87
|
})]
|
|
87
88
|
}), /* @__PURE__ */ jsxs("button", {
|
|
88
|
-
className: cn("flex w-6 grow items-center justify-center rounded-md text-fg-mute transition-colors", "hover:bg-bg-mute hover:text-fg-base", "disabled:cursor-not-allowed disabled:text-fg-mute hover:disabled:bg-transparent"),
|
|
89
|
+
className: cn("flex w-6 grow items-center justify-center rounded-md text-fg-mute transition-colors vertical:h-6 vertical:w-auto", "hover:bg-bg-mute hover:text-fg-base", "disabled:cursor-not-allowed disabled:text-fg-mute hover:disabled:bg-transparent"),
|
|
89
90
|
disabled: disabled || pending,
|
|
90
91
|
onClick: () => {
|
|
91
|
-
const newValue =
|
|
92
|
+
const newValue = clamp(toPrecision(cast(displayValue, precision) - step, precision), min, max);
|
|
92
93
|
handleChange(newValue);
|
|
93
94
|
setDisplayValue(newValue.toFixed(precision));
|
|
94
95
|
},
|
|
@@ -5,7 +5,7 @@ type Props = {
|
|
|
5
5
|
invalid?: boolean;
|
|
6
6
|
showLabel?: string;
|
|
7
7
|
hideLabel?: string;
|
|
8
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'className'>;
|
|
8
|
+
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'className' | 'style'>;
|
|
9
9
|
declare const PasswordInput: FC<Props>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { PasswordInput };
|
|
@@ -9,18 +9,18 @@ const PasswordInput = ({ invalid = false, autoComplete = "current-password", sho
|
|
|
9
9
|
const { isOpen: isVisible, toggle: toggleVisible } = useDisclosure();
|
|
10
10
|
const { pending } = useFormStatus();
|
|
11
11
|
return /* @__PURE__ */ jsxs("div", {
|
|
12
|
-
className: "relative w-full",
|
|
12
|
+
className: cn("relative flex w-full items-center rounded-xl border border-border-base bg-bg-base vertical:h-full vertical:w-auto", invalid && "border-border-error", (disabled || pending) && "cursor-not-allowed border-border-mute bg-bg-mute", "focus-within:border-transparent focus-within:outline-hidden focus-within:ring-2 focus-within:ring-border-info"),
|
|
13
13
|
children: [/* @__PURE__ */ jsx("input", {
|
|
14
14
|
"aria-invalid": invalid,
|
|
15
15
|
autoComplete,
|
|
16
|
-
className: cn("w-full
|
|
16
|
+
className: cn("w-full grow bg-transparent px-3 py-2 focus-visible:outline-hidden vertical:h-full vertical:w-auto", "disabled:cursor-not-allowed", "read-only:cursor-not-allowed read-only:bg-bg-subtle"),
|
|
17
17
|
disabled,
|
|
18
18
|
readOnly: pending || readOnly,
|
|
19
19
|
type: isVisible ? "text" : "password",
|
|
20
20
|
...rest
|
|
21
21
|
}), /* @__PURE__ */ jsx("button", {
|
|
22
22
|
"aria-label": isVisible ? hideLabel : showLabel,
|
|
23
|
-
className: cn("
|
|
23
|
+
className: cn("me-2 inline-flex shrink-0 items-center justify-center rounded-md p-1 text-fg-mute transition-colors", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", !disabled && !pending && "hover:bg-bg-mute hover:text-fg-base", (disabled || pending) && "cursor-not-allowed text-fg-mute/70"),
|
|
24
24
|
disabled: disabled || pending,
|
|
25
25
|
onClick: toggleVisible,
|
|
26
26
|
type: "button",
|