@linyao.tw/ui 0.0.0-snapshot.07df57
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/LICENSE +201 -0
- package/README.md +85 -0
- package/dist/components/date-time/calendar.d.ts +20 -0
- package/dist/components/date-time/calendar.js +102 -0
- package/dist/components/date-time/calendar.js.map +1 -0
- package/dist/components/date-time/date-field.d.ts +11 -0
- package/dist/components/date-time/date-field.js +44 -0
- package/dist/components/date-time/date-field.js.map +1 -0
- package/dist/components/date-time/date-picker.d.ts +28 -0
- package/dist/components/date-time/date-picker.js +74 -0
- package/dist/components/date-time/date-picker.js.map +1 -0
- package/dist/components/date-time/date-range-picker.d.ts +11 -0
- package/dist/components/date-time/date-range-picker.js +79 -0
- package/dist/components/date-time/date-range-picker.js.map +1 -0
- package/dist/components/date-time/date-types.d.ts +110 -0
- package/dist/components/date-time/index.d.ts +8 -0
- package/dist/components/date-time/index.js +8 -0
- package/dist/components/date-time/shared.d.ts +25 -0
- package/dist/components/date-time/shared.js +53 -0
- package/dist/components/date-time/shared.js.map +1 -0
- package/dist/components/date-time/time-field.d.ts +13 -0
- package/dist/components/date-time/time-field.js +52 -0
- package/dist/components/date-time/time-field.js.map +1 -0
- package/dist/components/feedback/alert.d.ts +21 -0
- package/dist/components/feedback/alert.js +44 -0
- package/dist/components/feedback/alert.js.map +1 -0
- package/dist/components/feedback/banner.d.ts +8 -0
- package/dist/components/feedback/banner.js +20 -0
- package/dist/components/feedback/banner.js.map +1 -0
- package/dist/components/feedback/empty-state.d.ts +12 -0
- package/dist/components/feedback/empty-state.js +48 -0
- package/dist/components/feedback/empty-state.js.map +1 -0
- package/dist/components/feedback/feedback.module.js +42 -0
- package/dist/components/feedback/feedback.module.js.map +1 -0
- package/dist/components/feedback/feedback.types.d.ts +8 -0
- package/dist/components/feedback/feedback.types.js +24 -0
- package/dist/components/feedback/feedback.types.js.map +1 -0
- package/dist/components/feedback/index.d.ts +9 -0
- package/dist/components/feedback/meter.d.ts +12 -0
- package/dist/components/feedback/meter.js +28 -0
- package/dist/components/feedback/meter.js.map +1 -0
- package/dist/components/feedback/progress.d.ts +12 -0
- package/dist/components/feedback/progress.js +28 -0
- package/dist/components/feedback/progress.js.map +1 -0
- package/dist/components/feedback/skeleton.d.ts +5 -0
- package/dist/components/feedback/skeleton.js +18 -0
- package/dist/components/feedback/skeleton.js.map +1 -0
- package/dist/components/feedback/spinner.d.ts +23 -0
- package/dist/components/feedback/spinner.js +35 -0
- package/dist/components/feedback/spinner.js.map +1 -0
- package/dist/components/feedback/toast.d.ts +33 -0
- package/dist/components/feedback/toast.js +76 -0
- package/dist/components/feedback/toast.js.map +1 -0
- package/dist/components/forms/CodeField.d.ts +23 -0
- package/dist/components/forms/CodeField.js +63 -0
- package/dist/components/forms/CodeField.js.map +1 -0
- package/dist/components/forms/FileUpload.d.ts +34 -0
- package/dist/components/forms/FileUpload.js +319 -0
- package/dist/components/forms/FileUpload.js.map +1 -0
- package/dist/components/forms/Input.d.ts +14 -0
- package/dist/components/forms/Input.js +33 -0
- package/dist/components/forms/Input.js.map +1 -0
- package/dist/components/forms/NumberField.d.ts +15 -0
- package/dist/components/forms/NumberField.js +71 -0
- package/dist/components/forms/NumberField.js.map +1 -0
- package/dist/components/forms/OTPField.d.ts +15 -0
- package/dist/components/forms/OTPField.js +54 -0
- package/dist/components/forms/OTPField.js.map +1 -0
- package/dist/components/forms/TextField.d.ts +61 -0
- package/dist/components/forms/TextField.js +199 -0
- package/dist/components/forms/TextField.js.map +1 -0
- package/dist/components/forms/index.d.ts +7 -0
- package/dist/components/forms/internal.d.ts +33 -0
- package/dist/components/forms/internal.js +61 -0
- package/dist/components/forms/internal.js.map +1 -0
- package/dist/components/foundations/Avatar.d.ts +33 -0
- package/dist/components/foundations/Avatar.js +45 -0
- package/dist/components/foundations/Avatar.js.map +1 -0
- package/dist/components/foundations/Badge.d.ts +15 -0
- package/dist/components/foundations/Badge.js +32 -0
- package/dist/components/foundations/Badge.js.map +1 -0
- package/dist/components/foundations/Button.d.ts +18 -0
- package/dist/components/foundations/Button.js +47 -0
- package/dist/components/foundations/Button.js.map +1 -0
- package/dist/components/foundations/Card.d.ts +47 -0
- package/dist/components/foundations/Card.js +57 -0
- package/dist/components/foundations/Card.js.map +1 -0
- package/dist/components/foundations/IconButton.d.ts +25 -0
- package/dist/components/foundations/IconButton.js +19 -0
- package/dist/components/foundations/IconButton.js.map +1 -0
- package/dist/components/foundations/Link.d.ts +19 -0
- package/dist/components/foundations/Link.js +40 -0
- package/dist/components/foundations/Link.js.map +1 -0
- package/dist/components/foundations/ListCell.d.ts +68 -0
- package/dist/components/foundations/ListCell.js +105 -0
- package/dist/components/foundations/ListCell.js.map +1 -0
- package/dist/components/foundations/SectionHeading.d.ts +17 -0
- package/dist/components/foundations/SectionHeading.js +50 -0
- package/dist/components/foundations/SectionHeading.js.map +1 -0
- package/dist/components/foundations/Separator.d.ts +11 -0
- package/dist/components/foundations/Separator.js +21 -0
- package/dist/components/foundations/Separator.js.map +1 -0
- package/dist/components/foundations/index.d.ts +9 -0
- package/dist/components/foundations/shared.d.ts +5 -0
- package/dist/components/foundations/shared.js +8 -0
- package/dist/components/foundations/shared.js.map +1 -0
- package/dist/components/navigation-data/breadcrumb-pagination.d.ts +34 -0
- package/dist/components/navigation-data/breadcrumb-pagination.js +161 -0
- package/dist/components/navigation-data/breadcrumb-pagination.js.map +1 -0
- package/dist/components/navigation-data/command-palette.d.ts +35 -0
- package/dist/components/navigation-data/command-palette.js +151 -0
- package/dist/components/navigation-data/command-palette.js.map +1 -0
- package/dist/components/navigation-data/header-tab-bar.d.ts +23 -0
- package/dist/components/navigation-data/header-tab-bar.js +102 -0
- package/dist/components/navigation-data/header-tab-bar.js.map +1 -0
- package/dist/components/navigation-data/index.d.ts +7 -0
- package/dist/components/navigation-data/menubar-toolbar.d.ts +26 -0
- package/dist/components/navigation-data/menubar-toolbar.js +161 -0
- package/dist/components/navigation-data/menubar-toolbar.js.map +1 -0
- package/dist/components/navigation-data/navigation-menu.d.ts +14 -0
- package/dist/components/navigation-data/navigation-menu.js +87 -0
- package/dist/components/navigation-data/navigation-menu.js.map +1 -0
- package/dist/components/navigation-data/scroll-area.d.ts +6 -0
- package/dist/components/navigation-data/scroll-area.js +52 -0
- package/dist/components/navigation-data/scroll-area.js.map +1 -0
- package/dist/components/navigation-data/table-collection.d.ts +61 -0
- package/dist/components/navigation-data/table-collection.js +181 -0
- package/dist/components/navigation-data/table-collection.js.map +1 -0
- package/dist/components/navigation-data/utils.d.ts +2 -0
- package/dist/components/navigation-data/utils.js +11 -0
- package/dist/components/navigation-data/utils.js.map +1 -0
- package/dist/components/overlays/class-names.d.ts +6 -0
- package/dist/components/overlays/class-names.js +11 -0
- package/dist/components/overlays/class-names.js.map +1 -0
- package/dist/components/overlays/dialog.d.ts +98 -0
- package/dist/components/overlays/dialog.js +158 -0
- package/dist/components/overlays/dialog.js.map +1 -0
- package/dist/components/overlays/disclosure.d.ts +40 -0
- package/dist/components/overlays/disclosure.js +138 -0
- package/dist/components/overlays/disclosure.js.map +1 -0
- package/dist/components/overlays/drawer.d.ts +88 -0
- package/dist/components/overlays/drawer.js +192 -0
- package/dist/components/overlays/drawer.js.map +1 -0
- package/dist/components/overlays/floating.d.ts +83 -0
- package/dist/components/overlays/floating.js +220 -0
- package/dist/components/overlays/floating.js.map +1 -0
- package/dist/components/overlays/index.d.ts +4 -0
- package/dist/components/selection/classnames.d.ts +4 -0
- package/dist/components/selection/classnames.js +14 -0
- package/dist/components/selection/classnames.js.map +1 -0
- package/dist/components/selection/combobox.d.ts +118 -0
- package/dist/components/selection/combobox.js +284 -0
- package/dist/components/selection/combobox.js.map +1 -0
- package/dist/components/selection/controls.d.ts +65 -0
- package/dist/components/selection/controls.js +171 -0
- package/dist/components/selection/controls.js.map +1 -0
- package/dist/components/selection/index.d.ts +7 -0
- package/dist/components/selection/menu.d.ts +87 -0
- package/dist/components/selection/menu.js +157 -0
- package/dist/components/selection/menu.js.map +1 -0
- package/dist/components/selection/select.d.ts +55 -0
- package/dist/components/selection/select.js +138 -0
- package/dist/components/selection/select.js.map +1 -0
- package/dist/components/selection/selection.module.js +51 -0
- package/dist/components/selection/selection.module.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +52 -0
- package/dist/styles.css +2 -0
- package/package.json +74 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/* empty css */
|
|
2
|
+
import { FieldFrame as e, cx as t } from "./internal.js";
|
|
3
|
+
import { Button as n } from "../foundations/Button.js";
|
|
4
|
+
import * as r from "react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
import { Input as o } from "@base-ui/react/input";
|
|
7
|
+
import { FileIcon as s } from "@phosphor-icons/react/dist/csr/File";
|
|
8
|
+
import { PlusIcon as c } from "@phosphor-icons/react/dist/csr/Plus";
|
|
9
|
+
//#region src/components/forms/FileUpload.tsx
|
|
10
|
+
function l({ file: e }) {
|
|
11
|
+
let [t, n] = r.useState(null);
|
|
12
|
+
return r.useEffect(() => {
|
|
13
|
+
if (typeof URL.createObjectURL != "function" || typeof URL.revokeObjectURL != "function") return;
|
|
14
|
+
let t = URL.createObjectURL(e), r = !1;
|
|
15
|
+
return queueMicrotask(() => {
|
|
16
|
+
r || n({
|
|
17
|
+
file: e,
|
|
18
|
+
url: t
|
|
19
|
+
});
|
|
20
|
+
}), () => {
|
|
21
|
+
r = !0, URL.revokeObjectURL(t);
|
|
22
|
+
};
|
|
23
|
+
}, [e]), t?.file === e ? /* @__PURE__ */ i("img", {
|
|
24
|
+
className: "lyds-file-selection__thumbnail",
|
|
25
|
+
src: t.url,
|
|
26
|
+
alt: "",
|
|
27
|
+
width: 48,
|
|
28
|
+
height: 48,
|
|
29
|
+
loading: "lazy",
|
|
30
|
+
decoding: "async"
|
|
31
|
+
}) : /* @__PURE__ */ i(s, {
|
|
32
|
+
"aria-hidden": "true",
|
|
33
|
+
weight: "regular"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function u(e, t) {
|
|
37
|
+
if (!t?.trim()) return !0;
|
|
38
|
+
let n = e.name.toLocaleLowerCase(), r = e.type.toLocaleLowerCase();
|
|
39
|
+
return t.split(",").some((e) => {
|
|
40
|
+
let t = e.trim().toLocaleLowerCase();
|
|
41
|
+
return t ? t.startsWith(".") ? n.endsWith(t) : t.endsWith("/*") ? r.startsWith(t.slice(0, -1)) : r === t : !1;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function d({ accept: e, files: n, invalidFileLabel: r, summaryId: o }) {
|
|
45
|
+
return /* @__PURE__ */ a("div", {
|
|
46
|
+
className: t("lyds-file-selection", n.length === 0 && "lyds-sr-only"),
|
|
47
|
+
children: [/* @__PURE__ */ i("p", {
|
|
48
|
+
id: o,
|
|
49
|
+
className: "lyds-file-selection__summary",
|
|
50
|
+
role: "status",
|
|
51
|
+
"aria-live": "polite",
|
|
52
|
+
"aria-atomic": "true",
|
|
53
|
+
children: n.length > 0 ? `已選擇 ${n.length} 個檔案` : null
|
|
54
|
+
}), n.length > 0 ? /* @__PURE__ */ i("ul", {
|
|
55
|
+
className: "lyds-file-selection__list",
|
|
56
|
+
"aria-label": "已選擇的檔案",
|
|
57
|
+
children: n.map((t, n) => {
|
|
58
|
+
let o = u(t, e);
|
|
59
|
+
return /* @__PURE__ */ a("li", {
|
|
60
|
+
className: "lyds-file-selection__item",
|
|
61
|
+
"data-invalid": o ? void 0 : "",
|
|
62
|
+
children: [/* @__PURE__ */ i("span", {
|
|
63
|
+
className: "lyds-file-selection__visual",
|
|
64
|
+
children: t.type.startsWith("image/") ? /* @__PURE__ */ i(l, { file: t }) : /* @__PURE__ */ i(s, {
|
|
65
|
+
"aria-hidden": "true",
|
|
66
|
+
weight: "regular"
|
|
67
|
+
})
|
|
68
|
+
}), /* @__PURE__ */ a("span", {
|
|
69
|
+
className: "lyds-file-selection__details",
|
|
70
|
+
children: [/* @__PURE__ */ i("span", {
|
|
71
|
+
className: "lyds-file-selection__name",
|
|
72
|
+
title: t.name,
|
|
73
|
+
children: t.name
|
|
74
|
+
}), o ? null : /* @__PURE__ */ i("span", {
|
|
75
|
+
className: "lyds-file-selection__status",
|
|
76
|
+
children: r
|
|
77
|
+
})]
|
|
78
|
+
})]
|
|
79
|
+
}, `${t.name}-${t.size}-${t.lastModified}-${n}`);
|
|
80
|
+
})
|
|
81
|
+
}) : null]
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function ee(e, t, n) {
|
|
85
|
+
r.useEffect(() => {
|
|
86
|
+
let t = e.current?.form;
|
|
87
|
+
if (t == null) return;
|
|
88
|
+
let r = () => n([]);
|
|
89
|
+
return t.addEventListener("reset", r), () => t.removeEventListener("reset", r);
|
|
90
|
+
}, [
|
|
91
|
+
t,
|
|
92
|
+
e,
|
|
93
|
+
n
|
|
94
|
+
]);
|
|
95
|
+
}
|
|
96
|
+
var f = r.forwardRef(function({ label: s, description: c, error: l, invalid: u, disabled: f, readOnly: p, required: m, name: h, size: g = "md", className: _, style: v, requiredIndicator: y, validate: b, validationMode: x, validationDebounceTime: S, dirty: C, touched: w, actionsRef: T, inputClassName: E, inputStyle: D, triggerLabel: O = "選擇檔案", invalidFileLabel: k = "不支援的檔案類型", onChange: A, onFilesChange: j, id: M, ...N }, P) {
|
|
97
|
+
let F = r.useId(), I = M ?? F, L = `${I}-label`, R = `${I}-description`, z = `${I}-error`, B = `${I}-trigger-label`, V = `${I}-selection-summary`, H = r.useRef(null), [U, W] = r.useState([]);
|
|
98
|
+
ee(H, N.form, W), r.useImperativeHandle(P, () => H.current);
|
|
99
|
+
let G = (e) => {
|
|
100
|
+
if (!(f || p) && (A?.(e), !e.defaultPrevented)) {
|
|
101
|
+
let t = Array.from(e.currentTarget.files ?? []);
|
|
102
|
+
W(t), j?.(t, e);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
return /* @__PURE__ */ i(e, {
|
|
106
|
+
label: s,
|
|
107
|
+
description: c,
|
|
108
|
+
error: l,
|
|
109
|
+
invalid: u,
|
|
110
|
+
disabled: f,
|
|
111
|
+
readOnly: p,
|
|
112
|
+
required: m,
|
|
113
|
+
name: h,
|
|
114
|
+
size: g,
|
|
115
|
+
className: _,
|
|
116
|
+
style: v,
|
|
117
|
+
requiredIndicator: y,
|
|
118
|
+
labelId: L,
|
|
119
|
+
descriptionId: R,
|
|
120
|
+
errorId: z,
|
|
121
|
+
validate: b,
|
|
122
|
+
validationMode: x,
|
|
123
|
+
validationDebounceTime: S,
|
|
124
|
+
dirty: C,
|
|
125
|
+
touched: w,
|
|
126
|
+
actionsRef: T,
|
|
127
|
+
children: /* @__PURE__ */ a("div", {
|
|
128
|
+
className: "lyds-file-upload",
|
|
129
|
+
"data-size": g,
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ i(o, {
|
|
132
|
+
...N,
|
|
133
|
+
ref: H,
|
|
134
|
+
id: I,
|
|
135
|
+
type: "file",
|
|
136
|
+
className: t("lyds-file-upload__input", E),
|
|
137
|
+
style: D,
|
|
138
|
+
disabled: f || p,
|
|
139
|
+
readOnly: p,
|
|
140
|
+
required: m,
|
|
141
|
+
"aria-invalid": u || void 0,
|
|
142
|
+
"aria-labelledby": s == null ? B : `${L} ${B}`,
|
|
143
|
+
"aria-describedby": [
|
|
144
|
+
c == null ? null : R,
|
|
145
|
+
U.length > 0 ? V : null,
|
|
146
|
+
z
|
|
147
|
+
].filter(Boolean).join(" "),
|
|
148
|
+
tabIndex: -1,
|
|
149
|
+
onChange: G
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ i(n, {
|
|
152
|
+
className: "lyds-file-upload__trigger",
|
|
153
|
+
disabled: f || p,
|
|
154
|
+
size: g,
|
|
155
|
+
variant: "secondary",
|
|
156
|
+
onClick: () => H.current?.click(),
|
|
157
|
+
children: /* @__PURE__ */ i("span", {
|
|
158
|
+
id: B,
|
|
159
|
+
children: O
|
|
160
|
+
})
|
|
161
|
+
}),
|
|
162
|
+
/* @__PURE__ */ i(d, {
|
|
163
|
+
accept: N.accept,
|
|
164
|
+
files: U,
|
|
165
|
+
invalidFileLabel: k,
|
|
166
|
+
summaryId: V
|
|
167
|
+
})
|
|
168
|
+
]
|
|
169
|
+
})
|
|
170
|
+
});
|
|
171
|
+
}), p = r.forwardRef(function({ label: s, description: l, error: u, invalid: f, disabled: p, readOnly: m, required: h, name: g, size: _ = "md", className: v, style: y, requiredIndicator: b, validate: x, validationMode: S, validationDebounceTime: C, dirty: w, touched: T, actionsRef: E, inputClassName: D, primaryLabel: O = "將檔案拖曳至此", secondaryLabel: k = "或從裝置選擇檔案", browseLabel: A = "選擇檔案", invalidFileLabel: j = "不支援的檔案類型", onChange: M, onFilesChange: N, onDragEnter: P, onDragOver: F, onDragLeave: I, onDrop: L, id: R, ...z }, B) {
|
|
172
|
+
let V = r.useId(), H = R ?? V, U = `${H}-label`, W = `${H}-description`, G = `${H}-error`, K = `${H}-trigger-label`, q = `${H}-selection-summary`, J = r.useRef(null), [te, Y] = r.useState(!1), [X, Z] = r.useState([]), Q = r.useRef(0), $ = r.useRef(null);
|
|
173
|
+
ee(J, z.form, Z), r.useImperativeHandle(B, () => J.current);
|
|
174
|
+
let ne = (e) => {
|
|
175
|
+
if (p || m || (M?.(e), e.defaultPrevented)) return;
|
|
176
|
+
let t = $.current;
|
|
177
|
+
if (t != null) {
|
|
178
|
+
t.handled = !0, Z(t.files), N?.(t.files, {
|
|
179
|
+
source: "drop",
|
|
180
|
+
event: t.event
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
let n = Array.from(e.currentTarget.files ?? []);
|
|
185
|
+
Z(n), N?.(n, {
|
|
186
|
+
source: "input",
|
|
187
|
+
event: e
|
|
188
|
+
});
|
|
189
|
+
}, re = (e) => {
|
|
190
|
+
if (p || m) {
|
|
191
|
+
P?.(e);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
e.preventDefault(), P?.(e), Q.current += 1, Y(!0);
|
|
195
|
+
}, ie = (e) => {
|
|
196
|
+
if (p || m) {
|
|
197
|
+
F?.(e);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
e.preventDefault(), e.dataTransfer.dropEffect = "copy", F?.(e);
|
|
201
|
+
}, ae = (e) => {
|
|
202
|
+
I?.(e), !(p || m) && (Q.current = Math.max(0, Q.current - 1), Q.current === 0 && Y(!1));
|
|
203
|
+
}, oe = (e) => {
|
|
204
|
+
if (p || m) {
|
|
205
|
+
L?.(e);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
e.preventDefault(), L?.(e), Q.current = 0, Y(!1);
|
|
209
|
+
let t = Array.from(e.dataTransfer.files ?? []);
|
|
210
|
+
if (J.current != null) {
|
|
211
|
+
try {
|
|
212
|
+
J.current.files = e.dataTransfer.files;
|
|
213
|
+
} catch {}
|
|
214
|
+
let n = {
|
|
215
|
+
event: e,
|
|
216
|
+
files: t,
|
|
217
|
+
handled: !1
|
|
218
|
+
};
|
|
219
|
+
$.current = n, J.current.dispatchEvent(new Event("change", { bubbles: !0 })), $.current = null, n.handled || (Z(t), N?.(t, {
|
|
220
|
+
source: "drop",
|
|
221
|
+
event: e
|
|
222
|
+
}));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
Z(t), N?.(t, {
|
|
226
|
+
source: "drop",
|
|
227
|
+
event: e
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
return /* @__PURE__ */ a(e, {
|
|
231
|
+
label: s,
|
|
232
|
+
description: l,
|
|
233
|
+
error: u,
|
|
234
|
+
invalid: f,
|
|
235
|
+
disabled: p,
|
|
236
|
+
readOnly: m,
|
|
237
|
+
required: h,
|
|
238
|
+
name: g,
|
|
239
|
+
size: _,
|
|
240
|
+
className: v,
|
|
241
|
+
style: y,
|
|
242
|
+
requiredIndicator: b,
|
|
243
|
+
labelId: U,
|
|
244
|
+
descriptionId: W,
|
|
245
|
+
errorId: G,
|
|
246
|
+
validate: x,
|
|
247
|
+
validationMode: S,
|
|
248
|
+
validationDebounceTime: C,
|
|
249
|
+
dirty: w,
|
|
250
|
+
touched: T,
|
|
251
|
+
actionsRef: E,
|
|
252
|
+
children: [/* @__PURE__ */ i(o, {
|
|
253
|
+
...z,
|
|
254
|
+
ref: J,
|
|
255
|
+
id: H,
|
|
256
|
+
type: "file",
|
|
257
|
+
className: t("lyds-drop-zone__input", D),
|
|
258
|
+
disabled: p || m,
|
|
259
|
+
readOnly: m,
|
|
260
|
+
required: h,
|
|
261
|
+
"aria-invalid": f || void 0,
|
|
262
|
+
"aria-labelledby": s == null ? K : `${U} ${K}`,
|
|
263
|
+
"aria-describedby": [
|
|
264
|
+
l == null ? null : W,
|
|
265
|
+
X.length > 0 ? q : null,
|
|
266
|
+
G
|
|
267
|
+
].filter(Boolean).join(" "),
|
|
268
|
+
tabIndex: -1,
|
|
269
|
+
onChange: ne
|
|
270
|
+
}), /* @__PURE__ */ a("div", {
|
|
271
|
+
className: "lyds-drop-zone",
|
|
272
|
+
"data-size": _,
|
|
273
|
+
"data-dragging": te || void 0,
|
|
274
|
+
"data-disabled": p || void 0,
|
|
275
|
+
"data-readonly": m || void 0,
|
|
276
|
+
onDragEnter: re,
|
|
277
|
+
onDragOver: ie,
|
|
278
|
+
onDragLeave: ae,
|
|
279
|
+
onDrop: oe,
|
|
280
|
+
children: [
|
|
281
|
+
/* @__PURE__ */ a("span", {
|
|
282
|
+
className: "lyds-drop-zone__copy",
|
|
283
|
+
children: [/* @__PURE__ */ i("span", {
|
|
284
|
+
className: "lyds-drop-zone__primary",
|
|
285
|
+
children: O
|
|
286
|
+
}), /* @__PURE__ */ i("span", {
|
|
287
|
+
className: "lyds-drop-zone__secondary",
|
|
288
|
+
children: k
|
|
289
|
+
})]
|
|
290
|
+
}),
|
|
291
|
+
/* @__PURE__ */ i(n, {
|
|
292
|
+
className: "lyds-drop-zone__button",
|
|
293
|
+
disabled: p || m,
|
|
294
|
+
size: _,
|
|
295
|
+
startIcon: /* @__PURE__ */ i(c, {
|
|
296
|
+
"aria-hidden": "true",
|
|
297
|
+
weight: "bold"
|
|
298
|
+
}),
|
|
299
|
+
variant: "secondary",
|
|
300
|
+
onClick: () => J.current?.click(),
|
|
301
|
+
children: /* @__PURE__ */ i("span", {
|
|
302
|
+
id: K,
|
|
303
|
+
children: A
|
|
304
|
+
})
|
|
305
|
+
}),
|
|
306
|
+
/* @__PURE__ */ i(d, {
|
|
307
|
+
accept: z.accept,
|
|
308
|
+
files: X,
|
|
309
|
+
invalidFileLabel: j,
|
|
310
|
+
summaryId: q
|
|
311
|
+
})
|
|
312
|
+
]
|
|
313
|
+
})]
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
//#endregion
|
|
317
|
+
export { p as DropZone, f as FileUpload };
|
|
318
|
+
|
|
319
|
+
//# sourceMappingURL=FileUpload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileUpload.js","names":[],"sources":["../../../src/components/forms/FileUpload.tsx"],"sourcesContent":["import { Input as BaseInput } from \"@base-ui/react/input\";\nimport { FileIcon } from \"@phosphor-icons/react/dist/csr/File\";\nimport { PlusIcon } from \"@phosphor-icons/react/dist/csr/Plus\";\nimport * as React from \"react\";\nimport { Button } from \"../foundations/Button\";\nimport \"./forms.css\";\nimport { cx, FieldFrame, type FieldAnatomyProps } from \"./internal\";\n\ntype NativeFileInputProps = Omit<\n\tReact.InputHTMLAttributes<HTMLInputElement>,\n\t\"children\" | \"className\" | \"defaultValue\" | \"disabled\" | \"name\" | \"onChange\" | \"readOnly\" | \"required\" | \"size\" | \"style\" | \"type\" | \"value\"\n>;\n\nfunction FileImagePreview({ file }: { file: File }) {\n\tconst [preview, setPreview] = React.useState<{ file: File; url: string } | null>(null);\n\n\tReact.useEffect(() => {\n\t\tif (typeof URL.createObjectURL !== \"function\" || typeof URL.revokeObjectURL !== \"function\") return;\n\n\t\tconst previewUrl = URL.createObjectURL(file);\n\t\tlet disposed = false;\n\t\tqueueMicrotask(() => {\n\t\t\tif (!disposed) {\n\t\t\t\tsetPreview({ file, url: previewUrl });\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tdisposed = true;\n\t\t\tURL.revokeObjectURL(previewUrl);\n\t\t};\n\t}, [file]);\n\n\tif (preview?.file !== file) return <FileIcon aria-hidden=\"true\" weight=\"regular\" />;\n\treturn <img className=\"lyds-file-selection__thumbnail\" src={preview.url} alt=\"\" width={48} height={48} loading=\"lazy\" decoding=\"async\" />;\n}\n\nfunction isFileAccepted(file: File, accept: string | undefined): boolean {\n\tif (!accept?.trim()) return true;\n\n\tconst fileName = file.name.toLocaleLowerCase();\n\tconst mimeType = file.type.toLocaleLowerCase();\n\treturn accept.split(\",\").some(rawRule => {\n\t\tconst rule = rawRule.trim().toLocaleLowerCase();\n\t\tif (!rule) return false;\n\t\tif (rule.startsWith(\".\")) return fileName.endsWith(rule);\n\t\tif (rule.endsWith(\"/*\")) return mimeType.startsWith(rule.slice(0, -1));\n\t\treturn mimeType === rule;\n\t});\n}\n\ninterface FileSelectionPreviewProps {\n\taccept: string | undefined;\n\tfiles: readonly File[];\n\tinvalidFileLabel: React.ReactNode;\n\tsummaryId: string;\n}\n\nfunction FileSelectionPreview({ accept, files, invalidFileLabel, summaryId }: FileSelectionPreviewProps) {\n\treturn (\n\t\t<div className={cx(\"lyds-file-selection\", files.length === 0 && \"lyds-sr-only\")}>\n\t\t\t<p id={summaryId} className=\"lyds-file-selection__summary\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n\t\t\t\t{files.length > 0 ? `已選擇 ${files.length} 個檔案` : null}\n\t\t\t</p>\n\t\t\t{files.length > 0 ? (\n\t\t\t\t<ul className=\"lyds-file-selection__list\" aria-label=\"已選擇的檔案\">\n\t\t\t\t\t{files.map((file, index) => {\n\t\t\t\t\t\tconst accepted = isFileAccepted(file, accept);\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<li className=\"lyds-file-selection__item\" data-invalid={accepted ? undefined : \"\"} key={`${file.name}-${file.size}-${file.lastModified}-${index}`}>\n\t\t\t\t\t\t\t\t<span className=\"lyds-file-selection__visual\">{file.type.startsWith(\"image/\") ? <FileImagePreview file={file} /> : <FileIcon aria-hidden=\"true\" weight=\"regular\" />}</span>\n\t\t\t\t\t\t\t\t<span className=\"lyds-file-selection__details\">\n\t\t\t\t\t\t\t\t\t<span className=\"lyds-file-selection__name\" title={file.name}>\n\t\t\t\t\t\t\t\t\t\t{file.name}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{accepted ? null : <span className=\"lyds-file-selection__status\">{invalidFileLabel}</span>}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</ul>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\nfunction useClearFileSelectionOnFormReset(inputRef: React.RefObject<HTMLInputElement | null>, formId: string | undefined, setSelectedFiles: React.Dispatch<React.SetStateAction<readonly File[]>>) {\n\tReact.useEffect(() => {\n\t\tconst form = inputRef.current?.form;\n\t\tif (form == null) return;\n\n\t\tconst handleReset = () => setSelectedFiles([]);\n\t\tform.addEventListener(\"reset\", handleReset);\n\t\treturn () => form.removeEventListener(\"reset\", handleReset);\n\t}, [formId, inputRef, setSelectedFiles]);\n}\n\nexport interface FileUploadProps extends NativeFileInputProps, FieldAnatomyProps {\n\tinputClassName?: string;\n\tinputStyle?: React.CSSProperties;\n\ttriggerLabel?: React.ReactNode;\n\tinvalidFileLabel?: React.ReactNode;\n\tonChange?: React.ChangeEventHandler<HTMLInputElement>;\n\tonFilesChange?: (files: readonly File[], event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\nexport const FileUpload = React.forwardRef<HTMLInputElement, FileUploadProps>(function FileUpload(\n\t{\n\t\tlabel,\n\t\tdescription,\n\t\terror,\n\t\tinvalid,\n\t\tdisabled,\n\t\treadOnly,\n\t\trequired,\n\t\tname,\n\t\tsize = \"md\",\n\t\tclassName,\n\t\tstyle,\n\t\trequiredIndicator,\n\t\tvalidate,\n\t\tvalidationMode,\n\t\tvalidationDebounceTime,\n\t\tdirty,\n\t\ttouched,\n\t\tactionsRef,\n\t\tinputClassName,\n\t\tinputStyle,\n\t\ttriggerLabel = \"選擇檔案\",\n\t\tinvalidFileLabel = \"不支援的檔案類型\",\n\t\tonChange,\n\t\tonFilesChange,\n\t\tid: idProp,\n\t\t...inputProps\n\t},\n\tforwardedRef\n) {\n\tconst generatedId = React.useId();\n\tconst id = idProp ?? generatedId;\n\tconst labelId = `${id}-label`;\n\tconst descriptionId = `${id}-description`;\n\tconst errorId = `${id}-error`;\n\tconst triggerId = `${id}-trigger-label`;\n\tconst selectionSummaryId = `${id}-selection-summary`;\n\tconst inputRef = React.useRef<HTMLInputElement>(null);\n\tconst [selectedFiles, setSelectedFiles] = React.useState<readonly File[]>([]);\n\tuseClearFileSelectionOnFormReset(inputRef, inputProps.form, setSelectedFiles);\n\tReact.useImperativeHandle(forwardedRef, () => inputRef.current as HTMLInputElement);\n\n\tconst handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n\t\tif (disabled || readOnly) return;\n\t\tonChange?.(event);\n\t\tif (!event.defaultPrevented) {\n\t\t\tconst files = Array.from(event.currentTarget.files ?? []);\n\t\t\tsetSelectedFiles(files);\n\t\t\tonFilesChange?.(files, event);\n\t\t}\n\t};\n\n\treturn (\n\t\t<FieldFrame\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\terror={error}\n\t\t\tinvalid={invalid}\n\t\t\tdisabled={disabled}\n\t\t\treadOnly={readOnly}\n\t\t\trequired={required}\n\t\t\tname={name}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\tstyle={style}\n\t\t\trequiredIndicator={requiredIndicator}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}\n\t\t\tvalidate={validate}\n\t\t\tvalidationMode={validationMode}\n\t\t\tvalidationDebounceTime={validationDebounceTime}\n\t\t\tdirty={dirty}\n\t\t\ttouched={touched}\n\t\t\tactionsRef={actionsRef}\n\t\t>\n\t\t\t<div className=\"lyds-file-upload\" data-size={size}>\n\t\t\t\t<BaseInput\n\t\t\t\t\t{...inputProps}\n\t\t\t\t\tref={inputRef}\n\t\t\t\t\tid={id}\n\t\t\t\t\ttype=\"file\"\n\t\t\t\t\tclassName={cx(\"lyds-file-upload__input\", inputClassName)}\n\t\t\t\t\tstyle={inputStyle}\n\t\t\t\t\tdisabled={disabled || readOnly}\n\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\trequired={required}\n\t\t\t\t\taria-invalid={invalid || undefined}\n\t\t\t\t\taria-labelledby={label != null ? `${labelId} ${triggerId}` : triggerId}\n\t\t\t\t\taria-describedby={[description != null ? descriptionId : null, selectedFiles.length > 0 ? selectionSummaryId : null, errorId].filter(Boolean).join(\" \")}\n\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t/>\n\t\t\t\t<Button className=\"lyds-file-upload__trigger\" disabled={disabled || readOnly} size={size} variant=\"secondary\" onClick={() => inputRef.current?.click()}>\n\t\t\t\t\t<span id={triggerId}>{triggerLabel}</span>\n\t\t\t\t</Button>\n\t\t\t\t<FileSelectionPreview accept={inputProps.accept} files={selectedFiles} invalidFileLabel={invalidFileLabel} summaryId={selectionSummaryId} />\n\t\t\t</div>\n\t\t</FieldFrame>\n\t);\n});\n\nexport type DropZoneChangeDetails = { source: \"input\"; event: React.ChangeEvent<HTMLInputElement> } | { source: \"drop\"; event: React.DragEvent<HTMLDivElement> };\n\nexport interface DropZoneProps extends NativeFileInputProps, FieldAnatomyProps {\n\tinputClassName?: string;\n\tprimaryLabel?: React.ReactNode;\n\tsecondaryLabel?: React.ReactNode;\n\tbrowseLabel?: string;\n\tinvalidFileLabel?: React.ReactNode;\n\tonChange?: React.ChangeEventHandler<HTMLInputElement>;\n\tonFilesChange?: (files: readonly File[], details: DropZoneChangeDetails) => void;\n\tonDragEnter?: React.DragEventHandler<HTMLDivElement>;\n\tonDragOver?: React.DragEventHandler<HTMLDivElement>;\n\tonDragLeave?: React.DragEventHandler<HTMLDivElement>;\n\tonDrop?: React.DragEventHandler<HTMLDivElement>;\n}\n\nexport const DropZone = React.forwardRef<HTMLInputElement, DropZoneProps>(function DropZone(\n\t{\n\t\tlabel,\n\t\tdescription,\n\t\terror,\n\t\tinvalid,\n\t\tdisabled,\n\t\treadOnly,\n\t\trequired,\n\t\tname,\n\t\tsize = \"md\",\n\t\tclassName,\n\t\tstyle,\n\t\trequiredIndicator,\n\t\tvalidate,\n\t\tvalidationMode,\n\t\tvalidationDebounceTime,\n\t\tdirty,\n\t\ttouched,\n\t\tactionsRef,\n\t\tinputClassName,\n\t\tprimaryLabel = \"將檔案拖曳至此\",\n\t\tsecondaryLabel = \"或從裝置選擇檔案\",\n\t\tbrowseLabel = \"選擇檔案\",\n\t\tinvalidFileLabel = \"不支援的檔案類型\",\n\t\tonChange,\n\t\tonFilesChange,\n\t\tonDragEnter,\n\t\tonDragOver,\n\t\tonDragLeave,\n\t\tonDrop,\n\t\tid: idProp,\n\t\t...inputProps\n\t},\n\tforwardedRef\n) {\n\tconst generatedId = React.useId();\n\tconst id = idProp ?? generatedId;\n\tconst labelId = `${id}-label`;\n\tconst descriptionId = `${id}-description`;\n\tconst errorId = `${id}-error`;\n\tconst triggerId = `${id}-trigger-label`;\n\tconst selectionSummaryId = `${id}-selection-summary`;\n\tconst inputRef = React.useRef<HTMLInputElement>(null);\n\tconst [dragging, setDragging] = React.useState(false);\n\tconst [selectedFiles, setSelectedFiles] = React.useState<readonly File[]>([]);\n\tconst dragDepth = React.useRef(0);\n\tconst pendingDrop = React.useRef<{ event: React.DragEvent<HTMLDivElement>; files: readonly File[]; handled: boolean } | null>(null);\n\tuseClearFileSelectionOnFormReset(inputRef, inputProps.form, setSelectedFiles);\n\n\tReact.useImperativeHandle(forwardedRef, () => inputRef.current as HTMLInputElement);\n\n\tconst handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n\t\tif (disabled || readOnly) return;\n\t\tonChange?.(event);\n\t\tif (event.defaultPrevented) return;\n\n\t\tconst drop = pendingDrop.current;\n\t\tif (drop != null) {\n\t\t\tdrop.handled = true;\n\t\t\tsetSelectedFiles(drop.files);\n\t\t\tonFilesChange?.(drop.files, { source: \"drop\", event: drop.event });\n\t\t\treturn;\n\t\t}\n\n\t\tconst files = Array.from(event.currentTarget.files ?? []);\n\t\tsetSelectedFiles(files);\n\t\tonFilesChange?.(files, { source: \"input\", event });\n\t};\n\n\tconst handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {\n\t\tif (disabled || readOnly) {\n\t\t\tonDragEnter?.(event);\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tonDragEnter?.(event);\n\t\tdragDepth.current += 1;\n\t\tsetDragging(true);\n\t};\n\n\tconst handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {\n\t\tif (disabled || readOnly) {\n\t\t\tonDragOver?.(event);\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tevent.dataTransfer.dropEffect = \"copy\";\n\t\tonDragOver?.(event);\n\t};\n\n\tconst handleDragLeave = (event: React.DragEvent<HTMLDivElement>) => {\n\t\tonDragLeave?.(event);\n\t\tif (disabled || readOnly) return;\n\t\tdragDepth.current = Math.max(0, dragDepth.current - 1);\n\t\tif (dragDepth.current === 0) setDragging(false);\n\t};\n\n\tconst handleDrop = (event: React.DragEvent<HTMLDivElement>) => {\n\t\tif (disabled || readOnly) {\n\t\t\tonDrop?.(event);\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tonDrop?.(event);\n\t\tdragDepth.current = 0;\n\t\tsetDragging(false);\n\t\tconst files = Array.from(event.dataTransfer.files ?? []);\n\t\tif (inputRef.current != null) {\n\t\t\ttry {\n\t\t\t\tinputRef.current.files = event.dataTransfer.files;\n\t\t\t} catch {\n\t\t\t\t// 部分瀏覽器會提供唯讀的 FileList。回呼仍是檔案狀態的主要來源,\n\t\t\t\t// 觸發 change 事件則可同步更新原生驗證狀態。\n\t\t\t}\n\n\t\t\tconst drop = { event, files, handled: false };\n\t\t\tpendingDrop.current = drop;\n\t\t\tinputRef.current.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\t\t\tpendingDrop.current = null;\n\t\t\tif (!drop.handled) {\n\t\t\t\tsetSelectedFiles(files);\n\t\t\t\tonFilesChange?.(files, { source: \"drop\", event });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tsetSelectedFiles(files);\n\t\tonFilesChange?.(files, { source: \"drop\", event });\n\t};\n\n\treturn (\n\t\t<FieldFrame\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\terror={error}\n\t\t\tinvalid={invalid}\n\t\t\tdisabled={disabled}\n\t\t\treadOnly={readOnly}\n\t\t\trequired={required}\n\t\t\tname={name}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\tstyle={style}\n\t\t\trequiredIndicator={requiredIndicator}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}\n\t\t\tvalidate={validate}\n\t\t\tvalidationMode={validationMode}\n\t\t\tvalidationDebounceTime={validationDebounceTime}\n\t\t\tdirty={dirty}\n\t\t\ttouched={touched}\n\t\t\tactionsRef={actionsRef}\n\t\t>\n\t\t\t<BaseInput\n\t\t\t\t{...inputProps}\n\t\t\t\tref={inputRef}\n\t\t\t\tid={id}\n\t\t\t\ttype=\"file\"\n\t\t\t\tclassName={cx(\"lyds-drop-zone__input\", inputClassName)}\n\t\t\t\tdisabled={disabled || readOnly}\n\t\t\t\treadOnly={readOnly}\n\t\t\t\trequired={required}\n\t\t\t\taria-invalid={invalid || undefined}\n\t\t\t\taria-labelledby={label != null ? `${labelId} ${triggerId}` : triggerId}\n\t\t\t\taria-describedby={[description != null ? descriptionId : null, selectedFiles.length > 0 ? selectionSummaryId : null, errorId].filter(Boolean).join(\" \")}\n\t\t\t\ttabIndex={-1}\n\t\t\t\tonChange={handleInputChange}\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tclassName=\"lyds-drop-zone\"\n\t\t\t\tdata-size={size}\n\t\t\t\tdata-dragging={dragging || undefined}\n\t\t\t\tdata-disabled={disabled || undefined}\n\t\t\t\tdata-readonly={readOnly || undefined}\n\t\t\t\tonDragEnter={handleDragEnter}\n\t\t\t\tonDragOver={handleDragOver}\n\t\t\t\tonDragLeave={handleDragLeave}\n\t\t\t\tonDrop={handleDrop}\n\t\t\t>\n\t\t\t\t<span className=\"lyds-drop-zone__copy\">\n\t\t\t\t\t<span className=\"lyds-drop-zone__primary\">{primaryLabel}</span>\n\t\t\t\t\t<span className=\"lyds-drop-zone__secondary\">{secondaryLabel}</span>\n\t\t\t\t</span>\n\t\t\t\t<Button\n\t\t\t\t\tclassName=\"lyds-drop-zone__button\"\n\t\t\t\t\tdisabled={disabled || readOnly}\n\t\t\t\t\tsize={size}\n\t\t\t\t\tstartIcon={<PlusIcon aria-hidden=\"true\" weight=\"bold\" />}\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\tonClick={() => inputRef.current?.click()}\n\t\t\t\t>\n\t\t\t\t\t<span id={triggerId}>{browseLabel}</span>\n\t\t\t\t</Button>\n\t\t\t\t<FileSelectionPreview accept={inputProps.accept} files={selectedFiles} invalidFileLabel={invalidFileLabel} summaryId={selectionSummaryId} />\n\t\t\t</div>\n\t\t</FieldFrame>\n\t);\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Input as BaseInput } from '@base-ui/react/input';
|
|
2
|
+
import { FieldSize } from './internal.js';
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
export interface InputProps extends Omit<BaseInput.Props, "size"> {
|
|
5
|
+
/** Linyao Design System 的控制項尺寸。原生 HTML `size` 屬性請使用 `inputSize`。 */
|
|
6
|
+
size?: FieldSize;
|
|
7
|
+
inputSize?: number;
|
|
8
|
+
invalid?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 使用 Linyao Design System 樣式與 Base UI 值變更資訊的基礎文字輸入元件。
|
|
12
|
+
* 需要可見標籤、說明或錯誤訊息時,請使用 TextField。
|
|
13
|
+
*/
|
|
14
|
+
export declare const Input: React.ForwardRefExoticComponent<Omit<InputProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* empty css */
|
|
2
|
+
import { withStateClassName as e } from "./internal.js";
|
|
3
|
+
import * as t from "react";
|
|
4
|
+
import { jsx as n } from "react/jsx-runtime";
|
|
5
|
+
import { Field as r } from "@base-ui/react/field";
|
|
6
|
+
import { Input as i } from "@base-ui/react/input";
|
|
7
|
+
//#region src/components/forms/Input.tsx
|
|
8
|
+
var a = t.forwardRef(function({ size: t = "md", inputSize: a, invalid: o, className: s, disabled: c, readOnly: l, required: u, name: d, "aria-invalid": f, ...p }, m) {
|
|
9
|
+
return /* @__PURE__ */ n(r.Root, {
|
|
10
|
+
className: "lyds-input-root",
|
|
11
|
+
name: d,
|
|
12
|
+
disabled: c,
|
|
13
|
+
invalid: o,
|
|
14
|
+
"data-size": t,
|
|
15
|
+
"data-readonly": l || void 0,
|
|
16
|
+
"data-required": u || void 0,
|
|
17
|
+
children: /* @__PURE__ */ n(i, {
|
|
18
|
+
...p,
|
|
19
|
+
ref: m,
|
|
20
|
+
className: e("lyds-input", s),
|
|
21
|
+
disabled: c,
|
|
22
|
+
readOnly: l,
|
|
23
|
+
required: u,
|
|
24
|
+
size: a,
|
|
25
|
+
"aria-invalid": o ? !0 : f,
|
|
26
|
+
"data-size": t
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//#endregion
|
|
31
|
+
export { a as Input };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=Input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.js","names":[],"sources":["../../../src/components/forms/Input.tsx"],"sourcesContent":["import { Field as BaseField } from \"@base-ui/react/field\";\nimport { Input as BaseInput } from \"@base-ui/react/input\";\nimport * as React from \"react\";\nimport \"./forms.css\";\nimport { withStateClassName, type FieldSize } from \"./internal\";\n\nexport interface InputProps extends Omit<BaseInput.Props, \"size\"> {\n\t/** Linyao Design System 的控制項尺寸。原生 HTML `size` 屬性請使用 `inputSize`。 */\n\tsize?: FieldSize;\n\tinputSize?: number;\n\tinvalid?: boolean;\n}\n\n/**\n * 使用 Linyao Design System 樣式與 Base UI 值變更資訊的基礎文字輸入元件。\n * 需要可見標籤、說明或錯誤訊息時,請使用 TextField。\n */\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n\t{ size = \"md\", inputSize, invalid, className, disabled, readOnly, required, name, \"aria-invalid\": ariaInvalid, ...props },\n\tref\n) {\n\treturn (\n\t\t<BaseField.Root className=\"lyds-input-root\" name={name} disabled={disabled} invalid={invalid} data-size={size} data-readonly={readOnly || undefined} data-required={required || undefined}>\n\t\t\t<BaseInput\n\t\t\t\t{...props}\n\t\t\t\tref={ref}\n\t\t\t\tclassName={withStateClassName<BaseInput.State>(\"lyds-input\", className)}\n\t\t\t\tdisabled={disabled}\n\t\t\t\treadOnly={readOnly}\n\t\t\t\trequired={required}\n\t\t\t\tsize={inputSize}\n\t\t\t\taria-invalid={invalid ? true : ariaInvalid}\n\t\t\t\tdata-size={size}\n\t\t\t/>\n\t\t</BaseField.Root>\n\t);\n});\n"],"mappings":";;;;;;;AAiBA,IAAa,IAAQ,EAAM,WAAyC,SACnE,EAAE,UAAO,MAAM,cAAW,YAAS,cAAW,aAAU,aAAU,aAAU,SAAM,gBAAgB,GAAa,GAAG,KAClH,GACC;CACD,OACC,kBAAC,EAAU,MAAX;EAAgB,WAAU;EAAwB;EAAgB;EAAmB;EAAS,aAAW;EAAM,iBAAe,KAAY,KAAA;EAAW,iBAAe,KAAY,KAAA;EAC/K,UAAA,kBAAC,GAAD;GACC,GAAI;GACC;GACL,WAAW,EAAoC,cAAc,CAAS;GAC5D;GACA;GACA;GACV,MAAM;GACN,gBAAc,IAAU,KAAO;GAC/B,aAAW;EACX,CAAA;CACc,CAAA;AAElB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NumberField as BaseNumberField } from '@base-ui/react/number-field';
|
|
2
|
+
import { FieldAnatomyProps } from './internal.js';
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
type NumberRootProps = Omit<BaseNumberField.Root.Props, "className" | "disabled" | "name" | "readOnly" | "required" | "style">;
|
|
5
|
+
export interface NumberFieldProps extends NumberRootProps, FieldAnatomyProps {
|
|
6
|
+
inputClassName?: BaseNumberField.Input.Props["className"];
|
|
7
|
+
inputStyle?: React.CSSProperties;
|
|
8
|
+
groupClassName?: BaseNumberField.Group.Props["className"];
|
|
9
|
+
showSteppers?: boolean;
|
|
10
|
+
incrementLabel?: string;
|
|
11
|
+
decrementLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
/** 以 Base UI Number Field 實作、支援地區格式的數字輸入元件。 */
|
|
14
|
+
export declare const NumberField: React.ForwardRefExoticComponent<Omit<NumberFieldProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/* empty css */
|
|
2
|
+
import { FieldFrame as e, cx as t, withStateClassName as n } from "./internal.js";
|
|
3
|
+
import * as r from "react";
|
|
4
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
5
|
+
import { PlusIcon as o } from "@phosphor-icons/react/dist/csr/Plus";
|
|
6
|
+
import { NumberField as s } from "@base-ui/react/number-field";
|
|
7
|
+
import { MinusIcon as c } from "@phosphor-icons/react/dist/csr/Minus";
|
|
8
|
+
//#region src/components/forms/NumberField.tsx
|
|
9
|
+
var l = r.forwardRef(function({ label: r, description: l, error: u, invalid: d, disabled: f, readOnly: p, required: m, name: h, size: g = "md", className: _, style: v, requiredIndicator: y, validate: b, validationMode: x, validationDebounceTime: S, dirty: C, touched: w, actionsRef: T, inputClassName: E, inputStyle: D, groupClassName: O, showSteppers: k = !0, incrementLabel: A = "增加數值", decrementLabel: j = "減少數值", ...M }, N) {
|
|
10
|
+
let P = M["aria-label"], F = M["aria-labelledby"];
|
|
11
|
+
return /* @__PURE__ */ i(e, {
|
|
12
|
+
label: r,
|
|
13
|
+
description: l,
|
|
14
|
+
error: u,
|
|
15
|
+
invalid: d,
|
|
16
|
+
disabled: f,
|
|
17
|
+
readOnly: p,
|
|
18
|
+
required: m,
|
|
19
|
+
name: h,
|
|
20
|
+
size: g,
|
|
21
|
+
className: _,
|
|
22
|
+
style: v,
|
|
23
|
+
requiredIndicator: y,
|
|
24
|
+
validate: b,
|
|
25
|
+
validationMode: x,
|
|
26
|
+
validationDebounceTime: S,
|
|
27
|
+
dirty: C,
|
|
28
|
+
touched: w,
|
|
29
|
+
actionsRef: T,
|
|
30
|
+
children: /* @__PURE__ */ i(s.Root, {
|
|
31
|
+
...M,
|
|
32
|
+
ref: N,
|
|
33
|
+
className: "lyds-number-field",
|
|
34
|
+
name: h,
|
|
35
|
+
disabled: f,
|
|
36
|
+
readOnly: p,
|
|
37
|
+
required: m,
|
|
38
|
+
"data-size": g,
|
|
39
|
+
children: /* @__PURE__ */ a(s.Group, {
|
|
40
|
+
className: n("lyds-number-field__group", O),
|
|
41
|
+
children: [/* @__PURE__ */ i(s.Input, {
|
|
42
|
+
"aria-label": P,
|
|
43
|
+
"aria-labelledby": F,
|
|
44
|
+
className: n("lyds-number-field__input", E),
|
|
45
|
+
style: D
|
|
46
|
+
}), k ? /* @__PURE__ */ a("span", {
|
|
47
|
+
className: "lyds-number-field__steppers",
|
|
48
|
+
children: [/* @__PURE__ */ i(s.Decrement, {
|
|
49
|
+
className: t("lyds-number-field__stepper", "lyds-number-field__stepper--decrement"),
|
|
50
|
+
"aria-label": j,
|
|
51
|
+
children: /* @__PURE__ */ i(c, {
|
|
52
|
+
"aria-hidden": "true",
|
|
53
|
+
weight: "bold"
|
|
54
|
+
})
|
|
55
|
+
}), /* @__PURE__ */ i(s.Increment, {
|
|
56
|
+
className: t("lyds-number-field__stepper", "lyds-number-field__stepper--increment"),
|
|
57
|
+
"aria-label": A,
|
|
58
|
+
children: /* @__PURE__ */ i(o, {
|
|
59
|
+
"aria-hidden": "true",
|
|
60
|
+
weight: "bold"
|
|
61
|
+
})
|
|
62
|
+
})]
|
|
63
|
+
}) : null]
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//#endregion
|
|
69
|
+
export { l as NumberField };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=NumberField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberField.js","names":[],"sources":["../../../src/components/forms/NumberField.tsx"],"sourcesContent":["import { NumberField as BaseNumberField } from \"@base-ui/react/number-field\";\nimport { MinusIcon } from \"@phosphor-icons/react/dist/csr/Minus\";\nimport { PlusIcon } from \"@phosphor-icons/react/dist/csr/Plus\";\nimport * as React from \"react\";\nimport \"./forms.css\";\nimport { cx, FieldFrame, withStateClassName, type FieldAnatomyProps } from \"./internal\";\n\ntype NumberRootProps = Omit<BaseNumberField.Root.Props, \"className\" | \"disabled\" | \"name\" | \"readOnly\" | \"required\" | \"style\">;\n\nexport interface NumberFieldProps extends NumberRootProps, FieldAnatomyProps {\n\tinputClassName?: BaseNumberField.Input.Props[\"className\"];\n\tinputStyle?: React.CSSProperties;\n\tgroupClassName?: BaseNumberField.Group.Props[\"className\"];\n\tshowSteppers?: boolean;\n\tincrementLabel?: string;\n\tdecrementLabel?: string;\n}\n\n/** 以 Base UI Number Field 實作、支援地區格式的數字輸入元件。 */\nexport const NumberField = React.forwardRef<HTMLDivElement, NumberFieldProps>(function NumberField(\n\t{\n\t\tlabel,\n\t\tdescription,\n\t\terror,\n\t\tinvalid,\n\t\tdisabled,\n\t\treadOnly,\n\t\trequired,\n\t\tname,\n\t\tsize = \"md\",\n\t\tclassName,\n\t\tstyle,\n\t\trequiredIndicator,\n\t\tvalidate,\n\t\tvalidationMode,\n\t\tvalidationDebounceTime,\n\t\tdirty,\n\t\ttouched,\n\t\tactionsRef,\n\t\tinputClassName,\n\t\tinputStyle,\n\t\tgroupClassName,\n\t\tshowSteppers = true,\n\t\tincrementLabel = \"增加數值\",\n\t\tdecrementLabel = \"減少數值\",\n\t\t...numberProps\n\t},\n\tref\n) {\n\tconst ariaLabel = numberProps[\"aria-label\"];\n\tconst ariaLabelledBy = numberProps[\"aria-labelledby\"];\n\n\treturn (\n\t\t<FieldFrame\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\terror={error}\n\t\t\tinvalid={invalid}\n\t\t\tdisabled={disabled}\n\t\t\treadOnly={readOnly}\n\t\t\trequired={required}\n\t\t\tname={name}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\tstyle={style}\n\t\t\trequiredIndicator={requiredIndicator}\n\t\t\tvalidate={validate}\n\t\t\tvalidationMode={validationMode}\n\t\t\tvalidationDebounceTime={validationDebounceTime}\n\t\t\tdirty={dirty}\n\t\t\ttouched={touched}\n\t\t\tactionsRef={actionsRef}\n\t\t>\n\t\t\t<BaseNumberField.Root {...numberProps} ref={ref} className=\"lyds-number-field\" name={name} disabled={disabled} readOnly={readOnly} required={required} data-size={size}>\n\t\t\t\t<BaseNumberField.Group className={withStateClassName<BaseNumberField.Group.State>(\"lyds-number-field__group\", groupClassName)}>\n\t\t\t\t\t<BaseNumberField.Input\n\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\t\tclassName={withStateClassName<BaseNumberField.Input.State>(\"lyds-number-field__input\", inputClassName)}\n\t\t\t\t\t\tstyle={inputStyle}\n\t\t\t\t\t/>\n\t\t\t\t\t{showSteppers ? (\n\t\t\t\t\t\t<span className=\"lyds-number-field__steppers\">\n\t\t\t\t\t\t\t<BaseNumberField.Decrement className={cx(\"lyds-number-field__stepper\", \"lyds-number-field__stepper--decrement\")} aria-label={decrementLabel}>\n\t\t\t\t\t\t\t\t<MinusIcon aria-hidden=\"true\" weight=\"bold\" />\n\t\t\t\t\t\t\t</BaseNumberField.Decrement>\n\t\t\t\t\t\t\t<BaseNumberField.Increment className={cx(\"lyds-number-field__stepper\", \"lyds-number-field__stepper--increment\")} aria-label={incrementLabel}>\n\t\t\t\t\t\t\t\t<PlusIcon aria-hidden=\"true\" weight=\"bold\" />\n\t\t\t\t\t\t\t</BaseNumberField.Increment>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : null}\n\t\t\t\t</BaseNumberField.Group>\n\t\t\t</BaseNumberField.Root>\n\t\t</FieldFrame>\n\t);\n});\n"],"mappings":";;;;;;;;AAmBA,IAAa,IAAc,EAAM,WAA6C,SAC7E,EACC,UACA,gBACA,UACA,YACA,aACA,aACA,aACA,SACA,UAAO,MACP,cACA,UACA,sBACA,aACA,mBACA,2BACA,UACA,YACA,eACA,mBACA,eACA,mBACA,kBAAe,IACf,oBAAiB,QACjB,oBAAiB,QACjB,GAAG,KAEJ,GACC;CACD,IAAM,IAAY,EAAY,eACxB,IAAiB,EAAY;CAEnC,OACC,kBAAC,GAAD;EACQ;EACM;EACN;EACE;EACC;EACA;EACA;EACJ;EACA;EACK;EACJ;EACY;EACT;EACM;EACQ;EACjB;EACE;EACG;EAEZ,UAAA,kBAAC,EAAgB,MAAjB;GAAsB,GAAI;GAAkB;GAAK,WAAU;GAA0B;GAAgB;GAAoB;GAAoB;GAAU,aAAW;GACjK,UAAA,kBAAC,EAAgB,OAAjB;IAAuB,WAAW,EAAgD,4BAA4B,CAAc;IAA5H,UAAA,CACC,kBAAC,EAAgB,OAAjB;KACC,cAAY;KACZ,mBAAiB;KACjB,WAAW,EAAgD,4BAA4B,CAAc;KACrG,OAAO;IACP,CAAA,GACA,IACA,kBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACC,kBAAC,EAAgB,WAAjB;MAA2B,WAAW,EAAG,8BAA8B,uCAAuC;MAAG,cAAY;MAC5H,UAAA,kBAAC,GAAD;OAAW,eAAY;OAAO,QAAO;MAAQ,CAAA;KACnB,CAAA,GAC3B,kBAAC,EAAgB,WAAjB;MAA2B,WAAW,EAAG,8BAA8B,uCAAuC;MAAG,cAAY;MAC5H,UAAA,kBAAC,GAAD;OAAU,eAAY;OAAO,QAAO;MAAQ,CAAA;KAClB,CAAA,CACtB;IACH,CAAA,IAAA,IACkB;;EACF,CAAA;CACX,CAAA;AAEd,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { OTPField as BaseOTPField } from '@base-ui/react/otp-field';
|
|
2
|
+
import { FieldAnatomyProps } from './internal.js';
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
type OTPRootProps = Omit<BaseOTPField.Root.Props, "className" | "disabled" | "name" | "readOnly" | "required" | "style">;
|
|
5
|
+
export interface OTPFieldProps extends OTPRootProps, FieldAnatomyProps {
|
|
6
|
+
inputClassName?: BaseOTPField.Input.Props["className"];
|
|
7
|
+
inputStyle?: React.CSSProperties;
|
|
8
|
+
/** 第一格之後各輸入格的選用在地化無障礙標籤。 */
|
|
9
|
+
getSlotLabel?: (index: number) => string;
|
|
10
|
+
separator?: React.ReactNode;
|
|
11
|
+
separatorAfter?: readonly number[];
|
|
12
|
+
}
|
|
13
|
+
/** 以 Base UI OTP Field 實作的多格驗證碼輸入元件。 */
|
|
14
|
+
export declare const OTPField: React.ForwardRefExoticComponent<Omit<OTPFieldProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* empty css */
|
|
2
|
+
import { FieldFrame as e, withStateClassName as t } from "./internal.js";
|
|
3
|
+
import * as n from "react";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
import { OTPField as a } from "@base-ui/react/otp-field";
|
|
6
|
+
//#region src/components/forms/OTPField.tsx
|
|
7
|
+
var o = n.forwardRef(function({ label: o, description: s, error: c, invalid: l, disabled: u, readOnly: d, required: f, name: p, size: m = "md", className: h, style: g, requiredIndicator: _, validate: v, validationMode: y, validationDebounceTime: b, dirty: x, touched: S, actionsRef: C, inputClassName: w, inputStyle: T, getSlotLabel: E, separator: D = /* @__PURE__ */ r("span", {
|
|
8
|
+
"aria-hidden": "true",
|
|
9
|
+
children: "—"
|
|
10
|
+
}), separatorAfter: O = [], length: k, ...A }, j) {
|
|
11
|
+
return /* @__PURE__ */ r(e, {
|
|
12
|
+
label: o,
|
|
13
|
+
description: s,
|
|
14
|
+
error: c,
|
|
15
|
+
invalid: l,
|
|
16
|
+
disabled: u,
|
|
17
|
+
readOnly: d,
|
|
18
|
+
required: f,
|
|
19
|
+
name: p,
|
|
20
|
+
size: m,
|
|
21
|
+
className: h,
|
|
22
|
+
style: g,
|
|
23
|
+
requiredIndicator: _,
|
|
24
|
+
validate: v,
|
|
25
|
+
validationMode: y,
|
|
26
|
+
validationDebounceTime: b,
|
|
27
|
+
dirty: x,
|
|
28
|
+
touched: S,
|
|
29
|
+
actionsRef: C,
|
|
30
|
+
children: /* @__PURE__ */ r(a.Root, {
|
|
31
|
+
...A,
|
|
32
|
+
ref: j,
|
|
33
|
+
className: "lyds-otp-field",
|
|
34
|
+
name: p,
|
|
35
|
+
disabled: u,
|
|
36
|
+
readOnly: d,
|
|
37
|
+
required: f,
|
|
38
|
+
length: k,
|
|
39
|
+
"data-size": m,
|
|
40
|
+
children: Array.from({ length: k }, (e, o) => /* @__PURE__ */ i(n.Fragment, { children: [/* @__PURE__ */ r(a.Input, {
|
|
41
|
+
className: t("lyds-otp-field__input", w),
|
|
42
|
+
style: T,
|
|
43
|
+
"aria-label": o > 0 ? E?.(o) ?? `第 ${o + 1} 個字元,共 ${k} 個` : void 0
|
|
44
|
+
}), O.includes(o + 1) && o < k - 1 ? /* @__PURE__ */ r("span", {
|
|
45
|
+
className: "lyds-otp-field__separator",
|
|
46
|
+
children: D
|
|
47
|
+
}) : null] }, o))
|
|
48
|
+
})
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
export { o as OTPField };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=OTPField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OTPField.js","names":[],"sources":["../../../src/components/forms/OTPField.tsx"],"sourcesContent":["import { OTPField as BaseOTPField } from \"@base-ui/react/otp-field\";\nimport * as React from \"react\";\nimport \"./forms.css\";\nimport { FieldFrame, withStateClassName, type FieldAnatomyProps } from \"./internal\";\n\ntype OTPRootProps = Omit<BaseOTPField.Root.Props, \"className\" | \"disabled\" | \"name\" | \"readOnly\" | \"required\" | \"style\">;\n\nexport interface OTPFieldProps extends OTPRootProps, FieldAnatomyProps {\n\tinputClassName?: BaseOTPField.Input.Props[\"className\"];\n\tinputStyle?: React.CSSProperties;\n\t/** 第一格之後各輸入格的選用在地化無障礙標籤。 */\n\tgetSlotLabel?: (index: number) => string;\n\tseparator?: React.ReactNode;\n\tseparatorAfter?: readonly number[];\n}\n\n/** 以 Base UI OTP Field 實作的多格驗證碼輸入元件。 */\nexport const OTPField = React.forwardRef<HTMLDivElement, OTPFieldProps>(function OTPField(\n\t{\n\t\tlabel,\n\t\tdescription,\n\t\terror,\n\t\tinvalid,\n\t\tdisabled,\n\t\treadOnly,\n\t\trequired,\n\t\tname,\n\t\tsize = \"md\",\n\t\tclassName,\n\t\tstyle,\n\t\trequiredIndicator,\n\t\tvalidate,\n\t\tvalidationMode,\n\t\tvalidationDebounceTime,\n\t\tdirty,\n\t\ttouched,\n\t\tactionsRef,\n\t\tinputClassName,\n\t\tinputStyle,\n\t\tgetSlotLabel,\n\t\tseparator = <span aria-hidden=\"true\">—</span>,\n\t\tseparatorAfter = [],\n\t\tlength,\n\t\t...otpProps\n\t},\n\tref\n) {\n\treturn (\n\t\t<FieldFrame\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\terror={error}\n\t\t\tinvalid={invalid}\n\t\t\tdisabled={disabled}\n\t\t\treadOnly={readOnly}\n\t\t\trequired={required}\n\t\t\tname={name}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\tstyle={style}\n\t\t\trequiredIndicator={requiredIndicator}\n\t\t\tvalidate={validate}\n\t\t\tvalidationMode={validationMode}\n\t\t\tvalidationDebounceTime={validationDebounceTime}\n\t\t\tdirty={dirty}\n\t\t\ttouched={touched}\n\t\t\tactionsRef={actionsRef}\n\t\t>\n\t\t\t<BaseOTPField.Root {...otpProps} ref={ref} className=\"lyds-otp-field\" name={name} disabled={disabled} readOnly={readOnly} required={required} length={length} data-size={size}>\n\t\t\t\t{Array.from({ length }, (_, index) => (\n\t\t\t\t\t<React.Fragment key={index}>\n\t\t\t\t\t\t<BaseOTPField.Input\n\t\t\t\t\t\t\tclassName={withStateClassName<BaseOTPField.Input.State>(\"lyds-otp-field__input\", inputClassName)}\n\t\t\t\t\t\t\tstyle={inputStyle}\n\t\t\t\t\t\t\taria-label={index > 0 ? (getSlotLabel?.(index) ?? `第 ${index + 1} 個字元,共 ${length} 個`) : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{separatorAfter.includes(index + 1) && index < length - 1 ? <span className=\"lyds-otp-field__separator\">{separator}</span> : null}\n\t\t\t\t\t</React.Fragment>\n\t\t\t\t))}\n\t\t\t</BaseOTPField.Root>\n\t\t</FieldFrame>\n\t);\n});\n"],"mappings":";;;;;;AAiBA,IAAa,IAAW,EAAM,WAA0C,SACvE,EACC,UACA,gBACA,UACA,YACA,aACA,aACA,aACA,SACA,UAAO,MACP,cACA,UACA,sBACA,aACA,mBACA,2BACA,UACA,YACA,eACA,mBACA,eACA,iBACA,eAAY,kBAAC,QAAD;CAAM,eAAY;CAAO,UAAA;AAAO,CAAA,GAC5C,oBAAiB,CAAC,GAClB,WACA,GAAG,KAEJ,GACC;CACD,OACC,kBAAC,GAAD;EACQ;EACM;EACN;EACE;EACC;EACA;EACA;EACJ;EACA;EACK;EACJ;EACY;EACT;EACM;EACQ;EACjB;EACE;EACG;EAEZ,UAAA,kBAAC,EAAa,MAAd;GAAmB,GAAI;GAAe;GAAK,WAAU;GAAuB;GAAgB;GAAoB;GAAoB;GAAkB;GAAQ,aAAW;GACvK,UAAA,MAAM,KAAK,EAAE,UAAO,IAAI,GAAG,MAC3B,kBAAC,EAAM,UAAP,EAAA,UAAA,CACC,kBAAC,EAAa,OAAd;IACC,WAAW,EAA6C,yBAAyB,CAAc;IAC/F,OAAO;IACP,cAAY,IAAQ,IAAK,IAAe,CAAK,KAAK,KAAK,IAAQ,EAAE,SAAS,EAAO,MAAO,KAAA;GACxF,CAAA,GACA,EAAe,SAAS,IAAQ,CAAC,KAAK,IAAQ,IAAS,IAAI,kBAAC,QAAD;IAAM,WAAU;IAA6B,UAAA;GAAgB,CAAA,IAAI,IAC9G,EAAA,GAPK,CAOL,CAChB;EACiB,CAAA;CACR,CAAA;AAEd,CAAC"}
|