@seekbuddy/dsh-ui 0.0.0-stage → 0.2.0-beta.1

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 (213) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/LICENSE +22 -0
  3. package/README.md +175 -2
  4. package/README.zh.md +176 -0
  5. package/THIRD_PARTY_NOTICES.md +42 -0
  6. package/UPSTREAM.md +59 -0
  7. package/dist/blocks.js +1617 -0
  8. package/dist/chunks/chunk-23KOEBWJ.js +104 -0
  9. package/dist/chunks/chunk-6SGSJ5KW.js +57 -0
  10. package/dist/chunks/chunk-7NH2UOZO.js +155 -0
  11. package/dist/chunks/chunk-7SKW4S35.js +66 -0
  12. package/dist/chunks/chunk-B3EEK7A2.js +408 -0
  13. package/dist/chunks/chunk-CEBTQO6W.js +24 -0
  14. package/dist/chunks/chunk-ENKPNYOB.js +26 -0
  15. package/dist/chunks/chunk-EWAZFWLW.js +27 -0
  16. package/dist/chunks/chunk-F352IICS.js +57 -0
  17. package/dist/chunks/chunk-FFJ6TCCF.js +31 -0
  18. package/dist/chunks/chunk-FZXK4LTI.js +129 -0
  19. package/dist/chunks/chunk-JA3XDLIA.js +1115 -0
  20. package/dist/chunks/chunk-L7XALG4J.js +36 -0
  21. package/dist/chunks/chunk-OCAQFVT3.js +3172 -0
  22. package/dist/chunks/chunk-RAXDA2PT.js +202 -0
  23. package/dist/chunks/chunk-RNVSCTW7.js +24 -0
  24. package/dist/chunks/chunk-RZOP2PFC.js +152 -0
  25. package/dist/chunks/chunk-SN6RSUWC.js +61 -0
  26. package/dist/chunks/chunk-SNVSQWCU.js +22 -0
  27. package/dist/chunks/chunk-SO3DCAWG.js +170 -0
  28. package/dist/chunks/chunk-UAEFKTV3.js +144 -0
  29. package/dist/chunks/chunk-UGEORMLD.js +89 -0
  30. package/dist/chunks/chunk-W6FLI3AK.js +112 -0
  31. package/dist/chunks/chunk-WX46TSKP.js +328 -0
  32. package/dist/chunks/chunk-XL33IPCV.js +261 -0
  33. package/dist/chunks/chunk-XW4L4ZGL.js +967 -0
  34. package/dist/chunks/chunk-YOBY6PSL.js +850 -0
  35. package/dist/chunks/chunk-ZA47FP7C.js +7 -0
  36. package/dist/icons.js +859 -0
  37. package/dist/index.js +1675 -0
  38. package/dist/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  39. package/dist/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  40. package/dist/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  41. package/dist/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  42. package/dist/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  43. package/dist/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  44. package/dist/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  45. package/dist/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  46. package/dist/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  47. package/dist/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  48. package/dist/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  49. package/dist/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  50. package/dist/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  51. package/dist/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  52. package/dist/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  53. package/dist/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  54. package/dist/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  55. package/dist/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  56. package/dist/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  57. package/dist/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  58. package/dist/katex.css +1 -0
  59. package/dist/katex.css.d.ts +2 -0
  60. package/dist/markdown.js +225 -0
  61. package/dist/meta.json +7575 -0
  62. package/dist/root-inputs.json +86 -0
  63. package/dist/seekbuddy-card.js +7 -0
  64. package/dist/seekbuddy-empty.js +8 -0
  65. package/dist/seekbuddy-internal/DangerButton.js +7 -0
  66. package/dist/seekbuddy-internal/Mark.js +7 -0
  67. package/dist/seekbuddy-internal/Message.js +10 -0
  68. package/dist/seekbuddy-internal/Pagination.js +9 -0
  69. package/dist/seekbuddy-internal/StatusBadge.js +7 -0
  70. package/dist/seekbuddy-internal/SubtleButton.js +7 -0
  71. package/dist/seekbuddy-internal/Switch.js +7 -0
  72. package/dist/seekbuddy-internal/Upload.js +7 -0
  73. package/dist/seekbuddy-internal/date/Calendar.js +8 -0
  74. package/dist/seekbuddy-internal/date/DatePicker.js +9 -0
  75. package/dist/seekbuddy-internal/date/DateRangePicker.js +9 -0
  76. package/dist/seekbuddy-internal/date/TimePicker.js +8 -0
  77. package/dist/seekbuddy-internal/date/fields.js +16 -0
  78. package/dist/seekbuddy-internal/qr/QrCode.js +7 -0
  79. package/dist/seekbuddy-spinner.js +7 -0
  80. package/dist/seekbuddy-tabs.js +7 -0
  81. package/dist/seekbuddy-timeline.js +8 -0
  82. package/dist/seekbuddy.js +89 -0
  83. package/dist/theme-bootstrap.js +13 -0
  84. package/dist/theme.js +37 -0
  85. package/dist/tokens.css +974 -0
  86. package/dist/tokens.css.d.ts +2 -0
  87. package/dist/types/AnimatedRows.d.ts +45 -0
  88. package/dist/types/Button.d.ts +18 -0
  89. package/dist/types/Checkbox.d.ts +19 -0
  90. package/dist/types/CodeFileIcon.d.ts +11 -0
  91. package/dist/types/CodeToolbar.d.ts +29 -0
  92. package/dist/types/CommandText.d.ts +15 -0
  93. package/dist/types/ConfigField.d.ts +32 -0
  94. package/dist/types/ConnectionIndicator.d.ts +25 -0
  95. package/dist/types/DetailDocument.d.ts +77 -0
  96. package/dist/types/DiffBlock.d.ts +51 -0
  97. package/dist/types/DisclosureRow.d.ts +37 -0
  98. package/dist/types/DraggableImage.d.ts +18 -0
  99. package/dist/types/FileTypeIcon.d.ts +42 -0
  100. package/dist/types/FoldToggle.d.ts +19 -0
  101. package/dist/types/HoverCard.d.ts +44 -0
  102. package/dist/types/HoverCardGroup.d.ts +24 -0
  103. package/dist/types/ImageLightbox.d.ts +29 -0
  104. package/dist/types/ImagePreview.d.ts +11 -0
  105. package/dist/types/InlineEditor.d.ts +22 -0
  106. package/dist/types/Input.d.ts +11 -0
  107. package/dist/types/JsonTree.d.ts +58 -0
  108. package/dist/types/LinkIcon.d.ts +33 -0
  109. package/dist/types/Menu.d.ts +163 -0
  110. package/dist/types/MenuGroup.d.ts +21 -0
  111. package/dist/types/MenuSurface.d.ts +24 -0
  112. package/dist/types/Modal.d.ts +43 -0
  113. package/dist/types/PermissionIcon.d.ts +50 -0
  114. package/dist/types/Pill.d.ts +12 -0
  115. package/dist/types/QuotePreview.d.ts +23 -0
  116. package/dist/types/ReadBlock.d.ts +47 -0
  117. package/dist/types/ReferenceIcon.d.ts +20 -0
  118. package/dist/types/RiskConfirmation.d.ts +19 -0
  119. package/dist/types/SearchBlock.d.ts +71 -0
  120. package/dist/types/SegmentedControl.d.ts +34 -0
  121. package/dist/types/SegmentedTabs.d.ts +27 -0
  122. package/dist/types/ShortcutKeys.d.ts +10 -0
  123. package/dist/types/SiteGlyph.d.ts +24 -0
  124. package/dist/types/StateDot.d.ts +19 -0
  125. package/dist/types/Switch.d.ts +19 -0
  126. package/dist/types/Tag.d.ts +31 -0
  127. package/dist/types/TerminalBlock.d.ts +85 -0
  128. package/dist/types/TextShimmer.d.ts +22 -0
  129. package/dist/types/Toast.d.ts +48 -0
  130. package/dist/types/Tooltip.d.ts +69 -0
  131. package/dist/types/UserMessageBubble.d.ts +10 -0
  132. package/dist/types/WebBlock.d.ts +60 -0
  133. package/dist/types/ZoomControls.d.ts +26 -0
  134. package/dist/types/ansi.d.ts +16 -0
  135. package/dist/types/blocks.d.ts +21 -0
  136. package/dist/types/clipboard.d.ts +8 -0
  137. package/dist/types/code-file-icon-artwork.d.ts +53 -0
  138. package/dist/types/code-file-types.d.ts +29 -0
  139. package/dist/types/code-highlighting.d.ts +11 -0
  140. package/dist/types/css-modules.d.ts +6 -0
  141. package/dist/types/darwin-desktop.d.ts +8 -0
  142. package/dist/types/document-zoom.d.ts +16 -0
  143. package/dist/types/file-drag-actions.d.ts +36 -0
  144. package/dist/types/file-size.d.ts +7 -0
  145. package/dist/types/focus.d.ts +15 -0
  146. package/dist/types/guide-artwork.d.ts +14 -0
  147. package/dist/types/head-tail-cap.d.ts +22 -0
  148. package/dist/types/icons/artwork.d.ts +421 -0
  149. package/dist/types/icons/index.d.ts +397 -0
  150. package/dist/types/icons/props.d.ts +8 -0
  151. package/dist/types/icons/shared-artwork.d.ts +36 -0
  152. package/dist/types/icons.d.ts +6 -0
  153. package/dist/types/image-drag.d.ts +16 -0
  154. package/dist/types/index.d.ts +71 -0
  155. package/dist/types/input-modality.d.ts +18 -0
  156. package/dist/types/keyboard-composition.d.ts +10 -0
  157. package/dist/types/markdown/CodeBlock.d.ts +34 -0
  158. package/dist/types/markdown/JsonBlock.d.ts +7 -0
  159. package/dist/types/markdown/MarkdownDelegate.d.ts +68 -0
  160. package/dist/types/markdown/MarkdownText.d.ts +54 -0
  161. package/dist/types/markdown/cjkFriendlyStrong.d.ts +8 -0
  162. package/dist/types/markdown/file-link.d.ts +22 -0
  163. package/dist/types/markdown/highlight.d.ts +169 -0
  164. package/dist/types/markdown/incremental.d.ts +79 -0
  165. package/dist/types/markdown/katex.d.ts +18 -0
  166. package/dist/types/markdown/local-image-syntax.d.ts +9 -0
  167. package/dist/types/markdown/mathCompatibility.d.ts +10 -0
  168. package/dist/types/markdown/parse.d.ts +24 -0
  169. package/dist/types/markdown/plain-text.d.ts +21 -0
  170. package/dist/types/markdown/quote-text.d.ts +7 -0
  171. package/dist/types/markdown/render.d.ts +145 -0
  172. package/dist/types/markdown/useViewportHighlighting.d.ts +10 -0
  173. package/dist/types/markdown/windows-path-destinations.d.ts +10 -0
  174. package/dist/types/markdown.d.ts +12 -0
  175. package/dist/types/overlay-top-margin.d.ts +14 -0
  176. package/dist/types/plugin-artwork.d.ts +16 -0
  177. package/dist/types/pointer-grace.d.ts +21 -0
  178. package/dist/types/rank-by-name.d.ts +21 -0
  179. package/dist/types/relative-time.d.ts +22 -0
  180. package/dist/types/seekbuddy/Card.d.ts +28 -0
  181. package/dist/types/seekbuddy/DangerButton.d.ts +31 -0
  182. package/dist/types/seekbuddy/Empty.d.ts +34 -0
  183. package/dist/types/seekbuddy/Mark.d.ts +27 -0
  184. package/dist/types/seekbuddy/Message.d.ts +52 -0
  185. package/dist/types/seekbuddy/Pagination.d.ts +66 -0
  186. package/dist/types/seekbuddy/Spinner.d.ts +20 -0
  187. package/dist/types/seekbuddy/StatusBadge.d.ts +33 -0
  188. package/dist/types/seekbuddy/SubtleButton.d.ts +30 -0
  189. package/dist/types/seekbuddy/Switch.d.ts +36 -0
  190. package/dist/types/seekbuddy/Tabs.d.ts +49 -0
  191. package/dist/types/seekbuddy/Timeline.d.ts +42 -0
  192. package/dist/types/seekbuddy/Upload.d.ts +101 -0
  193. package/dist/types/seekbuddy/date/Calendar.d.ts +94 -0
  194. package/dist/types/seekbuddy/date/DatePicker.d.ts +29 -0
  195. package/dist/types/seekbuddy/date/DateRangePicker.d.ts +41 -0
  196. package/dist/types/seekbuddy/date/TimePicker.d.ts +35 -0
  197. package/dist/types/seekbuddy/date/date.d.ts +79 -0
  198. package/dist/types/seekbuddy/date/fields.d.ts +45 -0
  199. package/dist/types/seekbuddy/index.d.ts +49 -0
  200. package/dist/types/seekbuddy/qr/QrCode.d.ts +37 -0
  201. package/dist/types/seekbuddy/qr/qr.d.ts +38 -0
  202. package/dist/types/theme-bootstrap.d.ts +3 -0
  203. package/dist/types/theme-core.d.ts +14 -0
  204. package/dist/types/theme.d.ts +4 -0
  205. package/dist/types/tooltip-placement.d.ts +34 -0
  206. package/dist/types/use-clipboard-copy.d.ts +13 -0
  207. package/dist/types/useAnchoredMaxHeight.d.ts +13 -0
  208. package/dist/types/useAnchoredPosition.d.ts +35 -0
  209. package/dist/types/useDismissOnOutsidePointer.d.ts +10 -0
  210. package/dist/types/useModalLayer.d.ts +26 -0
  211. package/dist/types/useRowDragPreview.d.ts +19 -0
  212. package/dist/types/user-text.d.ts +31 -0
  213. package/package.json +151 -4
@@ -0,0 +1,144 @@
1
+ import {
2
+ clampTime,
3
+ minutesToTime,
4
+ parseIsoTime,
5
+ timeToMinutes
6
+ } from "./chunk-RZOP2PFC.js";
7
+
8
+ // src/seekbuddy/date/TimePicker.tsx
9
+ import clsx from "clsx";
10
+ import { useEffect, useId, useRef } from "react";
11
+
12
+ // .build/css/seekbuddy/date/TimePicker.module.mjs
13
+ var id = "@seekbuddy/dsh-ui/seekbuddy/date/TimePicker.module.css";
14
+ if (typeof document !== "undefined" && !document.querySelector('style[data-dsh-ui-primitives="' + id + '"]')) {
15
+ const element = document.createElement("style");
16
+ element.setAttribute("data-dsh-ui-primitives", id);
17
+ element.textContent = ".A5-U5q_picker{--time-row:32px;--time-rows:7;color:var(--dsw-alias-label-primary);grid-template-columns:repeat(2,minmax(64px,auto));display:inline-grid}.A5-U5q_column{gap:4px;min-width:0;display:grid}.A5-U5q_column+.A5-U5q_column{border-left:.5px solid var(--dsw-alias-border-l1)}.A5-U5q_heading{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxs-12);text-align:center;padding:0 8px}.A5-U5q_list{max-height:calc(var(--time-row) * var(--time-rows));margin:0;padding:0 8px;list-style:none;overflow-y:auto}.A5-U5q_list:focus-visible{border-radius:var(--dsw-radius-sm);outline-offset:-2px;outline-style:solid}.A5-U5q_option{height:var(--time-row);border-radius:var(--dsw-radius-sm);cursor:pointer;font:var(--dsw-font-xs-13);font-variant-numeric:tabular-nums;user-select:none;justify-content:center;align-items:center;display:flex}.A5-U5q_option:hover:not(.A5-U5q_disabled):not(.A5-U5q_selected){background:var(--dsw-alias-interactive-bg-hover)}.A5-U5q_selected{color:var(--dsw-alias-label-primary-foreground);background:var(--dsw-alias-button-primary-fill)}.A5-U5q_selected:hover{background:var(--dsw-alias-button-primary-hover)}.A5-U5q_placeholder{background:var(--dsw-alias-bg-multi-select)}.A5-U5q_list:focus-visible [data-active]{box-shadow:inset 0 0 0 1px var(--dsw-alias-state-business-primary)}.A5-U5q_disabled{color:var(--dsw-alias-label-dimmed);cursor:not-allowed;text-decoration:line-through}";
18
+ document.head.appendChild(element);
19
+ }
20
+ var TimePicker_module_default = { "column": "A5-U5q_column", "selected": "A5-U5q_selected", "heading": "A5-U5q_heading", "option": "A5-U5q_option", "list": "A5-U5q_list", "placeholder": "A5-U5q_placeholder", "disabled": "A5-U5q_disabled", "picker": "A5-U5q_picker" };
21
+
22
+ // src/seekbuddy/date/TimePicker.tsx
23
+ import { jsx, jsxs } from "react/jsx-runtime";
24
+ var pad2 = (value) => String(value).padStart(2, "0");
25
+ function TimePicker({
26
+ value,
27
+ onChange,
28
+ minuteStep = 1,
29
+ min,
30
+ max,
31
+ labels,
32
+ autoFocus = false,
33
+ className
34
+ }) {
35
+ const idBase = useId();
36
+ const optionRefs = useRef(/* @__PURE__ */ new Map());
37
+ const hoursRef = useRef(null);
38
+ const pendingAutoFocus = useRef(autoFocus);
39
+ const parsed = value === null ? { h: 0, min: 0 } : parseIsoTime(value);
40
+ const lower = min === void 0 ? 0 : timeToMinutes(min);
41
+ const upper = max === void 0 ? 1439 : timeToMinutes(max);
42
+ const inWindow = (minutes2) => minutes2 >= lower && minutes2 <= upper;
43
+ const hours = Array.from({ length: 24 }, (_, hour) => hour);
44
+ const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, index) => index * minuteStep);
45
+ const emit = (h, m) => {
46
+ const next = clampTime(minutesToTime(h * 60 + m), min, max);
47
+ if (next !== value) onChange(next);
48
+ };
49
+ const columns = [
50
+ {
51
+ kind: "hours",
52
+ label: labels.hours,
53
+ options: hours,
54
+ cursor: parsed.h,
55
+ isDisabled: (hour) => !minutes.some((minute) => inWindow(hour * 60 + minute)),
56
+ pick: (hour) => emit(hour, parsed.min)
57
+ },
58
+ {
59
+ kind: "minutes",
60
+ label: labels.minutes,
61
+ options: minutes,
62
+ cursor: parsed.min,
63
+ isDisabled: (minute) => !inWindow(parsed.h * 60 + minute),
64
+ pick: (minute) => emit(parsed.h, minute)
65
+ }
66
+ ];
67
+ const optionId = (kind, option) => `${idBase}-${kind}-${option}`;
68
+ useEffect(() => {
69
+ for (const column of columns) {
70
+ const node = optionRefs.current.get(optionId(column.kind, column.cursor));
71
+ if (node !== void 0 && typeof node.scrollIntoView === "function") node.scrollIntoView({ block: "center" });
72
+ }
73
+ if (pendingAutoFocus.current) {
74
+ pendingAutoFocus.current = false;
75
+ hoursRef.current?.focus();
76
+ }
77
+ });
78
+ const onKeyDown = (column) => (event) => {
79
+ const enabled = column.options.filter((option) => !column.isDisabled(option));
80
+ if (enabled.length === 0) return;
81
+ let target;
82
+ if (event.key === "Home") target = enabled[0];
83
+ else if (event.key === "End") target = enabled[enabled.length - 1];
84
+ else if (event.key === "ArrowDown") target = enabled.find((option) => option > column.cursor);
85
+ else if (event.key === "ArrowUp") {
86
+ for (const option of enabled) if (option < column.cursor) target = option;
87
+ } else return;
88
+ event.preventDefault();
89
+ if (target !== void 0 && (target !== column.cursor || value === null)) column.pick(target);
90
+ };
91
+ return /* @__PURE__ */ jsx("div", { className: clsx(TimePicker_module_default.picker, className), children: columns.map((column) => {
92
+ const headingId = `${idBase}-${column.kind}-heading`;
93
+ return /* @__PURE__ */ jsxs("div", { className: TimePicker_module_default.column, children: [
94
+ /* @__PURE__ */ jsx("div", { id: headingId, className: TimePicker_module_default.heading, children: column.label }),
95
+ /* @__PURE__ */ jsx(
96
+ "ul",
97
+ {
98
+ ref: column.kind === "hours" ? hoursRef : void 0,
99
+ role: "listbox",
100
+ "aria-labelledby": headingId,
101
+ "aria-activedescendant": optionId(column.kind, column.cursor),
102
+ tabIndex: 0,
103
+ className: TimePicker_module_default.list,
104
+ onKeyDown: onKeyDown(column),
105
+ children: column.options.map((option) => {
106
+ const id2 = optionId(column.kind, option);
107
+ const disabled = column.isDisabled(option);
108
+ const active = column.cursor === option;
109
+ const selected = active && value !== null;
110
+ return /* @__PURE__ */ jsx(
111
+ "li",
112
+ {
113
+ id: id2,
114
+ ref: (node) => {
115
+ if (node === null) optionRefs.current.delete(id2);
116
+ else optionRefs.current.set(id2, node);
117
+ },
118
+ role: "option",
119
+ "aria-selected": selected,
120
+ "aria-disabled": disabled || void 0,
121
+ "data-active": active || void 0,
122
+ className: clsx(
123
+ TimePicker_module_default.option,
124
+ selected && TimePicker_module_default.selected,
125
+ active && !selected && TimePicker_module_default.placeholder,
126
+ disabled && TimePicker_module_default.disabled
127
+ ),
128
+ onClick: () => {
129
+ if (!disabled) column.pick(option);
130
+ },
131
+ children: pad2(option)
132
+ },
133
+ option
134
+ );
135
+ })
136
+ }
137
+ )
138
+ ] }, column.kind);
139
+ }) });
140
+ }
141
+
142
+ export {
143
+ TimePicker
144
+ };
@@ -0,0 +1,89 @@
1
+ import {
2
+ Calendar
3
+ } from "./chunk-XL33IPCV.js";
4
+ import {
5
+ formatDateMedium,
6
+ isOutsideBounds,
7
+ monthOf,
8
+ todayIso
9
+ } from "./chunk-RZOP2PFC.js";
10
+
11
+ // src/seekbuddy/date/DatePicker.tsx
12
+ import clsx from "clsx";
13
+ import { Button } from "@seekbuddy/dsh-ui";
14
+ import { useState } from "react";
15
+
16
+ // .build/css/seekbuddy/date/DatePicker.module.mjs
17
+ var id = "@seekbuddy/dsh-ui/seekbuddy/date/DatePicker.module.css";
18
+ if (typeof document !== "undefined" && !document.querySelector('style[data-dsh-ui-primitives="' + id + '"]')) {
19
+ const element = document.createElement("style");
20
+ element.setAttribute("data-dsh-ui-primitives", id);
21
+ element.textContent = "._41R-kq_picker{color:var(--dsw-alias-label-primary);gap:12px;display:inline-grid}._41R-kq_footer{border-top:.5px solid var(--dsw-alias-border-l1);justify-content:space-between;align-items:center;gap:12px;min-height:28px;padding-top:12px;display:flex}._41R-kq_summary{min-width:0;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xs-13);font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._41R-kq_empty{color:var(--dsw-alias-label-tertiary)}._41R-kq_today{color:var(--dsw-alias-state-business-primary);flex:none}._41R-kq_today:focus-visible{outline-offset:1px;outline-style:solid}";
22
+ document.head.appendChild(element);
23
+ }
24
+ var DatePicker_module_default = { "picker": "_41R-kq_picker", "summary": "_41R-kq_summary", "today": "_41R-kq_today", "footer": "_41R-kq_footer", "empty": "_41R-kq_empty" };
25
+
26
+ // src/seekbuddy/date/DatePicker.tsx
27
+ import { jsx, jsxs } from "react/jsx-runtime";
28
+ function DatePicker({
29
+ value,
30
+ onChange,
31
+ labels,
32
+ formatSelected,
33
+ month,
34
+ onMonthChange,
35
+ min,
36
+ max,
37
+ isDateDisabled,
38
+ locale,
39
+ today: todayProp,
40
+ className,
41
+ ...calendar
42
+ }) {
43
+ const [todayFallback] = useState(() => todayProp ?? todayIso());
44
+ const today = todayProp ?? todayFallback;
45
+ const [monthState, setMonthState] = useState(() => monthOf(value ?? today));
46
+ const [seenValue, setSeenValue] = useState(value);
47
+ if (value !== seenValue) {
48
+ setSeenValue(value);
49
+ if (value !== null && monthOf(value) !== monthState) setMonthState(monthOf(value));
50
+ }
51
+ const visibleMonth = month ?? monthState;
52
+ const showMonth = (next) => {
53
+ if (month === void 0) setMonthState(next);
54
+ onMonthChange?.(next);
55
+ };
56
+ const todayDisabled = isOutsideBounds(today, min, max) || (isDateDisabled?.(today) ?? false);
57
+ const pickToday = () => {
58
+ if (monthOf(today) !== visibleMonth) showMonth(monthOf(today));
59
+ onChange(today);
60
+ };
61
+ const format = formatSelected ?? ((date) => formatDateMedium(locale, date));
62
+ return /* @__PURE__ */ jsxs("div", { className: clsx(DatePicker_module_default.picker, className), children: [
63
+ /* @__PURE__ */ jsx(
64
+ Calendar,
65
+ {
66
+ ...calendar,
67
+ mode: "single",
68
+ value,
69
+ onChange,
70
+ month: visibleMonth,
71
+ onMonthChange: showMonth,
72
+ min,
73
+ max,
74
+ isDateDisabled,
75
+ locale,
76
+ today,
77
+ labels
78
+ }
79
+ ),
80
+ /* @__PURE__ */ jsxs("div", { className: DatePicker_module_default.footer, children: [
81
+ /* @__PURE__ */ jsx("span", { className: clsx(DatePicker_module_default.summary, value === null && DatePicker_module_default.empty), children: value === null ? labels.empty : format(value) }),
82
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: DatePicker_module_default.today, disabled: todayDisabled, onClick: pickToday, children: labels.today })
83
+ ] })
84
+ ] });
85
+ }
86
+
87
+ export {
88
+ DatePicker
89
+ };
@@ -0,0 +1,112 @@
1
+ // src/seekbuddy/Tabs.tsx
2
+ import clsx from "clsx";
3
+ import { useId, useRef } from "react";
4
+
5
+ // .build/css/seekbuddy/Tabs.module.mjs
6
+ var id = "@seekbuddy/dsh-ui/seekbuddy/Tabs.module.css";
7
+ if (typeof document !== "undefined" && !document.querySelector('style[data-dsh-ui-primitives="' + id + '"]')) {
8
+ const element = document.createElement("style");
9
+ element.setAttribute("data-dsh-ui-primitives", id);
10
+ element.textContent = '.XNMLKW_tabs{min-width:0;display:grid}.XNMLKW_tablist{min-height:41px;box-shadow:inset 0 -1px 0 var(--dsw-alias-border-l1);align-items:flex-end;gap:20px;display:flex;overflow-x:auto}.XNMLKW_tab{min-height:41px;color:var(--dsw-alias-label-tertiary);cursor:pointer;font:var(--dsw-font-xxs-12);white-space:nowrap;background:0 0;border:0;flex:none;align-items:center;gap:7px;padding:0 1px;font-weight:500;display:inline-flex;position:relative}.XNMLKW_md .XNMLKW_tab{font:var(--dsw-font-s-14);font-weight:500}.XNMLKW_lg .XNMLKW_tab{min-height:44px;font:var(--dsw-font-base-16);font-weight:500}.XNMLKW_bold .XNMLKW_tab{font:var(--dsw-font-xxs-strong-12)}.XNMLKW_bold.XNMLKW_md .XNMLKW_tab{font:var(--dsw-font-s-strong-14)}.XNMLKW_bold.XNMLKW_lg .XNMLKW_tab{font:var(--dsw-font-base-strong-16)}.XNMLKW_tab:hover:not(:disabled),.XNMLKW_active{color:var(--dsw-alias-label-primary)}.XNMLKW_active:after{content:"";background:var(--dsw-alias-state-business-primary);height:2px;position:absolute;bottom:0;left:0;right:0}.XNMLKW_tab:disabled{cursor:not-allowed;opacity:.5}.XNMLKW_tab:focus-visible{border-radius:var(--dsw-radius-xs);outline-offset:2px;outline-style:solid}.XNMLKW_count{border-radius:var(--dsw-radius-sm);min-width:20px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-interactive-bg-active);font:var(--dsw-font-xxxs-11);text-align:center;padding:1px 6px;font-weight:500}.XNMLKW_panel{min-width:0;color:var(--dsw-alias-label-primary);padding-top:16px}.XNMLKW_panel:focus-visible{border-radius:var(--dsw-radius-xs);outline-offset:2px;outline-style:solid}';
11
+ document.head.appendChild(element);
12
+ }
13
+ var Tabs_module_default = { "count": "XNMLKW_count", "tablist": "XNMLKW_tablist", "active": "XNMLKW_active", "md": "XNMLKW_md", "bold": "XNMLKW_bold", "lg": "XNMLKW_lg", "tabs": "XNMLKW_tabs", "tab": "XNMLKW_tab", "panel": "XNMLKW_panel" };
14
+
15
+ // src/seekbuddy/Tabs.tsx
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ var NEXT_KEYS = /* @__PURE__ */ new Set(["ArrowRight", "ArrowDown"]);
18
+ var PREVIOUS_KEYS = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowUp"]);
19
+ function Tabs({
20
+ label,
21
+ items,
22
+ activeKey,
23
+ onChange,
24
+ panelId,
25
+ size = "sm",
26
+ bold = false,
27
+ className
28
+ }) {
29
+ const generatedId = useId();
30
+ const buttons = useRef(/* @__PURE__ */ new Map());
31
+ const withPanels = items.some((item) => item.children !== void 0);
32
+ const idBase = panelId === void 0 || withPanels ? generatedId : panelId;
33
+ const tabId = (key) => `${idBase}-tab-${key}`;
34
+ const ownPanelId = (key) => `${idBase}-panel-${key}`;
35
+ const enabled = items.filter((item) => item.disabled !== true);
36
+ const selected = enabled.some((item) => item.key === activeKey) ? activeKey : enabled[0]?.key;
37
+ const active = items.find((item) => item.key === selected);
38
+ const move = (event) => {
39
+ if (enabled.length === 0) return;
40
+ const current = Math.max(
41
+ 0,
42
+ enabled.findIndex((item) => item.key === selected)
43
+ );
44
+ let next;
45
+ if (NEXT_KEYS.has(event.key)) next = (current + 1) % enabled.length;
46
+ else if (PREVIOUS_KEYS.has(event.key)) next = (current - 1 + enabled.length) % enabled.length;
47
+ else if (event.key === "Home") next = 0;
48
+ else if (event.key === "End") next = enabled.length - 1;
49
+ else return;
50
+ event.preventDefault();
51
+ const target = enabled[next];
52
+ if (target === void 0) return;
53
+ onChange(target.key);
54
+ buttons.current.get(target.key)?.focus();
55
+ };
56
+ const tablist = /* @__PURE__ */ jsx(
57
+ "div",
58
+ {
59
+ className: clsx(Tabs_module_default.tablist, Tabs_module_default[size], bold && Tabs_module_default.bold, !withPanels && className),
60
+ role: "tablist",
61
+ "aria-label": label,
62
+ onKeyDown: move,
63
+ children: items.map((item) => {
64
+ const isActive = item.key === selected;
65
+ return /* @__PURE__ */ jsxs(
66
+ "button",
67
+ {
68
+ ref: (node) => {
69
+ if (node === null) buttons.current.delete(item.key);
70
+ else buttons.current.set(item.key, node);
71
+ },
72
+ type: "button",
73
+ role: "tab",
74
+ id: tabId(item.key),
75
+ "aria-selected": isActive,
76
+ "aria-controls": withPanels ? ownPanelId(item.key) : panelId,
77
+ tabIndex: isActive ? 0 : -1,
78
+ disabled: item.disabled,
79
+ className: clsx(Tabs_module_default.tab, isActive && Tabs_module_default.active),
80
+ onClick: () => {
81
+ if (!isActive) onChange(item.key);
82
+ },
83
+ children: [
84
+ item.label,
85
+ item.count !== void 0 && /* @__PURE__ */ jsx("span", { className: Tabs_module_default.count, children: item.count })
86
+ ]
87
+ },
88
+ item.key
89
+ );
90
+ })
91
+ }
92
+ );
93
+ if (!withPanels) return tablist;
94
+ return /* @__PURE__ */ jsxs("div", { className: clsx(Tabs_module_default.tabs, className), children: [
95
+ tablist,
96
+ active !== void 0 && /* @__PURE__ */ jsx(
97
+ "div",
98
+ {
99
+ role: "tabpanel",
100
+ id: ownPanelId(active.key),
101
+ "aria-labelledby": tabId(active.key),
102
+ tabIndex: 0,
103
+ className: Tabs_module_default.panel,
104
+ children: active.children
105
+ }
106
+ )
107
+ ] });
108
+ }
109
+
110
+ export {
111
+ Tabs
112
+ };
@@ -0,0 +1,328 @@
1
+ // src/seekbuddy/Upload.tsx
2
+ import clsx from "clsx";
3
+ import {
4
+ useEffect,
5
+ useId,
6
+ useRef,
7
+ useState
8
+ } from "react";
9
+ import { Button } from "@seekbuddy/dsh-ui";
10
+ import {
11
+ IconCloseOutlineRegular,
12
+ IconPaperclipOutlineRegular,
13
+ IconRefreshOutlineRegular
14
+ } from "@seekbuddy/dsh-ui/icons";
15
+
16
+ // .build/css/seekbuddy/Upload.module.mjs
17
+ var id = "@seekbuddy/dsh-ui/seekbuddy/Upload.module.css";
18
+ if (typeof document !== "undefined" && !document.querySelector('style[data-dsh-ui-primitives="' + id + '"]')) {
19
+ const element = document.createElement("style");
20
+ element.setAttribute("data-dsh-ui-primitives", id);
21
+ element.textContent = "._8vfhUq_upload{flex-direction:column;gap:8px;display:flex}._8vfhUq_input{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute;overflow:hidden}._8vfhUq_trigger{flex-wrap:wrap;align-items:center;gap:12px;display:flex;position:relative}._8vfhUq_hint{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xs-13)}._8vfhUq_dropzone{box-sizing:border-box;border:1px dashed var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-lg);text-align:center;cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:4px;padding:24px;display:flex;position:relative}._8vfhUq_dropzone:hover:not(._8vfhUq_disabled){background:var(--dsw-alias-interactive-bg-hover)}._8vfhUq_dropzone:focus-visible{outline-offset:2px;outline-style:solid}._8vfhUq_dropIcon{color:var(--dsw-alias-label-tertiary);margin-bottom:4px;display:inline-flex}._8vfhUq_dropTitle{color:var(--dsw-alias-label-primary);font:var(--dsw-font-s-strong-14)}._8vfhUq_dragging{border-color:var(--dsw-alias-state-business-primary)}._8vfhUq_dragging ._8vfhUq_dropIcon,._8vfhUq_dragging ._8vfhUq_dropTitle{color:var(--dsw-alias-state-business-primary)}._8vfhUq_disabled{color:var(--dsw-alias-label-dimmed);cursor:not-allowed}._8vfhUq_disabled ._8vfhUq_dropIcon,._8vfhUq_disabled ._8vfhUq_dropTitle,._8vfhUq_disabled ._8vfhUq_hint{color:var(--dsw-alias-label-dimmed)}._8vfhUq_list{flex-direction:column;gap:2px;margin:0;padding:0;list-style:none;display:flex}._8vfhUq_item{border-radius:var(--dsw-radius-sm);grid-template-columns:auto minmax(0,1fr) auto;align-items:center;column-gap:8px;padding:6px 8px;display:grid}._8vfhUq_item:hover{background:var(--dsw-alias-interactive-bg-hover)}._8vfhUq_fileIcon{color:var(--dsw-alias-label-tertiary);display:inline-flex}._8vfhUq_name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font:var(--dsw-font-xs-13);text-align:left;overflow:hidden}._8vfhUq_nameButton{cursor:pointer;background:0 0;border:0;padding:0}._8vfhUq_nameButton:hover{text-decoration:underline}._8vfhUq_nameButton:focus-visible{outline-offset:2px;border-radius:var(--dsw-radius-xs);outline-style:solid}._8vfhUq_actions{gap:2px;display:flex}._8vfhUq_action{width:28px;min-width:28px;padding:0}._8vfhUq_meta{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxs-12);grid-column:2;gap:8px;display:flex}._8vfhUq_error ._8vfhUq_fileIcon,._8vfhUq_error ._8vfhUq_name,._8vfhUq_error ._8vfhUq_status{color:var(--dsw-alias-state-error-primary)}._8vfhUq_track{corner-shape:round;background:var(--dsw-alias-interactive-bg-active);border-radius:999px;grid-column:2/-1;height:2px;margin-top:4px;display:block;overflow:hidden}._8vfhUq_fill{background:var(--dsw-alias-state-business-primary);height:100%;display:block}";
22
+ document.head.appendChild(element);
23
+ }
24
+ var Upload_module_default = { "dropzone": "_8vfhUq_dropzone", "track": "_8vfhUq_track", "meta": "_8vfhUq_meta", "dropIcon": "_8vfhUq_dropIcon", "name": "_8vfhUq_name", "actions": "_8vfhUq_actions", "hint": "_8vfhUq_hint", "list": "_8vfhUq_list", "item": "_8vfhUq_item", "upload": "_8vfhUq_upload", "dropTitle": "_8vfhUq_dropTitle", "nameButton": "_8vfhUq_nameButton", "disabled": "_8vfhUq_disabled", "error": "_8vfhUq_error", "dragging": "_8vfhUq_dragging", "status": "_8vfhUq_status", "fill": "_8vfhUq_fill", "input": "_8vfhUq_input", "fileIcon": "_8vfhUq_fileIcon", "trigger": "_8vfhUq_trigger", "action": "_8vfhUq_action" };
25
+
26
+ // src/seekbuddy/Upload.tsx
27
+ import { jsx, jsxs } from "react/jsx-runtime";
28
+ function Upload({
29
+ layout = "button",
30
+ accept,
31
+ multiple = false,
32
+ maxCount,
33
+ maxSize,
34
+ disabled = false,
35
+ items,
36
+ defaultItems,
37
+ beforeUpload,
38
+ upload,
39
+ onChange,
40
+ onReject,
41
+ onRemove,
42
+ onPreview,
43
+ showList = true,
44
+ labels,
45
+ className
46
+ }) {
47
+ const [ownItems, setOwnItems] = useState(() => defaultItems ?? []);
48
+ const list = items ?? ownItems;
49
+ const latest = useRef(list);
50
+ latest.current = list;
51
+ const controllers = useRef(/* @__PURE__ */ new Map());
52
+ const mounted = useRef(true);
53
+ const sequence = useRef(0);
54
+ const input = useRef(null);
55
+ const [dragging, setDragging] = useState(false);
56
+ const dragDepth = useRef(0);
57
+ const prefix = useId();
58
+ useEffect(() => {
59
+ mounted.current = true;
60
+ const active = controllers.current;
61
+ return () => {
62
+ mounted.current = false;
63
+ for (const controller of active.values()) controller.abort();
64
+ active.clear();
65
+ };
66
+ }, []);
67
+ const commit = (next) => {
68
+ latest.current = next;
69
+ if (items === void 0) setOwnItems(next);
70
+ onChange?.(next);
71
+ };
72
+ const patch = (uid, change) => {
73
+ if (!mounted.current) return;
74
+ const index = latest.current.findIndex((item) => item.uid === uid);
75
+ if (index === -1) return;
76
+ const next = latest.current.slice();
77
+ next[index] = { ...next[index], ...change };
78
+ commit(next);
79
+ };
80
+ const start = (uid, file) => {
81
+ controllers.current.get(uid)?.abort();
82
+ const controller = new AbortController();
83
+ controllers.current.set(uid, controller);
84
+ patch(uid, { status: "uploading", percent: 0, error: void 0 });
85
+ upload(file, {
86
+ onProgress: (percent) => {
87
+ if (!controller.signal.aborted) patch(uid, { percent: Math.min(100, Math.max(0, Math.round(percent))) });
88
+ },
89
+ signal: controller.signal
90
+ }).then(
91
+ (response) => {
92
+ if (!controller.signal.aborted) patch(uid, { status: "done", percent: 100, response });
93
+ },
94
+ (reason) => {
95
+ if (!controller.signal.aborted) patch(uid, { status: "error", error: errorMessage(reason) });
96
+ }
97
+ );
98
+ };
99
+ const add = async (picked) => {
100
+ if (disabled) return;
101
+ const candidates = multiple ? picked : picked.slice(0, 1);
102
+ const rejections = [];
103
+ let accepted = [];
104
+ for (const file of candidates) {
105
+ if (accept !== void 0 && !matchesAccept(file, accept)) rejections.push({ file, reason: "accept" });
106
+ else if (maxSize !== void 0 && file.size > maxSize) rejections.push({ file, reason: "size" });
107
+ else accepted.push(file);
108
+ }
109
+ if (maxCount !== void 0) {
110
+ const room = maxCount === 1 ? 1 : Math.max(0, maxCount - latest.current.length);
111
+ for (const file of accepted.slice(room)) rejections.push({ file, reason: "count" });
112
+ accepted = accepted.slice(0, room);
113
+ }
114
+ if (rejections.length > 0) onReject?.(rejections);
115
+ if (beforeUpload !== void 0) {
116
+ const checks = await Promise.all(
117
+ accepted.map((file) => Promise.resolve(beforeUpload(file, accepted)).catch(() => false))
118
+ );
119
+ accepted = accepted.filter((_, index) => checks[index]);
120
+ }
121
+ if (accepted.length === 0 || !mounted.current) return;
122
+ const fresh = accepted.map((file) => {
123
+ sequence.current += 1;
124
+ return {
125
+ uid: `${prefix}-${sequence.current}`,
126
+ name: file.name,
127
+ size: file.size,
128
+ status: "uploading",
129
+ percent: 0,
130
+ file
131
+ };
132
+ });
133
+ if (maxCount === 1) {
134
+ for (const item of latest.current) controllers.current.get(item.uid)?.abort();
135
+ commit(fresh);
136
+ } else {
137
+ commit([...latest.current, ...fresh]);
138
+ }
139
+ for (const item of fresh) start(item.uid, item.file);
140
+ };
141
+ const remove = async (item) => {
142
+ if (onRemove !== void 0 && !await onRemove(item)) return;
143
+ controllers.current.get(item.uid)?.abort();
144
+ controllers.current.delete(item.uid);
145
+ commit(latest.current.filter((entry) => entry.uid !== item.uid));
146
+ };
147
+ const open = () => {
148
+ if (!disabled) input.current?.click();
149
+ };
150
+ const onInputChange = (event) => {
151
+ const files = [...event.target.files ?? []];
152
+ event.target.value = "";
153
+ void add(files);
154
+ };
155
+ const onKeyDown = (event) => {
156
+ if (event.key === "Enter" || event.key === " ") {
157
+ event.preventDefault();
158
+ open();
159
+ }
160
+ };
161
+ const onDragEnter = (event) => {
162
+ if (!hasFiles(event)) return;
163
+ event.preventDefault();
164
+ dragDepth.current += 1;
165
+ setDragging(true);
166
+ };
167
+ const onDragLeave = (event) => {
168
+ if (!hasFiles(event)) return;
169
+ dragDepth.current = Math.max(0, dragDepth.current - 1);
170
+ if (dragDepth.current === 0) setDragging(false);
171
+ };
172
+ const onDragOver = (event) => {
173
+ if (!hasFiles(event)) return;
174
+ event.preventDefault();
175
+ event.dataTransfer.dropEffect = disabled ? "none" : "copy";
176
+ };
177
+ const onDrop = (event) => {
178
+ if (!hasFiles(event)) return;
179
+ event.preventDefault();
180
+ dragDepth.current = 0;
181
+ setDragging(false);
182
+ void add([...event.dataTransfer.files]);
183
+ };
184
+ const picker = /* @__PURE__ */ jsx(
185
+ "input",
186
+ {
187
+ ref: input,
188
+ className: Upload_module_default.input,
189
+ type: "file",
190
+ tabIndex: -1,
191
+ accept,
192
+ multiple,
193
+ disabled,
194
+ onClick: (event) => event.stopPropagation(),
195
+ onChange: onInputChange
196
+ }
197
+ );
198
+ return /* @__PURE__ */ jsxs("div", { className: clsx(Upload_module_default.upload, className), children: [
199
+ layout === "dragger" ? /* @__PURE__ */ jsxs(
200
+ "div",
201
+ {
202
+ className: clsx(Upload_module_default.dropzone, dragging && Upload_module_default.dragging, disabled && Upload_module_default.disabled),
203
+ role: "button",
204
+ tabIndex: disabled ? -1 : 0,
205
+ "aria-disabled": disabled || void 0,
206
+ onClick: open,
207
+ onKeyDown,
208
+ onDragEnter,
209
+ onDragLeave,
210
+ onDragOver,
211
+ onDrop,
212
+ children: [
213
+ picker,
214
+ /* @__PURE__ */ jsx("span", { className: Upload_module_default.dropIcon, "aria-hidden": "true", children: /* @__PURE__ */ jsx(UploadGlyph, {}) }),
215
+ /* @__PURE__ */ jsx("span", { className: Upload_module_default.dropTitle, children: labels.trigger }),
216
+ labels.hint === void 0 ? null : /* @__PURE__ */ jsx("span", { className: Upload_module_default.hint, children: labels.hint })
217
+ ]
218
+ }
219
+ ) : /* @__PURE__ */ jsxs("div", { className: Upload_module_default.trigger, children: [
220
+ picker,
221
+ /* @__PURE__ */ jsx(Button, { variant: "outline", icon: /* @__PURE__ */ jsx(UploadGlyph, {}), disabled, onClick: open, children: labels.trigger }),
222
+ labels.hint === void 0 ? null : /* @__PURE__ */ jsx("span", { className: Upload_module_default.hint, children: labels.hint })
223
+ ] }),
224
+ showList && list.length > 0 ? /* @__PURE__ */ jsx("ul", { className: Upload_module_default.list, "aria-label": labels.list, children: list.map((item) => /* @__PURE__ */ jsxs("li", { className: clsx(Upload_module_default.item, Upload_module_default[item.status]), "data-status": item.status, children: [
225
+ /* @__PURE__ */ jsx("span", { className: Upload_module_default.fileIcon, "aria-hidden": "true", children: /* @__PURE__ */ jsx(IconPaperclipOutlineRegular, {}) }),
226
+ onPreview === void 0 ? /* @__PURE__ */ jsx("span", { className: Upload_module_default.name, children: item.name }) : /* @__PURE__ */ jsx("button", { type: "button", className: clsx(Upload_module_default.name, Upload_module_default.nameButton), onClick: () => onPreview(item), children: item.name }),
227
+ /* @__PURE__ */ jsxs("span", { className: Upload_module_default.actions, children: [
228
+ item.status === "error" && item.file !== void 0 ? /* @__PURE__ */ jsx(
229
+ Button,
230
+ {
231
+ variant: "ghost",
232
+ size: "sm",
233
+ className: Upload_module_default.action,
234
+ "aria-label": labels.retry,
235
+ disabled,
236
+ icon: /* @__PURE__ */ jsx(IconRefreshOutlineRegular, {}),
237
+ onClick: () => start(item.uid, item.file)
238
+ }
239
+ ) : null,
240
+ /* @__PURE__ */ jsx(
241
+ Button,
242
+ {
243
+ variant: "ghost",
244
+ size: "sm",
245
+ className: Upload_module_default.action,
246
+ "aria-label": labels.remove,
247
+ disabled,
248
+ icon: /* @__PURE__ */ jsx(IconCloseOutlineRegular, {}),
249
+ onClick: () => void remove(item)
250
+ }
251
+ )
252
+ ] }),
253
+ /* @__PURE__ */ jsxs("span", { className: Upload_module_default.meta, children: [
254
+ /* @__PURE__ */ jsx("span", { children: formatBytes(item.size) }),
255
+ /* @__PURE__ */ jsx("span", { className: Upload_module_default.status, role: "status", children: statusText(item, labels) })
256
+ ] }),
257
+ item.status === "uploading" ? /* @__PURE__ */ jsx(
258
+ "span",
259
+ {
260
+ className: Upload_module_default.track,
261
+ role: "progressbar",
262
+ "aria-label": labels.uploading,
263
+ "aria-valuemin": 0,
264
+ "aria-valuemax": 100,
265
+ "aria-valuenow": item.percent,
266
+ children: /* @__PURE__ */ jsx("span", { className: Upload_module_default.fill, style: { width: `${item.percent}%` } })
267
+ }
268
+ ) : null
269
+ ] }, item.uid)) }) : null
270
+ ] });
271
+ }
272
+ function statusText(item, labels) {
273
+ if (item.status === "uploading") return `${labels.uploading} ${item.percent}%`;
274
+ if (item.status === "error") return item.error === void 0 || item.error === "" ? labels.error : item.error;
275
+ return labels.done;
276
+ }
277
+ function errorMessage(reason) {
278
+ return reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "";
279
+ }
280
+ function matchesAccept(file, accept) {
281
+ const name = file.name.toLowerCase();
282
+ const type = file.type.toLowerCase();
283
+ return accept.split(",").map((rule) => rule.trim().toLowerCase()).filter((rule) => rule !== "").some((rule) => {
284
+ if (rule.startsWith(".")) return name.endsWith(rule);
285
+ if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
286
+ return type === rule;
287
+ });
288
+ }
289
+ function hasFiles(event) {
290
+ return [...event.dataTransfer?.types ?? []].includes("Files");
291
+ }
292
+ function formatBytes(bytes) {
293
+ if (bytes < 1024) return `${bytes} B`;
294
+ const units = ["KB", "MB", "GB"];
295
+ let value = bytes / 1024;
296
+ let unit = 0;
297
+ while (value >= 1024 && unit < units.length - 1) {
298
+ value /= 1024;
299
+ unit += 1;
300
+ }
301
+ return `${value.toFixed(1).replace(/\.0$/, "")} ${units[unit]}`;
302
+ }
303
+ function UploadGlyph() {
304
+ return /* @__PURE__ */ jsxs(
305
+ "svg",
306
+ {
307
+ width: 20,
308
+ height: 20,
309
+ viewBox: "0 0 24 24",
310
+ fill: "none",
311
+ stroke: "currentColor",
312
+ strokeWidth: "2",
313
+ strokeLinecap: "round",
314
+ strokeLinejoin: "round",
315
+ "aria-hidden": "true",
316
+ focusable: "false",
317
+ children: [
318
+ /* @__PURE__ */ jsx("path", { d: "M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3" }),
319
+ /* @__PURE__ */ jsx("path", { d: "M12 15V4" }),
320
+ /* @__PURE__ */ jsx("path", { d: "M7.5 8.5 12 4l4.5 4.5" })
321
+ ]
322
+ }
323
+ );
324
+ }
325
+
326
+ export {
327
+ Upload
328
+ };