@linyao.tw/ui 1.0.0 → 1.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.
Files changed (175) hide show
  1. package/README.md +9 -1
  2. package/dist/components/date-time/calendar.js +7 -6
  3. package/dist/components/date-time/calendar.js.map +1 -1
  4. package/dist/components/date-time/date-field.js +9 -8
  5. package/dist/components/date-time/date-field.js.map +1 -1
  6. package/dist/components/date-time/date-picker.js +7 -6
  7. package/dist/components/date-time/date-picker.js.map +1 -1
  8. package/dist/components/date-time/date-range-picker.js +7 -6
  9. package/dist/components/date-time/date-range-picker.js.map +1 -1
  10. package/dist/components/date-time/index.js +0 -1
  11. package/dist/components/date-time/shared.d.ts +0 -1
  12. package/dist/components/date-time/shared.js +6 -9
  13. package/dist/components/date-time/shared.js.map +1 -1
  14. package/dist/components/date-time/time-field.js +7 -6
  15. package/dist/components/date-time/time-field.js.map +1 -1
  16. package/dist/components/feedback/alert.js +34 -34
  17. package/dist/components/feedback/alert.js.map +1 -1
  18. package/dist/components/feedback/banner.js +14 -14
  19. package/dist/components/feedback/banner.js.map +1 -1
  20. package/dist/components/feedback/empty-state.d.ts +2 -1
  21. package/dist/components/feedback/empty-state.js +30 -31
  22. package/dist/components/feedback/empty-state.js.map +1 -1
  23. package/dist/components/feedback/feedback.types.d.ts +0 -1
  24. package/dist/components/feedback/feedback.types.js +2 -5
  25. package/dist/components/feedback/feedback.types.js.map +1 -1
  26. package/dist/components/feedback/index.d.ts +8 -8
  27. package/dist/components/feedback/meter.js +20 -21
  28. package/dist/components/feedback/meter.js.map +1 -1
  29. package/dist/components/feedback/progress.js +20 -21
  30. package/dist/components/feedback/progress.js.map +1 -1
  31. package/dist/components/feedback/skeleton.js +10 -11
  32. package/dist/components/feedback/skeleton.js.map +1 -1
  33. package/dist/components/feedback/spinner.js +24 -25
  34. package/dist/components/feedback/spinner.js.map +1 -1
  35. package/dist/components/feedback/toast.js +22 -21
  36. package/dist/components/feedback/toast.js.map +1 -1
  37. package/dist/components/forms/{CodeField.d.ts → code-field.d.ts} +1 -1
  38. package/dist/components/forms/code-field.js +65 -0
  39. package/dist/components/forms/code-field.js.map +1 -0
  40. package/dist/components/forms/{FileUpload.d.ts → file-upload.d.ts} +1 -1
  41. package/dist/components/forms/{FileUpload.js → file-upload.js} +127 -111
  42. package/dist/components/forms/file-upload.js.map +1 -0
  43. package/dist/components/forms/index.d.ts +6 -6
  44. package/dist/components/forms/{Input.js → input.js} +3 -3
  45. package/dist/components/forms/input.js.map +1 -0
  46. package/dist/components/forms/internal.d.ts +0 -2
  47. package/dist/components/forms/internal.js +12 -17
  48. package/dist/components/forms/internal.js.map +1 -1
  49. package/dist/components/forms/number-field.js +73 -0
  50. package/dist/components/forms/number-field.js.map +1 -0
  51. package/dist/components/forms/otp-field.js +57 -0
  52. package/dist/components/forms/otp-field.js.map +1 -0
  53. package/dist/components/forms/{TextField.d.ts → text-field.d.ts} +5 -0
  54. package/dist/components/forms/text-field.js +200 -0
  55. package/dist/components/forms/text-field.js.map +1 -0
  56. package/dist/components/foundations/{Avatar.js → avatar.js} +3 -3
  57. package/dist/components/foundations/avatar.js.map +1 -0
  58. package/dist/components/foundations/{Badge.d.ts → badge.d.ts} +1 -1
  59. package/dist/components/foundations/{Badge.js → badge.js} +3 -3
  60. package/dist/components/foundations/badge.js.map +1 -0
  61. package/dist/components/foundations/{Button.js → button.js} +3 -3
  62. package/dist/components/foundations/button.js.map +1 -0
  63. package/dist/components/foundations/{Card.d.ts → card.d.ts} +9 -2
  64. package/dist/components/foundations/{Card.js → card.js} +5 -5
  65. package/dist/components/foundations/card.js.map +1 -0
  66. package/dist/components/foundations/{IconButton.d.ts → icon-button.d.ts} +2 -8
  67. package/dist/components/foundations/{IconButton.js → icon-button.js} +4 -4
  68. package/dist/components/foundations/icon-button.js.map +1 -0
  69. package/dist/components/foundations/index.d.ts +9 -9
  70. package/dist/components/foundations/{Link.d.ts → link.d.ts} +1 -1
  71. package/dist/components/foundations/link.js +46 -0
  72. package/dist/components/foundations/link.js.map +1 -0
  73. package/dist/components/foundations/{ListCell.d.ts → list-cell.d.ts} +1 -8
  74. package/dist/components/foundations/{ListCell.js → list-cell.js} +3 -3
  75. package/dist/components/foundations/list-cell.js.map +1 -0
  76. package/dist/components/foundations/{SectionHeading.d.ts → section-heading.d.ts} +5 -2
  77. package/dist/components/foundations/{SectionHeading.js → section-heading.js} +3 -3
  78. package/dist/components/foundations/section-heading.js.map +1 -0
  79. package/dist/components/foundations/{Separator.js → separator.js} +3 -3
  80. package/dist/components/foundations/separator.js.map +1 -0
  81. package/dist/components/navigation-data/breadcrumb-pagination.js +88 -81
  82. package/dist/components/navigation-data/breadcrumb-pagination.js.map +1 -1
  83. package/dist/components/navigation-data/command-palette.d.ts +26 -0
  84. package/dist/components/navigation-data/command-palette.js +100 -72
  85. package/dist/components/navigation-data/command-palette.js.map +1 -1
  86. package/dist/components/navigation-data/header-tab-bar.js +49 -46
  87. package/dist/components/navigation-data/header-tab-bar.js.map +1 -1
  88. package/dist/components/navigation-data/index.d.ts +7 -7
  89. package/dist/components/navigation-data/menubar-toolbar.js +1 -1
  90. package/dist/components/navigation-data/menubar-toolbar.js.map +1 -1
  91. package/dist/components/navigation-data/navigation-menu.js +1 -1
  92. package/dist/components/navigation-data/navigation-menu.js.map +1 -1
  93. package/dist/components/navigation-data/scroll-area.js +1 -1
  94. package/dist/components/navigation-data/scroll-area.js.map +1 -1
  95. package/dist/components/navigation-data/table-collection.d.ts +12 -3
  96. package/dist/components/navigation-data/table-collection.js +11 -9
  97. package/dist/components/navigation-data/table-collection.js.map +1 -1
  98. package/dist/components/overlays/dialog.d.ts +13 -2
  99. package/dist/components/overlays/dialog.js +136 -131
  100. package/dist/components/overlays/dialog.js.map +1 -1
  101. package/dist/components/overlays/disclosure.js +1 -1
  102. package/dist/components/overlays/disclosure.js.map +1 -1
  103. package/dist/components/overlays/drawer.d.ts +5 -1
  104. package/dist/components/overlays/drawer.js +156 -152
  105. package/dist/components/overlays/drawer.js.map +1 -1
  106. package/dist/components/overlays/floating.js +115 -113
  107. package/dist/components/overlays/floating.js.map +1 -1
  108. package/dist/components/overlays/index.d.ts +4 -4
  109. package/dist/components/selection/combobox.js +93 -93
  110. package/dist/components/selection/combobox.js.map +1 -1
  111. package/dist/components/selection/controls.d.ts +4 -1
  112. package/dist/components/selection/controls.js +140 -118
  113. package/dist/components/selection/controls.js.map +1 -1
  114. package/dist/components/selection/menu.js +120 -121
  115. package/dist/components/selection/menu.js.map +1 -1
  116. package/dist/components/selection/select.js +107 -107
  117. package/dist/components/selection/select.js.map +1 -1
  118. package/dist/fonts.css +13 -0
  119. package/dist/index.d.ts +1 -0
  120. package/dist/index.js +37 -33
  121. package/dist/internal/accessible-name.d.ts +12 -0
  122. package/dist/internal/class-names.d.ts +12 -0
  123. package/dist/{components/selection/classnames.js → internal/class-names.js} +3 -3
  124. package/dist/internal/class-names.js.map +1 -0
  125. package/dist/internal/index.d.ts +3 -0
  126. package/dist/{components/foundations/shared.d.ts → internal/render.d.ts} +2 -1
  127. package/dist/intl/index.d.ts +2 -0
  128. package/dist/intl/messages.d.ts +48 -0
  129. package/dist/intl/messages.js +80 -0
  130. package/dist/intl/messages.js.map +1 -0
  131. package/dist/intl/provider.d.ts +18 -0
  132. package/dist/intl/provider.js +22 -0
  133. package/dist/intl/provider.js.map +1 -0
  134. package/dist/styles.css +1 -1
  135. package/package.json +6 -4
  136. package/dist/components/feedback/feedback.module.js +0 -42
  137. package/dist/components/feedback/feedback.module.js.map +0 -1
  138. package/dist/components/forms/CodeField.js +0 -63
  139. package/dist/components/forms/CodeField.js.map +0 -1
  140. package/dist/components/forms/FileUpload.js.map +0 -1
  141. package/dist/components/forms/Input.js.map +0 -1
  142. package/dist/components/forms/NumberField.js +0 -71
  143. package/dist/components/forms/NumberField.js.map +0 -1
  144. package/dist/components/forms/OTPField.js +0 -54
  145. package/dist/components/forms/OTPField.js.map +0 -1
  146. package/dist/components/forms/TextField.js +0 -199
  147. package/dist/components/forms/TextField.js.map +0 -1
  148. package/dist/components/foundations/Avatar.js.map +0 -1
  149. package/dist/components/foundations/Badge.js.map +0 -1
  150. package/dist/components/foundations/Button.js.map +0 -1
  151. package/dist/components/foundations/Card.js.map +0 -1
  152. package/dist/components/foundations/IconButton.js.map +0 -1
  153. package/dist/components/foundations/Link.js +0 -40
  154. package/dist/components/foundations/Link.js.map +0 -1
  155. package/dist/components/foundations/ListCell.js.map +0 -1
  156. package/dist/components/foundations/SectionHeading.js.map +0 -1
  157. package/dist/components/foundations/Separator.js.map +0 -1
  158. package/dist/components/foundations/shared.js +0 -8
  159. package/dist/components/foundations/shared.js.map +0 -1
  160. package/dist/components/navigation-data/utils.d.ts +0 -2
  161. package/dist/components/navigation-data/utils.js +0 -11
  162. package/dist/components/navigation-data/utils.js.map +0 -1
  163. package/dist/components/overlays/class-names.d.ts +0 -6
  164. package/dist/components/overlays/class-names.js +0 -11
  165. package/dist/components/overlays/class-names.js.map +0 -1
  166. package/dist/components/selection/classnames.d.ts +0 -4
  167. package/dist/components/selection/classnames.js.map +0 -1
  168. package/dist/components/selection/selection.module.js +0 -51
  169. package/dist/components/selection/selection.module.js.map +0 -1
  170. /package/dist/components/forms/{Input.d.ts → input.d.ts} +0 -0
  171. /package/dist/components/forms/{NumberField.d.ts → number-field.d.ts} +0 -0
  172. /package/dist/components/forms/{OTPField.d.ts → otp-field.d.ts} +0 -0
  173. /package/dist/components/foundations/{Avatar.d.ts → avatar.d.ts} +0 -0
  174. /package/dist/components/foundations/{Button.d.ts → button.d.ts} +0 -0
  175. /package/dist/components/foundations/{Separator.d.ts → separator.d.ts} +0 -0
@@ -0,0 +1,65 @@
1
+ /* empty css */
2
+ import { cx as e, withStateClassName as t } from "../../internal/class-names.js";
3
+ import { useMessages as n } from "../../intl/provider.js";
4
+ import { FieldFrame as r } from "./internal.js";
5
+ import * as i from "react";
6
+ import { jsx as a } from "react/jsx-runtime";
7
+ import { OTPField as o } from "@base-ui/react/otp-field";
8
+ //#region src/components/forms/code-field.tsx
9
+ function s(e, t, n) {
10
+ return Number.isFinite(e) ? Math.min(n, Math.max(t, Math.trunc(e))) : t;
11
+ }
12
+ var c = i.forwardRef(function({ label: i, description: c, error: l, invalid: u, disabled: d, readOnly: f, required: p, name: m, size: h = "md", className: g, style: _, requiredIndicator: v, validate: y, validationMode: b, validationDebounceTime: x, dirty: S, touched: C, actionsRef: w, inputClassName: T, inputStyle: E, getSlotLabel: D, length: O = 6, groupSize: k, groupClassName: A, groupStyle: j, placeholder: M, validationType: N = "numeric", ...P }, F) {
13
+ let I = n(), L = s(O, 2, 12), R = s(k ?? (L >= 9 ? 4 : 1), 1, L), z = R > 1, B = [], V = typeof M == "string" ? Array.from(M) : null;
14
+ for (let e = 0; e < L; e += R) B.push(Array.from({ length: Math.min(R, L - e) }, (t, n) => e + n));
15
+ let H = (n, r) => /* @__PURE__ */ a(o.Input, {
16
+ className: t(e("lyds-otp-field__input", "lyds-code-field__input", r && "lyds-code-field__group-input"), T),
17
+ style: E,
18
+ placeholder: typeof M == "function" ? M(n) : V?.[n],
19
+ "aria-label": n > 0 ? D?.(n) ?? I.codeSlotLabel(n + 1, L) : void 0
20
+ }, n);
21
+ return /* @__PURE__ */ a(r, {
22
+ label: i,
23
+ description: c,
24
+ error: l,
25
+ invalid: u,
26
+ disabled: d,
27
+ readOnly: f,
28
+ required: p,
29
+ name: m,
30
+ size: h,
31
+ className: g,
32
+ style: _,
33
+ requiredIndicator: v,
34
+ validate: y,
35
+ validationMode: b,
36
+ validationDebounceTime: x,
37
+ dirty: S,
38
+ touched: C,
39
+ actionsRef: w,
40
+ children: /* @__PURE__ */ a(o.Root, {
41
+ ...P,
42
+ ref: F,
43
+ className: e("lyds-otp-field", "lyds-code-field"),
44
+ name: m,
45
+ disabled: d,
46
+ readOnly: f,
47
+ required: p,
48
+ length: L,
49
+ validationType: N,
50
+ "data-size": h,
51
+ "data-grouped": z || void 0,
52
+ "data-group-size": R,
53
+ children: B.map((t, n) => z ? /* @__PURE__ */ a("span", {
54
+ className: e("lyds-code-field__group", A),
55
+ style: j,
56
+ "data-group-index": n,
57
+ children: t.map((e) => H(e, !0))
58
+ }, t[0]) : H(t[0], !1))
59
+ })
60
+ });
61
+ });
62
+ //#endregion
63
+ export { c as CodeField };
64
+
65
+ //# sourceMappingURL=code-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-field.js","names":[],"sources":["../../../src/components/forms/code-field.tsx"],"sourcesContent":["import { cx, withStateClassName } from \"@/internal\";\nimport { useMessages } from \"@/intl\";\nimport { OTPField as BaseOTPField } from \"@base-ui/react/otp-field\";\nimport * as React from \"react\";\nimport \"./forms.css\";\nimport { FieldFrame } from \"./internal\";\nimport type { OTPFieldProps } from \"./otp-field\";\n\nexport interface CodeFieldProps extends Omit<OTPFieldProps, \"length\" | \"separator\" | \"separatorAfter\"> {\n\t/**\n\t * 驗證碼字元數。數值限制為 2 至 12。\n\t * @default 6\n\t */\n\tlength?: number;\n\t/**\n\t * 每個視覺群組顯示的字元數。長度為 9 至 12 時預設每四個字元一組;\n\t * 較短的驗證碼預設各自獨立。設為 1 可強制使用獨立輸入格。\n\t */\n\tgroupSize?: number;\n\tgroupClassName?: string;\n\tgroupStyle?: React.CSSProperties;\n\t/**\n\t * 空白輸入格的選用提示。字串會依序將每個字元分配至各輸入格;\n\t * 需要個別在地化或自訂時可使用函式。\n\t */\n\tplaceholder?: string | ((index: number) => string | undefined);\n}\n\nfunction constrainInteger(value: number, minimum: number, maximum: number): number {\n\tif (!Number.isFinite(value)) return minimum;\n\treturn Math.min(maximum, Math.max(minimum, Math.trunc(value)));\n}\n\n/** 以 Base UI OTP Field 實作的多格驗證碼控制項。 */\nexport const CodeField = React.forwardRef<HTMLDivElement, CodeFieldProps>(function CodeField(\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\tlength: lengthProp = 6,\n\t\tgroupSize: groupSizeProp,\n\t\tgroupClassName,\n\t\tgroupStyle,\n\t\tplaceholder,\n\t\tvalidationType = \"numeric\",\n\t\t...otpProps\n\t},\n\tref\n) {\n\tconst messages = useMessages();\n\tconst length = constrainInteger(lengthProp, 2, 12);\n\tconst defaultGroupSize = length >= 9 ? 4 : 1;\n\tconst groupSize = constrainInteger(groupSizeProp ?? defaultGroupSize, 1, length);\n\tconst grouped = groupSize > 1;\n\tconst groups: number[][] = [];\n\tconst placeholderCharacters = typeof placeholder === \"string\" ? Array.from(placeholder) : null;\n\n\tfor (let start = 0; start < length; start += groupSize) {\n\t\tgroups.push(Array.from({ length: Math.min(groupSize, length - start) }, (_, offset) => start + offset));\n\t}\n\n\tconst renderSlot = (index: number, insideGroup: boolean) => (\n\t\t<BaseOTPField.Input\n\t\t\tkey={index}\n\t\t\tclassName={withStateClassName<BaseOTPField.Input.State>(cx(\"lyds-otp-field__input\", \"lyds-code-field__input\", insideGroup && \"lyds-code-field__group-input\"), inputClassName)}\n\t\t\tstyle={inputStyle}\n\t\t\tplaceholder={typeof placeholder === \"function\" ? placeholder(index) : placeholderCharacters?.[index]}\n\t\t\taria-label={index > 0 ? (getSlotLabel?.(index) ?? messages.codeSlotLabel(index + 1, length)) : undefined}\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\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\n\t\t\t\t{...otpProps}\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cx(\"lyds-otp-field\", \"lyds-code-field\")}\n\t\t\t\tname={name}\n\t\t\t\tdisabled={disabled}\n\t\t\t\treadOnly={readOnly}\n\t\t\t\trequired={required}\n\t\t\t\tlength={length}\n\t\t\t\tvalidationType={validationType}\n\t\t\t\tdata-size={size}\n\t\t\t\tdata-grouped={grouped || undefined}\n\t\t\t\tdata-group-size={groupSize}\n\t\t\t>\n\t\t\t\t{groups.map((indices, groupIndex) =>\n\t\t\t\t\tgrouped ? (\n\t\t\t\t\t\t<span key={indices[0]} className={cx(\"lyds-code-field__group\", groupClassName)} style={groupStyle} data-group-index={groupIndex}>\n\t\t\t\t\t\t\t{indices.map(index => renderSlot(index, true))}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t) : (\n\t\t\t\t\t\trenderSlot(indices[0] as number, false)\n\t\t\t\t\t)\n\t\t\t\t)}\n\t\t\t</BaseOTPField.Root>\n\t\t</FieldFrame>\n\t);\n});\n"],"mappings":";;;;;;;;AA4BA,SAAS,EAAiB,GAAe,GAAiB,GAAyB;CAElF,OADK,OAAO,SAAS,CAAK,IACnB,KAAK,IAAI,GAAS,KAAK,IAAI,GAAS,KAAK,MAAM,CAAK,CAAC,CAAC,IADzB;AAErC;AAGA,IAAa,IAAY,EAAM,WAA2C,SACzE,EACC,UACA,gBACA,UACA,YACA,aACA,aACA,aACA,SACA,UAAO,MACP,cACA,UACA,sBACA,aACA,mBACA,2BACA,UACA,YACA,eACA,mBACA,eACA,iBACA,QAAQ,IAAa,GACrB,WAAW,GACX,mBACA,eACA,gBACA,oBAAiB,WACjB,GAAG,KAEJ,GACC;CACD,IAAM,IAAW,EAAY,GACvB,IAAS,EAAiB,GAAY,GAAG,EAAE,GAE3C,IAAY,EAAiB,MADV,KAAU,IAAI,IAAI,IAC2B,GAAG,CAAM,GACzE,IAAU,IAAY,GACtB,IAAqB,CAAC,GACtB,IAAwB,OAAO,KAAgB,WAAW,MAAM,KAAK,CAAW,IAAI;CAE1F,KAAK,IAAI,IAAQ,GAAG,IAAQ,GAAQ,KAAS,GAC5C,EAAO,KAAK,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAW,IAAS,CAAK,EAAE,IAAI,GAAG,MAAW,IAAQ,CAAM,CAAC;CAGvG,IAAM,KAAc,GAAe,MAClC,kBAAC,EAAa,OAAd;EAEC,WAAW,EAA6C,EAAG,yBAAyB,0BAA0B,KAAe,8BAA8B,GAAG,CAAc;EAC5K,OAAO;EACP,aAAa,OAAO,KAAgB,aAAa,EAAY,CAAK,IAAI,IAAwB;EAC9F,cAAY,IAAQ,IAAK,IAAe,CAAK,KAAK,EAAS,cAAc,IAAQ,GAAG,CAAM,IAAK,KAAA;CAC/F,GALK,CAKL;CAGF,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;GACC,GAAI;GACC;GACL,WAAW,EAAG,kBAAkB,iBAAiB;GAC3C;GACI;GACA;GACA;GACF;GACQ;GAChB,aAAW;GACX,gBAAc,KAAW,KAAA;GACzB,mBAAiB;GAEhB,UAAA,EAAO,KAAK,GAAS,MACrB,IACC,kBAAC,QAAD;IAAuB,WAAW,EAAG,0BAA0B,CAAc;IAAG,OAAO;IAAY,oBAAkB;IACnH,UAAA,EAAQ,KAAI,MAAS,EAAW,GAAO,EAAI,CAAC;GACxC,GAFK,EAAQ,EAEb,IAEN,EAAW,EAAQ,IAAc,EAAK,CAExC;EACkB,CAAA;CACR,CAAA;AAEd,CAAC"}
@@ -21,7 +21,7 @@ export interface DropZoneProps extends NativeFileInputProps, FieldAnatomyProps {
21
21
  inputClassName?: string;
22
22
  primaryLabel?: React.ReactNode;
23
23
  secondaryLabel?: React.ReactNode;
24
- browseLabel?: string;
24
+ browseLabel?: React.ReactNode;
25
25
  invalidFileLabel?: React.ReactNode;
26
26
  onChange?: React.ChangeEventHandler<HTMLInputElement>;
27
27
  onFilesChange?: (files: readonly File[], details: DropZoneChangeDetails) => void;
@@ -1,12 +1,13 @@
1
1
  /* empty css */
2
- import { FieldFrame as e, cx as t } from "./internal.js";
3
- import { Button as n } from "../foundations/Button.js";
2
+ import { cx as e } from "../../internal/class-names.js";
3
+ import { useMessages as t } from "../../intl/provider.js";
4
+ import { FieldFrame as n } from "./internal.js";
4
5
  import * as r from "react";
5
6
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
7
  import { Input as o } from "@base-ui/react/input";
7
8
  import { FileIcon as s } from "@phosphor-icons/react/dist/csr/File";
8
9
  import { PlusIcon as c } from "@phosphor-icons/react/dist/csr/Plus";
9
- //#region src/components/forms/FileUpload.tsx
10
+ //#region src/components/forms/file-upload.tsx
10
11
  function l({ file: e }) {
11
12
  let [t, n] = r.useState(null);
12
13
  return r.useEffect(() => {
@@ -41,27 +42,28 @@ function u(e, t) {
41
42
  return t ? t.startsWith(".") ? n.endsWith(t) : t.endsWith("/*") ? r.startsWith(t.slice(0, -1)) : r === t : !1;
42
43
  });
43
44
  }
44
- function d({ accept: e, files: n, invalidFileLabel: r, summaryId: o }) {
45
+ function d({ accept: n, files: r, invalidFileLabel: o, summaryId: c }) {
46
+ let d = t();
45
47
  return /* @__PURE__ */ a("div", {
46
- className: t("lyds-file-selection", n.length === 0 && "lyds-sr-only"),
48
+ className: e("lyds-file-selection", r.length === 0 && "lyds-sr-only"),
47
49
  children: [/* @__PURE__ */ i("p", {
48
- id: o,
50
+ id: c,
49
51
  className: "lyds-file-selection__summary",
50
52
  role: "status",
51
53
  "aria-live": "polite",
52
54
  "aria-atomic": "true",
53
- children: n.length > 0 ? `已選擇 ${n.length} 個檔案` : null
54
- }), n.length > 0 ? /* @__PURE__ */ i("ul", {
55
+ children: r.length > 0 ? d.fileSelectionSummary(r.length) : null
56
+ }), r.length > 0 ? /* @__PURE__ */ i("ul", {
55
57
  className: "lyds-file-selection__list",
56
- "aria-label": "已選擇的檔案",
57
- children: n.map((t, n) => {
58
- let o = u(t, e);
58
+ "aria-label": d.fileSelectionLabel,
59
+ children: r.map((e, t) => {
60
+ let r = u(e, n);
59
61
  return /* @__PURE__ */ a("li", {
60
62
  className: "lyds-file-selection__item",
61
- "data-invalid": o ? void 0 : "",
63
+ "data-invalid": r ? void 0 : "",
62
64
  children: [/* @__PURE__ */ i("span", {
63
65
  className: "lyds-file-selection__visual",
64
- children: t.type.startsWith("image/") ? /* @__PURE__ */ i(l, { file: t }) : /* @__PURE__ */ i(s, {
66
+ children: e.type.startsWith("image/") ? /* @__PURE__ */ i(l, { file: e }) : /* @__PURE__ */ i(s, {
65
67
  "aria-hidden": "true",
66
68
  weight: "regular"
67
69
  })
@@ -69,14 +71,14 @@ function d({ accept: e, files: n, invalidFileLabel: r, summaryId: o }) {
69
71
  className: "lyds-file-selection__details",
70
72
  children: [/* @__PURE__ */ i("span", {
71
73
  className: "lyds-file-selection__name",
72
- title: t.name,
73
- children: t.name
74
- }), o ? null : /* @__PURE__ */ i("span", {
74
+ title: e.name,
75
+ children: e.name
76
+ }), r ? null : /* @__PURE__ */ i("span", {
75
77
  className: "lyds-file-selection__status",
76
- children: r
78
+ children: o
77
79
  })]
78
80
  })]
79
- }, `${t.name}-${t.size}-${t.lastModified}-${n}`);
81
+ }, `${e.name}-${e.size}-${e.lastModified}-${t}`);
80
82
  })
81
83
  }) : null]
82
84
  });
@@ -93,16 +95,40 @@ function ee(e, t, n) {
93
95
  n
94
96
  ]);
95
97
  }
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) => {
98
+ function te(e, t) {
99
+ return (n) => {
100
+ t?.(n), e && n.preventDefault();
101
+ };
102
+ }
103
+ function ne({ children: t, className: n, disabled: r, htmlFor: o, id: s, readOnly: c, size: l, startIcon: u }) {
104
+ return /* @__PURE__ */ a("label", {
105
+ className: e("lyds-button", n),
106
+ "data-disabled": r || void 0,
107
+ "data-readonly": c || void 0,
108
+ "data-size": l,
109
+ "data-variant": "secondary",
110
+ htmlFor: o,
111
+ children: [u == null ? null : /* @__PURE__ */ i("span", {
112
+ className: "lyds-button__icon",
113
+ "aria-hidden": "true",
114
+ children: u
115
+ }), /* @__PURE__ */ i("span", {
116
+ className: "lyds-button__label",
117
+ id: s,
118
+ children: t
119
+ })]
120
+ });
121
+ }
122
+ 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: re, ...M }, N) {
123
+ let P = t(), F = te(p, M.onClick), I = r.useId(), L = re ?? I, R = `${L}-label`, z = `${L}-description`, B = `${L}-error`, V = `${L}-trigger-label`, H = `${L}-selection-summary`, U = r.useRef(null), [W, G] = r.useState([]);
124
+ ee(U, M.form, G), r.useImperativeHandle(N, () => U.current);
125
+ let K = (e) => {
100
126
  if (!(f || p) && (A?.(e), !e.defaultPrevented)) {
101
127
  let t = Array.from(e.currentTarget.files ?? []);
102
- W(t), j?.(t, e);
128
+ G(t), j?.(t, e);
103
129
  }
104
130
  };
105
- return /* @__PURE__ */ i(e, {
131
+ return /* @__PURE__ */ i(n, {
106
132
  label: s,
107
133
  description: c,
108
134
  error: l,
@@ -115,9 +141,9 @@ var f = r.forwardRef(function({ label: s, description: c, error: l, invalid: u,
115
141
  className: _,
116
142
  style: v,
117
143
  requiredIndicator: y,
118
- labelId: L,
119
- descriptionId: R,
120
- errorId: z,
144
+ labelId: R,
145
+ descriptionId: z,
146
+ errorId: B,
121
147
  validate: b,
122
148
  validationMode: x,
123
149
  validationDebounceTime: S,
@@ -129,105 +155,100 @@ var f = r.forwardRef(function({ label: s, description: c, error: l, invalid: u,
129
155
  "data-size": g,
130
156
  children: [
131
157
  /* @__PURE__ */ i(o, {
132
- ...N,
133
- ref: H,
134
- id: I,
158
+ ...M,
159
+ ref: U,
160
+ id: L,
135
161
  type: "file",
136
- className: t("lyds-file-upload__input", E),
162
+ className: e("lyds-file-upload__input", E),
137
163
  style: D,
138
- disabled: f || p,
164
+ disabled: f,
139
165
  readOnly: p,
166
+ "aria-disabled": p || void 0,
167
+ onClick: F,
140
168
  required: m,
141
169
  "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
170
+ "aria-labelledby": s == null ? V : `${R} ${V}`,
171
+ "aria-describedby": e(c != null && z, W.length > 0 && H, l != null && B) || void 0,
172
+ onChange: K
150
173
  }),
151
- /* @__PURE__ */ i(n, {
174
+ /* @__PURE__ */ i(ne, {
152
175
  className: "lyds-file-upload__trigger",
153
- disabled: f || p,
176
+ disabled: !!f,
177
+ htmlFor: L,
178
+ id: V,
179
+ readOnly: !!p,
154
180
  size: g,
155
- variant: "secondary",
156
- onClick: () => H.current?.click(),
157
- children: /* @__PURE__ */ i("span", {
158
- id: B,
159
- children: O
160
- })
181
+ children: O ?? P.fileUploadTrigger
161
182
  }),
162
183
  /* @__PURE__ */ i(d, {
163
- accept: N.accept,
164
- files: U,
165
- invalidFileLabel: k,
166
- summaryId: V
184
+ accept: M.accept,
185
+ files: W,
186
+ invalidFileLabel: k ?? P.fileUploadInvalidFile,
187
+ summaryId: H
167
188
  })
168
189
  ]
169
190
  })
170
191
  });
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;
192
+ }), 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: re, onFilesChange: M, onDragEnter: N, onDragOver: P, onDragLeave: F, onDrop: I, id: L, ...R }, z) {
193
+ let B = t(), V = te(m, R.onClick), H = r.useId(), U = L ?? H, W = `${U}-label`, G = `${U}-description`, K = `${U}-error`, q = `${U}-trigger-label`, J = `${U}-selection-summary`, Y = r.useRef(null), [ie, X] = r.useState(!1), [ae, Z] = r.useState([]), Q = r.useRef(0), $ = r.useRef(null);
194
+ ee(Y, R.form, Z), r.useImperativeHandle(z, () => Y.current);
195
+ let oe = (e) => {
196
+ if (p || m || (re?.(e), e.defaultPrevented)) return;
176
197
  let t = $.current;
177
198
  if (t != null) {
178
- t.handled = !0, Z(t.files), N?.(t.files, {
199
+ t.handled = !0, Z(t.files), M?.(t.files, {
179
200
  source: "drop",
180
201
  event: t.event
181
202
  });
182
203
  return;
183
204
  }
184
205
  let n = Array.from(e.currentTarget.files ?? []);
185
- Z(n), N?.(n, {
206
+ Z(n), M?.(n, {
186
207
  source: "input",
187
208
  event: e
188
209
  });
189
- }, re = (e) => {
210
+ }, se = (e) => {
190
211
  if (p || m) {
191
- P?.(e);
212
+ N?.(e);
192
213
  return;
193
214
  }
194
- e.preventDefault(), P?.(e), Q.current += 1, Y(!0);
195
- }, ie = (e) => {
215
+ e.preventDefault(), N?.(e), Q.current += 1, X(!0);
216
+ }, ce = (e) => {
196
217
  if (p || m) {
197
- F?.(e);
218
+ P?.(e);
198
219
  return;
199
220
  }
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) => {
221
+ e.preventDefault(), e.dataTransfer.dropEffect = "copy", P?.(e);
222
+ }, le = (e) => {
223
+ F?.(e), !(p || m) && (Q.current = Math.max(0, Q.current - 1), Q.current === 0 && X(!1));
224
+ }, ue = (e) => {
204
225
  if (p || m) {
205
- L?.(e);
226
+ I?.(e);
206
227
  return;
207
228
  }
208
- e.preventDefault(), L?.(e), Q.current = 0, Y(!1);
229
+ e.preventDefault(), I?.(e), Q.current = 0, X(!1);
209
230
  let t = Array.from(e.dataTransfer.files ?? []);
210
- if (J.current != null) {
231
+ if (Y.current != null) {
211
232
  try {
212
- J.current.files = e.dataTransfer.files;
233
+ Y.current.files = e.dataTransfer.files;
213
234
  } catch {}
214
235
  let n = {
215
236
  event: e,
216
237
  files: t,
217
238
  handled: !1
218
239
  };
219
- $.current = n, J.current.dispatchEvent(new Event("change", { bubbles: !0 })), $.current = null, n.handled || (Z(t), N?.(t, {
240
+ $.current = n, Y.current.dispatchEvent(new Event("change", { bubbles: !0 })), $.current = null, n.handled || (Z(t), M?.(t, {
220
241
  source: "drop",
221
242
  event: e
222
243
  }));
223
244
  return;
224
245
  }
225
- Z(t), N?.(t, {
246
+ Z(t), M?.(t, {
226
247
  source: "drop",
227
248
  event: e
228
249
  });
229
250
  };
230
- return /* @__PURE__ */ a(e, {
251
+ return /* @__PURE__ */ a(n, {
231
252
  label: s,
232
253
  description: l,
233
254
  error: u,
@@ -240,9 +261,9 @@ var f = r.forwardRef(function({ label: s, description: c, error: l, invalid: u,
240
261
  className: v,
241
262
  style: y,
242
263
  requiredIndicator: b,
243
- labelId: U,
244
- descriptionId: W,
245
- errorId: G,
264
+ labelId: W,
265
+ descriptionId: G,
266
+ errorId: K,
246
267
  validate: x,
247
268
  validationMode: S,
248
269
  validationDebounceTime: C,
@@ -250,64 +271,59 @@ var f = r.forwardRef(function({ label: s, description: c, error: l, invalid: u,
250
271
  touched: T,
251
272
  actionsRef: E,
252
273
  children: [/* @__PURE__ */ i(o, {
253
- ...z,
254
- ref: J,
255
- id: H,
274
+ ...R,
275
+ ref: Y,
276
+ id: U,
256
277
  type: "file",
257
- className: t("lyds-drop-zone__input", D),
258
- disabled: p || m,
278
+ className: e("lyds-drop-zone__input", D),
279
+ disabled: p,
259
280
  readOnly: m,
281
+ "aria-disabled": m || void 0,
282
+ onClick: V,
260
283
  required: h,
261
284
  "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
285
+ "aria-labelledby": s == null ? q : `${W} ${q}`,
286
+ "aria-describedby": e(l != null && G, ae.length > 0 && J, u != null && K) || void 0,
287
+ onChange: oe
270
288
  }), /* @__PURE__ */ a("div", {
271
289
  className: "lyds-drop-zone",
272
290
  "data-size": _,
273
- "data-dragging": te || void 0,
291
+ "data-dragging": ie || void 0,
274
292
  "data-disabled": p || void 0,
275
293
  "data-readonly": m || void 0,
276
- onDragEnter: re,
277
- onDragOver: ie,
278
- onDragLeave: ae,
279
- onDrop: oe,
294
+ onDragEnter: se,
295
+ onDragOver: ce,
296
+ onDragLeave: le,
297
+ onDrop: ue,
280
298
  children: [
281
299
  /* @__PURE__ */ a("span", {
282
300
  className: "lyds-drop-zone__copy",
283
301
  children: [/* @__PURE__ */ i("span", {
284
302
  className: "lyds-drop-zone__primary",
285
- children: O
303
+ children: O ?? B.dropZonePrimary
286
304
  }), /* @__PURE__ */ i("span", {
287
305
  className: "lyds-drop-zone__secondary",
288
- children: k
306
+ children: k ?? B.dropZoneSecondary
289
307
  })]
290
308
  }),
291
- /* @__PURE__ */ i(n, {
309
+ /* @__PURE__ */ i(ne, {
292
310
  className: "lyds-drop-zone__button",
293
- disabled: p || m,
311
+ disabled: !!p,
312
+ htmlFor: U,
313
+ id: q,
314
+ readOnly: !!m,
294
315
  size: _,
295
316
  startIcon: /* @__PURE__ */ i(c, {
296
317
  "aria-hidden": "true",
297
318
  weight: "bold"
298
319
  }),
299
- variant: "secondary",
300
- onClick: () => J.current?.click(),
301
- children: /* @__PURE__ */ i("span", {
302
- id: K,
303
- children: A
304
- })
320
+ children: A ?? B.dropZoneBrowse
305
321
  }),
306
322
  /* @__PURE__ */ i(d, {
307
- accept: z.accept,
308
- files: X,
309
- invalidFileLabel: j,
310
- summaryId: q
323
+ accept: R.accept,
324
+ files: ae,
325
+ invalidFileLabel: j ?? B.fileUploadInvalidFile,
326
+ summaryId: J
311
327
  })
312
328
  ]
313
329
  })]
@@ -316,4 +332,4 @@ var f = r.forwardRef(function({ label: s, description: c, error: l, invalid: u,
316
332
  //#endregion
317
333
  export { p as DropZone, f as FileUpload };
318
334
 
319
- //# sourceMappingURL=FileUpload.js.map
335
+ //# sourceMappingURL=file-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload.js","names":[],"sources":["../../../src/components/forms/file-upload.tsx"],"sourcesContent":["import { cx } from \"@/internal\";\nimport { useMessages } from \"@/intl\";\nimport { 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 \"./forms.css\";\nimport { FieldFrame, type FieldAnatomyProps } from \"./internal\";\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\tconst messages = useMessages();\n\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 ? messages.fileSelectionSummary(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={messages.fileSelectionLabel}>\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\n/**\n * HTML has no read-only file input. Disabling one would drop whatever the user already picked from\n * the submission, so a read-only field stays enabled and simply refuses to open the picker.\n */\nfunction useBlockedPicker(readOnly: boolean | undefined, onClick: React.MouseEventHandler<HTMLInputElement> | undefined) {\n\treturn (event: React.MouseEvent<HTMLInputElement>) => {\n\t\tonClick?.(event);\n\t\tif (readOnly) event.preventDefault();\n\t};\n}\n\ninterface FileTriggerProps {\n\tchildren: React.ReactNode;\n\tclassName: string;\n\tdisabled: boolean;\n\thtmlFor: string;\n\tid: string;\n\treadOnly: boolean;\n\tsize: FieldAnatomyProps[\"size\"];\n\tstartIcon?: React.ReactNode;\n}\n\n/**\n * The visible affordance is a label bound to the real file input, so the input keeps the single\n * tab stop, the accessible name and native picker activation. Rendering a button beside the input\n * instead would leave the description, error and validity on an element the keyboard cannot reach.\n */\nfunction FileTrigger({ children, className, disabled, htmlFor, id, readOnly, size, startIcon }: FileTriggerProps) {\n\treturn (\n\t\t<label className={cx(\"lyds-button\", className)} data-disabled={disabled || undefined} data-readonly={readOnly || undefined} data-size={size} data-variant=\"secondary\" htmlFor={htmlFor}>\n\t\t\t{startIcon != null ? (\n\t\t\t\t<span className=\"lyds-button__icon\" aria-hidden=\"true\">\n\t\t\t\t\t{startIcon}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span className=\"lyds-button__label\" id={id}>\n\t\t\t\t{children}\n\t\t\t</span>\n\t\t</label>\n\t);\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 messages = useMessages();\n\tconst blockPickerWhenReadOnly = useBlockedPicker(readOnly, inputProps.onClick);\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}\n\t\t\t\t\treadOnly={readOnly}\n\t\t\t\t\taria-disabled={readOnly || undefined}\n\t\t\t\t\tonClick={blockPickerWhenReadOnly}\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={cx(description != null && descriptionId, selectedFiles.length > 0 && selectionSummaryId, error != null && errorId) || undefined}\n\t\t\t\t\tonChange={handleChange}\n\t\t\t\t/>\n\t\t\t\t<FileTrigger className=\"lyds-file-upload__trigger\" disabled={Boolean(disabled)} htmlFor={id} id={triggerId} readOnly={Boolean(readOnly)} size={size}>\n\t\t\t\t\t{triggerLabel ?? messages.fileUploadTrigger}\n\t\t\t\t</FileTrigger>\n\t\t\t\t<FileSelectionPreview accept={inputProps.accept} files={selectedFiles} invalidFileLabel={invalidFileLabel ?? messages.fileUploadInvalidFile} 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?: React.ReactNode;\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 messages = useMessages();\n\tconst blockPickerWhenReadOnly = useBlockedPicker(readOnly, inputProps.onClick);\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}\n\t\t\t\treadOnly={readOnly}\n\t\t\t\taria-disabled={readOnly || undefined}\n\t\t\t\tonClick={blockPickerWhenReadOnly}\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={cx(description != null && descriptionId, selectedFiles.length > 0 && selectionSummaryId, error != null && errorId) || undefined}\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 ?? messages.dropZonePrimary}</span>\n\t\t\t\t\t<span className=\"lyds-drop-zone__secondary\">{secondaryLabel ?? messages.dropZoneSecondary}</span>\n\t\t\t\t</span>\n\t\t\t\t<FileTrigger\n\t\t\t\t\tclassName=\"lyds-drop-zone__button\"\n\t\t\t\t\tdisabled={Boolean(disabled)}\n\t\t\t\t\thtmlFor={id}\n\t\t\t\t\tid={triggerId}\n\t\t\t\t\treadOnly={Boolean(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>\n\t\t\t\t\t{browseLabel ?? messages.dropZoneBrowse}\n\t\t\t\t</FileTrigger>\n\t\t\t\t<FileSelectionPreview accept={inputProps.accept} files={selectedFiles} invalidFileLabel={invalidFileLabel ?? messages.fileUploadInvalidFile} summaryId={selectionSummaryId} />\n\t\t\t</div>\n\t\t</FieldFrame>\n\t);\n});\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- export { CodeField, type CodeFieldProps } from './CodeField.js';
2
- export { DropZone, FileUpload, type DropZoneChangeDetails, type DropZoneProps, type FileUploadProps } from './FileUpload.js';
3
- export { Input, type InputProps } from './Input.js';
1
+ export { CodeField, type CodeFieldProps } from './code-field.js';
2
+ export { DropZone, FileUpload, type DropZoneChangeDetails, type DropZoneProps, type FileUploadProps } from './file-upload.js';
3
+ export { Input, type InputProps } from './input.js';
4
4
  export type { FieldAnatomyProps, FieldSize, FieldValidationProps } from './internal.js';
5
- export { NumberField, type NumberFieldProps } from './NumberField.js';
6
- export { OTPField, type OTPFieldProps } from './OTPField.js';
7
- export { PasswordField, PhoneField, SearchField, TextField, TextView, Textarea, type PasswordFieldProps, type PhoneFieldCountrySelectorState, type PhoneFieldProps, type SearchFieldProps, type TextFieldProps, type TextViewProps, type TextareaProps } from './TextField.js';
5
+ export { NumberField, type NumberFieldProps } from './number-field.js';
6
+ export { OTPField, type OTPFieldProps } from './otp-field.js';
7
+ export { PasswordField, PhoneField, SearchField, TextField, TextView, Textarea, type PasswordFieldProps, type PhoneFieldCountrySelectorState, type PhoneFieldProps, type SearchFieldProps, type TextFieldProps, type TextViewProps, type TextareaProps } from './text-field.js';
@@ -1,10 +1,10 @@
1
1
  /* empty css */
2
- import { withStateClassName as e } from "./internal.js";
2
+ import { withStateClassName as e } from "../../internal/class-names.js";
3
3
  import * as t from "react";
4
4
  import { jsx as n } from "react/jsx-runtime";
5
5
  import { Field as r } from "@base-ui/react/field";
6
6
  import { Input as i } from "@base-ui/react/input";
7
- //#region src/components/forms/Input.tsx
7
+ //#region src/components/forms/input.tsx
8
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
9
  return /* @__PURE__ */ n(r.Root, {
10
10
  className: "lyds-input-root",
@@ -30,4 +30,4 @@ var a = t.forwardRef(function({ size: t = "md", inputSize: a, invalid: o, classN
30
30
  //#endregion
31
31
  export { a as Input };
32
32
 
33
- //# sourceMappingURL=Input.js.map
33
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input.js","names":[],"sources":["../../../src/components/forms/input.tsx"],"sourcesContent":["import { withStateClassName } from \"@/internal\";\nimport { 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 { type FieldSize } from \"./internal\";\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"}
@@ -27,7 +27,5 @@ interface FieldFrameProps extends FieldAnatomyProps {
27
27
  descriptionId?: string | undefined;
28
28
  errorId?: string | undefined;
29
29
  }
30
- export declare function cx(...classes: Array<string | false | null | undefined>): string;
31
- export declare function withStateClassName<State>(baseClassName: string, className: string | ((state: State) => string | undefined) | undefined): string | ((state: State) => string);
32
30
  export declare function FieldFrame({ children, label, description, error, invalid, disabled, readOnly, required, name, size, className, style, requiredIndicator, labelId, descriptionId, errorId, validate, validationMode, validationDebounceTime, dirty, touched, actionsRef }: FieldFrameProps): React.JSX.Element;
33
31
  export {};