@runlume/admin-ui 0.1.0 → 0.2.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 (286) hide show
  1. package/README.en.md +6 -13
  2. package/README.md +5 -11
  3. package/dist-package/_virtual/_rolldown/runtime.cjs +1 -0
  4. package/dist-package/admin-ui.cjs +1 -0
  5. package/dist-package/admin-ui.d.ts +41 -1
  6. package/dist-package/admin-ui.d.ts.map +1 -1
  7. package/dist-package/admin-ui.js +79 -0
  8. package/dist-package/components/calendar.cjs +1 -0
  9. package/dist-package/components/calendar.d.ts +13 -0
  10. package/dist-package/components/calendar.d.ts.map +1 -0
  11. package/dist-package/components/calendar.js +91 -0
  12. package/dist-package/components/cascader.cjs +1 -0
  13. package/dist-package/components/cascader.d.ts +19 -0
  14. package/dist-package/components/cascader.d.ts.map +1 -0
  15. package/dist-package/components/cascader.js +85 -0
  16. package/dist-package/components/charts.cjs +1 -0
  17. package/dist-package/components/charts.d.ts +80 -0
  18. package/dist-package/components/charts.d.ts.map +1 -0
  19. package/dist-package/components/charts.js +374 -0
  20. package/dist-package/components/code-block.cjs +1 -0
  21. package/dist-package/components/code-block.d.ts +7 -0
  22. package/dist-package/components/code-block.d.ts.map +1 -0
  23. package/dist-package/components/code-block.js +47 -0
  24. package/dist-package/components/column-chart.cjs +1 -0
  25. package/dist-package/components/column-chart.d.ts +18 -0
  26. package/dist-package/components/column-chart.d.ts.map +1 -0
  27. package/dist-package/components/column-chart.js +89 -0
  28. package/dist-package/components/combobox.cjs +1 -0
  29. package/dist-package/components/combobox.d.ts +24 -0
  30. package/dist-package/components/combobox.d.ts.map +1 -0
  31. package/dist-package/components/combobox.js +111 -0
  32. package/dist-package/components/confirm-dialog.cjs +1 -0
  33. package/dist-package/components/confirm-dialog.d.ts +17 -0
  34. package/dist-package/components/confirm-dialog.d.ts.map +1 -0
  35. package/dist-package/components/confirm-dialog.js +44 -0
  36. package/dist-package/components/count-to.cjs +1 -0
  37. package/dist-package/components/count-to.d.ts +13 -0
  38. package/dist-package/components/count-to.d.ts.map +1 -0
  39. package/dist-package/components/count-to.js +36 -0
  40. package/dist-package/components/cursor-pagination.cjs +1 -0
  41. package/dist-package/components/cursor-pagination.d.ts +11 -0
  42. package/dist-package/components/cursor-pagination.d.ts.map +1 -0
  43. package/dist-package/components/cursor-pagination.js +39 -0
  44. package/dist-package/components/data-table.cjs +1 -0
  45. package/dist-package/components/data-table.d.ts +69 -0
  46. package/dist-package/components/data-table.d.ts.map +1 -0
  47. package/dist-package/components/data-table.js +377 -0
  48. package/dist-package/components/descriptions.cjs +1 -0
  49. package/dist-package/components/descriptions.d.ts +16 -0
  50. package/dist-package/components/descriptions.d.ts.map +1 -0
  51. package/dist-package/components/descriptions.js +28 -0
  52. package/dist-package/components/editable-table.cjs +1 -0
  53. package/dist-package/components/editable-table.d.ts +27 -0
  54. package/dist-package/components/editable-table.d.ts.map +1 -0
  55. package/dist-package/components/editable-table.js +212 -0
  56. package/dist-package/components/filter-presets.cjs +1 -0
  57. package/dist-package/components/filter-presets.d.ts +11 -0
  58. package/dist-package/components/filter-presets.d.ts.map +1 -0
  59. package/dist-package/components/filter-presets.js +17 -0
  60. package/dist-package/components/fixed-bar.cjs +1 -0
  61. package/dist-package/components/fixed-bar.d.ts +11 -0
  62. package/dist-package/components/fixed-bar.d.ts.map +1 -0
  63. package/dist-package/components/fixed-bar.js +18 -0
  64. package/dist-package/components/image-preview.cjs +1 -0
  65. package/dist-package/components/image-preview.d.ts +14 -0
  66. package/dist-package/components/image-preview.d.ts.map +1 -0
  67. package/dist-package/components/image-preview.js +166 -0
  68. package/dist-package/components/layout-container.cjs +1 -0
  69. package/dist-package/components/layout-container.d.ts +17 -0
  70. package/dist-package/components/layout-container.d.ts.map +1 -0
  71. package/dist-package/components/layout-container.js +85 -0
  72. package/dist-package/components/mention.cjs +1 -0
  73. package/dist-package/components/mention.d.ts +20 -0
  74. package/dist-package/components/mention.d.ts.map +1 -0
  75. package/dist-package/components/mention.js +126 -0
  76. package/dist-package/components/multi-select.cjs +1 -0
  77. package/dist-package/components/multi-select.d.ts +17 -0
  78. package/dist-package/components/multi-select.d.ts.map +1 -0
  79. package/dist-package/components/multi-select.js +126 -0
  80. package/dist-package/components/multi-step-loader.cjs +1 -0
  81. package/dist-package/components/multi-step-loader.d.ts +18 -0
  82. package/dist-package/components/multi-step-loader.d.ts.map +1 -0
  83. package/dist-package/components/multi-step-loader.js +38 -0
  84. package/dist-package/components/page-button.cjs +1 -0
  85. package/dist-package/components/page-button.d.ts +6 -0
  86. package/dist-package/components/page-button.d.ts.map +1 -0
  87. package/dist-package/components/page-button.js +24 -0
  88. package/dist-package/components/page-pager.cjs +1 -0
  89. package/dist-package/components/page-pager.d.ts +11 -0
  90. package/dist-package/components/page-pager.d.ts.map +1 -0
  91. package/dist-package/components/page-pager.js +51 -0
  92. package/dist-package/components/page.cjs +1 -0
  93. package/dist-package/components/page.d.ts +34 -0
  94. package/dist-package/components/page.d.ts.map +1 -0
  95. package/dist-package/components/page.js +208 -0
  96. package/dist-package/components/pagination-bar.cjs +1 -0
  97. package/dist-package/components/pagination-bar.d.ts +8 -0
  98. package/dist-package/components/pagination-bar.d.ts.map +1 -0
  99. package/dist-package/components/pagination-bar.js +23 -0
  100. package/dist-package/components/password-strength.cjs +1 -0
  101. package/dist-package/components/password-strength.d.ts +11 -0
  102. package/dist-package/components/password-strength.d.ts.map +1 -0
  103. package/dist-package/components/password-strength.js +70 -0
  104. package/dist-package/components/rate.cjs +1 -0
  105. package/dist-package/components/rate.d.ts +13 -0
  106. package/dist-package/components/rate.d.ts.map +1 -0
  107. package/dist-package/components/rate.js +56 -0
  108. package/dist-package/components/resizable-panel.cjs +1 -0
  109. package/dist-package/components/resizable-panel.d.ts +15 -0
  110. package/dist-package/components/resizable-panel.d.ts.map +1 -0
  111. package/dist-package/components/resizable-panel.js +56 -0
  112. package/dist-package/components/search-filters.cjs +1 -0
  113. package/dist-package/components/search-filters.d.ts +31 -0
  114. package/dist-package/components/search-filters.d.ts.map +1 -0
  115. package/dist-package/components/search-filters.js +110 -0
  116. package/dist-package/components/sortable-list.cjs +1 -0
  117. package/dist-package/components/sortable-list.d.ts +14 -0
  118. package/dist-package/components/sortable-list.d.ts.map +1 -0
  119. package/dist-package/components/sortable-list.js +48 -0
  120. package/dist-package/components/sparkline.cjs +1 -0
  121. package/dist-package/components/sparkline.d.ts +11 -0
  122. package/dist-package/components/sparkline.d.ts.map +1 -0
  123. package/dist-package/components/sparkline.js +50 -0
  124. package/dist-package/components/status-badge.cjs +1 -0
  125. package/dist-package/components/status-badge.d.ts +4 -0
  126. package/dist-package/components/status-badge.d.ts.map +1 -0
  127. package/dist-package/components/status-badge.js +28 -0
  128. package/dist-package/components/steps.cjs +1 -0
  129. package/dist-package/components/steps.d.ts +15 -0
  130. package/dist-package/components/steps.d.ts.map +1 -0
  131. package/dist-package/components/steps.js +41 -0
  132. package/dist-package/components/storage-box.cjs +1 -0
  133. package/dist-package/components/storage-box.d.ts +19 -0
  134. package/dist-package/components/storage-box.d.ts.map +1 -0
  135. package/dist-package/components/storage-box.js +153 -0
  136. package/dist-package/components/table-cell-overflow.cjs +1 -0
  137. package/dist-package/components/table-cell-overflow.d.ts +5 -0
  138. package/dist-package/components/table-cell-overflow.d.ts.map +1 -0
  139. package/dist-package/components/table-cell-overflow.js +31 -0
  140. package/dist-package/components/table-toolbar.cjs +1 -0
  141. package/dist-package/components/table-toolbar.d.ts +5 -0
  142. package/dist-package/components/table-toolbar.d.ts.map +1 -0
  143. package/dist-package/components/table-toolbar.js +11 -0
  144. package/dist-package/components/timeline.cjs +1 -0
  145. package/dist-package/components/timeline.d.ts +14 -0
  146. package/dist-package/components/timeline.d.ts.map +1 -0
  147. package/dist-package/components/timeline.js +40 -0
  148. package/dist-package/components/transfer.cjs +1 -0
  149. package/dist-package/components/transfer.d.ts +18 -0
  150. package/dist-package/components/transfer.d.ts.map +1 -0
  151. package/dist-package/components/transfer.js +98 -0
  152. package/dist-package/components/tree-table.cjs +1 -0
  153. package/dist-package/components/tree-table.d.ts +23 -0
  154. package/dist-package/components/tree-table.d.ts.map +1 -0
  155. package/dist-package/components/tree-table.js +53 -0
  156. package/dist-package/components/tree.cjs +1 -0
  157. package/dist-package/components/tree.d.ts +36 -0
  158. package/dist-package/components/tree.d.ts.map +1 -0
  159. package/dist-package/components/tree.js +204 -0
  160. package/dist-package/components/trend.cjs +1 -0
  161. package/dist-package/components/trend.d.ts +19 -0
  162. package/dist-package/components/trend.d.ts.map +1 -0
  163. package/dist-package/components/trend.js +18 -0
  164. package/dist-package/components/ui/alert-dialog.cjs +1 -0
  165. package/dist-package/components/ui/alert-dialog.js +57 -0
  166. package/dist-package/components/ui/alert.cjs +1 -0
  167. package/dist-package/components/ui/alert.js +63 -0
  168. package/dist-package/components/ui/avatar.cjs +1 -0
  169. package/dist-package/components/ui/avatar.js +27 -0
  170. package/dist-package/components/ui/badge.cjs +1 -0
  171. package/dist-package/components/ui/badge.js +40 -0
  172. package/dist-package/components/ui/breadcrumb.cjs +1 -0
  173. package/dist-package/components/ui/breadcrumb.js +70 -0
  174. package/dist-package/components/ui/button.cjs +1 -0
  175. package/dist-package/components/ui/button.js +58 -0
  176. package/dist-package/components/ui/card.cjs +1 -0
  177. package/dist-package/components/ui/card.js +55 -0
  178. package/dist-package/components/ui/checkbox.cjs +1 -0
  179. package/dist-package/components/ui/checkbox.js +19 -0
  180. package/dist-package/components/ui/collapsible.cjs +1 -0
  181. package/dist-package/components/ui/collapsible.js +32 -0
  182. package/dist-package/components/ui/context-menu.cjs +1 -0
  183. package/dist-package/components/ui/context-menu.js +46 -0
  184. package/dist-package/components/ui/date-input.cjs +1 -0
  185. package/dist-package/components/ui/date-input.js +183 -0
  186. package/dist-package/components/ui/date-range-input.cjs +1 -0
  187. package/dist-package/components/ui/date-range-input.js +209 -0
  188. package/dist-package/components/ui/date-time-input.cjs +1 -0
  189. package/dist-package/components/ui/date-time-input.js +23 -0
  190. package/dist-package/components/ui/dialog.cjs +1 -0
  191. package/dist-package/components/ui/dialog.js +189 -0
  192. package/dist-package/components/ui/dropdown-menu.cjs +1 -0
  193. package/dist-package/components/ui/dropdown-menu.js +124 -0
  194. package/dist-package/components/ui/file-upload.cjs +1 -0
  195. package/dist-package/components/ui/file-upload.js +160 -0
  196. package/dist-package/components/ui/hover-card.cjs +1 -0
  197. package/dist-package/components/ui/hover-card.js +28 -0
  198. package/dist-package/components/ui/input-otp.cjs +1 -0
  199. package/dist-package/components/ui/input-otp.js +33 -0
  200. package/dist-package/components/ui/input.cjs +1 -0
  201. package/dist-package/components/ui/input.js +65 -0
  202. package/dist-package/components/ui/kbd.cjs +1 -0
  203. package/dist-package/components/ui/kbd.js +20 -0
  204. package/dist-package/components/ui/label.cjs +1 -0
  205. package/dist-package/components/ui/label.js +14 -0
  206. package/dist-package/components/ui/native-select.cjs +1 -0
  207. package/dist-package/components/ui/native-select.js +125 -0
  208. package/dist-package/components/ui/number-field.cjs +1 -0
  209. package/dist-package/components/ui/number-field.js +50 -0
  210. package/dist-package/components/ui/progress.cjs +1 -0
  211. package/dist-package/components/ui/progress.js +28 -0
  212. package/dist-package/components/ui/radio-group.cjs +1 -0
  213. package/dist-package/components/ui/radio-group.js +27 -0
  214. package/dist-package/components/ui/scroll-area.cjs +1 -0
  215. package/dist-package/components/ui/scroll-area.js +25 -0
  216. package/dist-package/components/ui/select.cjs +1 -0
  217. package/dist-package/components/ui/select.js +23 -0
  218. package/dist-package/components/ui/separator.cjs +1 -0
  219. package/dist-package/components/ui/separator.js +17 -0
  220. package/dist-package/components/ui/sheet.cjs +1 -0
  221. package/dist-package/components/ui/sheet.js +86 -0
  222. package/dist-package/components/ui/sidebar.cjs +1 -0
  223. package/dist-package/components/ui/sidebar.js +350 -0
  224. package/dist-package/components/ui/skeleton.cjs +1 -0
  225. package/dist-package/components/ui/skeleton.js +12 -0
  226. package/dist-package/components/ui/slider.cjs +1 -0
  227. package/dist-package/components/ui/slider.js +36 -0
  228. package/dist-package/components/ui/switch.cjs +1 -0
  229. package/dist-package/components/ui/switch.js +14 -0
  230. package/dist-package/components/ui/table.cjs +1 -0
  231. package/dist-package/components/ui/table.js +66 -0
  232. package/dist-package/components/ui/tabs.cjs +1 -0
  233. package/dist-package/components/ui/tabs.js +47 -0
  234. package/dist-package/components/ui/tag-variants.cjs +1 -0
  235. package/dist-package/components/ui/tag-variants.js +15 -0
  236. package/dist-package/components/ui/tag.cjs +1 -0
  237. package/dist-package/components/ui/tag.js +31 -0
  238. package/dist-package/components/ui/textarea.cjs +1 -0
  239. package/dist-package/components/ui/textarea.js +13 -0
  240. package/dist-package/components/ui/time-input.cjs +1 -0
  241. package/dist-package/components/ui/time-input.js +89 -0
  242. package/dist-package/components/ui/tooltip.cjs +1 -0
  243. package/dist-package/components/ui/tooltip.js +35 -0
  244. package/dist-package/hooks/use-mobile.cjs +1 -0
  245. package/dist-package/hooks/use-mobile.js +11 -0
  246. package/dist-package/lib/dialog-focus.cjs +1 -0
  247. package/dist-package/lib/dialog-focus.js +10 -0
  248. package/dist-package/lib/metrics.cjs +1 -0
  249. package/dist-package/lib/metrics.d.ts +18 -0
  250. package/dist-package/lib/metrics.d.ts.map +1 -0
  251. package/dist-package/lib/metrics.js +22 -0
  252. package/dist-package/lib/pager.cjs +1 -0
  253. package/dist-package/lib/pager.d.ts +8 -0
  254. package/dist-package/lib/pager.d.ts.map +1 -0
  255. package/dist-package/lib/pager.js +18 -0
  256. package/dist-package/lib/password.cjs +1 -0
  257. package/dist-package/lib/password.d.ts +14 -0
  258. package/dist-package/lib/password.d.ts.map +1 -0
  259. package/dist-package/lib/password.js +34 -0
  260. package/dist-package/lib/presets.cjs +1 -0
  261. package/dist-package/lib/presets.d.ts +25 -0
  262. package/dist-package/lib/presets.d.ts.map +1 -0
  263. package/dist-package/lib/presets.js +48 -0
  264. package/dist-package/lib/range.cjs +1 -0
  265. package/dist-package/lib/range.js +57 -0
  266. package/dist-package/lib/storage-key.cjs +1 -0
  267. package/dist-package/lib/storage-key.d.ts +2 -0
  268. package/dist-package/lib/storage-key.d.ts.map +1 -0
  269. package/dist-package/lib/storage-key.js +6 -0
  270. package/dist-package/lib/table-prefs.cjs +1 -0
  271. package/dist-package/lib/table-prefs.d.ts +17 -0
  272. package/dist-package/lib/table-prefs.d.ts.map +1 -0
  273. package/dist-package/lib/table-prefs.js +64 -0
  274. package/dist-package/lib/tree.cjs +1 -0
  275. package/dist-package/lib/tree.d.ts +37 -0
  276. package/dist-package/lib/tree.d.ts.map +1 -0
  277. package/dist-package/lib/tree.js +57 -0
  278. package/dist-package/lib/use-ui-translation.cjs +1 -0
  279. package/dist-package/lib/use-ui-translation.d.ts +15 -0
  280. package/dist-package/lib/use-ui-translation.d.ts.map +1 -0
  281. package/dist-package/lib/use-ui-translation.js +65 -0
  282. package/dist-package/lib/utils.cjs +1 -0
  283. package/dist-package/lib/utils.js +8 -0
  284. package/dist-package/styles.css +1 -1
  285. package/package.json +25 -15
  286. package/dist-package/index.js +0 -12212
@@ -0,0 +1,212 @@
1
+ import { cn as e } from "../lib/utils.js";
2
+ import { Button as t } from "./ui/button.js";
3
+ import { useUiTranslation as n } from "../lib/use-ui-translation.js";
4
+ import { Input as r } from "./ui/input.js";
5
+ import { NativeSelect as i } from "./ui/native-select.js";
6
+ import { Switch as a } from "./ui/switch.js";
7
+ import { Table as o, TableBody as s, TableCell as c, TableHead as l, TableHeader as u, TableRow as d } from "./ui/table.js";
8
+ import { useEffect as f, useRef as p, useState as m } from "react";
9
+ import { Check as h, Plus as g, SquarePen as _, Trash2 as v, X as y } from "lucide-react";
10
+ import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
11
+ //#region src/components/editable-table.tsx
12
+ function C({ id: e, column: t, index: o, value: s, onChange: c }) {
13
+ let { t: l } = n(), u = l("editableTable.cellLabel", {
14
+ column: t.label,
15
+ index: o + 1
16
+ });
17
+ switch (t.type) {
18
+ case "select": return /* @__PURE__ */ S(i, {
19
+ id: e,
20
+ "aria-label": u,
21
+ value: s,
22
+ onChange: (e) => c(e.target.value),
23
+ children: [/* @__PURE__ */ x("option", {
24
+ value: "",
25
+ children: l("editableTable.emptyCell")
26
+ }), t.options?.map((e) => /* @__PURE__ */ x("option", {
27
+ value: e.value,
28
+ children: e.label
29
+ }, e.value))]
30
+ });
31
+ case "switch": return /* @__PURE__ */ x(a, {
32
+ id: e,
33
+ "aria-label": u,
34
+ checked: s === "true",
35
+ onCheckedChange: (e) => c(e ? "true" : "false")
36
+ });
37
+ case "date":
38
+ case "number": return /* @__PURE__ */ x(r, {
39
+ id: e,
40
+ type: t.type,
41
+ className: "h-9",
42
+ "aria-label": u,
43
+ placeholder: t.placeholder,
44
+ value: s,
45
+ onChange: (e) => c(e.target.value)
46
+ });
47
+ default: return /* @__PURE__ */ x(r, {
48
+ id: e,
49
+ className: "h-9",
50
+ "aria-label": u,
51
+ placeholder: t.placeholder,
52
+ value: s,
53
+ onChange: (e) => c(e.target.value)
54
+ });
55
+ }
56
+ }
57
+ function w({ column: t, value: r }) {
58
+ let { t: i } = n();
59
+ if (t.type === "switch") return /* @__PURE__ */ x("span", {
60
+ className: e("text-sm", r !== "true" && "text-muted-foreground"),
61
+ children: i(r === "true" ? "editableTable.on" : "editableTable.off")
62
+ });
63
+ let a = t.type === "select" ? t.options?.find((e) => e.value === r)?.label : r;
64
+ return /* @__PURE__ */ x("span", {
65
+ className: e(!a && "text-muted-foreground"),
66
+ children: a || i("editableTable.emptyCell")
67
+ });
68
+ }
69
+ function T({ columns: r, defaultRows: i = [], onChange: a, maxRows: T, stickyActions: E = !0, className: D }) {
70
+ let { t: O } = n(), [k, A] = m(() => i.map((e) => ({
71
+ ...e,
72
+ editing: !1,
73
+ draft: e.values,
74
+ isNew: !1
75
+ }))), j = p(0), M = p(null);
76
+ f(() => {
77
+ if (!M.current) return;
78
+ let e = r[0], t = e ? document.getElementById(`${M.current}-${e.key}`) : null;
79
+ M.current = null, t instanceof HTMLInputElement && t.focus();
80
+ });
81
+ function N(e) {
82
+ A(e), a?.(e.map(({ id: e, values: t }) => ({
83
+ id: e,
84
+ values: t
85
+ })));
86
+ }
87
+ function P() {
88
+ j.current += 1;
89
+ let e = `new-${j.current}`;
90
+ M.current = e, N([...k, {
91
+ id: e,
92
+ values: {},
93
+ draft: {},
94
+ editing: !0,
95
+ isNew: !0
96
+ }]);
97
+ }
98
+ function F(e) {
99
+ N(k.map((t) => t.id === e ? {
100
+ ...t,
101
+ editing: !0,
102
+ draft: t.values
103
+ } : t));
104
+ }
105
+ function I(e) {
106
+ N(k.map((t) => t.id === e ? {
107
+ ...t,
108
+ editing: !1,
109
+ values: t.draft,
110
+ isNew: !1
111
+ } : t));
112
+ }
113
+ function L(e) {
114
+ if (k.find((t) => t.id === e)?.isNew) {
115
+ N(k.filter((t) => t.id !== e));
116
+ return;
117
+ }
118
+ N(k.map((t) => t.id === e ? {
119
+ ...t,
120
+ editing: !1,
121
+ draft: t.values
122
+ } : t));
123
+ }
124
+ function R(e) {
125
+ N(k.filter((t) => t.id !== e));
126
+ }
127
+ function z(e, t, n) {
128
+ A((r) => r.map((r) => r.id === e ? {
129
+ ...r,
130
+ draft: {
131
+ ...r.draft,
132
+ [t]: n
133
+ }
134
+ } : r));
135
+ }
136
+ return /* @__PURE__ */ x("div", {
137
+ className: e("data-table flex flex-col overflow-hidden rounded-lg border border-table-border bg-card", "[&>[data-slot=table-container]]:overflow-x-auto", "[&_[data-slot=table-header]]:sticky [&_[data-slot=table-header]]:top-0 [&_[data-slot=table-header]]:z-10", T && "[&>[data-slot=table-container]]:max-h-(--editable-table-max-height)", D),
138
+ style: T ? { "--editable-table-max-height": `${T * 45 + 45}px` } : void 0,
139
+ children: /* @__PURE__ */ S(o, { children: [/* @__PURE__ */ x(u, { children: /* @__PURE__ */ S(d, { children: [r.map((e) => /* @__PURE__ */ x(l, { children: e.label }, e.key)), /* @__PURE__ */ x(l, {
140
+ className: e("w-px whitespace-nowrap text-left", E && "sticky right-0 z-10 border-l border-table-border bg-table-header"),
141
+ children: O("sample.columnActions")
142
+ })] }) }), /* @__PURE__ */ S(s, { children: [k.map((n, i) => /* @__PURE__ */ S(d, {
143
+ className: "group/row",
144
+ "data-editing": n.editing || void 0,
145
+ children: [r.map((e) => /* @__PURE__ */ x(c, {
146
+ className: "align-middle",
147
+ children: n.editing ? /* @__PURE__ */ x(C, {
148
+ id: `${n.id}-${e.key}`,
149
+ column: e,
150
+ index: i,
151
+ value: n.draft[e.key] ?? "",
152
+ onChange: (t) => z(n.id, e.key, t)
153
+ }) : /* @__PURE__ */ x(w, {
154
+ column: e,
155
+ value: n.values[e.key] ?? ""
156
+ })
157
+ }, e.key)), /* @__PURE__ */ x(c, {
158
+ className: e(E && "sticky right-0 z-10 border-l border-table-border bg-card group-hover/row:bg-table-hover"),
159
+ children: /* @__PURE__ */ x("div", {
160
+ className: "flex justify-start gap-2",
161
+ children: n.editing ? /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(t, {
162
+ type: "button",
163
+ size: "icon-sm",
164
+ onClick: () => I(n.id),
165
+ "aria-label": O("editableTable.saveRow", { index: i + 1 }),
166
+ title: O("save"),
167
+ children: /* @__PURE__ */ x(h, { "aria-hidden": "true" })
168
+ }), /* @__PURE__ */ x(t, {
169
+ type: "button",
170
+ size: "icon-sm",
171
+ variant: "outline",
172
+ onClick: () => L(n.id),
173
+ "aria-label": O("editableTable.cancelRow", { index: i + 1 }),
174
+ title: O("cancel"),
175
+ children: /* @__PURE__ */ x(y, { "aria-hidden": "true" })
176
+ })] }) : /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(t, {
177
+ type: "button",
178
+ size: "icon-sm",
179
+ variant: "outline",
180
+ onClick: () => F(n.id),
181
+ "aria-label": O("editableTable.editRow", { index: i + 1 }),
182
+ title: O("editableTable.edit"),
183
+ children: /* @__PURE__ */ x(_, { "aria-hidden": "true" })
184
+ }), /* @__PURE__ */ x(t, {
185
+ type: "button",
186
+ size: "icon-sm",
187
+ variant: "outline",
188
+ className: "border-danger/25 bg-danger-soft text-danger hover:border-danger/40 hover:bg-danger/12 hover:text-danger",
189
+ onClick: () => R(n.id),
190
+ "aria-label": O("editableTable.removeRow", { index: i + 1 }),
191
+ title: O("editableTable.remove"),
192
+ children: /* @__PURE__ */ x(v, { "aria-hidden": "true" })
193
+ })] })
194
+ })
195
+ })]
196
+ }, n.id)), /* @__PURE__ */ x(d, { children: /* @__PURE__ */ x(c, {
197
+ colSpan: r.length + 1,
198
+ className: "p-0",
199
+ children: /* @__PURE__ */ S("button", {
200
+ type: "button",
201
+ onClick: P,
202
+ className: "flex h-11 w-full items-center justify-center gap-2 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
203
+ children: [/* @__PURE__ */ x(g, {
204
+ "aria-hidden": "true",
205
+ className: "size-4"
206
+ }), O("editableTable.addRow")]
207
+ })
208
+ }) })] })] })
209
+ });
210
+ }
211
+ //#endregion
212
+ export { T as EditableTable };
@@ -0,0 +1 @@
1
+ const e=require("../lib/use-ui-translation.cjs"),t=require("../lib/presets.cjs"),n=require("./storage-box.cjs");let r=require("react/jsx-runtime");function i({storageId:i,value:a,onApply:o,summary:s}){let{t:c}=e.useUiTranslation();return(0,r.jsx)(n.StorageBox,{title:c(`presets`),storageId:`filter.${i}`,snapshot:a,onRestore:o,summary:s??(e=>t.describePresetValue(e))})}exports.FilterPresets=i;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * 筛选预设:储物箱在"筛选条件"场景的语义化封装,保持既有调用方 API 不变。
3
+ */
4
+ export declare function FilterPresets<T>({ storageId, value, onApply, summary, }: {
5
+ storageId: string;
6
+ value: T;
7
+ onApply: (value: T) => void;
8
+ /** 列表里的摘要文案;不传时用通用格式化(键: 值 · 键: 值) */
9
+ summary?: (value: T) => string;
10
+ }): import("react").JSX.Element;
11
+ //# sourceMappingURL=filter-presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-presets.d.ts","sourceRoot":"","sources":["../../src/components/filter-presets.tsx"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,EAC/B,SAAS,EACT,KAAK,EACL,OAAO,EACP,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,CAAC,CAAA;IACR,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;IAC3B,sCAAsC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAA;CAC/B,+BAWA"}
@@ -0,0 +1,17 @@
1
+ import { useUiTranslation as e } from "../lib/use-ui-translation.js";
2
+ import { describePresetValue as t } from "../lib/presets.js";
3
+ import { StorageBox as n } from "./storage-box.js";
4
+ import { jsx as r } from "react/jsx-runtime";
5
+ //#region src/components/filter-presets.tsx
6
+ function i({ storageId: i, value: a, onApply: o, summary: s }) {
7
+ let { t: c } = e();
8
+ return /* @__PURE__ */ r(n, {
9
+ title: c("presets"),
10
+ storageId: `filter.${i}`,
11
+ snapshot: a,
12
+ onRestore: o,
13
+ summary: s ?? ((e) => t(e))
14
+ });
15
+ }
16
+ //#endregion
17
+ export { i as FilterPresets };
@@ -0,0 +1 @@
1
+ const e=require("../lib/utils.cjs");let t=require("react/jsx-runtime");function n({children:n,hint:r,className:i}){return(0,t.jsxs)(`div`,{"data-slot":`fixed-bar`,className:e.cn(`sticky bottom-0 z-20 -mx-4 mt-6 flex flex-wrap items-center justify-between gap-3 border-t bg-background/95 px-4 py-3 backdrop-blur sm:-mx-6 sm:px-6`,i),children:[(0,t.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:r}),(0,t.jsx)(`div`,{className:`flex flex-wrap items-center gap-2`,children:n})]})}exports.FixedBar=n;
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ /**
3
+ * 页面底部固定操作条。
4
+ * 长表单或详情页把保存、取消放在这里,滚动时始终可见。
5
+ */
6
+ export declare function FixedBar({ children, hint, className, }: {
7
+ children: ReactNode;
8
+ hint?: ReactNode;
9
+ className?: string;
10
+ }): import("react").JSX.Element;
11
+ //# sourceMappingURL=fixed-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixed-bar.d.ts","sourceRoot":"","sources":["../../src/components/fixed-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,IAAI,EACJ,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAA;IACnB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,+BAaA"}
@@ -0,0 +1,18 @@
1
+ import { cn as e } from "../lib/utils.js";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ //#region src/components/fixed-bar.tsx
4
+ function r({ children: r, hint: i, className: a }) {
5
+ return /* @__PURE__ */ n("div", {
6
+ "data-slot": "fixed-bar",
7
+ className: e("sticky bottom-0 z-20 -mx-4 mt-6 flex flex-wrap items-center justify-between gap-3 border-t bg-background/95 px-4 py-3 backdrop-blur sm:-mx-6 sm:px-6", a),
8
+ children: [/* @__PURE__ */ t("span", {
9
+ className: "text-xs text-muted-foreground",
10
+ children: i
11
+ }), /* @__PURE__ */ t("div", {
12
+ className: "flex flex-wrap items-center gap-2",
13
+ children: r
14
+ })]
15
+ });
16
+ }
17
+ //#endregion
18
+ export { r as FixedBar };
@@ -0,0 +1 @@
1
+ const e=require("../lib/utils.cjs"),t=require("./ui/button.cjs"),n=require("../lib/use-ui-translation.cjs"),r=require("./ui/dialog.cjs");let i=require("react"),a=require("lucide-react"),o=require("react/jsx-runtime");function s({src:s,alt:c,images:l,children:u}){let{t:d}=n.useUiTranslation(),[f,p]=(0,i.useState)(!1),m=l?.length?l:[{src:s,alt:c}],[h,g]=(0,i.useState)(0),[_,v]=(0,i.useState)(1),[y,b]=(0,i.useState)({x:0,y:0}),x=(0,i.useRef)(null),S=m[Math.min(h,m.length-1)]??{src:s,alt:c};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(`button`,{type:`button`,"aria-label":`${d(`imagePreview.open`)} ${c}`,className:`rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-ring/40`,onClick:()=>p(!0),children:u??(0,o.jsx)(`img`,{src:s,alt:c,className:`max-h-32 rounded-lg border`})}),(0,o.jsx)(r.Dialog,{open:f,onOpenChange:e=>{p(e),e||(v(1),b({x:0,y:0}))},children:(0,o.jsxs)(r.DialogContent,{className:`h-[min(88dvh,56rem)] grid-rows-[1fr] overflow-hidden p-0 sm:max-w-[min(92vw,80rem)] [&_[data-slot=dialog-close]]:top-5 [&_[data-slot=dialog-close]]:right-5 [&_[data-slot=dialog-close]]:rounded-md [&_[data-slot=dialog-close]]:p-2`,children:[(0,o.jsx)(r.DialogTitle,{className:`sr-only`,children:S.alt}),(0,o.jsx)(r.DialogDescription,{className:`sr-only`,children:d(`imagePreview.hint`)}),(0,o.jsxs)(`div`,{className:`absolute top-4 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1 rounded-xl border bg-background/90 p-1.5 shadow-sm backdrop-blur`,children:[(0,o.jsx)(t.Button,{type:`button`,variant:`outline`,size:`icon-sm`,"aria-label":d(`imagePreview.zoomOut`),disabled:_<=.5,onClick:()=>{v(e=>Math.max(.5,e-.25)),b({x:0,y:0})},children:(0,o.jsx)(a.Minus,{"aria-hidden":`true`})}),(0,o.jsxs)(`span`,{className:`w-12 text-center text-xs tabular-nums text-muted-foreground`,children:[Math.round(_*100),`%`]}),(0,o.jsx)(t.Button,{type:`button`,variant:`outline`,size:`icon-sm`,"aria-label":d(`imagePreview.zoomIn`),disabled:_>=3,onClick:()=>v(e=>Math.min(3,e+.25)),children:(0,o.jsx)(a.Plus,{"aria-hidden":`true`})}),(0,o.jsx)(t.Button,{type:`button`,variant:`outline`,size:`icon-sm`,"aria-label":d(`imagePreview.resetZoom`),onClick:()=>{v(1),b({x:0,y:0})},children:(0,o.jsx)(a.RotateCcw,{"aria-hidden":`true`})})]}),(0,o.jsx)(`div`,{className:`flex min-h-0 items-center justify-center overflow-hidden px-6 pt-20 pb-6`,children:(0,o.jsx)(`img`,{src:S.src,alt:S.alt,style:{scale:String(_),translate:`${y.x}px ${y.y}px`},draggable:!1,onPointerDown:e=>{_<=1||(e.currentTarget.setPointerCapture(e.pointerId),x.current={x:e.clientX,y:e.clientY,origin:y})},onPointerMove:e=>{x.current&&b({x:x.current.origin.x+(e.clientX-x.current.x),y:x.current.origin.y+(e.clientY-x.current.y)})},onPointerUp:()=>{x.current=null},onDoubleClick:()=>{v(e=>e===1?2:1),b({x:0,y:0})},className:e.cn(`h-full w-full select-none rounded-lg object-contain transition-transform`,_>1&&`cursor-grab active:cursor-grabbing`)})}),m.length>1&&(0,o.jsxs)(`div`,{className:`absolute inset-x-6 bottom-4 flex items-center justify-between gap-3 rounded-xl border bg-background/90 p-2 shadow-sm backdrop-blur`,children:[(0,o.jsx)(t.Button,{type:`button`,variant:`outline`,size:`sm`,disabled:h===0,onClick:()=>g(e=>Math.max(0,e-1)),children:d(`previous`)}),(0,o.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:d(`imagePreview.position`,{current:h+1,total:m.length})}),(0,o.jsx)(t.Button,{type:`button`,variant:`outline`,size:`sm`,disabled:h>=m.length-1,onClick:()=>g(e=>Math.min(m.length-1,e+1)),children:d(`next`)})]}),(0,o.jsx)(`p`,{className:`sr-only`,children:(0,o.jsx)(a.Maximize2,{"aria-hidden":`true`})})]})})]})}exports.ImagePreview=s;
@@ -0,0 +1,14 @@
1
+ import { type ReactNode } from 'react';
2
+ /** 图片预览:点击缩略图放大,Esc 关闭。 */
3
+ export declare function ImagePreview({ src, alt, images, children, }: {
4
+ src: string;
5
+ alt: string;
6
+ /** 传入多张图时可在预览里左右切换;不传则只看 src。 */
7
+ images?: {
8
+ src: string;
9
+ alt: string;
10
+ }[];
11
+ /** 缩略图内容,默认直接渲染图片。 */
12
+ children?: ReactNode;
13
+ }): import("react").JSX.Element;
14
+ //# sourceMappingURL=image-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-preview.d.ts","sourceRoot":"","sources":["../../src/components/image-preview.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOxD,2BAA2B;AAC3B,wBAAgB,YAAY,CAAC,EAC3B,GAAG,EACH,GAAG,EACH,MAAM,EACN,QAAQ,GACT,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,iCAAiC;IACjC,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACvC,sBAAsB;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,+BAuIA"}
@@ -0,0 +1,166 @@
1
+ import { cn as e } from "../lib/utils.js";
2
+ import { Button as t } from "./ui/button.js";
3
+ import { useUiTranslation as n } from "../lib/use-ui-translation.js";
4
+ import { Dialog as r, DialogContent as i, DialogDescription as a, DialogTitle as o } from "./ui/dialog.js";
5
+ import { useRef as s, useState as c } from "react";
6
+ import { Maximize2 as l, Minus as u, Plus as d, RotateCcw as f } from "lucide-react";
7
+ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
8
+ //#region src/components/image-preview.tsx
9
+ function g({ src: g, alt: _, images: v, children: y }) {
10
+ let { t: b } = n(), [x, S] = c(!1), C = v?.length ? v : [{
11
+ src: g,
12
+ alt: _
13
+ }], [w, T] = c(0), [E, D] = c(1), [O, k] = c({
14
+ x: 0,
15
+ y: 0
16
+ }), A = s(null), j = C[Math.min(w, C.length - 1)] ?? {
17
+ src: g,
18
+ alt: _
19
+ };
20
+ return /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("button", {
21
+ type: "button",
22
+ "aria-label": `${b("imagePreview.open")} ${_}`,
23
+ className: "rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-ring/40",
24
+ onClick: () => S(!0),
25
+ children: y ?? /* @__PURE__ */ m("img", {
26
+ src: g,
27
+ alt: _,
28
+ className: "max-h-32 rounded-lg border"
29
+ })
30
+ }), /* @__PURE__ */ m(r, {
31
+ open: x,
32
+ onOpenChange: (e) => {
33
+ S(e), e || (D(1), k({
34
+ x: 0,
35
+ y: 0
36
+ }));
37
+ },
38
+ children: /* @__PURE__ */ h(i, {
39
+ className: "h-[min(88dvh,56rem)] grid-rows-[1fr] overflow-hidden p-0 sm:max-w-[min(92vw,80rem)] [&_[data-slot=dialog-close]]:top-5 [&_[data-slot=dialog-close]]:right-5 [&_[data-slot=dialog-close]]:rounded-md [&_[data-slot=dialog-close]]:p-2",
40
+ children: [
41
+ /* @__PURE__ */ m(o, {
42
+ className: "sr-only",
43
+ children: j.alt
44
+ }),
45
+ /* @__PURE__ */ m(a, {
46
+ className: "sr-only",
47
+ children: b("imagePreview.hint")
48
+ }),
49
+ /* @__PURE__ */ h("div", {
50
+ className: "absolute top-4 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1 rounded-xl border bg-background/90 p-1.5 shadow-sm backdrop-blur",
51
+ children: [
52
+ /* @__PURE__ */ m(t, {
53
+ type: "button",
54
+ variant: "outline",
55
+ size: "icon-sm",
56
+ "aria-label": b("imagePreview.zoomOut"),
57
+ disabled: E <= .5,
58
+ onClick: () => {
59
+ D((e) => Math.max(.5, e - .25)), k({
60
+ x: 0,
61
+ y: 0
62
+ });
63
+ },
64
+ children: /* @__PURE__ */ m(u, { "aria-hidden": "true" })
65
+ }),
66
+ /* @__PURE__ */ h("span", {
67
+ className: "w-12 text-center text-xs tabular-nums text-muted-foreground",
68
+ children: [Math.round(E * 100), "%"]
69
+ }),
70
+ /* @__PURE__ */ m(t, {
71
+ type: "button",
72
+ variant: "outline",
73
+ size: "icon-sm",
74
+ "aria-label": b("imagePreview.zoomIn"),
75
+ disabled: E >= 3,
76
+ onClick: () => D((e) => Math.min(3, e + .25)),
77
+ children: /* @__PURE__ */ m(d, { "aria-hidden": "true" })
78
+ }),
79
+ /* @__PURE__ */ m(t, {
80
+ type: "button",
81
+ variant: "outline",
82
+ size: "icon-sm",
83
+ "aria-label": b("imagePreview.resetZoom"),
84
+ onClick: () => {
85
+ D(1), k({
86
+ x: 0,
87
+ y: 0
88
+ });
89
+ },
90
+ children: /* @__PURE__ */ m(f, { "aria-hidden": "true" })
91
+ })
92
+ ]
93
+ }),
94
+ /* @__PURE__ */ m("div", {
95
+ className: "flex min-h-0 items-center justify-center overflow-hidden px-6 pt-20 pb-6",
96
+ children: /* @__PURE__ */ m("img", {
97
+ src: j.src,
98
+ alt: j.alt,
99
+ style: {
100
+ scale: String(E),
101
+ translate: `${O.x}px ${O.y}px`
102
+ },
103
+ draggable: !1,
104
+ onPointerDown: (e) => {
105
+ E <= 1 || (e.currentTarget.setPointerCapture(e.pointerId), A.current = {
106
+ x: e.clientX,
107
+ y: e.clientY,
108
+ origin: O
109
+ });
110
+ },
111
+ onPointerMove: (e) => {
112
+ A.current && k({
113
+ x: A.current.origin.x + (e.clientX - A.current.x),
114
+ y: A.current.origin.y + (e.clientY - A.current.y)
115
+ });
116
+ },
117
+ onPointerUp: () => {
118
+ A.current = null;
119
+ },
120
+ onDoubleClick: () => {
121
+ D((e) => e === 1 ? 2 : 1), k({
122
+ x: 0,
123
+ y: 0
124
+ });
125
+ },
126
+ className: e("h-full w-full select-none rounded-lg object-contain transition-transform", E > 1 && "cursor-grab active:cursor-grabbing")
127
+ })
128
+ }),
129
+ C.length > 1 && /* @__PURE__ */ h("div", {
130
+ className: "absolute inset-x-6 bottom-4 flex items-center justify-between gap-3 rounded-xl border bg-background/90 p-2 shadow-sm backdrop-blur",
131
+ children: [
132
+ /* @__PURE__ */ m(t, {
133
+ type: "button",
134
+ variant: "outline",
135
+ size: "sm",
136
+ disabled: w === 0,
137
+ onClick: () => T((e) => Math.max(0, e - 1)),
138
+ children: b("previous")
139
+ }),
140
+ /* @__PURE__ */ m("span", {
141
+ className: "text-xs text-muted-foreground",
142
+ children: b("imagePreview.position", {
143
+ current: w + 1,
144
+ total: C.length
145
+ })
146
+ }),
147
+ /* @__PURE__ */ m(t, {
148
+ type: "button",
149
+ variant: "outline",
150
+ size: "sm",
151
+ disabled: w >= C.length - 1,
152
+ onClick: () => T((e) => Math.min(C.length - 1, e + 1)),
153
+ children: b("next")
154
+ })
155
+ ]
156
+ }),
157
+ /* @__PURE__ */ m("p", {
158
+ className: "sr-only",
159
+ children: /* @__PURE__ */ m(l, { "aria-hidden": "true" })
160
+ })
161
+ ]
162
+ })
163
+ })] });
164
+ }
165
+ //#endregion
166
+ export { g as ImagePreview };
@@ -0,0 +1 @@
1
+ const e=require("../lib/utils.cjs"),t=require("./ui/button.cjs"),n=require("../lib/use-ui-translation.cjs"),r=require("../lib/storage-key.cjs");let i=require("react"),a=require("lucide-react"),o=require("react/jsx-runtime");function s({children:s,aside:c,asideLabel:l,defaultCollapsed:u=!1,storageId:d,onWidthChange:f,className:p}){let{t:m}=n.useUiTranslation(),[h,g]=(0,i.useState)(u),[_,v]=(0,i.useState)(()=>{if(!d)return 288;let e=Number(localStorage.getItem(r.storageKey(`aside.${d}`)));return Number.isFinite(e)&&e>=200&&e<=560?e:288});(0,i.useEffect)(()=>{if(f?.(_),d)try{localStorage.setItem(r.storageKey(`aside.${d}`),String(_))}catch{}},[d,_,f]);let y=(0,i.useRef)(null),[b,x]=(0,i.useState)(!1);return(0,o.jsxs)(`div`,{"data-slot":`layout-container`,className:e.cn(`flex min-h-0 w-full gap-4`,p),children:[(0,o.jsx)(`div`,{className:`min-w-0 flex-1`,children:s}),c&&(0,o.jsxs)(`aside`,{"aria-label":l??m(`layoutContainer.aside`),style:{width:h?48:_},className:e.cn(`relative shrink-0 overflow-hidden border-l pl-4`,!b&&`transition-[width] duration-200`),children:[(0,o.jsx)(t.Button,{type:`button`,variant:`ghost`,size:`icon-sm`,"aria-expanded":!h,"aria-label":m(h?`layoutContainer.expand`:`layoutContainer.collapse`),onClick:()=>g(e=>!e),children:h?(0,o.jsx)(a.PanelLeftOpen,{"aria-hidden":`true`}):(0,o.jsx)(a.PanelLeftClose,{"aria-hidden":`true`})}),!h&&(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(`span`,{role:`separator`,"aria-orientation":`vertical`,"aria-label":m(`layoutContainer.resize`),"aria-valuenow":_,"aria-valuemin":200,"aria-valuemax":560,tabIndex:0,className:`absolute inset-y-0 left-0 w-1.5 cursor-col-resize hover:bg-primary/30`,onPointerDown:e=>{e.currentTarget.setPointerCapture(e.pointerId),y.current={x:e.clientX,width:_},x(!0)},onPointerMove:e=>{if(!y.current)return;let t=y.current.width-(e.clientX-y.current.x);v(Math.min(560,Math.max(200,t)))},onPointerUp:()=>{y.current=null,x(!1)},onDoubleClick:()=>v(288),onKeyDown:e=>{(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&(e.preventDefault(),v(t=>Math.min(560,Math.max(200,t+(e.key===`ArrowRight`?16:-16)))))}}),(0,o.jsx)(`div`,{className:`mt-3 space-y-3 text-sm`,children:c}),(0,o.jsx)(a.GripVertical,{"aria-hidden":`true`,className:`sr-only`})]})]})]})}exports.LayoutContainer=s;
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * 布局容器:主内容 + 可折叠侧栏(三栏详情常用右侧详情面板)。
4
+ * 侧栏折叠状态只影响当前视图,不写入偏好。
5
+ */
6
+ export declare function LayoutContainer({ children, aside, asideLabel, defaultCollapsed, storageId, onWidthChange, className, }: {
7
+ children: ReactNode;
8
+ aside?: ReactNode;
9
+ /** 侧栏的访问名称。 */
10
+ asideLabel?: string;
11
+ defaultCollapsed?: boolean;
12
+ /** 传入后把宽度保存在浏览器,并与业务共享当前宽度。 */
13
+ storageId?: string;
14
+ onWidthChange?: (width: number) => void;
15
+ className?: string;
16
+ }): import("react").JSX.Element;
17
+ //# sourceMappingURL=layout-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout-container.d.ts","sourceRoot":"","sources":["../../src/components/layout-container.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOnE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,KAAK,EACL,UAAU,EACV,gBAAwB,EACxB,SAAS,EACT,aAAa,EACb,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,eAAe;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,+BA6FA"}
@@ -0,0 +1,85 @@
1
+ import { cn as e } from "../lib/utils.js";
2
+ import { Button as t } from "./ui/button.js";
3
+ import { useUiTranslation as n } from "../lib/use-ui-translation.js";
4
+ import { storageKey as r } from "../lib/storage-key.js";
5
+ import { useEffect as i, useRef as a, useState as o } from "react";
6
+ import { GripVertical as s, PanelLeftClose as c, PanelLeftOpen as l } from "lucide-react";
7
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ //#region src/components/layout-container.tsx
9
+ function p({ children: p, aside: m, asideLabel: h, defaultCollapsed: g = !1, storageId: _, onWidthChange: v, className: y }) {
10
+ let { t: b } = n(), [x, S] = o(g), [C, w] = o(() => {
11
+ if (!_) return 288;
12
+ let e = Number(localStorage.getItem(r(`aside.${_}`)));
13
+ return Number.isFinite(e) && e >= 200 && e <= 560 ? e : 288;
14
+ });
15
+ i(() => {
16
+ if (v?.(C), _) try {
17
+ localStorage.setItem(r(`aside.${_}`), String(C));
18
+ } catch {}
19
+ }, [
20
+ _,
21
+ C,
22
+ v
23
+ ]);
24
+ let T = a(null), [E, D] = o(!1);
25
+ return /* @__PURE__ */ f("div", {
26
+ "data-slot": "layout-container",
27
+ className: e("flex min-h-0 w-full gap-4", y),
28
+ children: [/* @__PURE__ */ d("div", {
29
+ className: "min-w-0 flex-1",
30
+ children: p
31
+ }), m && /* @__PURE__ */ f("aside", {
32
+ "aria-label": h ?? b("layoutContainer.aside"),
33
+ style: { width: x ? 48 : C },
34
+ className: e("relative shrink-0 overflow-hidden border-l pl-4", !E && "transition-[width] duration-200"),
35
+ children: [/* @__PURE__ */ d(t, {
36
+ type: "button",
37
+ variant: "ghost",
38
+ size: "icon-sm",
39
+ "aria-expanded": !x,
40
+ "aria-label": b(x ? "layoutContainer.expand" : "layoutContainer.collapse"),
41
+ onClick: () => S((e) => !e),
42
+ children: d(x ? l : c, { "aria-hidden": "true" })
43
+ }), !x && /* @__PURE__ */ f(u, { children: [
44
+ /* @__PURE__ */ d("span", {
45
+ role: "separator",
46
+ "aria-orientation": "vertical",
47
+ "aria-label": b("layoutContainer.resize"),
48
+ "aria-valuenow": C,
49
+ "aria-valuemin": 200,
50
+ "aria-valuemax": 560,
51
+ tabIndex: 0,
52
+ className: "absolute inset-y-0 left-0 w-1.5 cursor-col-resize hover:bg-primary/30",
53
+ onPointerDown: (e) => {
54
+ e.currentTarget.setPointerCapture(e.pointerId), T.current = {
55
+ x: e.clientX,
56
+ width: C
57
+ }, D(!0);
58
+ },
59
+ onPointerMove: (e) => {
60
+ if (!T.current) return;
61
+ let t = T.current.width - (e.clientX - T.current.x);
62
+ w(Math.min(560, Math.max(200, t)));
63
+ },
64
+ onPointerUp: () => {
65
+ T.current = null, D(!1);
66
+ },
67
+ onDoubleClick: () => w(288),
68
+ onKeyDown: (e) => {
69
+ (e.key === "ArrowLeft" || e.key === "ArrowRight") && (e.preventDefault(), w((t) => Math.min(560, Math.max(200, t + (e.key === "ArrowRight" ? 16 : -16)))));
70
+ }
71
+ }),
72
+ /* @__PURE__ */ d("div", {
73
+ className: "mt-3 space-y-3 text-sm",
74
+ children: m
75
+ }),
76
+ /* @__PURE__ */ d(s, {
77
+ "aria-hidden": "true",
78
+ className: "sr-only"
79
+ })
80
+ ] })]
81
+ })]
82
+ });
83
+ }
84
+ //#endregion
85
+ export { p as LayoutContainer };
@@ -0,0 +1 @@
1
+ const e=require("../lib/utils.cjs"),t=require("../lib/use-ui-translation.cjs");let n=require("react"),r=require("react/jsx-runtime"),i=require("pinyin-pro");var a=4,o=112;function s({value:s,onValueChange:c,options:l,trigger:u=`@`,label:d,placeholder:f,className:p}){let{t:m}=t.useUiTranslation(),h=(0,n.useRef)(null),[g,_]=(0,n.useState)(),[v,y]=(0,n.useState)(0),[b,x]=(0,n.useState)(`bottom`),S=l.filter(e=>g!==void 0&&(e.label.toLowerCase().includes(g.toLowerCase())||((0,i.match)(e.label,g,{continuous:!0})?.length??0)>0)),C=g!==void 0&&S.length>0;function w(){let e=window.getSelection();if(!e?.rangeCount)return;let t=e.anchorNode;if(!t||t.nodeType!==Node.TEXT_NODE)return;let n=(t.textContent??``).slice(0,e.anchorOffset),r=n.lastIndexOf(u);if(!(r<0||n.slice(r+u.length).includes(` `)))return n.slice(r+u.length)}function T(){c(h.current?.textContent??``),_(w()),y(0)}function E(){let e=h.current?.getBoundingClientRect();if(!e)return;let t=window.innerHeight-e.bottom-a,n=e.top-a;x(t<o&&n>t?`top`:`bottom`)}function D(e){let t=window.getSelection(),n=t?.anchorNode;if(!t||!n||n.nodeType!==Node.TEXT_NODE)return;let r=n.textContent??``,i=t.anchorOffset,a=r.slice(0,i).lastIndexOf(u);if(a<0)return;let o=document.createRange();o.setStart(n,a),o.setEnd(n,i),o.deleteContents();let s=document.createElement(`span`);s.dataset.mention=e.value,s.contentEditable=`false`,s.className=`mention-tag`,s.textContent=`${u}${e.label}`;let c=document.createTextNode(`\xA0`);o.insertNode(c),o.insertNode(s);let l=document.createRange();l.setStart(c,c.length),l.collapse(!0),t.removeAllRanges(),t.addRange(l),_(void 0),window.requestAnimationFrame(()=>{T(),h.current?.focus()})}function O(e){if(e.key===`Backspace`&&!C){let t=window.getSelection();if(t?.isCollapsed&&t.anchorNode){let n=t.anchorNode.previousSibling;if(n instanceof HTMLElement&&n.dataset.mention){e.preventDefault(),n.remove(),T();return}if(t.anchorOffset===0&&t.anchorNode.parentElement?.dataset.mention){e.preventDefault(),t.anchorNode.parentElement.remove(),T();return}}}if(C){if(e.key===`ArrowDown`)e.preventDefault(),y((v+1)%S.length);else if(e.key===`ArrowUp`)e.preventDefault(),y((v-1+S.length)%S.length);else if(e.key===`Enter`){e.preventDefault();let t=S[v];t&&D(t)}else e.key===`Escape`&&_(void 0)}}return(0,n.useEffect)(()=>{if(C)return E(),window.addEventListener(`resize`,E),window.addEventListener(`scroll`,E,!0),()=>{window.removeEventListener(`resize`,E),window.removeEventListener(`scroll`,E,!0)}},[C]),(0,r.jsxs)(`div`,{"data-slot":`mention`,className:e.cn(`relative`,p),children:[(0,r.jsx)(`div`,{ref:h,role:`textbox`,"aria-multiline":`true`,"aria-label":d,contentEditable:!0,suppressContentEditableWarning:!0,"data-placeholder":f??m(`mention.placeholder`,{trigger:u}),className:`mention-editor min-h-20 w-full rounded-lg border border-input bg-card px-3.5 py-2 text-sm outline-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/20`,onInput:T,onKeyDown:O,onBlur:()=>_(void 0),onPaste:e=>{e.preventDefault();let t=e.clipboardData.getData(`text/plain`);document.execCommand(`insertText`,!1,t)}}),C&&(0,r.jsx)(`ul`,{role:`listbox`,"aria-label":m(`mention.title`),className:e.cn(`absolute z-30 max-h-48 w-64 overflow-y-auto rounded-lg border bg-popover p-1 shadow-md`,b===`top`?`bottom-full mb-1`:`top-full mt-1`),children:S.map((t,n)=>(0,r.jsx)(`li`,{children:(0,r.jsx)(`button`,{type:`button`,role:`option`,"aria-selected":n===v,className:e.cn(`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm`,n===v&&`bg-accent text-accent-foreground`),onMouseEnter:()=>y(n),onMouseDown:e=>e.preventDefault(),onClick:()=>D(t),children:(0,r.jsxs)(`span`,{className:`min-w-0 flex-1 truncate`,children:[(0,r.jsx)(`span`,{className:`block`,children:t.label}),t.description&&(0,r.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:t.description})]})})},t.value))}),(0,r.jsx)(`span`,{className:`sr-only`,children:s})]})}exports.Mention=s;
@@ -0,0 +1,20 @@
1
+ export type MentionOption = {
2
+ value: string;
3
+ label: string;
4
+ description?: string;
5
+ };
6
+ /**
7
+ * 提及输入:输入触发字符(默认 `@`)后弹出候选,
8
+ * 采纳后插入**内联标签**(不是纯文本),↑/↓ 选择、Enter 采纳、Esc 关闭。
9
+ * 用 contentEditable 承载,`value` 仍然是可以直接提交的纯文本。
10
+ */
11
+ export declare function Mention({ value, onValueChange, options, trigger, label, placeholder, className, }: {
12
+ value: string;
13
+ onValueChange: (value: string) => void;
14
+ options: MentionOption[];
15
+ trigger?: string;
16
+ label: string;
17
+ placeholder?: string;
18
+ className?: string;
19
+ }): import("react").JSX.Element;
20
+ //# sourceMappingURL=mention.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mention.d.ts","sourceRoot":"","sources":["../../src/components/mention.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAOlF;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,aAAa,EACb,OAAO,EACP,OAAa,EACb,KAAK,EACL,WAAW,EACX,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,+BAwLA"}