@wzrhine/react 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/LICENSE +21 -0
  3. package/README.md +37 -3
  4. package/dist/advanced.css +398 -0
  5. package/dist/archive.css +704 -0
  6. package/dist/command.css +671 -0
  7. package/dist/components/Accordion.d.ts +82 -0
  8. package/dist/components/Accordion.d.ts.map +1 -0
  9. package/dist/components/Accordion.js +19 -0
  10. package/dist/components/Accordion.js.map +1 -0
  11. package/dist/components/Alert.d.ts +60 -0
  12. package/dist/components/Alert.d.ts.map +1 -0
  13. package/dist/components/Alert.js +29 -0
  14. package/dist/components/Alert.js.map +1 -0
  15. package/dist/components/AlertDialog.d.ts +41 -0
  16. package/dist/components/AlertDialog.d.ts.map +1 -0
  17. package/dist/components/AlertDialog.js +101 -0
  18. package/dist/components/AlertDialog.js.map +1 -0
  19. package/dist/components/ArchiveCard.d.ts +58 -0
  20. package/dist/components/ArchiveCard.d.ts.map +1 -0
  21. package/dist/components/ArchiveCard.js +40 -0
  22. package/dist/components/ArchiveCard.js.map +1 -0
  23. package/dist/components/Breadcrumb.d.ts +48 -0
  24. package/dist/components/Breadcrumb.d.ts.map +1 -0
  25. package/dist/components/Breadcrumb.js +55 -0
  26. package/dist/components/Breadcrumb.js.map +1 -0
  27. package/dist/components/Button.d.ts +30 -0
  28. package/dist/components/Button.d.ts.map +1 -0
  29. package/dist/components/Button.js +24 -0
  30. package/dist/components/Button.js.map +1 -0
  31. package/dist/components/Checkbox.d.ts +81 -0
  32. package/dist/components/Checkbox.d.ts.map +1 -0
  33. package/dist/components/Checkbox.js +34 -0
  34. package/dist/components/Checkbox.js.map +1 -0
  35. package/dist/components/Collapsible.d.ts +47 -0
  36. package/dist/components/Collapsible.d.ts.map +1 -0
  37. package/dist/components/Collapsible.js +12 -0
  38. package/dist/components/Collapsible.js.map +1 -0
  39. package/dist/components/Combobox.d.ts +74 -0
  40. package/dist/components/Combobox.d.ts.map +1 -0
  41. package/dist/components/Combobox.js +61 -0
  42. package/dist/components/Combobox.js.map +1 -0
  43. package/dist/components/CommandPalette.d.ts +77 -0
  44. package/dist/components/CommandPalette.d.ts.map +1 -0
  45. package/dist/components/CommandPalette.js +150 -0
  46. package/dist/components/CommandPalette.js.map +1 -0
  47. package/dist/components/ContextMenu.d.ts +31 -0
  48. package/dist/components/ContextMenu.d.ts.map +1 -0
  49. package/dist/components/ContextMenu.js +25 -0
  50. package/dist/components/ContextMenu.js.map +1 -0
  51. package/dist/components/DataTable.d.ts +83 -0
  52. package/dist/components/DataTable.d.ts.map +1 -0
  53. package/dist/components/DataTable.js +97 -0
  54. package/dist/components/DataTable.js.map +1 -0
  55. package/dist/components/Dialog.d.ts +45 -0
  56. package/dist/components/Dialog.d.ts.map +1 -0
  57. package/dist/components/Dialog.js +46 -0
  58. package/dist/components/Dialog.js.map +1 -0
  59. package/dist/components/Drawer.d.ts +56 -0
  60. package/dist/components/Drawer.d.ts.map +1 -0
  61. package/dist/components/Drawer.js +92 -0
  62. package/dist/components/Drawer.js.map +1 -0
  63. package/dist/components/EmptyState.d.ts +39 -0
  64. package/dist/components/EmptyState.d.ts.map +1 -0
  65. package/dist/components/EmptyState.js +19 -0
  66. package/dist/components/EmptyState.js.map +1 -0
  67. package/dist/components/Field.d.ts +37 -0
  68. package/dist/components/Field.d.ts.map +1 -0
  69. package/dist/components/Field.js +12 -0
  70. package/dist/components/Field.js.map +1 -0
  71. package/dist/components/Fieldset.d.ts +24 -0
  72. package/dist/components/Fieldset.d.ts.map +1 -0
  73. package/dist/components/Fieldset.js +17 -0
  74. package/dist/components/Fieldset.js.map +1 -0
  75. package/dist/components/FileDropZone.d.ts +60 -0
  76. package/dist/components/FileDropZone.d.ts.map +1 -0
  77. package/dist/components/FileDropZone.js +121 -0
  78. package/dist/components/FileDropZone.js.map +1 -0
  79. package/dist/components/Form.d.ts +21 -0
  80. package/dist/components/Form.d.ts.map +1 -0
  81. package/dist/components/Form.js +20 -0
  82. package/dist/components/Form.js.map +1 -0
  83. package/dist/components/IconButton.d.ts +25 -0
  84. package/dist/components/IconButton.d.ts.map +1 -0
  85. package/dist/components/IconButton.js +14 -0
  86. package/dist/components/IconButton.js.map +1 -0
  87. package/dist/components/Input.d.ts +24 -0
  88. package/dist/components/Input.d.ts.map +1 -0
  89. package/dist/components/Input.js +15 -0
  90. package/dist/components/Input.js.map +1 -0
  91. package/dist/components/Menu.d.ts +66 -0
  92. package/dist/components/Menu.d.ts.map +1 -0
  93. package/dist/components/Menu.js +34 -0
  94. package/dist/components/Menu.js.map +1 -0
  95. package/dist/components/MetadataList.d.ts +51 -0
  96. package/dist/components/MetadataList.d.ts.map +1 -0
  97. package/dist/components/MetadataList.js +25 -0
  98. package/dist/components/MetadataList.js.map +1 -0
  99. package/dist/components/NumberField.d.ts +52 -0
  100. package/dist/components/NumberField.d.ts.map +1 -0
  101. package/dist/components/NumberField.js +21 -0
  102. package/dist/components/NumberField.js.map +1 -0
  103. package/dist/components/Pagination.d.ts +40 -0
  104. package/dist/components/Pagination.d.ts.map +1 -0
  105. package/dist/components/Pagination.js +64 -0
  106. package/dist/components/Pagination.js.map +1 -0
  107. package/dist/components/Popover.d.ts +44 -0
  108. package/dist/components/Popover.d.ts.map +1 -0
  109. package/dist/components/Popover.js +14 -0
  110. package/dist/components/Popover.js.map +1 -0
  111. package/dist/components/Progress.d.ts +57 -0
  112. package/dist/components/Progress.d.ts.map +1 -0
  113. package/dist/components/Progress.js +31 -0
  114. package/dist/components/Progress.js.map +1 -0
  115. package/dist/components/Radio.d.ts +61 -0
  116. package/dist/components/Radio.d.ts.map +1 -0
  117. package/dist/components/Radio.js +18 -0
  118. package/dist/components/Radio.js.map +1 -0
  119. package/dist/components/RecordHeader.d.ts +53 -0
  120. package/dist/components/RecordHeader.d.ts.map +1 -0
  121. package/dist/components/RecordHeader.js +19 -0
  122. package/dist/components/RecordHeader.js.map +1 -0
  123. package/dist/components/ScrollArea.d.ts +55 -0
  124. package/dist/components/ScrollArea.d.ts.map +1 -0
  125. package/dist/components/ScrollArea.js +63 -0
  126. package/dist/components/ScrollArea.js.map +1 -0
  127. package/dist/components/Select.d.ts +39 -0
  128. package/dist/components/Select.d.ts.map +1 -0
  129. package/dist/components/Select.js +24 -0
  130. package/dist/components/Select.js.map +1 -0
  131. package/dist/components/Separator.d.ts +26 -0
  132. package/dist/components/Separator.d.ts.map +1 -0
  133. package/dist/components/Separator.js +22 -0
  134. package/dist/components/Separator.js.map +1 -0
  135. package/dist/components/Skeleton.d.ts +31 -0
  136. package/dist/components/Skeleton.d.ts.map +1 -0
  137. package/dist/components/Skeleton.js +17 -0
  138. package/dist/components/Skeleton.js.map +1 -0
  139. package/dist/components/Slider.d.ts +65 -0
  140. package/dist/components/Slider.d.ts.map +1 -0
  141. package/dist/components/Slider.js +30 -0
  142. package/dist/components/Slider.js.map +1 -0
  143. package/dist/components/Spinner.d.ts +23 -0
  144. package/dist/components/Spinner.d.ts.map +1 -0
  145. package/dist/components/Spinner.js +13 -0
  146. package/dist/components/Spinner.js.map +1 -0
  147. package/dist/components/SplitButton.d.ts +59 -0
  148. package/dist/components/SplitButton.d.ts.map +1 -0
  149. package/dist/components/SplitButton.js +30 -0
  150. package/dist/components/SplitButton.js.map +1 -0
  151. package/dist/components/Stat.d.ts +53 -0
  152. package/dist/components/Stat.d.ts.map +1 -0
  153. package/dist/components/Stat.js +23 -0
  154. package/dist/components/Stat.js.map +1 -0
  155. package/dist/components/StatusBadge.d.ts +19 -0
  156. package/dist/components/StatusBadge.d.ts.map +1 -0
  157. package/dist/components/StatusBadge.js +8 -0
  158. package/dist/components/StatusBadge.js.map +1 -0
  159. package/dist/components/StatusIndicator.d.ts +29 -0
  160. package/dist/components/StatusIndicator.d.ts.map +1 -0
  161. package/dist/components/StatusIndicator.js +8 -0
  162. package/dist/components/StatusIndicator.js.map +1 -0
  163. package/dist/components/Surface.d.ts +29 -0
  164. package/dist/components/Surface.d.ts.map +1 -0
  165. package/dist/components/Surface.js +8 -0
  166. package/dist/components/Surface.js.map +1 -0
  167. package/dist/components/Switch.d.ts +22 -0
  168. package/dist/components/Switch.d.ts.map +1 -0
  169. package/dist/components/Switch.js +11 -0
  170. package/dist/components/Switch.js.map +1 -0
  171. package/dist/components/Tabs.d.ts +45 -0
  172. package/dist/components/Tabs.d.ts.map +1 -0
  173. package/dist/components/Tabs.js +49 -0
  174. package/dist/components/Tabs.js.map +1 -0
  175. package/dist/components/Text.d.ts +33 -0
  176. package/dist/components/Text.d.ts.map +1 -0
  177. package/dist/components/Text.js +21 -0
  178. package/dist/components/Text.js.map +1 -0
  179. package/dist/components/Textarea.d.ts +54 -0
  180. package/dist/components/Textarea.d.ts.map +1 -0
  181. package/dist/components/Textarea.js +31 -0
  182. package/dist/components/Textarea.js.map +1 -0
  183. package/dist/components/Timeline.d.ts +35 -0
  184. package/dist/components/Timeline.d.ts.map +1 -0
  185. package/dist/components/Timeline.js +13 -0
  186. package/dist/components/Timeline.js.map +1 -0
  187. package/dist/components/Toast.d.ts +67 -0
  188. package/dist/components/Toast.d.ts.map +1 -0
  189. package/dist/components/Toast.js +94 -0
  190. package/dist/components/Toast.js.map +1 -0
  191. package/dist/components/Tooltip.d.ts +26 -0
  192. package/dist/components/Tooltip.d.ts.map +1 -0
  193. package/dist/components/Tooltip.js +15 -0
  194. package/dist/components/Tooltip.js.map +1 -0
  195. package/dist/components/VisuallyHidden.d.ts +17 -0
  196. package/dist/components/VisuallyHidden.d.ts.map +1 -0
  197. package/dist/components/VisuallyHidden.js +12 -0
  198. package/dist/components/VisuallyHidden.js.map +1 -0
  199. package/dist/components/fieldParts.d.ts +17 -0
  200. package/dist/components/fieldParts.d.ts.map +1 -0
  201. package/dist/components/fieldParts.js +22 -0
  202. package/dist/components/fieldParts.js.map +1 -0
  203. package/dist/components/meter-utils.d.ts +15 -0
  204. package/dist/components/meter-utils.d.ts.map +1 -0
  205. package/dist/components/meter-utils.js +15 -0
  206. package/dist/components/meter-utils.js.map +1 -0
  207. package/dist/components/pagination-utils.d.ts +10 -0
  208. package/dist/components/pagination-utils.d.ts.map +1 -0
  209. package/dist/components/pagination-utils.js +36 -0
  210. package/dist/components/pagination-utils.js.map +1 -0
  211. package/dist/components.css +632 -0
  212. package/dist/data.css +600 -0
  213. package/dist/disclosure.css +93 -0
  214. package/dist/drawer.css +226 -0
  215. package/dist/feedback.css +454 -0
  216. package/dist/forms.css +516 -0
  217. package/dist/index.d.ts +117 -0
  218. package/dist/index.d.ts.map +1 -0
  219. package/dist/index.js +61 -0
  220. package/dist/index.js.map +1 -0
  221. package/dist/motion/lifecycle.d.ts +44 -0
  222. package/dist/motion/lifecycle.d.ts.map +1 -0
  223. package/dist/motion/lifecycle.js +73 -0
  224. package/dist/motion/lifecycle.js.map +1 -0
  225. package/dist/motion/presence.d.ts +69 -0
  226. package/dist/motion/presence.d.ts.map +1 -0
  227. package/dist/motion/presence.js +103 -0
  228. package/dist/motion/presence.js.map +1 -0
  229. package/dist/motion/presets.d.ts +63 -0
  230. package/dist/motion/presets.d.ts.map +1 -0
  231. package/dist/motion/presets.js +30 -0
  232. package/dist/motion/presets.js.map +1 -0
  233. package/dist/motion/resolve.d.ts +31 -0
  234. package/dist/motion/resolve.d.ts.map +1 -0
  235. package/dist/motion/resolve.js +40 -0
  236. package/dist/motion/resolve.js.map +1 -0
  237. package/dist/motion/useRhineMotion.d.ts +19 -0
  238. package/dist/motion/useRhineMotion.d.ts.map +1 -0
  239. package/dist/motion/useRhineMotion.js +19 -0
  240. package/dist/motion/useRhineMotion.js.map +1 -0
  241. package/dist/motion/visibility.d.ts +6 -0
  242. package/dist/motion/visibility.d.ts.map +1 -0
  243. package/dist/motion/visibility.js +31 -0
  244. package/dist/motion/visibility.js.map +1 -0
  245. package/dist/overlays.css +465 -0
  246. package/dist/provider/RhineProvider.d.ts +65 -0
  247. package/dist/provider/RhineProvider.d.ts.map +1 -0
  248. package/dist/provider/RhineProvider.js +26 -0
  249. package/dist/provider/RhineProvider.js.map +1 -0
  250. package/dist/provider/messages.d.ts +190 -0
  251. package/dist/provider/messages.d.ts.map +1 -0
  252. package/dist/provider/messages.js +160 -0
  253. package/dist/provider/messages.js.map +1 -0
  254. package/dist/provider/portal.d.ts +17 -0
  255. package/dist/provider/portal.d.ts.map +1 -0
  256. package/dist/provider/portal.js +20 -0
  257. package/dist/provider/portal.js.map +1 -0
  258. package/dist/reset.css +45 -0
  259. package/dist/split.css +159 -0
  260. package/dist/status.css +353 -0
  261. package/dist/utils/cx.d.ts +2 -0
  262. package/dist/utils/cx.d.ts.map +1 -0
  263. package/dist/utils/cx.js +4 -0
  264. package/dist/utils/cx.js.map +1 -0
  265. package/package.json +62 -3
@@ -0,0 +1,82 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Stacked disclosure sections on Base UI Accordion (ADR-0010 §2). Each header is a real heading
4
+ * (`headingLevel`, default 3) wrapping a `<button>` with `aria-expanded` / `aria-controls`; the
5
+ * panel is a labelled region. Height animates through Base UI's `--accordion-panel-height`
6
+ * (CSS transition, interruptible); reduced motion zeroes the duration token, so it snaps.
7
+ *
8
+ * Keyboard: Tab moves between triggers, Enter / Space toggles. Base UI 1.9 follows the updated
9
+ * APG guidance and no longer adds arrow-key roving focus between headers.
10
+ *
11
+ * <Accordion items={[{ value: 'scope', title: '适用范围', content: '…' }]} />
12
+ * <Accordion multiple defaultValue={['a']}>
13
+ * <AccordionItem value="a" title="采样">…</AccordionItem>
14
+ * </Accordion>
15
+ */
16
+ export type AccordionHeadingLevel = 2 | 3 | 4 | 5 | 6;
17
+ export interface AccordionItemData {
18
+ /** Stable identifier used by `value` / `defaultValue`. */
19
+ value: string;
20
+ title: React.ReactNode;
21
+ content: React.ReactNode;
22
+ /** Secondary text at the end of the trigger (count, status). Part of the button's name. */
23
+ meta?: React.ReactNode;
24
+ disabled?: boolean;
25
+ }
26
+ export type AccordionProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'defaultValue' | 'onChange'> & {
27
+ /** Convenience data form. Ignored when `children` is given. */
28
+ items?: readonly AccordionItemData[];
29
+ /** Composition form: `AccordionItem` elements. */
30
+ children?: React.ReactNode;
31
+ /** Allow more than one item open at a time (default: opening one closes the others). */
32
+ multiple?: boolean;
33
+ value?: string[];
34
+ defaultValue?: string[];
35
+ onValueChange?: (value: string[]) => void;
36
+ /** Heading element wrapping each trigger; pick the level that fits the page outline. */
37
+ headingLevel?: AccordionHeadingLevel;
38
+ disabled?: boolean;
39
+ /** Keep closed panels in the DOM (hidden). */
40
+ keepMounted?: boolean;
41
+ /** Closed panels use `hidden="until-found"` so browser find-in-page can open them. */
42
+ hiddenUntilFound?: boolean;
43
+ };
44
+ export type AccordionItemProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'children' | 'title' | 'onChange'> & {
45
+ value: string;
46
+ title: React.ReactNode;
47
+ meta?: React.ReactNode;
48
+ disabled?: boolean;
49
+ /** Overrides the parent Accordion's `headingLevel`. */
50
+ headingLevel?: AccordionHeadingLevel;
51
+ children?: React.ReactNode;
52
+ onOpenChange?: (open: boolean) => void;
53
+ };
54
+ export declare const AccordionItem: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "title" | "onChange"> & {
55
+ value: string;
56
+ title: React.ReactNode;
57
+ meta?: React.ReactNode;
58
+ disabled?: boolean;
59
+ /** Overrides the parent Accordion's `headingLevel`. */
60
+ headingLevel?: AccordionHeadingLevel;
61
+ children?: React.ReactNode;
62
+ onOpenChange?: (open: boolean) => void;
63
+ } & React.RefAttributes<HTMLDivElement>>;
64
+ export declare const Accordion: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "defaultValue" | "onChange"> & {
65
+ /** Convenience data form. Ignored when `children` is given. */
66
+ items?: readonly AccordionItemData[];
67
+ /** Composition form: `AccordionItem` elements. */
68
+ children?: React.ReactNode;
69
+ /** Allow more than one item open at a time (default: opening one closes the others). */
70
+ multiple?: boolean;
71
+ value?: string[];
72
+ defaultValue?: string[];
73
+ onValueChange?: (value: string[]) => void;
74
+ /** Heading element wrapping each trigger; pick the level that fits the page outline. */
75
+ headingLevel?: AccordionHeadingLevel;
76
+ disabled?: boolean;
77
+ /** Keep closed panels in the DOM (hidden). */
78
+ keepMounted?: boolean;
79
+ /** Closed panels use `hidden="until-found"` so browser find-in-page can open them. */
80
+ hiddenUntilFound?: boolean;
81
+ } & React.RefAttributes<HTMLDivElement>>;
82
+ //# sourceMappingURL=Accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../src/components/Accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,UAAU,CAAC,GAAG;IAClH,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrC,kDAAkD;IAClD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1C,wFAAwF;IACxF,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC,GAAG;IAC/G,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC,CAAC;AAYF,eAAO,MAAM,aAAa;WApBjB,MAAM;WACN,KAAK,CAAC,SAAS;WACf,KAAK,CAAC,SAAS;eACX,OAAO;IAClB,uDAAuD;mBACxC,qBAAqB;eACzB,KAAK,CAAC,SAAS;mBACX,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI;wCA0CtC,CAAC;AAEH,eAAO,MAAM,SAAS;IAtEpB,+DAA+D;YACvD,SAAS,iBAAiB,EAAE;IACpC,kDAAkD;eACvC,KAAK,CAAC,SAAS;IAC1B,wFAAwF;eAC7E,OAAO;YACV,MAAM,EAAE;mBACD,MAAM,EAAE;oBACP,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI;IACzC,wFAAwF;mBACzE,qBAAqB;eACzB,OAAO;IAClB,8CAA8C;kBAChC,OAAO;IACrB,sFAAsF;uBACnE,OAAO;wCAgG1B,CAAC"}
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { Accordion as BaseAccordion } from '@base-ui/react/accordion';
5
+ import { cx } from '../utils/cx.js';
6
+ const HeadingLevelContext = React.createContext(3);
7
+ function Chevron() {
8
+ return (_jsx("svg", { className: "rl-accordion__chevron", viewBox: "0 0 16 16", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "m4 6 4 4 4-4" }) }));
9
+ }
10
+ export const AccordionItem = React.forwardRef(function AccordionItem({ value, title, meta, disabled, headingLevel, children, onOpenChange, className, ...rest }, ref) {
11
+ const inheritedLevel = React.useContext(HeadingLevelContext);
12
+ const Heading = `h${headingLevel ?? inheritedLevel}`;
13
+ return (_jsxs(BaseAccordion.Item, { ...rest, ref: ref, value: value, disabled: disabled, onOpenChange: onOpenChange ? (open) => onOpenChange(open) : undefined, className: cx('rl-accordion__item', className), children: [_jsx(BaseAccordion.Header, { className: "rl-accordion__header", render: _jsx(Heading, {}), children: _jsxs(BaseAccordion.Trigger, { className: "rl-accordion__trigger", children: [_jsx("span", { className: "rl-accordion__title", children: title }), meta != null && ' ', meta != null && _jsx("span", { className: "rl-accordion__meta", children: meta }), _jsx(Chevron, {})] }) }), _jsx(BaseAccordion.Panel, { className: "rl-accordion__panel", children: _jsx("div", { className: "rl-accordion__content", children: children }) })] }));
14
+ });
15
+ export const Accordion = React.forwardRef(function Accordion({ items, children, multiple = false, value, defaultValue, onValueChange, headingLevel = 3, disabled, keepMounted, hiddenUntilFound, className, ...rest }, ref) {
16
+ return (_jsx(HeadingLevelContext.Provider, { value: headingLevel, children: _jsx(BaseAccordion.Root, { ...rest, ref: ref, multiple: multiple, value: value, defaultValue: defaultValue, onValueChange: onValueChange ? (next) => onValueChange([...next]) : undefined, disabled: disabled, keepMounted: keepMounted, hiddenUntilFound: hiddenUntilFound, className: cx('rl-accordion', className), "data-slot": "accordion", children: children ??
17
+ items?.map((item) => (_jsx(AccordionItem, { value: item.value, title: item.title, meta: item.meta, disabled: item.disabled, children: item.content }, item.value))) }) }));
18
+ });
19
+ //# sourceMappingURL=Accordion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.js","sourceRoot":"","sources":["../../src/components/Accordion.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * In-page status message and explanatory note (ADR-0006 §5). Tone is always carried by an
4
+ * icon and text as well as colour.
5
+ *
6
+ * `Alert` chooses its announcement explicitly with `live`: `off` (default; present on load,
7
+ * not announced), `polite` (`role="status"`) or `assertive` (`role="alert"`, failures only).
8
+ * Live regions announce changes, so render a polite Alert first and then change its content.
9
+ * One message, one live container: do not repeat it in a Toast. The role sits on the message
10
+ * text, so the action and dismiss buttons are not read out as part of the announcement.
11
+ * The component holds no hidden state: `onDismiss` renders a close button and the caller
12
+ * removes the Alert and moves focus somewhere sensible (e.g. the control that triggered it).
13
+ *
14
+ * <Alert tone="warning" title="3 条记录未通过校验" onDismiss={hide}>导出前请先修正。</Alert>
15
+ *
16
+ * `Callout` is a side note (`role="note"`): never live, never dismissible.
17
+ */
18
+ export type AlertTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
19
+ export type AlertLive = 'off' | 'polite' | 'assertive';
20
+ type BaseProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title' | 'role'> & {
21
+ tone?: AlertTone;
22
+ title?: React.ReactNode;
23
+ children?: React.ReactNode;
24
+ /** Replace the tone icon; `null` removes it. */
25
+ icon?: React.ReactNode;
26
+ };
27
+ export type AlertProps = BaseProps & {
28
+ live?: AlertLive;
29
+ /** Follow-up control(s), e.g. a small Button 「查看」. */
30
+ action?: React.ReactNode;
31
+ /** Shows a close button. The caller removes the Alert and places focus. */
32
+ onDismiss?: () => void;
33
+ /** Accessible name of the close button. */
34
+ dismissLabel?: string;
35
+ };
36
+ export type CalloutProps = BaseProps;
37
+ export declare const Alert: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "role" | "title"> & {
38
+ tone?: AlertTone;
39
+ title?: React.ReactNode;
40
+ children?: React.ReactNode;
41
+ /** Replace the tone icon; `null` removes it. */
42
+ icon?: React.ReactNode;
43
+ } & {
44
+ live?: AlertLive;
45
+ /** Follow-up control(s), e.g. a small Button 「查看」. */
46
+ action?: React.ReactNode;
47
+ /** Shows a close button. The caller removes the Alert and places focus. */
48
+ onDismiss?: () => void;
49
+ /** Accessible name of the close button. */
50
+ dismissLabel?: string;
51
+ } & React.RefAttributes<HTMLDivElement>>;
52
+ export declare const Callout: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "role" | "title"> & {
53
+ tone?: AlertTone;
54
+ title?: React.ReactNode;
55
+ children?: React.ReactNode;
56
+ /** Replace the tone icon; `null` removes it. */
57
+ icon?: React.ReactNode;
58
+ } & React.RefAttributes<HTMLDivElement>>;
59
+ export {};
60
+ //# sourceMappingURL=Alert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Alert.d.ts","sourceRoot":"","sources":["../../src/components/Alert.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC9E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,KAAK,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,GAAG;IAC9E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,gDAAgD;IAChD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACnC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,sDAAsD;IACtD,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC;AA2DrC,eAAO,MAAM,KAAK;WA5ET,SAAS;YACR,KAAK,CAAC,SAAS;eACZ,KAAK,CAAC,SAAS;IAC1B,gDAAgD;WACzC,KAAK,CAAC,SAAS;;WAIf,SAAS;IAChB,sDAAsD;aAC7C,KAAK,CAAC,SAAS;IACxB,2EAA2E;gBAC/D,MAAM,IAAI;IACtB,2CAA2C;mBAC5B,MAAM;wCA8ErB,CAAC;AAEH,eAAO,MAAM,OAAO;WA9FX,SAAS;YACR,KAAK,CAAC,SAAS;eACZ,KAAK,CAAC,SAAS;IAC1B,gDAAgD;WACzC,KAAK,CAAC,SAAS;wCAqGtB,CAAC"}
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { useRhineMessages } from '../provider/messages.js';
5
+ import { cx } from '../utils/cx.js';
6
+ import { IconButton } from './IconButton.js';
7
+ const liveRole = {
8
+ off: undefined,
9
+ polite: 'status',
10
+ assertive: 'alert',
11
+ };
12
+ /** Tone glyphs; same shapes as the Toast status icon so a status reads the same everywhere. */
13
+ function ToneIcon({ tone, className }) {
14
+ return (_jsxs("svg", { className: className, viewBox: "0 0 16 16", "aria-hidden": "true", focusable: "false", "data-tone": tone, children: [tone === 'success' && _jsx("path", { d: "m3.5 8.5 3 3 6-7" }), tone === 'danger' && _jsx("path", { d: "M5 5l6 6M11 5l-6 6" }), tone === 'warning' && _jsx("path", { d: "M8 2.5 14 13.5H2L8 2.5ZM8 7v2.5M8 11.5v.01" }), tone === 'info' && _jsx("path", { d: "M8 7.5V11.5M8 5v.01" }), tone === 'neutral' && _jsx("path", { d: "M4 8h8" })] }));
15
+ }
16
+ function CloseIcon() {
17
+ return (_jsx("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", focusable: "false", className: "rl-alert__close-icon", children: _jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) }));
18
+ }
19
+ function Message({ tone, icon, title, children, role, }) {
20
+ return (_jsxs("div", { className: "rl-alert__message", role: role, children: [icon === undefined ? (_jsx(ToneIcon, { tone: tone, className: "rl-alert__icon rl-alert__glyph" })) : icon === null ? null : (_jsx("span", { className: "rl-alert__icon", "aria-hidden": "true", children: icon })), _jsxs("div", { className: "rl-alert__text", children: [title != null && title !== false && _jsx("p", { className: "rl-alert__title", children: title }), children != null && children !== false && _jsx("div", { className: "rl-alert__body", children: children })] })] }));
21
+ }
22
+ export const Alert = React.forwardRef(function Alert({ tone = 'info', title, children, icon, live = 'off', action, onDismiss, dismissLabel, className, ...rest }, ref) {
23
+ const messages = useRhineMessages();
24
+ return (_jsxs("div", { ...rest, ref: ref, className: cx('rl-alert', className), "data-slot": "alert", "data-tone": tone, "data-live": live, children: [_jsx(Message, { tone: tone, icon: icon, title: title, role: liveRole[live], children: children }), action != null && _jsx("div", { className: "rl-alert__action", children: action }), onDismiss && (_jsx(IconButton, { className: "rl-alert__dismiss", size: "sm", variant: "ghost", icon: _jsx(CloseIcon, {}), label: dismissLabel ?? messages.alert.dismiss, onClick: onDismiss }))] }));
25
+ });
26
+ export const Callout = React.forwardRef(function Callout({ tone = 'info', title, children, icon, className, ...rest }, ref) {
27
+ return (_jsx("div", { ...rest, ref: ref, role: "note", className: cx('rl-alert', 'rl-callout', className), "data-slot": "callout", "data-tone": tone, children: _jsx(Message, { tone: tone, icon: icon, title: title, children: children }) }));
28
+ });
29
+ //# sourceMappingURL=Alert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Alert.js","sourceRoot":"","sources":["../../src/components/Alert.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Confirmation for destructive or irreversible actions (ADR-0006 §2) on Base UI AlertDialog:
4
+ * role="alertdialog", always modal, outside clicks never dismiss, Escape = cancel. Initial focus
5
+ * lands on the cancel button. `onConfirm` may return a Promise: while it is pending the confirm
6
+ * button shows `loading` (and keeps focus) and every way of cancelling is ignored; on resolve the
7
+ * dialog closes, on reject it stays open with `errorText` in a role="alert" message.
8
+ * Motion matches Dialog (backdrop fast, panel + 8px rise; opacity only when reduced).
9
+ */
10
+ export type AlertDialogTone = 'danger' | 'default';
11
+ export type AlertDialogProps = {
12
+ /** Element that opens the dialog (usually a Button). Omit when opening programmatically. */
13
+ trigger?: React.ReactElement<Record<string, unknown>>;
14
+ title: React.ReactNode;
15
+ /** Required: a confirmation must say what will happen. */
16
+ description: React.ReactNode;
17
+ /** Small archive-style label above the title, e.g. "ARCHIVE / DELETE". */
18
+ eyebrow?: React.ReactNode;
19
+ /** Extra detail about the consequences, e.g. the affected records. */
20
+ children?: React.ReactNode;
21
+ /** Label of the confirming action; name it after the action ("删除记录"), not "确定". */
22
+ confirmLabel: React.ReactNode;
23
+ cancelLabel?: React.ReactNode;
24
+ /** `danger` (default) fills the confirm button with the danger colour. */
25
+ tone?: AlertDialogTone;
26
+ /** Runs on confirm. Return a Promise to keep the dialog open until it settles. */
27
+ onConfirm: () => void | Promise<unknown>;
28
+ /** Shown in a role="alert" message when the Promise from `onConfirm` rejects. */
29
+ errorText?: React.ReactNode;
30
+ open?: boolean;
31
+ defaultOpen?: boolean;
32
+ onOpenChange?: (open: boolean) => void;
33
+ /** Fires after the exit animation, when focus has returned. */
34
+ onClosed?: () => void;
35
+ className?: string;
36
+ /** The accessible name and description always come from `title` / `description`. */
37
+ 'aria-label'?: never;
38
+ 'aria-labelledby'?: never;
39
+ };
40
+ export declare function AlertDialog({ trigger, title, description, eyebrow, children, confirmLabel, cancelLabel: cancelLabelProp, tone, onConfirm, errorText: errorTextProp, open: openProp, defaultOpen, onOpenChange, onClosed, className, }: AlertDialogProps): React.JSX.Element;
41
+ //# sourceMappingURL=AlertDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../src/components/AlertDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B;;;;;;;GAOG;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4FAA4F;IAC5F,OAAO,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0DAA0D;IAC1D,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,mFAAmF;IACnF,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,kFAAkF;IAClF,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,iFAAiF;IACjF,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,iBAAiB,CAAC,EAAE,KAAK,CAAC;CAC3B,CAAC;AAOF,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,WAAW,EACX,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,WAAW,EAAE,eAAe,EAC5B,IAAe,EACf,SAAS,EACT,SAAS,EAAE,aAAa,EACxB,IAAI,EAAE,QAAQ,EACd,WAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,SAAS,GACV,EAAE,gBAAgB,qBAmKlB"}
@@ -0,0 +1,101 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { AlertDialog as BaseAlertDialog } from '@base-ui/react/alert-dialog';
5
+ import { AnimatePresence, motion } from 'motion/react';
6
+ import { useRhineMessages } from '../provider/messages.js';
7
+ import { usePortalContainer } from '../provider/portal.js';
8
+ import { useRhineMotion } from '../motion/useRhineMotion.js';
9
+ import { cx } from '../utils/cx.js';
10
+ import { Button } from './Button.js';
11
+ const offset = 8;
12
+ const isThenable = (value) => value != null && typeof value.then === 'function';
13
+ export function AlertDialog({ trigger, title, description, eyebrow, children, confirmLabel, cancelLabel: cancelLabelProp, tone = 'danger', onConfirm, errorText: errorTextProp, open: openProp, defaultOpen = false, onOpenChange, onClosed, className, }) {
14
+ const messages = useRhineMessages();
15
+ const cancelLabel = cancelLabelProp === undefined ? messages.alertDialog.cancel : cancelLabelProp;
16
+ const errorText = errorTextProp === undefined ? messages.alertDialog.error : errorTextProp;
17
+ const [uncontrolled, setUncontrolled] = React.useState(defaultOpen);
18
+ const controlled = openProp !== undefined;
19
+ const open = controlled ? openProp : uncontrolled;
20
+ const [pending, setPending] = React.useState(false);
21
+ const [failures, setFailures] = React.useState(0);
22
+ const container = usePortalContainer();
23
+ const motionPrefs = useRhineMotion();
24
+ const rise = motionPrefs.reduced ? 0 : offset;
25
+ const cancelRef = React.useRef(null);
26
+ const confirmRef = React.useRef(null);
27
+ // Identifies the confirmation in flight; bumped on close / reopen / unmount so a stale
28
+ // promise can neither close a later opening nor set state after unmount.
29
+ const attempt = React.useRef(0);
30
+ // Each opening starts clean.
31
+ const [lastOpen, setLastOpen] = React.useState(open);
32
+ if (open !== lastOpen) {
33
+ setLastOpen(open);
34
+ setPending(false);
35
+ if (open)
36
+ setFailures(0);
37
+ }
38
+ React.useEffect(() => {
39
+ attempt.current += 1;
40
+ }, [open]);
41
+ React.useEffect(() => () => {
42
+ attempt.current += 1;
43
+ }, []);
44
+ // After a failed attempt, focus returns to the confirm button (it is focusable again).
45
+ React.useEffect(() => {
46
+ if (failures > 0)
47
+ confirmRef.current?.focus();
48
+ }, [failures]);
49
+ const setOpen = (next) => {
50
+ if (!controlled)
51
+ setUncontrolled(next);
52
+ onOpenChange?.(next);
53
+ };
54
+ const fail = () => {
55
+ setPending(false);
56
+ setFailures((n) => n + 1);
57
+ };
58
+ const handleConfirm = () => {
59
+ if (pending)
60
+ return;
61
+ attempt.current += 1;
62
+ const id = attempt.current;
63
+ let result;
64
+ try {
65
+ result = onConfirm();
66
+ }
67
+ catch {
68
+ fail();
69
+ return;
70
+ }
71
+ if (!isThenable(result)) {
72
+ setOpen(false);
73
+ return;
74
+ }
75
+ setPending(true);
76
+ result.then(() => {
77
+ if (attempt.current !== id)
78
+ return;
79
+ setPending(false);
80
+ setOpen(false);
81
+ }, () => {
82
+ if (attempt.current !== id)
83
+ return;
84
+ fail();
85
+ });
86
+ };
87
+ return (_jsxs(BaseAlertDialog.Root, { open: open, onOpenChange: (next, eventDetails) => {
88
+ // While a confirmation is in flight, cancelling would look like it undid the action.
89
+ if (!next && pending) {
90
+ eventDetails.cancel();
91
+ return;
92
+ }
93
+ setOpen(next);
94
+ }, onOpenChangeComplete: (isOpen) => {
95
+ if (!isOpen)
96
+ onClosed?.();
97
+ }, children: [trigger && _jsx(BaseAlertDialog.Trigger, { render: trigger }), _jsx(AnimatePresence, { children: open && (_jsxs(BaseAlertDialog.Portal, { keepMounted: true, container: container, children: [_jsx(BaseAlertDialog.Backdrop, { className: "rl-dialog__backdrop", render: _jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: motionPrefs.get('fast') }) }), _jsxs(BaseAlertDialog.Popup, { className: cx('rl-dialog rl-alert-dialog', className), "data-slot": "alert-dialog", "data-size": "sm", "data-tone": tone, initialFocus: cancelRef, render: _jsx(motion.div, { initial: { opacity: 0, y: rise }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: rise }, transition: motionPrefs.get('panel') }), children: [_jsxs("header", { className: "rl-dialog__header", children: [eyebrow != null && _jsx("p", { className: "rl-dialog__eyebrow", children: eyebrow }), _jsx(BaseAlertDialog.Title, { className: "rl-dialog__title", children: title }), _jsx(BaseAlertDialog.Description, { className: "rl-dialog__description", children: description })] }), (children != null || failures > 0) && (_jsxs("div", { className: "rl-dialog__body", children: [children, failures > 0 && (
98
+ // Remounted per failure so a repeated failure is announced again.
99
+ _jsx("p", { className: "rl-alert-dialog__error", role: "alert", children: errorText }, failures))] })), _jsxs("footer", { className: "rl-dialog__actions", children: [_jsx(BaseAlertDialog.Close, { disabled: pending, render: _jsx(Button, { ref: cancelRef, variant: "ghost", className: "rl-alert-dialog__cancel" }), children: cancelLabel }), _jsx(Button, { ref: confirmRef, className: "rl-alert-dialog__confirm", "data-tone": tone, loading: pending, onClick: handleConfirm, children: confirmLabel })] })] })] })) })] }));
100
+ }
101
+ //# sourceMappingURL=AlertDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AlertDialog.js","sourceRoot":"","sources":["../../src/components/AlertDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import * as React from 'react';
2
+ import type { StatusKind } from './StatusBadge.js';
3
+ /**
4
+ * Compact archive record for lists and grids (COMPONENTS.md "标准档案卡").
5
+ * Only `id` and `title` are required; every other field is hidden when missing, so
6
+ * the card never shows invented times, readings or permissions. When `href` or
7
+ * `onOpen` is set the whole card is one link/button whose name is the title; secondary
8
+ * metadata is attached as its description.
9
+ *
10
+ * Shared identity (opt-in, ADR-0007): with `motion="identity"` the record ID is a shared element;
11
+ * an `<ArchiveIdentity id>` for the same record elsewhere (e.g. a detail header) moves from the card's
12
+ * ID to its own place (`scene` 420ms, position only so text never stretches). Reduced motion: the
13
+ * detail just appears. Use it only when the detail *replaces* the card (list view → detail view):
14
+ * motion hides every non-leading member of a shared identity, so a card and its detail must not be
15
+ * on screen together. Scope duplicate lists with motion's `<LayoutGroup id>`.
16
+ */
17
+ export interface ArchiveCardStatus {
18
+ tone: StatusKind;
19
+ label: React.ReactNode;
20
+ }
21
+ export type ArchiveCardProps = {
22
+ id: string;
23
+ title: React.ReactNode;
24
+ category?: React.ReactNode;
25
+ /** Short secondary classification, e.g. a discipline. */
26
+ subcategory?: React.ReactNode;
27
+ status?: ArchiveCardStatus;
28
+ /** ISO date for <time dateTime>; `updatedLabel` is the visible text (defaults to the ISO string). */
29
+ updatedAt?: string;
30
+ updatedLabel?: React.ReactNode;
31
+ /** Optional thumbnail. Provide `alt` that describes it, or `alt=""` when purely decorative. */
32
+ media?: {
33
+ src: string;
34
+ alt: string;
35
+ };
36
+ /** Navigate to the record (renders <a>). */
37
+ href?: string;
38
+ /** Open the record in place (renders <button>). Ignored when `href` is set. */
39
+ onOpen?: () => void;
40
+ /** Selected in a list/detail layout. */
41
+ selected?: boolean;
42
+ /** `row` for lists, `tile` for grids. */
43
+ layout?: 'row' | 'tile';
44
+ /** `identity`: the record ID continues into a matching `ArchiveIdentity` (list → detail). Default `none`. */
45
+ motion?: 'none' | 'identity';
46
+ className?: string;
47
+ };
48
+ export type ArchiveIdentityProps = {
49
+ /** Record ID; must match the `ArchiveCard` it continues from. */
50
+ id: string;
51
+ /** Visible text; defaults to the ID. */
52
+ children?: React.ReactNode;
53
+ className?: string;
54
+ };
55
+ /** Target end of an ArchiveCard shared identity, e.g. the ID line of a detail pane. */
56
+ export declare function ArchiveIdentity({ id, children, className }: ArchiveIdentityProps): React.JSX.Element;
57
+ export declare const ArchiveCard: React.ForwardRefExoticComponent<ArchiveCardProps & React.RefAttributes<HTMLElement>>;
58
+ //# sourceMappingURL=ArchiveCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArchiveCard.d.ts","sourceRoot":"","sources":["../../src/components/ArchiveCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,yDAAyD;IACzD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,qGAAqG;IACrG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,+FAA+F;IAC/F,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yCAAyC;IACzC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,6GAA6G;IAC7G,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAmBF,MAAM,MAAM,oBAAoB,GAAG;IACjC,iEAAiE;IACjE,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,oBAAoB,qBAMhF;AAED,eAAO,MAAM,WAAW,sFAgGtB,CAAC"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { motion } from 'motion/react';
5
+ import { useRhineMotion } from '../motion/useRhineMotion.js';
6
+ import { cx } from '../utils/cx.js';
7
+ import { StatusBadge } from './StatusBadge.js';
8
+ const identityKey = (id) => `rl-archive-identity:${id}`;
9
+ function IdentityLabel({ id, className, children }) {
10
+ const motionPrefs = useRhineMotion();
11
+ return (_jsx(motion.span, { className: className, layoutId: identityKey(id), layout: "position", "data-rl-identity": id, transition: motionPrefs.resolve('layout', 'scene'), children: children }));
12
+ }
13
+ /** Target end of an ArchiveCard shared identity, e.g. the ID line of a detail pane. */
14
+ export function ArchiveIdentity({ id, children, className }) {
15
+ return (_jsx(IdentityLabel, { id: id, className: cx('rl-archive-identity', className), children: children ?? id }));
16
+ }
17
+ export const ArchiveCard = React.forwardRef(function ArchiveCard({ id, title, category, subcategory, status, updatedAt, updatedLabel, media, href, onOpen, selected, layout = 'row', motion: motionMode = 'none', className }, ref) {
18
+ const reactId = React.useId();
19
+ const titleId = `${reactId}-title`;
20
+ const metaId = `${reactId}-meta`;
21
+ const hasClassification = category != null || subcategory != null;
22
+ const interactive = href != null || onOpen != null;
23
+ const body = (_jsxs(_Fragment, { children: [media && (_jsx("span", { className: "rl-archive-card__media", children: _jsx("img", { src: media.src, alt: media.alt, loading: "lazy", decoding: "async" }) })), _jsxs("span", { className: "rl-archive-card__body", children: [motionMode === 'identity' ? (_jsx(IdentityLabel, { id: id, className: "rl-archive-card__id", children: id })) : (_jsx("span", { className: "rl-archive-card__id", children: id })), _jsx("span", { className: "rl-archive-card__title", id: titleId, children: title }), hasClassification && (_jsxs("span", { className: "rl-archive-card__class", children: [category != null && _jsx("span", { children: category }), subcategory != null && _jsx("span", { children: subcategory })] }))] }), (updatedAt || status) && (_jsxs("span", { className: "rl-archive-card__aside", id: metaId, children: [updatedAt && (_jsx("time", { className: "rl-archive-card__date", dateTime: updatedAt, children: updatedLabel ?? updatedAt })), status && (_jsx(StatusBadge, { status: status.tone, size: "sm", appearance: "outline", children: status.label }))] }))] }));
24
+ const common = {
25
+ className: cx('rl-archive-card', className),
26
+ 'data-slot': 'archive-card',
27
+ 'data-layout': layout,
28
+ 'data-selected': selected || undefined,
29
+ 'data-interactive': interactive || undefined,
30
+ };
31
+ const describedBy = updatedAt || status ? metaId : undefined;
32
+ if (href != null) {
33
+ return (_jsx("a", { ...common, ref: ref, href: href, "aria-labelledby": titleId, "aria-describedby": describedBy, "aria-current": selected ? 'true' : undefined, children: body }));
34
+ }
35
+ if (onOpen != null) {
36
+ return (_jsx("button", { ...common, ref: ref, type: "button", onClick: onOpen, "aria-labelledby": titleId, "aria-describedby": describedBy, "aria-pressed": selected ?? undefined, children: body }));
37
+ }
38
+ return (_jsx("article", { ...common, ref: ref, "aria-labelledby": titleId, children: body }));
39
+ });
40
+ //# sourceMappingURL=ArchiveCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArchiveCard.js","sourceRoot":"","sources":["../../src/components/ArchiveCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import * as React from 'react';
2
+ /**
3
+ * Location path (ADR-0005 §4): `<nav>` + ordered list; the last item without `href` is the
4
+ * current page. Separators are CSS-generated, so assistive tech reads only the items.
5
+ * Long paths collapse their middle items behind a button that expands in place.
6
+ *
7
+ * <Breadcrumb items={[{ label: '档案库', href: '#/' }, { label: '样本', href: '#/samples' }, { label: 'ARC-1024' }]} />
8
+ */
9
+ export interface BreadcrumbItem {
10
+ label: React.ReactNode;
11
+ /** Omit for the current page; items with `href` render as links. */
12
+ href?: string;
13
+ }
14
+ export interface BreadcrumbLinkProps {
15
+ href: string;
16
+ className: string;
17
+ title?: string;
18
+ children: React.ReactNode;
19
+ }
20
+ export type BreadcrumbProps = Omit<React.HTMLAttributes<HTMLElement>, 'children'> & {
21
+ items: readonly BreadcrumbItem[];
22
+ /** Accessible name of the navigation landmark. */
23
+ label?: string;
24
+ /**
25
+ * Collapse when the path has more than this many items: the first item and the last two stay,
26
+ * the rest hide behind an expand button. `0` never collapses.
27
+ */
28
+ maxItems?: number;
29
+ /** Accessible name of the expand button; receives the total number of levels. */
30
+ expandLabel?: (count: number) => string;
31
+ /** Render links with a router component instead of `<a>`. */
32
+ renderLink?: (props: BreadcrumbLinkProps) => React.ReactNode;
33
+ };
34
+ export declare const Breadcrumb: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLElement>, "children"> & {
35
+ items: readonly BreadcrumbItem[];
36
+ /** Accessible name of the navigation landmark. */
37
+ label?: string;
38
+ /**
39
+ * Collapse when the path has more than this many items: the first item and the last two stay,
40
+ * the rest hide behind an expand button. `0` never collapses.
41
+ */
42
+ maxItems?: number;
43
+ /** Accessible name of the expand button; receives the total number of levels. */
44
+ expandLabel?: (count: number) => string;
45
+ /** Render links with a router component instead of `<a>`. */
46
+ renderLink?: (props: BreadcrumbLinkProps) => React.ReactNode;
47
+ } & React.RefAttributes<HTMLElement>>;
48
+ //# sourceMappingURL=Breadcrumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb.d.ts","sourceRoot":"","sources":["../../src/components/Breadcrumb.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;GAMG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,GAAG;IAClF,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,KAAK,CAAC,SAAS,CAAC;CAC9D,CAAC;AAoBF,eAAO,MAAM,UAAU;WAhCd,SAAS,cAAc,EAAE;IAChC,kDAAkD;YAC1C,MAAM;IACd;;;OAGG;eACQ,MAAM;IACjB,iFAAiF;kBACnE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM;IACvC,6DAA6D;iBAChD,CAAC,KAAK,EAAE,mBAAmB,KAAK,KAAK,CAAC,SAAS;qCAyG5D,CAAC"}
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { useRhineLocale } from '../provider/messages.js';
5
+ import { cx } from '../utils/cx.js';
6
+ const textOf = (node) => typeof node === 'string' || typeof node === 'number' ? String(node) : undefined;
7
+ /** Labels up to this many characters never shrink: truncating them would leave nothing readable. */
8
+ const SHORT_LABEL = 4;
9
+ /**
10
+ * Width (in em of the trail's mono type) of the first three characters plus an ellipsis: the
11
+ * narrowest an ancestor may get. Only used for labels longer than SHORT_LABEL, so the minimum
12
+ * is always smaller than the label itself and can never open a gap after it.
13
+ */
14
+ function shrinkFloor(text) {
15
+ const wide = (ch) => /[\u1100-\u115f\u2e80-\ua4cf\uac00-\ud7a3\uf900-\ufaff\ufe30-\ufe4f\uff00-\uff60\uffe0-\uffe6]/.test(ch);
16
+ // 1em per CJK glyph, 0.6em per Latin mono glyph, plus the 0.12em caps tracking each.
17
+ const glyphs = [...text].slice(0, 3).reduce((sum, ch) => sum + (wide(ch) ? 1.12 : 0.72), 0);
18
+ return Math.round((glyphs + 0.72) * 100) / 100;
19
+ }
20
+ export const Breadcrumb = React.forwardRef(function Breadcrumb({ items, label: labelProp, maxItems = 4, expandLabel: expandLabelProp, renderLink, className, ...rest }, ref) {
21
+ const { messages, formatNumber } = useRhineLocale();
22
+ const label = labelProp ?? messages.breadcrumb.nav;
23
+ const expandLabel = (count) => expandLabelProp ? expandLabelProp(count) : messages.breadcrumb.expand(count, formatNumber);
24
+ const [expanded, setExpanded] = React.useState(false);
25
+ const listRef = React.useRef(null);
26
+ const collapsible = maxItems > 0 && items.length > maxItems && items.length > 3;
27
+ const collapsed = collapsible && !expanded;
28
+ const hiddenFrom = 1;
29
+ const hiddenTo = items.length - 2;
30
+ const expand = () => {
31
+ setExpanded(true);
32
+ // The button disappears; move focus to the first revealed link so it is not lost.
33
+ requestAnimationFrame(() => {
34
+ listRef.current?.querySelectorAll('a, [aria-current]')[hiddenFrom]?.focus();
35
+ });
36
+ };
37
+ if (items.length === 0)
38
+ return null;
39
+ return (_jsx("nav", { ...rest, ref: ref, className: cx('rl-breadcrumb', className), "aria-label": rest['aria-label'] ?? label, "data-slot": "breadcrumb", children: _jsx("ol", { ref: listRef, className: "rl-breadcrumb__list", children: items.map((item, index) => {
40
+ if (collapsed && index >= hiddenFrom && index < hiddenTo) {
41
+ if (index !== hiddenFrom)
42
+ return null;
43
+ return (_jsx("li", { className: "rl-breadcrumb__item", "data-collapsed": "", children: _jsx("button", { type: "button", className: "rl-breadcrumb__expand", "aria-label": expandLabel(items.length), onClick: expand, children: _jsx("span", { "aria-hidden": "true", children: "\u2026" }) }) }, "collapsed"));
44
+ }
45
+ const last = index === items.length - 1;
46
+ const current = last && !item.href;
47
+ const title = textOf(item.label);
48
+ // Ancestors with a long text label may shrink to a floor; everything else keeps its width.
49
+ const floor = !last && title && [...title].length > SHORT_LABEL ? shrinkFloor(title) : undefined;
50
+ return (_jsx("li", { className: "rl-breadcrumb__item", "data-shrink": floor != null || undefined, style: floor != null ? { '--rl-crumb-floor': `${floor}em` } : undefined, children: item.href ? (renderLink ? (renderLink({ href: item.href, className: 'rl-breadcrumb__link', title, children: item.label })) : (_jsx("a", { className: "rl-breadcrumb__link", href: item.href, title: title, children: item.label }))) : (_jsx("span", { className: "rl-breadcrumb__current", "aria-current": current ? 'page' : undefined, title: title,
51
+ // Focus target after expanding; never in the tab order.
52
+ tabIndex: collapsible ? -1 : undefined, children: item.label })) }, index));
53
+ }) }) }));
54
+ });
55
+ //# sourceMappingURL=Breadcrumb.js.map