@pearpages/pulp-react 0.0.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 (286) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/dist/ListboxOptions-DLsT-dkV.d.ts +11 -0
  4. package/dist/ToggleField-C-qKSgHh.d.ts +3 -0
  5. package/dist/accordion.css +90 -0
  6. package/dist/accordion.css.map +1 -0
  7. package/dist/accordion.d.ts +71 -0
  8. package/dist/accordion.js +6 -0
  9. package/dist/accordion.js.map +1 -0
  10. package/dist/alert.css +246 -0
  11. package/dist/alert.css.map +1 -0
  12. package/dist/alert.d.ts +46 -0
  13. package/dist/alert.js +10 -0
  14. package/dist/alert.js.map +1 -0
  15. package/dist/badge.css +89 -0
  16. package/dist/badge.css.map +1 -0
  17. package/dist/badge.d.ts +38 -0
  18. package/dist/badge.js +5 -0
  19. package/dist/badge.js.map +1 -0
  20. package/dist/button.css +162 -0
  21. package/dist/button.css.map +1 -0
  22. package/dist/button.d.ts +61 -0
  23. package/dist/button.js +8 -0
  24. package/dist/button.js.map +1 -0
  25. package/dist/calendar.css +128 -0
  26. package/dist/calendar.css.map +1 -0
  27. package/dist/calendar.d.ts +48 -0
  28. package/dist/calendar.js +6 -0
  29. package/dist/calendar.js.map +1 -0
  30. package/dist/card.css +66 -0
  31. package/dist/card.css.map +1 -0
  32. package/dist/card.d.ts +69 -0
  33. package/dist/card.js +5 -0
  34. package/dist/card.js.map +1 -0
  35. package/dist/checkbox.css +106 -0
  36. package/dist/checkbox.css.map +1 -0
  37. package/dist/checkbox.d.ts +41 -0
  38. package/dist/checkbox.js +7 -0
  39. package/dist/checkbox.js.map +1 -0
  40. package/dist/chunk-2PXTVZ7H.js +95 -0
  41. package/dist/chunk-2PXTVZ7H.js.map +1 -0
  42. package/dist/chunk-2ZP4ZBI5.js +43 -0
  43. package/dist/chunk-2ZP4ZBI5.js.map +1 -0
  44. package/dist/chunk-3GWESUGD.js +28 -0
  45. package/dist/chunk-3GWESUGD.js.map +1 -0
  46. package/dist/chunk-4HRNRTXI.js +25 -0
  47. package/dist/chunk-4HRNRTXI.js.map +1 -0
  48. package/dist/chunk-5SBKZS56.js +56 -0
  49. package/dist/chunk-5SBKZS56.js.map +1 -0
  50. package/dist/chunk-6I26MMQF.js +19 -0
  51. package/dist/chunk-6I26MMQF.js.map +1 -0
  52. package/dist/chunk-75GTNRBH.js +45 -0
  53. package/dist/chunk-75GTNRBH.js.map +1 -0
  54. package/dist/chunk-7DS4I7OJ.js +30 -0
  55. package/dist/chunk-7DS4I7OJ.js.map +1 -0
  56. package/dist/chunk-ASNTNTJW.js +27 -0
  57. package/dist/chunk-ASNTNTJW.js.map +1 -0
  58. package/dist/chunk-ASOQ2MVR.js +19 -0
  59. package/dist/chunk-ASOQ2MVR.js.map +1 -0
  60. package/dist/chunk-AWQHULJC.js +31 -0
  61. package/dist/chunk-AWQHULJC.js.map +1 -0
  62. package/dist/chunk-BBV4L5WO.js +43 -0
  63. package/dist/chunk-BBV4L5WO.js.map +1 -0
  64. package/dist/chunk-CZBCGLEM.js +9 -0
  65. package/dist/chunk-CZBCGLEM.js.map +1 -0
  66. package/dist/chunk-DWE374JX.js +65 -0
  67. package/dist/chunk-DWE374JX.js.map +1 -0
  68. package/dist/chunk-DXOOW6Q6.js +159 -0
  69. package/dist/chunk-DXOOW6Q6.js.map +1 -0
  70. package/dist/chunk-F3OFZGGE.js +116 -0
  71. package/dist/chunk-F3OFZGGE.js.map +1 -0
  72. package/dist/chunk-FH54XQ35.js +125 -0
  73. package/dist/chunk-FH54XQ35.js.map +1 -0
  74. package/dist/chunk-FXRSZUDH.js +38 -0
  75. package/dist/chunk-FXRSZUDH.js.map +1 -0
  76. package/dist/chunk-GTTXRDXV.js +181 -0
  77. package/dist/chunk-GTTXRDXV.js.map +1 -0
  78. package/dist/chunk-I4KC4V6A.js +31 -0
  79. package/dist/chunk-I4KC4V6A.js.map +1 -0
  80. package/dist/chunk-I5OZ63W7.js +50 -0
  81. package/dist/chunk-I5OZ63W7.js.map +1 -0
  82. package/dist/chunk-IDNGNQNV.js +41 -0
  83. package/dist/chunk-IDNGNQNV.js.map +1 -0
  84. package/dist/chunk-J5S2HVHO.js +67 -0
  85. package/dist/chunk-J5S2HVHO.js.map +1 -0
  86. package/dist/chunk-K5QGGQOV.js +84 -0
  87. package/dist/chunk-K5QGGQOV.js.map +1 -0
  88. package/dist/chunk-KPQGS4PG.js +77 -0
  89. package/dist/chunk-KPQGS4PG.js.map +1 -0
  90. package/dist/chunk-MI4QUKQS.js +8 -0
  91. package/dist/chunk-MI4QUKQS.js.map +1 -0
  92. package/dist/chunk-MRQWUCBA.js +57 -0
  93. package/dist/chunk-MRQWUCBA.js.map +1 -0
  94. package/dist/chunk-MXWXJZFS.js +48 -0
  95. package/dist/chunk-MXWXJZFS.js.map +1 -0
  96. package/dist/chunk-N7L66GMG.js +129 -0
  97. package/dist/chunk-N7L66GMG.js.map +1 -0
  98. package/dist/chunk-NAYFLTK6.js +32 -0
  99. package/dist/chunk-NAYFLTK6.js.map +1 -0
  100. package/dist/chunk-O6OBFL3Q.js +155 -0
  101. package/dist/chunk-O6OBFL3Q.js.map +1 -0
  102. package/dist/chunk-OGIQRHNF.js +52 -0
  103. package/dist/chunk-OGIQRHNF.js.map +1 -0
  104. package/dist/chunk-OUFAFINB.js +45 -0
  105. package/dist/chunk-OUFAFINB.js.map +1 -0
  106. package/dist/chunk-OXYP34CG.js +43 -0
  107. package/dist/chunk-OXYP34CG.js.map +1 -0
  108. package/dist/chunk-P5C2U5ZF.js +73 -0
  109. package/dist/chunk-P5C2U5ZF.js.map +1 -0
  110. package/dist/chunk-PM4YO67Q.js +53 -0
  111. package/dist/chunk-PM4YO67Q.js.map +1 -0
  112. package/dist/chunk-Q6J6BMSB.js +86 -0
  113. package/dist/chunk-Q6J6BMSB.js.map +1 -0
  114. package/dist/chunk-T76YSNTZ.js +33 -0
  115. package/dist/chunk-T76YSNTZ.js.map +1 -0
  116. package/dist/chunk-TGMDOQCL.js +53 -0
  117. package/dist/chunk-TGMDOQCL.js.map +1 -0
  118. package/dist/chunk-TVI5AXLE.js +41 -0
  119. package/dist/chunk-TVI5AXLE.js.map +1 -0
  120. package/dist/chunk-U6QRAD73.js +22 -0
  121. package/dist/chunk-U6QRAD73.js.map +1 -0
  122. package/dist/chunk-UX42PQLT.js +76 -0
  123. package/dist/chunk-UX42PQLT.js.map +1 -0
  124. package/dist/chunk-XDVS7HX7.js +100 -0
  125. package/dist/chunk-XDVS7HX7.js.map +1 -0
  126. package/dist/chunk-Y4TZA77G.js +57 -0
  127. package/dist/chunk-Y4TZA77G.js.map +1 -0
  128. package/dist/chunk-YUHS5S5Y.js +12 -0
  129. package/dist/chunk-YUHS5S5Y.js.map +1 -0
  130. package/dist/chunk-Z4PN6B2C.js +17 -0
  131. package/dist/chunk-Z4PN6B2C.js.map +1 -0
  132. package/dist/chunk-ZVDN3GRI.js +49 -0
  133. package/dist/chunk-ZVDN3GRI.js.map +1 -0
  134. package/dist/combobox.css +280 -0
  135. package/dist/combobox.css.map +1 -0
  136. package/dist/combobox.d.ts +75 -0
  137. package/dist/combobox.js +10 -0
  138. package/dist/combobox.js.map +1 -0
  139. package/dist/component-manifest.json +3370 -0
  140. package/dist/date-picker.css +267 -0
  141. package/dist/date-picker.css.map +1 -0
  142. package/dist/date-picker.d.ts +59 -0
  143. package/dist/date-picker.js +8 -0
  144. package/dist/date-picker.js.map +1 -0
  145. package/dist/dialog.css +62 -0
  146. package/dist/dialog.css.map +1 -0
  147. package/dist/dialog.d.ts +56 -0
  148. package/dist/dialog.js +3 -0
  149. package/dist/dialog.js.map +1 -0
  150. package/dist/field.css +28 -0
  151. package/dist/field.css.map +1 -0
  152. package/dist/field.d.ts +98 -0
  153. package/dist/field.js +5 -0
  154. package/dist/field.js.map +1 -0
  155. package/dist/floating-Bw-LN_QT.d.ts +5 -0
  156. package/dist/heading.css +30 -0
  157. package/dist/heading.css.map +1 -0
  158. package/dist/heading.d.ts +316 -0
  159. package/dist/heading.js +4 -0
  160. package/dist/heading.js.map +1 -0
  161. package/dist/icon-button.css +177 -0
  162. package/dist/icon-button.css.map +1 -0
  163. package/dist/icon-button.d.ts +29 -0
  164. package/dist/icon-button.js +9 -0
  165. package/dist/icon-button.js.map +1 -0
  166. package/dist/icon.css +25 -0
  167. package/dist/icon.css.map +1 -0
  168. package/dist/icon.d.ts +33 -0
  169. package/dist/icon.js +4 -0
  170. package/dist/icon.js.map +1 -0
  171. package/dist/index.css +2345 -0
  172. package/dist/index.css.map +1 -0
  173. package/dist/index.d.ts +42 -0
  174. package/dist/index.js +49 -0
  175. package/dist/index.js.map +1 -0
  176. package/dist/inline.css +63 -0
  177. package/dist/inline.css.map +1 -0
  178. package/dist/inline.d.ts +322 -0
  179. package/dist/inline.js +4 -0
  180. package/dist/inline.js.map +1 -0
  181. package/dist/listbox.css +95 -0
  182. package/dist/listbox.css.map +1 -0
  183. package/dist/listbox.d.ts +47 -0
  184. package/dist/listbox.js +7 -0
  185. package/dist/listbox.js.map +1 -0
  186. package/dist/menu.css +102 -0
  187. package/dist/menu.css.map +1 -0
  188. package/dist/menu.d.ts +76 -0
  189. package/dist/menu.js +9 -0
  190. package/dist/menu.js.map +1 -0
  191. package/dist/pagination.css +212 -0
  192. package/dist/pagination.css.map +1 -0
  193. package/dist/pagination.d.ts +52 -0
  194. package/dist/pagination.js +10 -0
  195. package/dist/pagination.js.map +1 -0
  196. package/dist/picker.css +209 -0
  197. package/dist/picker.css.map +1 -0
  198. package/dist/picker.d.ts +57 -0
  199. package/dist/picker.js +8 -0
  200. package/dist/picker.js.map +1 -0
  201. package/dist/popover.css +48 -0
  202. package/dist/popover.css.map +1 -0
  203. package/dist/popover.d.ts +68 -0
  204. package/dist/popover.js +7 -0
  205. package/dist/popover.js.map +1 -0
  206. package/dist/progress.css +83 -0
  207. package/dist/progress.css.map +1 -0
  208. package/dist/progress.d.ts +40 -0
  209. package/dist/progress.js +5 -0
  210. package/dist/progress.js.map +1 -0
  211. package/dist/radio.css +107 -0
  212. package/dist/radio.css.map +1 -0
  213. package/dist/radio.d.ts +68 -0
  214. package/dist/radio.js +6 -0
  215. package/dist/radio.js.map +1 -0
  216. package/dist/select.css +98 -0
  217. package/dist/select.css.map +1 -0
  218. package/dist/select.d.ts +39 -0
  219. package/dist/select.js +6 -0
  220. package/dist/select.js.map +1 -0
  221. package/dist/skeleton.css +59 -0
  222. package/dist/skeleton.css.map +1 -0
  223. package/dist/skeleton.d.ts +34 -0
  224. package/dist/skeleton.js +4 -0
  225. package/dist/skeleton.js.map +1 -0
  226. package/dist/slider.css +126 -0
  227. package/dist/slider.css.map +1 -0
  228. package/dist/slider.d.ts +61 -0
  229. package/dist/slider.js +5 -0
  230. package/dist/slider.js.map +1 -0
  231. package/dist/spinner.css +60 -0
  232. package/dist/spinner.css.map +1 -0
  233. package/dist/spinner.d.ts +34 -0
  234. package/dist/spinner.js +5 -0
  235. package/dist/spinner.js.map +1 -0
  236. package/dist/stack.css +60 -0
  237. package/dist/stack.css.map +1 -0
  238. package/dist/stack.d.ts +319 -0
  239. package/dist/stack.js +4 -0
  240. package/dist/stack.js.map +1 -0
  241. package/dist/switch.css +97 -0
  242. package/dist/switch.css.map +1 -0
  243. package/dist/switch.d.ts +35 -0
  244. package/dist/switch.js +7 -0
  245. package/dist/switch.js.map +1 -0
  246. package/dist/table.css +188 -0
  247. package/dist/table.css.map +1 -0
  248. package/dist/table.d.ts +137 -0
  249. package/dist/table.js +6 -0
  250. package/dist/table.js.map +1 -0
  251. package/dist/tabs.css +75 -0
  252. package/dist/tabs.css.map +1 -0
  253. package/dist/tabs.d.ts +73 -0
  254. package/dist/tabs.js +5 -0
  255. package/dist/tabs.js.map +1 -0
  256. package/dist/text-field.css +75 -0
  257. package/dist/text-field.css.map +1 -0
  258. package/dist/text-field.d.ts +43 -0
  259. package/dist/text-field.js +6 -0
  260. package/dist/text-field.js.map +1 -0
  261. package/dist/text.css +53 -0
  262. package/dist/text.css.map +1 -0
  263. package/dist/text.d.ts +331 -0
  264. package/dist/text.js +4 -0
  265. package/dist/text.js.map +1 -0
  266. package/dist/textarea.css +84 -0
  267. package/dist/textarea.css.map +1 -0
  268. package/dist/textarea.d.ts +40 -0
  269. package/dist/textarea.js +6 -0
  270. package/dist/textarea.js.map +1 -0
  271. package/dist/toast.css +300 -0
  272. package/dist/toast.css.map +1 -0
  273. package/dist/toast.d.ts +60 -0
  274. package/dist/toast.js +11 -0
  275. package/dist/toast.js.map +1 -0
  276. package/dist/tooltip.css +36 -0
  277. package/dist/tooltip.css.map +1 -0
  278. package/dist/tooltip.d.ts +34 -0
  279. package/dist/tooltip.js +5 -0
  280. package/dist/tooltip.js.map +1 -0
  281. package/dist/visually-hidden.css +15 -0
  282. package/dist/visually-hidden.css.map +1 -0
  283. package/dist/visually-hidden.d.ts +308 -0
  284. package/dist/visually-hidden.js +4 -0
  285. package/dist/visually-hidden.js.map +1 -0
  286. package/package.json +261 -0
@@ -0,0 +1,116 @@
1
+ import { VisuallyHidden } from './chunk-Z4PN6B2C.js';
2
+ import { selectionToIds } from './chunk-CZBCGLEM.js';
3
+ import { classes } from './chunk-MI4QUKQS.js';
4
+ import { createContext, useRef, useCallback, useState, useContext, useEffect } from 'react';
5
+ import { Table as Table$1, useTableOptions, TableHeader as TableHeader$1, Column, TableBody as TableBody$1, Row, Cell, Checkbox } from 'react-aria-components';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+
8
+ // src/table/Table.module.css
9
+ var Table_default = {
10
+ container: "Table_container",
11
+ table: "Table_table",
12
+ header: "Table_header",
13
+ column: "Table_column",
14
+ row: "Table_row",
15
+ cell: "Table_cell",
16
+ body: "Table_body",
17
+ selectColumn: "Table_selectColumn",
18
+ selectCell: "Table_selectCell",
19
+ selectBox: "Table_selectBox",
20
+ select: "Table_select",
21
+ empty: "Table_empty"
22
+ };
23
+ var RowIdsContext = createContext(null);
24
+ function Table({
25
+ selectionMode = "none",
26
+ selected,
27
+ defaultSelected = [],
28
+ onSelectedChange,
29
+ disabledIds,
30
+ sort,
31
+ defaultSort,
32
+ onSortChange,
33
+ density = "default",
34
+ stickyHeader = false,
35
+ onRowAction,
36
+ className,
37
+ ref,
38
+ children,
39
+ ...rest
40
+ }) {
41
+ const ids = useRef(/* @__PURE__ */ new Set());
42
+ const add = useCallback((id) => {
43
+ ids.current.add(id);
44
+ return () => {
45
+ ids.current.delete(id);
46
+ };
47
+ }, []);
48
+ const all = useCallback(() => Array.from(ids.current), []);
49
+ const [uncontrolledSort, setUncontrolledSort] = useState(defaultSort);
50
+ const currentSort = sort === void 0 ? uncontrolledSort : sort ?? void 0;
51
+ return /* @__PURE__ */ jsx(RowIdsContext.Provider, { value: { add, all }, children: /* @__PURE__ */ jsx("div", { className: classes(Table_default.container, className), "data-sticky-header": stickyHeader ? "" : void 0, children: /* @__PURE__ */ jsx(
52
+ Table$1,
53
+ {
54
+ ...rest,
55
+ ref,
56
+ className: Table_default.table,
57
+ "data-density": density,
58
+ selectionMode,
59
+ selectedKeys: selected,
60
+ defaultSelectedKeys: defaultSelected,
61
+ onSelectionChange: (selection) => onSelectedChange?.(selectionToIds(selection, all)),
62
+ disabledKeys: disabledIds,
63
+ sortDescriptor: currentSort,
64
+ onSortChange: (descriptor) => {
65
+ const next = { column: String(descriptor.column), direction: descriptor.direction };
66
+ if (sort === void 0) setUncontrolledSort(next);
67
+ onSortChange?.(next);
68
+ },
69
+ onRowAction: onRowAction && ((key) => onRowAction(String(key))),
70
+ children
71
+ }
72
+ ) }) });
73
+ }
74
+ function TableHeader({ className, children }) {
75
+ const { selectionMode, selectionBehavior } = useTableOptions();
76
+ return /* @__PURE__ */ jsxs(TableHeader$1, { className: classes(Table_default.header, className), children: [
77
+ selectionMode !== "none" && selectionBehavior === "toggle" && /* @__PURE__ */ jsx(Column, { className: classes(Table_default.column, Table_default.selectColumn), children: selectionMode === "multiple" ? /* @__PURE__ */ jsx(SelectionCheckbox, {}) : /* @__PURE__ */ jsx(VisuallyHidden, { children: "Selection" }) }),
78
+ children
79
+ ] });
80
+ }
81
+ function TableColumn({ id, allowsSorting = false, isRowHeader = false, align = "start", className, children }) {
82
+ return /* @__PURE__ */ jsx(Column, { id, allowsSorting, isRowHeader, className: classes(Table_default.column, className), "data-align": align, children });
83
+ }
84
+ function TableBody({ items, emptyMessage = "No rows", className, children }) {
85
+ return /* @__PURE__ */ jsx(TableBody$1, { items, className: classes(Table_default.body, className), renderEmptyState: () => /* @__PURE__ */ jsx("div", { className: Table_default.empty, children: emptyMessage }), children });
86
+ }
87
+ function TableRow({ id, className, children }) {
88
+ const { selectionBehavior } = useTableOptions();
89
+ const registry = useContext(RowIdsContext);
90
+ useEffect(() => id !== void 0 && registry ? registry.add(id) : void 0, [id, registry]);
91
+ return /* @__PURE__ */ jsxs(Row, { id, className: classes(Table_default.row, className), children: [
92
+ selectionBehavior === "toggle" && /* @__PURE__ */ jsx(Cell, { className: classes(Table_default.cell, Table_default.selectCell), children: /* @__PURE__ */ jsx(SelectionCheckbox, {}) }),
93
+ children
94
+ ] });
95
+ }
96
+ function TableCell({ align = "start", className, children }) {
97
+ return /* @__PURE__ */ jsx(Cell, { className: classes(Table_default.cell, className), "data-align": align, children });
98
+ }
99
+ function SelectionCheckbox() {
100
+ return /* @__PURE__ */ jsx(Checkbox, { slot: "selection", className: Table_default.select, children: /* @__PURE__ */ jsx("span", { className: Table_default.selectBox, "aria-hidden": "true" }) });
101
+ }
102
+ Table.displayName = "Table";
103
+ TableHeader.displayName = "Table.Header";
104
+ TableColumn.displayName = "Table.Column";
105
+ TableBody.displayName = "Table.Body";
106
+ TableRow.displayName = "Table.Row";
107
+ TableCell.displayName = "Table.Cell";
108
+ Table.Header = TableHeader;
109
+ Table.Column = TableColumn;
110
+ Table.Body = TableBody;
111
+ Table.Row = TableRow;
112
+ Table.Cell = TableCell;
113
+
114
+ export { Table };
115
+ //# sourceMappingURL=chunk-F3OFZGGE.js.map
116
+ //# sourceMappingURL=chunk-F3OFZGGE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/table/Table.module.css","../src/table/Table.tsx"],"names":["container","table","header","column","row","cell","body","selectColumn","selectCell","selectBox","select","empty","AriaTable","AriaTableHeader","AriaColumn","AriaTableBody","AriaRow","AriaCell","AriaCheckbox"],"mappings":"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","file":"chunk-F3OFZGGE.js","sourcesContent":["/*\n * Every value is a token (--table-*). Density resolves the row padding into a\n * private custom property on the table. React Aria writes the state:\n * data-hovered, data-selected, data-disabled, data-focus-visible on rows and\n * cells; data-allows-sorting and data-sort-direction on columns;\n * data-selected and data-indeterminate on the selection checkbox.\n * Rules are ordered from general to specific so no later selector has a lower\n * specificity than an earlier one for the same element.\n */\n\n@layer components {\n .container {\n overflow: auto;\n border: var(--size-hairline) solid var(--table-border);\n border-radius: var(--table-radius);\n background-color: var(--table-bg);\n color: var(--table-fg);\n font-family: var(--table-font-family);\n font-size: var(--table-font-size);\n }\n\n .table {\n --_padding-block: var(--table-cell-padding-block-default);\n\n inline-size: 100%;\n border-collapse: collapse;\n border-spacing: 0;\n outline: none;\n\n &[data-density=\"compact\"] {\n --_padding-block: var(--table-cell-padding-block-compact);\n }\n\n &[data-focus-visible] {\n outline: var(--table-focus-ring-width) solid var(--table-focus-ring);\n outline-offset: calc(-1 * var(--table-focus-ring-width));\n }\n }\n\n .header {\n background-color: var(--table-header-bg);\n }\n\n .container[data-sticky-header] .header {\n position: sticky;\n inset-block-start: 0;\n }\n\n .column {\n padding-block: var(--_padding-block);\n padding-inline: var(--table-cell-padding-inline);\n border-block-end: var(--size-hairline) solid var(--table-border);\n color: var(--table-header-fg);\n font-size: var(--table-header-font-size);\n font-weight: var(--table-header-font-weight);\n text-align: start;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n outline: none;\n\n &[data-align=\"end\"] {\n text-align: end;\n }\n\n &[data-allows-sorting] {\n cursor: pointer;\n }\n\n &[data-allows-sorting]::after {\n content: \"\";\n display: inline-block;\n inline-size: var(--table-header-sort-indicator-size);\n block-size: var(--table-header-sort-indicator-size);\n margin-inline-start: var(--table-header-sort-indicator-size);\n border-inline-end: var(--table-header-sort-indicator-width) solid currentcolor;\n border-block-end: var(--table-header-sort-indicator-width) solid currentcolor;\n rotate: -135deg;\n translate: 0 25%;\n opacity: 0;\n transition: opacity var(--table-motion-duration) var(--motion-easing-standard);\n }\n\n &[data-hovered]::after {\n opacity: 0.5;\n }\n\n &[data-sort-direction] {\n color: var(--table-header-fg-active);\n }\n\n &[data-sort-direction]::after {\n color: var(--table-header-sort-indicator);\n opacity: 1;\n }\n\n &[data-sort-direction=\"descending\"]::after {\n rotate: 45deg;\n translate: 0 -25%;\n }\n\n &[data-focus-visible] {\n outline: var(--table-focus-ring-width) solid var(--table-focus-ring);\n outline-offset: calc(-1 * var(--table-focus-ring-width));\n }\n }\n\n .row {\n outline: none;\n transition: background-color var(--table-motion-duration) var(--motion-easing-standard);\n\n &[data-hovered] {\n background-color: var(--table-row-bg-hover);\n }\n\n &[data-selected] {\n background-color: var(--table-row-bg-selected);\n }\n\n &[data-disabled] {\n color: var(--table-row-fg-disabled);\n }\n\n &[data-focus-visible] {\n outline: var(--table-focus-ring-width) solid var(--table-focus-ring);\n outline-offset: calc(-1 * var(--table-focus-ring-width));\n }\n }\n\n .cell {\n padding-block: var(--_padding-block);\n padding-inline: var(--table-cell-padding-inline);\n outline: none;\n\n &[data-align=\"end\"] {\n text-align: end;\n font-variant-numeric: tabular-nums;\n }\n\n &[data-focus-visible] {\n outline: var(--table-focus-ring-width) solid var(--table-focus-ring);\n outline-offset: calc(-1 * var(--table-focus-ring-width));\n }\n }\n\n .body .row:not(:last-child) .cell {\n border-block-end: var(--size-hairline) solid var(--table-border);\n }\n\n .selectColumn,\n .selectCell {\n inline-size: var(--table-select-size);\n padding-inline-end: 0;\n }\n\n .selectBox {\n display: grid;\n place-content: center;\n inline-size: var(--table-select-size);\n block-size: var(--table-select-size);\n border: var(--size-hairline) solid var(--table-select-border);\n border-radius: var(--table-select-radius);\n background-color: var(--table-select-bg);\n transition:\n background-color var(--table-motion-duration) var(--motion-easing-standard),\n border-color var(--table-motion-duration) var(--motion-easing-standard);\n\n &::after {\n content: \"\";\n inline-size: calc(var(--table-select-size) * 0.3);\n block-size: calc(var(--table-select-size) * 0.55);\n border-style: solid;\n border-color: var(--table-select-check);\n border-width: 0 var(--table-select-check-width) var(--table-select-check-width) 0;\n rotate: 45deg;\n translate: 0 -10%;\n opacity: 0;\n }\n }\n\n .select {\n display: inline-grid;\n place-items: center;\n inline-size: var(--table-select-size);\n block-size: var(--table-select-size);\n cursor: pointer;\n\n &[data-focus-visible] .selectBox {\n outline: var(--table-focus-ring-width) solid var(--table-focus-ring);\n outline-offset: var(--table-focus-ring-offset);\n }\n\n &[data-selected] .selectBox,\n &[data-indeterminate] .selectBox {\n border-color: var(--table-select-bg-checked);\n background-color: var(--table-select-bg-checked);\n\n &::after {\n opacity: 1;\n }\n }\n\n &[data-indeterminate] .selectBox::after {\n inline-size: calc(var(--table-select-size) * 0.55);\n block-size: 0;\n border-width: 0 0 var(--table-select-check-width);\n rotate: 0deg;\n translate: 0 0;\n }\n }\n\n .empty {\n padding: var(--table-empty-padding);\n color: var(--table-empty-fg);\n text-align: center;\n }\n}\n","import { createContext, useCallback, useContext, useEffect, useRef, useState, type ReactElement, type ReactNode, type Ref } from 'react';\nimport {\n Cell as AriaCell,\n Checkbox as AriaCheckbox,\n Column as AriaColumn,\n Row as AriaRow,\n Table as AriaTable,\n TableBody as AriaTableBody,\n TableHeader as AriaTableHeader,\n useTableOptions,\n type Key,\n type SortDescriptor,\n} from 'react-aria-components';\nimport { classes } from '../internal/classes';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { selectionToIds } from '../internal/selection';\nimport styles from './Table.module.css';\n\nexport type TableSelectionMode = 'none' | 'single' | 'multiple';\nexport type TableDensity = 'default' | 'compact';\nexport type TableSortDirection = 'ascending' | 'descending';\nexport interface TableSort {\n column: string;\n direction: TableSortDirection;\n}\n\n/** Rows register their ids so `'all'` (Ctrl/Cmd+A) resolves to an array without a second source of truth. */\nconst RowIdsContext = createContext<{ add: (id: Key) => () => void; all: () => Key[] } | null>(null);\n\nexport interface TableProps {\n /** The table's accessible name. Pass `aria-labelledby` instead when a visible heading names it. */\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n /** @default 'none' */\n selectionMode?: TableSelectionMode;\n /** Selected row ids (controlled). */\n selected?: readonly string[];\n /** @default [] */\n defaultSelected?: readonly string[];\n onSelectedChange?: (ids: string[]) => void;\n /** Rows that cannot be selected or activated. */\n disabledIds?: readonly string[];\n /** Current sort (controlled). Sorting the data is the caller's job: this is the header state. */\n sort?: TableSort | null;\n defaultSort?: TableSort;\n onSortChange?: (sort: TableSort) => void;\n /** Row padding steps down one token. The brand's `space.unit` sets the base. @default 'default' */\n density?: TableDensity;\n /** The header stays visible while the container scrolls. Give the container a height through `className`. @default false */\n stickyHeader?: boolean;\n /**\n * Called with the row id on Enter, on click, and on double click. Once\n * rows are selectable and a selection exists, Enter and click toggle the\n * selection instead (the vendor's rule, so touch users select without a\n * modifier key); double click still runs the action.\n */\n onRowAction?: (id: string) => void;\n /** Applied to the scroll container around the table. */\n className?: string;\n /** The `<table>` element. */\n ref?: Ref<HTMLTableElement>;\n /** `Table.Header` then `Table.Body`. */\n children: ReactNode;\n}\n\n/**\n * A data table on React Aria's grid (decision record 001): one Tab stop,\n * arrows move between rows and cells, Space toggles selection, Enter runs\n * the row action (see `onRowAction` for the selection rule), sortable\n * headers carry `aria-sort` and are pressed to change direction. Selection and sort are the caller's state; the table\n * reports changes and renders them. Compose with `Table.Header`,\n * `Table.Column`, `Table.Body`, `Table.Row` and `Table.Cell`; the selection\n * column appears by itself when rows are selectable.\n *\n * @status experimental\n * @category Data\n * @accessibility `role=\"grid\"` named by `aria-label` or `aria-labelledby`; one column is the row header (`isRowHeader`), sortable columns carry `aria-sort`, selectable rows `aria-selected`, and the selection column holds real checkboxes (\"Select All\" in the header). One tab stop: arrows move between rows and cells, Space toggles selection, Enter runs the row action, the header cells are pressed to sort.\n * @do Mark exactly one column `isRowHeader`.\n * Give the table a name that says what the rows are.\n * @dont Sort the data inside the table; sort your data from `onSortChange` and pass it back.\n * Use it for layout.\n */\nexport function Table({\n selectionMode = 'none',\n selected,\n defaultSelected = [],\n onSelectedChange,\n disabledIds,\n sort,\n defaultSort,\n onSortChange,\n density = 'default',\n stickyHeader = false,\n onRowAction,\n className,\n ref,\n children,\n ...rest\n}: TableProps) {\n const ids = useRef(new Set<Key>());\n const add = useCallback((id: Key) => {\n ids.current.add(id);\n return () => {\n ids.current.delete(id);\n };\n }, []);\n const all = useCallback(() => Array.from(ids.current), []);\n // The vendor has no default for the sort descriptor; hold it here when uncontrolled.\n const [uncontrolledSort, setUncontrolledSort] = useState<TableSort | undefined>(defaultSort);\n const currentSort = sort === undefined ? uncontrolledSort : (sort ?? undefined);\n\n return (\n <RowIdsContext.Provider value={{ add, all }}>\n <div className={classes(styles.container, className)} data-sticky-header={stickyHeader ? '' : undefined}>\n <AriaTable\n {...rest}\n ref={ref as Ref<HTMLDivElement | HTMLTableElement>}\n className={styles.table}\n data-density={density}\n selectionMode={selectionMode}\n selectedKeys={selected}\n defaultSelectedKeys={defaultSelected}\n onSelectionChange={(selection) => onSelectedChange?.(selectionToIds(selection, all))}\n disabledKeys={disabledIds}\n sortDescriptor={currentSort as SortDescriptor | undefined}\n onSortChange={(descriptor) => {\n const next = { column: String(descriptor.column), direction: descriptor.direction };\n if (sort === undefined) setUncontrolledSort(next);\n onSortChange?.(next);\n }}\n onRowAction={onRowAction && ((key) => onRowAction(String(key)))}\n >\n {children}\n </AriaTable>\n </div>\n </RowIdsContext.Provider>\n );\n}\n\ninterface TableHeaderProps {\n className?: string;\n /** `Table.Column` elements. */\n children: ReactNode;\n}\n\nfunction TableHeader({ className, children }: TableHeaderProps) {\n const { selectionMode, selectionBehavior } = useTableOptions();\n return (\n <AriaTableHeader className={classes(styles.header, className)}>\n {selectionMode !== 'none' && selectionBehavior === 'toggle' && (\n <AriaColumn className={classes(styles.column, styles.selectColumn)}>\n {selectionMode === 'multiple' ? <SelectionCheckbox /> : <VisuallyHidden>Selection</VisuallyHidden>}\n </AriaColumn>\n )}\n {children}\n </AriaTableHeader>\n );\n}\n\nexport type TableAlign = 'start' | 'end';\n\ninterface TableColumnProps {\n /** The column id `sort.column` refers to. Defaults to the column's text. */\n id?: string;\n /** Pressing the header sorts by it; the table reports the change through `onSortChange`. @default false */\n allowsSorting?: boolean;\n /** This column names the row for assistive technology. Exactly one column per table. @default false */\n isRowHeader?: boolean;\n /** @default 'start' */\n align?: TableAlign;\n className?: string;\n children: ReactNode;\n}\n\nfunction TableColumn({ id, allowsSorting = false, isRowHeader = false, align = 'start', className, children }: TableColumnProps) {\n return (\n <AriaColumn id={id} allowsSorting={allowsSorting} isRowHeader={isRowHeader} className={classes(styles.column, className)} data-align={align}>\n {children}\n </AriaColumn>\n );\n}\n\ninterface TableBodyProps<T extends { id: string }> {\n /** Rows from data: each item renders through the `children` function, keyed by `item.id`. */\n items?: Iterable<T>;\n /** Shown when there are no rows. @default 'No rows' */\n emptyMessage?: ReactNode;\n className?: string;\n /** `Table.Row` elements, or a function from an item to one when `items` is given. */\n children: ReactNode | ((item: T) => ReactElement);\n}\n\nfunction TableBody<T extends { id: string }>({ items, emptyMessage = 'No rows', className, children }: TableBodyProps<T>) {\n return (\n <AriaTableBody items={items} className={classes(styles.body, className)} renderEmptyState={() => <div className={styles.empty}>{emptyMessage}</div>}>\n {children}\n </AriaTableBody>\n );\n}\n\ninterface TableRowProps {\n /** The row id used for selection, sorting callbacks and `onRowAction`. Required unless the row comes from `items`. */\n id?: string;\n className?: string;\n /** `Table.Cell` elements. */\n children: ReactNode;\n}\n\nfunction TableRow({ id, className, children }: TableRowProps) {\n const { selectionBehavior } = useTableOptions();\n const registry = useContext(RowIdsContext);\n useEffect(() => (id !== undefined && registry ? registry.add(id) : undefined), [id, registry]);\n return (\n <AriaRow id={id} className={classes(styles.row, className)}>\n {selectionBehavior === 'toggle' && (\n <AriaCell className={classes(styles.cell, styles.selectCell)}>\n <SelectionCheckbox />\n </AriaCell>\n )}\n {children}\n </AriaRow>\n );\n}\n\ninterface TableCellProps {\n /** @default 'start' */\n align?: TableAlign;\n className?: string;\n children: ReactNode;\n}\n\nfunction TableCell({ align = 'start', className, children }: TableCellProps) {\n return (\n <AriaCell className={classes(styles.cell, className)} data-align={align}>\n {children}\n </AriaCell>\n );\n}\n\n/** React Aria's checkbox wired to the row (or all rows) through `slot=\"selection\"`; drawn from the table's tokens. */\nfunction SelectionCheckbox() {\n return (\n <AriaCheckbox slot=\"selection\" className={styles.select}>\n <span className={styles.selectBox} aria-hidden=\"true\" />\n </AriaCheckbox>\n );\n}\n\nTable.displayName = 'Table';\nTableHeader.displayName = 'Table.Header';\nTableColumn.displayName = 'Table.Column';\nTableBody.displayName = 'Table.Body';\nTableRow.displayName = 'Table.Row';\nTableCell.displayName = 'Table.Cell';\n\nTable.Header = TableHeader;\nTable.Column = TableColumn;\nTable.Body = TableBody;\nTable.Row = TableRow;\nTable.Cell = TableCell;\n"]}
@@ -0,0 +1,125 @@
1
+ import { useRovingFocus } from './chunk-I5OZ63W7.js';
2
+ import { classes } from './chunk-MI4QUKQS.js';
3
+ import { createContext, useState, useCallback, useId, useContext } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ // src/tabs/Tabs.module.css
7
+ var Tabs_default = {
8
+ root: "Tabs_root",
9
+ list: "Tabs_list",
10
+ tab: "Tabs_tab",
11
+ panel: "Tabs_panel"
12
+ };
13
+ var TabsContext = createContext(null);
14
+ function useTabs(component) {
15
+ const context = useContext(TabsContext);
16
+ if (!context) throw new Error(`${component} must be rendered inside <Tabs>`);
17
+ return context;
18
+ }
19
+ function Tabs({
20
+ value,
21
+ defaultValue,
22
+ onValueChange,
23
+ orientation = "horizontal",
24
+ activation = "automatic",
25
+ className,
26
+ ref,
27
+ children,
28
+ ...rest
29
+ }) {
30
+ const [uncontrolled, setUncontrolled] = useState(defaultValue ?? "");
31
+ const controlled = value !== void 0;
32
+ const current = controlled ? value : uncontrolled;
33
+ const setValue = useCallback(
34
+ (next) => {
35
+ if (!controlled) setUncontrolled(next);
36
+ onValueChange?.(next);
37
+ },
38
+ [controlled, onValueChange]
39
+ );
40
+ const baseId = useId();
41
+ return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { value: current, setValue, orientation, activation, baseId }, children: /* @__PURE__ */ jsx("div", { ...rest, ref, className: classes(Tabs_default.root, className), "data-orientation": orientation, children }) });
42
+ }
43
+ function TabsList({ className, ref, onKeyDown, children, ...rest }) {
44
+ const { orientation, activation, setValue } = useTabs("Tabs.List");
45
+ const rove = useRovingFocus({
46
+ orientation,
47
+ selector: '[role="tab"]',
48
+ onFocusItem: (item) => {
49
+ if (activation === "automatic" && item.dataset.value !== void 0) setValue(item.dataset.value);
50
+ }
51
+ });
52
+ return /* @__PURE__ */ jsx(
53
+ "div",
54
+ {
55
+ ...rest,
56
+ ref,
57
+ role: "tablist",
58
+ "aria-orientation": orientation,
59
+ className: classes(Tabs_default.list, className),
60
+ "data-orientation": orientation,
61
+ onKeyDown: (event) => {
62
+ onKeyDown?.(event);
63
+ if (!event.defaultPrevented) rove(event);
64
+ },
65
+ children
66
+ }
67
+ );
68
+ }
69
+ function TabsTab({ value, disabled, className, onClick, ref, children, ...rest }) {
70
+ const tabs = useTabs("Tabs.Tab");
71
+ const selected = tabs.value === value;
72
+ return /* @__PURE__ */ jsx(
73
+ "button",
74
+ {
75
+ ...rest,
76
+ ref,
77
+ type: "button",
78
+ role: "tab",
79
+ id: `${tabs.baseId}-tab-${value}`,
80
+ "aria-selected": selected,
81
+ "aria-controls": `${tabs.baseId}-panel-${value}`,
82
+ tabIndex: selected ? 0 : -1,
83
+ disabled,
84
+ className: classes(Tabs_default.tab, className),
85
+ "data-value": value,
86
+ "data-state": selected ? "active" : "inactive",
87
+ "data-disabled": disabled ? "" : void 0,
88
+ onClick: (event) => {
89
+ onClick?.(event);
90
+ if (!event.defaultPrevented) tabs.setValue(value);
91
+ },
92
+ children
93
+ }
94
+ );
95
+ }
96
+ function TabsPanel({ value, className, ref, children, ...rest }) {
97
+ const tabs = useTabs("Tabs.Panel");
98
+ const selected = tabs.value === value;
99
+ return /* @__PURE__ */ jsx(
100
+ "div",
101
+ {
102
+ ...rest,
103
+ ref,
104
+ role: "tabpanel",
105
+ id: `${tabs.baseId}-panel-${value}`,
106
+ "aria-labelledby": `${tabs.baseId}-tab-${value}`,
107
+ hidden: !selected,
108
+ tabIndex: 0,
109
+ className: classes(Tabs_default.panel, className),
110
+ "data-state": selected ? "active" : "inactive",
111
+ children
112
+ }
113
+ );
114
+ }
115
+ Tabs.displayName = "Tabs";
116
+ TabsList.displayName = "Tabs.List";
117
+ TabsTab.displayName = "Tabs.Tab";
118
+ TabsPanel.displayName = "Tabs.Panel";
119
+ Tabs.List = TabsList;
120
+ Tabs.Tab = TabsTab;
121
+ Tabs.Panel = TabsPanel;
122
+
123
+ export { Tabs };
124
+ //# sourceMappingURL=chunk-FH54XQ35.js.map
125
+ //# sourceMappingURL=chunk-FH54XQ35.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tabs/Tabs.module.css","../src/tabs/Tabs.tsx"],"names":["root","list","tab","panel"],"mappings":"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","file":"chunk-FH54XQ35.js","sourcesContent":["/* Every value is a token (--tabs-*). The indicator is a logical border on the active tab, so vertical orientation just flips the side. */\n\n@layer components {\n .root {\n display: flex;\n flex-direction: column;\n gap: 0;\n\n &[data-orientation=\"vertical\"] {\n flex-direction: row;\n }\n }\n\n .list {\n display: flex;\n gap: var(--tabs-gap);\n border-block-end: 1px solid var(--tabs-list-border);\n\n &[data-orientation=\"vertical\"] {\n flex-direction: column;\n border-block-end: none;\n border-inline-end: 1px solid var(--tabs-list-border);\n }\n }\n\n .tab {\n position: relative;\n padding-block: var(--tabs-tab-padding-block);\n padding-inline: var(--tabs-tab-padding-inline);\n border: none;\n border-radius: var(--tabs-tab-radius) var(--tabs-tab-radius) 0 0;\n background-color: transparent;\n color: var(--tabs-tab-fg);\n font-size: var(--tabs-tab-font-size);\n font-weight: var(--tabs-tab-font-weight);\n line-height: 1;\n white-space: nowrap;\n cursor: pointer;\n transition:\n color var(--tabs-motion-duration) var(--motion-easing-standard),\n background-color var(--tabs-motion-duration) var(--motion-easing-standard);\n\n /* Indicator: a transparent border always present, coloured when active, so nothing shifts. */\n border-block-end: 2px solid transparent;\n\n &:focus-visible {\n outline: var(--tabs-focus-ring-width) solid var(--tabs-focus-ring);\n outline-offset: calc(-1 * var(--tabs-focus-ring-offset));\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &[data-state=\"active\"] {\n color: var(--tabs-tab-fg-active);\n border-block-end-color: var(--tabs-tab-indicator);\n }\n\n &:hover:not(:disabled, [data-state=\"active\"]) {\n color: var(--tabs-tab-fg-hover);\n background-color: var(--tabs-tab-bg-hover);\n }\n }\n\n .list[data-orientation=\"vertical\"] .tab {\n border-radius: var(--tabs-tab-radius) 0 0 var(--tabs-tab-radius);\n border-block-end: none;\n border-inline-end: 2px solid transparent;\n text-align: start;\n\n &[data-state=\"active\"] {\n border-inline-end-color: var(--tabs-tab-indicator);\n }\n }\n\n .panel {\n padding-block: var(--tabs-panel-padding-block);\n color: var(--tabs-panel-fg);\n\n &:focus-visible {\n outline: var(--tabs-focus-ring-width) solid var(--tabs-focus-ring);\n outline-offset: var(--tabs-focus-ring-offset);\n }\n }\n\n .root[data-orientation=\"vertical\"] .panel {\n padding-block: 0;\n padding-inline-start: var(--tabs-tab-padding-inline);\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useId,\n useState,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { classes } from '../internal/classes';\nimport { useRovingFocus } from '../internal/useRovingFocus';\nimport styles from './Tabs.module.css';\n\nexport type TabsOrientation = 'horizontal' | 'vertical';\nexport type TabsActivation = 'automatic' | 'manual';\n\ninterface TabsContextValue {\n value: string;\n setValue: (value: string) => void;\n orientation: TabsOrientation;\n activation: TabsActivation;\n baseId: string;\n}\n\nconst TabsContext = createContext<TabsContextValue | null>(null);\n\nfunction useTabs(component: string): TabsContextValue {\n const context = useContext(TabsContext);\n if (!context) throw new Error(`${component} must be rendered inside <Tabs>`);\n return context;\n}\n\nexport interface TabsProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> {\n /** Controlled selected tab. */\n value?: string;\n /** Initially selected tab when uncontrolled. */\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n /** Layout and arrow-key axis. @default 'horizontal' */\n orientation?: TabsOrientation;\n /**\n * `automatic` selects a tab when it receives focus (arrow keys); `manual`\n * moves focus only and selects on Enter, Space or click.\n * @default 'automatic'\n */\n activation?: TabsActivation;\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\n/**\n * Tabbed sections following the WAI-ARIA Tabs pattern. Compose with\n * `Tabs.List`, `Tabs.Tab` and `Tabs.Panel`; ids and ARIA relationships are\n * wired automatically. One tab stop: arrows move between tabs, Home and End\n * jump to the ends, disabled tabs are skipped. State on the DOM:\n * `data-orientation`, `data-state=\"active|inactive\"`.\n *\n * @status stable\n * @category Navigation\n * @accessibility The WAI-ARIA Tabs pattern: `tablist` with `aria-orientation`, `tab`s carrying `aria-selected` and `aria-controls`, `tabpanel`s labelled by their tab. One tab stop: arrows move (and select with automatic activation), Home/End jump, disabled tabs are skipped.\n * @do Use `activation=\"manual\"` when switching a tab is expensive.\n * Name the `Tabs.List` with `aria-label`.\n * @dont Use tabs for sequential steps; use a stepper pattern.\n * Put a link inside a tab.\n */\nexport function Tabs({\n value,\n defaultValue,\n onValueChange,\n orientation = 'horizontal',\n activation = 'automatic',\n className,\n ref,\n children,\n ...rest\n}: TabsProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultValue ?? '');\n const controlled = value !== undefined;\n const current = controlled ? value : uncontrolled;\n const setValue = useCallback(\n (next: string) => {\n if (!controlled) setUncontrolled(next);\n onValueChange?.(next);\n },\n [controlled, onValueChange],\n );\n const baseId = useId();\n\n return (\n <TabsContext.Provider value={{ value: current, setValue, orientation, activation, baseId }}>\n <div {...rest} ref={ref} className={classes(styles.root, className)} data-orientation={orientation}>\n {children}\n </div>\n </TabsContext.Provider>\n );\n}\n\ninterface TabsListProps extends HTMLAttributes<HTMLDivElement> {\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nfunction TabsList({ className, ref, onKeyDown, children, ...rest }: TabsListProps) {\n const { orientation, activation, setValue } = useTabs('Tabs.List');\n const rove = useRovingFocus({\n orientation,\n selector: '[role=\"tab\"]',\n onFocusItem: (item) => {\n if (activation === 'automatic' && item.dataset.value !== undefined) setValue(item.dataset.value);\n },\n });\n return (\n <div\n {...rest}\n ref={ref}\n role=\"tablist\"\n aria-orientation={orientation}\n className={classes(styles.list, className)}\n data-orientation={orientation}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) rove(event);\n }}\n >\n {children}\n </div>\n );\n}\n\ninterface TabsTabProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value'> {\n /** Identifies the tab; the panel with the same value belongs to it. */\n value: string;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction TabsTab({ value, disabled, className, onClick, ref, children, ...rest }: TabsTabProps) {\n const tabs = useTabs('Tabs.Tab');\n const selected = tabs.value === value;\n return (\n <button\n {...rest}\n ref={ref}\n type=\"button\"\n role=\"tab\"\n id={`${tabs.baseId}-tab-${value}`}\n aria-selected={selected}\n aria-controls={`${tabs.baseId}-panel-${value}`}\n tabIndex={selected ? 0 : -1}\n disabled={disabled}\n className={classes(styles.tab, className)}\n data-value={value}\n data-state={selected ? 'active' : 'inactive'}\n data-disabled={disabled ? '' : undefined}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) tabs.setValue(value);\n }}\n >\n {children}\n </button>\n );\n}\n\ninterface TabsPanelProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n ref?: Ref<HTMLDivElement>;\n children?: ReactNode;\n}\n\nfunction TabsPanel({ value, className, ref, children, ...rest }: TabsPanelProps) {\n const tabs = useTabs('Tabs.Panel');\n const selected = tabs.value === value;\n return (\n <div\n {...rest}\n ref={ref}\n role=\"tabpanel\"\n id={`${tabs.baseId}-panel-${value}`}\n aria-labelledby={`${tabs.baseId}-tab-${value}`}\n hidden={!selected}\n tabIndex={0}\n className={classes(styles.panel, className)}\n data-state={selected ? 'active' : 'inactive'}\n >\n {children}\n </div>\n );\n}\n\nTabs.displayName = 'Tabs';\nTabsList.displayName = 'Tabs.List';\nTabsTab.displayName = 'Tabs.Tab';\nTabsPanel.displayName = 'Tabs.Panel';\n\nTabs.List = TabsList;\nTabs.Tab = TabsTab;\nTabs.Panel = TabsPanel;\n"]}
@@ -0,0 +1,38 @@
1
+ import { Button } from './chunk-KPQGS4PG.js';
2
+ import { Icon } from './chunk-ASNTNTJW.js';
3
+ import { classes } from './chunk-MI4QUKQS.js';
4
+ import { isValidElement, cloneElement } from 'react';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ // src/icon-button/IconButton.module.css
8
+ var IconButton_default = {
9
+ iconButton: "IconButton_iconButton"
10
+ };
11
+ function IconButton({
12
+ label,
13
+ icon,
14
+ title,
15
+ className,
16
+ asChild = false,
17
+ children,
18
+ ...rest
19
+ }) {
20
+ const glyph = /* @__PURE__ */ jsx(Icon, { size: "inherit", children: icon });
21
+ return /* @__PURE__ */ jsx(
22
+ Button,
23
+ {
24
+ ...rest,
25
+ asChild,
26
+ "aria-label": label,
27
+ title: title ?? label,
28
+ "data-icon-only": "",
29
+ className: classes(IconButton_default.iconButton, className),
30
+ children: asChild && isValidElement(children) ? cloneElement(children, void 0, glyph) : glyph
31
+ }
32
+ );
33
+ }
34
+ IconButton.displayName = "IconButton";
35
+
36
+ export { IconButton };
37
+ //# sourceMappingURL=chunk-FXRSZUDH.js.map
38
+ //# sourceMappingURL=chunk-FXRSZUDH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/icon-button/IconButton.module.css","../src/icon-button/IconButton.tsx"],"names":["iconButton"],"mappings":";;;;;;;AAAA,IAAA,kBAAA,GAAA;AAAA,EAGG,UAAA,EAAAA;AAAA,CAAA;ACwBI,SAAS,UAAA,CAAsD;AAAA,EACpE,KAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA,GAAU,KAAA;AAAA,EACV,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAuB;AACrB,EAAA,MAAM,KAAA,mBAAQ,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAK,WAAW,QAAA,EAAA,IAAA,EAAK,CAAA;AACzC,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,OAAA;AAAA,MACA,YAAA,EAAY,KAAA;AAAA,MACZ,OAAO,KAAA,IAAS,KAAA;AAAA,MAChB,gBAAA,EAAe,EAAA;AAAA,MACf,SAAA,EAAW,OAAA,CAAQ,kBAAA,CAAO,UAAA,EAAY,SAAS,CAAA;AAAA,MAE9C,QAAA,EAAA,OAAA,IAAW,eAAe,QAAQ,CAAA,GAAI,aAAa,QAAA,EAAU,MAAA,EAAW,KAAK,CAAA,GAAI;AAAA;AAAA,GACpF;AAEJ;AAEA,UAAA,CAAW,WAAA,GAAc,YAAA","file":"chunk-FXRSZUDH.js","sourcesContent":["/* Squares a Button. Selectors carry the data attribute so they outrank Button's own size rules. */\n\n@layer components {\n .iconButton[data-icon-only] {\n gap: 0;\n inline-size: var(--icon-button-size-md);\n padding-inline: 0;\n\n &[data-size=\"sm\"] { inline-size: var(--icon-button-size-sm); }\n &[data-size=\"lg\"] { inline-size: var(--icon-button-size-lg); }\n }\n}\n","import { cloneElement, isValidElement, type ReactElement, type ReactNode } from 'react';\nimport { Button, type ButtonProps } from '../button';\nimport { Icon } from '../icon';\nimport { classes } from '../internal/classes';\nimport styles from './IconButton.module.css';\n\nexport interface IconButtonProps<E extends HTMLElement = HTMLButtonElement>\n extends Omit<ButtonProps<E>, 'children' | 'iconStart' | 'iconEnd'> {\n /** The accessible name. Required: an icon alone is not a name. Also used as the tooltip unless `title` is given. */\n label: string;\n /** The glyph, for instance from `@pearpages/pulp-icons`. */\n icon: ReactNode;\n /** With `asChild`: the element to render (a link, for instance). Its own children are replaced by the icon. */\n children?: ReactElement;\n}\n\n/**\n * A square Button that shows only an icon and therefore *requires* a name.\n * Everything else (variants, sizes, loading, asChild) is Button's; the\n * `--icon-button-size-*` tokens make it square.\n *\n * @status stable\n * @category Actions\n * @accessibility A Button with `aria-label` from the required `label`; `title` shows it as a tooltip. Everything else is Button's.\n * @do Write the label as the action (\"Close\", \"Add item\").\n * @dont Use the icon's name as the label.\n */\nexport function IconButton<E extends HTMLElement = HTMLButtonElement>({\n label,\n icon,\n title,\n className,\n asChild = false,\n children,\n ...rest\n}: IconButtonProps<E>) {\n const glyph = <Icon size=\"inherit\">{icon}</Icon>;\n return (\n <Button\n {...rest}\n asChild={asChild}\n aria-label={label}\n title={title ?? label}\n data-icon-only=\"\"\n className={classes(styles.iconButton, className)}\n >\n {asChild && isValidElement(children) ? cloneElement(children, undefined, glyph) : glyph}\n </Button>\n );\n}\n\nIconButton.displayName = 'IconButton';\n"]}
@@ -0,0 +1,181 @@
1
+ import { useRovingFocus } from './chunk-I5OZ63W7.js';
2
+ import { useDismiss } from './chunk-NAYFLTK6.js';
3
+ import { useFloatingPosition } from './chunk-U6QRAD73.js';
4
+ import { renderAsChild } from './chunk-ZVDN3GRI.js';
5
+ import { Icon } from './chunk-ASNTNTJW.js';
6
+ import { classes } from './chunk-MI4QUKQS.js';
7
+ import { createContext, useState, useCallback, useId, useRef, useEffect, useContext } from 'react';
8
+ import { createPortal } from 'react-dom';
9
+ import { jsx, jsxs } from 'react/jsx-runtime';
10
+
11
+ // src/menu/Menu.module.css
12
+ var Menu_default = {
13
+ content: "Menu_content",
14
+ item: "Menu_item",
15
+ label: "Menu_label",
16
+ separator: "Menu_separator"
17
+ };
18
+ var MenuContext = createContext(null);
19
+ function useMenu(part) {
20
+ const context = useContext(MenuContext);
21
+ if (!context) throw new Error(`${part} must be rendered inside <Menu>`);
22
+ return context;
23
+ }
24
+ function Menu({ open, defaultOpen = false, onOpenChange, placement = "bottom-start", children }) {
25
+ const [uncontrolled, setUncontrolled] = useState(defaultOpen);
26
+ const [focusTarget, setFocusTarget] = useState(null);
27
+ const controlled = open !== void 0;
28
+ const isOpen = controlled ? open : uncontrolled;
29
+ const setOpen = useCallback(
30
+ (next, focus = null) => {
31
+ setFocusTarget(next ? focus : null);
32
+ if (!controlled) setUncontrolled(next);
33
+ onOpenChange?.(next);
34
+ },
35
+ [controlled, onOpenChange]
36
+ );
37
+ const id = useId();
38
+ const floating = useFloatingPosition({ open: isOpen, placement });
39
+ return /* @__PURE__ */ jsx(MenuContext.Provider, { value: { open: isOpen, setOpen, focusTarget, triggerId: `${id}-trigger`, contentId: `${id}-menu`, floating }, children });
40
+ }
41
+ function mergeRefs(a, b) {
42
+ return (node) => {
43
+ b(node);
44
+ if (typeof a === "function") a(node);
45
+ else if (a) a.current = node;
46
+ };
47
+ }
48
+ function MenuTrigger({ asChild = false, onClick, onKeyDown, ref, children, ...rest }) {
49
+ const menu = useMenu("Menu.Trigger");
50
+ const props = {
51
+ ...rest,
52
+ id: menu.triggerId,
53
+ "aria-haspopup": "menu",
54
+ "aria-expanded": menu.open,
55
+ "aria-controls": menu.open ? menu.contentId : void 0,
56
+ onClick: (event) => {
57
+ onClick?.(event);
58
+ if (!event.defaultPrevented) menu.setOpen(!menu.open, "first");
59
+ },
60
+ onKeyDown: (event) => {
61
+ onKeyDown?.(event);
62
+ if (event.defaultPrevented) return;
63
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
64
+ event.preventDefault();
65
+ menu.setOpen(true, event.key === "ArrowDown" ? "first" : "last");
66
+ }
67
+ }
68
+ };
69
+ const setRef = mergeRefs(ref, menu.floating.refs.setReference);
70
+ if (asChild) return renderAsChild("Menu.Trigger", children, { ...props, ref: setRef });
71
+ return /* @__PURE__ */ jsx("button", { type: "button", ...props, ref: setRef, children });
72
+ }
73
+ function MenuContent({ className, onKeyDown, ref, children, ...rest }) {
74
+ const menu = useMenu("Menu.Content");
75
+ const { refs, positionStyle, placement } = menu.floating;
76
+ const contentRef = useRef(null);
77
+ const rove = useRovingFocus({ orientation: "vertical", selector: '[role="menuitem"]' });
78
+ useDismiss({
79
+ open: menu.open,
80
+ onDismiss: () => menu.setOpen(false),
81
+ inside: () => [refs.reference.current, refs.floating.current]
82
+ });
83
+ useEffect(() => {
84
+ if (!menu.open) return;
85
+ const content = contentRef.current;
86
+ if (!content) return;
87
+ const items = Array.from(content.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])'));
88
+ const target = menu.focusTarget === "last" ? items.at(-1) : items[0];
89
+ (target ?? content).focus();
90
+ return () => {
91
+ const reference = refs.reference.current;
92
+ if (content.contains(document.activeElement) || document.activeElement === document.body) reference?.focus();
93
+ };
94
+ }, [menu.open, menu.focusTarget, refs.reference]);
95
+ const typeahead = (event) => {
96
+ if (event.key.length !== 1 || event.altKey || event.ctrlKey || event.metaKey) return false;
97
+ const items = Array.from(event.currentTarget.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])'));
98
+ const current = items.indexOf(document.activeElement);
99
+ const ordered = [...items.slice(current + 1), ...items.slice(0, current + 1)];
100
+ const match = ordered.find((item) => item.textContent?.trim().toLowerCase().startsWith(event.key.toLowerCase()));
101
+ if (!match) return false;
102
+ event.preventDefault();
103
+ match.focus();
104
+ return true;
105
+ };
106
+ if (!menu.open) return null;
107
+ return createPortal(
108
+ /* @__PURE__ */ jsx(
109
+ "div",
110
+ {
111
+ ...rest,
112
+ ref: mergeRefs(ref, (node) => {
113
+ contentRef.current = node;
114
+ refs.setFloating(node);
115
+ }),
116
+ id: menu.contentId,
117
+ role: "menu",
118
+ "aria-labelledby": menu.triggerId,
119
+ tabIndex: -1,
120
+ className: classes(Menu_default.content, className),
121
+ "data-placement": placement,
122
+ style: positionStyle,
123
+ onKeyDown: (event) => {
124
+ onKeyDown?.(event);
125
+ if (event.defaultPrevented) return;
126
+ if (event.key === "Tab") {
127
+ menu.setOpen(false);
128
+ return;
129
+ }
130
+ if (typeahead(event)) return;
131
+ rove(event);
132
+ },
133
+ children
134
+ }
135
+ ),
136
+ document.body
137
+ );
138
+ }
139
+ function MenuItem({ onSelect, tone = "default", icon, disabled, className, onClick, ref, children, ...rest }) {
140
+ const menu = useMenu("Menu.Item");
141
+ return /* @__PURE__ */ jsxs(
142
+ "button",
143
+ {
144
+ ...rest,
145
+ ref,
146
+ type: "button",
147
+ role: "menuitem",
148
+ tabIndex: -1,
149
+ "aria-disabled": disabled || void 0,
150
+ className: classes(Menu_default.item, className),
151
+ "data-tone": tone,
152
+ "data-disabled": disabled ? "" : void 0,
153
+ onClick: (event) => {
154
+ onClick?.(event);
155
+ if (event.defaultPrevented || disabled) return;
156
+ onSelect?.();
157
+ menu.setOpen(false);
158
+ },
159
+ children: [
160
+ icon && /* @__PURE__ */ jsx(Icon, { size: "inherit", children: icon }),
161
+ /* @__PURE__ */ jsx("span", { className: Menu_default.label, children })
162
+ ]
163
+ }
164
+ );
165
+ }
166
+ function MenuSeparator({ className, ...rest }) {
167
+ return /* @__PURE__ */ jsx("div", { ...rest, role: "separator", className: classes(Menu_default.separator, className) });
168
+ }
169
+ Menu.displayName = "Menu";
170
+ MenuTrigger.displayName = "Menu.Trigger";
171
+ MenuContent.displayName = "Menu.Content";
172
+ MenuItem.displayName = "Menu.Item";
173
+ MenuSeparator.displayName = "Menu.Separator";
174
+ Menu.Trigger = MenuTrigger;
175
+ Menu.Content = MenuContent;
176
+ Menu.Item = MenuItem;
177
+ Menu.Separator = MenuSeparator;
178
+
179
+ export { Menu };
180
+ //# sourceMappingURL=chunk-GTTXRDXV.js.map
181
+ //# sourceMappingURL=chunk-GTTXRDXV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/menu/Menu.module.css","../src/menu/Menu.tsx"],"names":["content","item","label","separator"],"mappings":"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","file":"chunk-GTTXRDXV.js","sourcesContent":["/* Every value is a token (--menu-*). Position comes in as --_x/--_y from the floating hook. */\n\n@layer components {\n .content {\n --_gap: var(--menu-gap);\n\n position: fixed;\n z-index: var(--menu-layer);\n inset-block-start: var(--_y);\n inset-inline-start: var(--_x);\n display: flex;\n flex-direction: column;\n min-inline-size: var(--menu-min-width);\n max-inline-size: calc(100vw - 2 * var(--space-4));\n padding: var(--menu-padding);\n border: var(--size-hairline) solid var(--menu-border);\n border-radius: var(--menu-radius);\n background-color: var(--menu-bg);\n color: var(--menu-fg);\n font-family: var(--font-family-body);\n box-shadow: var(--menu-shadow);\n animation: fade var(--menu-duration) var(--motion-easing-standard);\n\n &:focus-visible {\n outline: var(--menu-focus-ring-width) solid var(--menu-focus-ring);\n outline-offset: var(--menu-focus-ring-offset);\n }\n }\n\n .item {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n inline-size: 100%;\n padding-block: var(--menu-item-padding-block);\n padding-inline: var(--menu-item-padding-inline);\n border: none;\n border-radius: var(--menu-item-radius);\n background-color: transparent;\n color: var(--menu-item-fg);\n font-size: var(--menu-item-font-size);\n text-align: start;\n cursor: pointer;\n\n &[data-tone=\"danger\"] {\n color: var(--menu-item-fg-danger);\n }\n\n &[data-disabled] {\n color: var(--menu-item-fg-muted);\n cursor: not-allowed;\n }\n\n &:focus-visible {\n outline: none;\n background-color: var(--menu-item-bg-active);\n }\n\n &:hover:not([data-disabled]) {\n background-color: var(--menu-item-bg-active);\n }\n }\n\n .label {\n flex: 1;\n }\n\n .separator {\n block-size: var(--size-hairline);\n margin-block: var(--menu-padding);\n background-color: var(--menu-separator);\n }\n\n @keyframes fade {\n from {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .content {\n animation: none;\n }\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { Icon } from '../icon';\nimport { renderAsChild } from '../internal/asChild';\nimport { classes } from '../internal/classes';\nimport { useFloatingPosition, type FloatingPlacement } from '../internal/floating';\nimport { useDismiss } from '../internal/useDismiss';\nimport { useRovingFocus } from '../internal/useRovingFocus';\nimport styles from './Menu.module.css';\n\nexport type MenuPlacement = FloatingPlacement;\ntype FocusTarget = 'first' | 'last' | null;\n\ninterface MenuContextValue {\n open: boolean;\n setOpen: (open: boolean, focus?: FocusTarget) => void;\n focusTarget: FocusTarget;\n triggerId: string;\n contentId: string;\n floating: ReturnType<typeof useFloatingPosition>;\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null);\n\nfunction useMenu(part: string): MenuContextValue {\n const context = useContext(MenuContext);\n if (!context) throw new Error(`${part} must be rendered inside <Menu>`);\n return context;\n}\n\nexport interface MenuProps {\n open?: boolean;\n /** @default false */\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** @default 'bottom-start' */\n placement?: MenuPlacement;\n children: ReactNode;\n}\n\n/**\n * A list of actions opened from a button, following the WAI-ARIA menu\n * button pattern: Down/Up arrow on the trigger opens and focuses the first\n * or last item, arrows move with wraparound, Home and End jump, typing\n * jumps to the next item starting with that letter, Enter, Space or click\n * selects and closes, Escape and Tab close and return focus. Compose with\n * `Menu.Trigger`, `Menu.Content`, `Menu.Item` and `Menu.Separator`.\n *\n * @status stable\n * @category Overlays\n * @accessibility The WAI-ARIA menu button pattern: the trigger has `aria-haspopup=\"menu\"` and `aria-expanded`; the popup is `role=\"menu\"` named by the trigger with `menuitem` children. Down/Up opens to the first/last item, arrows wrap, Home/End jump, typing jumps, Enter/Space/click select and close, Escape and Tab close and return focus.\n * @do Use `tone=\"danger\"` for destructive items and put them after a separator.\n * @dont Put form controls or links that navigate inside a menu; those want Popover or a navigation list.\n * Use it for navigation between pages.\n */\nexport function Menu({ open, defaultOpen = false, onOpenChange, placement = 'bottom-start', children }: MenuProps) {\n const [uncontrolled, setUncontrolled] = useState(defaultOpen);\n const [focusTarget, setFocusTarget] = useState<FocusTarget>(null);\n const controlled = open !== undefined;\n const isOpen = controlled ? open : uncontrolled;\n const setOpen = useCallback(\n (next: boolean, focus: FocusTarget = null) => {\n setFocusTarget(next ? focus : null);\n if (!controlled) setUncontrolled(next);\n onOpenChange?.(next);\n },\n [controlled, onOpenChange],\n );\n const id = useId();\n const floating = useFloatingPosition({ open: isOpen, placement });\n\n return (\n <MenuContext.Provider value={{ open: isOpen, setOpen, focusTarget, triggerId: `${id}-trigger`, contentId: `${id}-menu`, floating }}>\n {children}\n </MenuContext.Provider>\n );\n}\n\nfunction mergeRefs<T>(a: Ref<T> | undefined, b: (node: T | null) => void) {\n return (node: T | null) => {\n b(node);\n if (typeof a === 'function') a(node);\n else if (a) a.current = node;\n };\n}\n\ninterface MenuTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n asChild?: boolean;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction MenuTrigger({ asChild = false, onClick, onKeyDown, ref, children, ...rest }: MenuTriggerProps) {\n const menu = useMenu('Menu.Trigger');\n const props = {\n ...rest,\n id: menu.triggerId,\n 'aria-haspopup': 'menu' as const,\n 'aria-expanded': menu.open,\n 'aria-controls': menu.open ? menu.contentId : undefined,\n onClick: (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (!event.defaultPrevented) menu.setOpen(!menu.open, 'first');\n },\n onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n menu.setOpen(true, event.key === 'ArrowDown' ? 'first' : 'last');\n }\n },\n };\n const setRef = mergeRefs(ref, menu.floating.refs.setReference);\n // eslint-disable-next-line react-hooks/refs -- forwarded to the reference element, not read\n if (asChild) return renderAsChild('Menu.Trigger', children, { ...props, ref: setRef });\n return (\n <button type=\"button\" {...props} ref={setRef}>\n {children}\n </button>\n );\n}\n\ninterface MenuContentProps extends HTMLAttributes<HTMLDivElement> {\n ref?: Ref<HTMLDivElement>;\n children: ReactNode;\n}\n\nfunction MenuContent({ className, onKeyDown, ref, children, ...rest }: MenuContentProps) {\n const menu = useMenu('Menu.Content');\n const { refs, positionStyle, placement } = menu.floating;\n const contentRef = useRef<HTMLDivElement | null>(null);\n const rove = useRovingFocus({ orientation: 'vertical', selector: '[role=\"menuitem\"]' });\n\n useDismiss({\n open: menu.open,\n onDismiss: () => menu.setOpen(false),\n inside: () => [refs.reference.current as Element | null, refs.floating.current],\n });\n\n useEffect(() => {\n if (!menu.open) return;\n const content = contentRef.current;\n if (!content) return;\n const items = Array.from(content.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])'));\n const target = menu.focusTarget === 'last' ? items.at(-1) : items[0];\n (target ?? content).focus();\n return () => {\n const reference = refs.reference.current as HTMLElement | null;\n if (content.contains(document.activeElement) || document.activeElement === document.body) reference?.focus();\n };\n }, [menu.open, menu.focusTarget, refs.reference]);\n\n const typeahead = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key.length !== 1 || event.altKey || event.ctrlKey || event.metaKey) return false;\n const items = Array.from(event.currentTarget.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])'));\n const current = items.indexOf(document.activeElement as HTMLElement);\n const ordered = [...items.slice(current + 1), ...items.slice(0, current + 1)];\n const match = ordered.find((item) => item.textContent?.trim().toLowerCase().startsWith(event.key.toLowerCase()));\n if (!match) return false;\n event.preventDefault();\n match.focus();\n return true;\n };\n\n if (!menu.open) return null;\n return createPortal(\n <div\n {...rest}\n ref={mergeRefs(ref, (node) => {\n contentRef.current = node;\n refs.setFloating(node);\n })}\n id={menu.contentId}\n role=\"menu\"\n aria-labelledby={menu.triggerId}\n tabIndex={-1}\n className={classes(styles.content, className)}\n data-placement={placement}\n // eslint-disable-next-line react/forbid-dom-props -- per-instance position (--_x/--_y), see internal/floating.ts\n style={positionStyle}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) return;\n if (event.key === 'Tab') {\n menu.setOpen(false);\n return;\n }\n if (typeahead(event)) return;\n rove(event);\n }}\n >\n {children}\n </div>,\n document.body,\n );\n}\n\nexport type MenuItemTone = 'default' | 'danger';\n\ninterface MenuItemProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onSelect'> {\n /** Called when the item is chosen; the menu closes afterwards. */\n onSelect?: () => void;\n /** @default 'default' */\n tone?: MenuItemTone;\n /** Leading glyph, decorative. */\n icon?: ReactNode;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n}\n\nfunction MenuItem({ onSelect, tone = 'default', icon, disabled, className, onClick, ref, children, ...rest }: MenuItemProps) {\n const menu = useMenu('Menu.Item');\n return (\n <button\n {...rest}\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n aria-disabled={disabled || undefined}\n className={classes(styles.item, className)}\n data-tone={tone}\n data-disabled={disabled ? '' : undefined}\n onClick={(event) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) return;\n onSelect?.();\n menu.setOpen(false);\n }}\n >\n {icon && <Icon size=\"inherit\">{icon}</Icon>}\n <span className={styles.label}>{children}</span>\n </button>\n );\n}\n\nfunction MenuSeparator({ className, ...rest }: HTMLAttributes<HTMLDivElement>) {\n return <div {...rest} role=\"separator\" className={classes(styles.separator, className)} />;\n}\n\nMenu.displayName = 'Menu';\nMenuTrigger.displayName = 'Menu.Trigger';\nMenuContent.displayName = 'Menu.Content';\nMenuItem.displayName = 'Menu.Item';\nMenuSeparator.displayName = 'Menu.Separator';\n\nMenu.Trigger = MenuTrigger;\nMenu.Content = MenuContent;\nMenu.Item = MenuItem;\nMenu.Separator = MenuSeparator;\n"]}
@@ -0,0 +1,31 @@
1
+ import { VisuallyHidden } from './chunk-Z4PN6B2C.js';
2
+ import { classes } from './chunk-MI4QUKQS.js';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ // src/spinner/Spinner.module.css
6
+ var Spinner_default = {
7
+ spinner: "Spinner_spinner",
8
+ ring: "Spinner_ring"};
9
+ function Spinner({ size = "md", tone = "default", label = "Loading", decorative = false, className, ref, ...rest }) {
10
+ return /* @__PURE__ */ jsxs(
11
+ "span",
12
+ {
13
+ ...rest,
14
+ ref,
15
+ className: classes(Spinner_default.spinner, className),
16
+ "data-size": size,
17
+ "data-tone": tone,
18
+ role: decorative ? void 0 : "status",
19
+ "aria-hidden": decorative || void 0,
20
+ children: [
21
+ /* @__PURE__ */ jsx("span", { className: Spinner_default.ring, "aria-hidden": "true" }),
22
+ !decorative && /* @__PURE__ */ jsx(VisuallyHidden, { children: label })
23
+ ]
24
+ }
25
+ );
26
+ }
27
+ Spinner.displayName = "Spinner";
28
+
29
+ export { Spinner };
30
+ //# sourceMappingURL=chunk-I4KC4V6A.js.map
31
+ //# sourceMappingURL=chunk-I4KC4V6A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/spinner/Spinner.module.css","../src/spinner/Spinner.tsx"],"names":["spinner","ring"],"mappings":";;;;;AAAA,IAAA,eAAA,GAAA;AAAA,EAGG,OAAA,EAAAA,iBAAAA;AAAA,EAqBA,IAAA,EAAAC,cAMY,CAAA;ACER,SAAS,OAAA,CAAQ,EAAE,IAAA,GAAO,IAAA,EAAM,OAAO,SAAA,EAAW,KAAA,GAAQ,SAAA,EAAW,UAAA,GAAa,KAAA,EAAO,SAAA,EAAW,GAAA,EAAK,GAAG,MAAK,EAAiB;AACvI,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MACA,SAAA,EAAW,OAAA,CAAQ,eAAA,CAAO,OAAA,EAAS,SAAS,CAAA;AAAA,MAC5C,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,IAAA;AAAA,MACX,IAAA,EAAM,aAAa,MAAA,GAAY,QAAA;AAAA,MAC/B,eAAa,UAAA,IAAc,MAAA;AAAA,MAE3B,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAW,eAAA,CAAO,IAAA,EAAM,eAAY,MAAA,EAAO,CAAA;AAAA,QAChD,CAAC,UAAA,oBAAc,GAAA,CAAC,cAAA,EAAA,EAAgB,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,GACzC;AAEJ;AAEA,OAAA,CAAQ,WAAA,GAAc,SAAA","file":"chunk-I4KC4V6A.js","sourcesContent":["/* Every value is a token (--spinner-*). The ring is a border with one coloured side. */\n\n@layer components {\n .spinner {\n --_size: var(--spinner-size-md);\n --_track: var(--spinner-track);\n --_indicator: var(--spinner-indicator);\n\n display: inline-flex;\n flex: none;\n inline-size: var(--_size);\n block-size: var(--_size);\n vertical-align: middle;\n\n &[data-size=\"sm\"] { --_size: var(--spinner-size-sm); }\n &[data-size=\"lg\"] { --_size: var(--spinner-size-lg); }\n &[data-size=\"inherit\"] { --_size: 1em; }\n\n &[data-tone=\"inherit\"] {\n --_track: transparent;\n --_indicator: currentcolor;\n }\n }\n\n .ring {\n inline-size: 100%;\n block-size: 100%;\n border: var(--spinner-width) solid var(--_track);\n border-block-start-color: var(--_indicator);\n border-radius: var(--radius-full);\n animation: spin var(--spinner-duration) linear infinite;\n }\n\n @keyframes spin {\n to {\n rotate: 1turn;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .ring {\n animation: none;\n }\n }\n}\n","import type { HTMLAttributes, Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport { VisuallyHidden } from '../visually-hidden';\nimport styles from './Spinner.module.css';\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg' | 'inherit';\nexport type SpinnerTone = 'default' | 'inherit';\n\nexport interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {\n /** `inherit` follows the surrounding font size, for spinners inside controls. @default 'md' */\n size?: SpinnerSize;\n /** `inherit` draws with the surrounding text colour, for coloured controls. @default 'default' */\n tone?: SpinnerTone;\n /** Announced to assistive technology (`role=\"status\"`). @default 'Loading' */\n label?: string;\n /** Hide from assistive technology: the parent already announces busy. @default false */\n decorative?: boolean;\n ref?: Ref<HTMLSpanElement>;\n}\n\n/**\n * An indeterminate progress indicator. Announces its label as a status\n * unless `decorative`, in which case the parent is responsible (Button sets\n * `aria-busy`). Under reduced motion the ring stops but keeps its coloured\n * quarter, so it still reads as \"in progress\".\n *\n * @status stable\n * @category Feedback\n * @accessibility `role=\"status\"` with a visually hidden label (\"Loading\" by default) unless `decorative`, in which case the parent announces busy. Under reduced motion the ring stops but keeps its coloured quarter.\n * @do Use `decorative` inside a control that already sets `aria-busy`.\n * @dont Show several spinners for one operation.\n */\nexport function Spinner({ size = 'md', tone = 'default', label = 'Loading', decorative = false, className, ref, ...rest }: SpinnerProps) {\n return (\n <span\n {...rest}\n ref={ref}\n className={classes(styles.spinner, className)}\n data-size={size}\n data-tone={tone}\n role={decorative ? undefined : 'status'}\n aria-hidden={decorative || undefined}\n >\n <span className={styles.ring} aria-hidden=\"true\" />\n {!decorative && <VisuallyHidden>{label}</VisuallyHidden>}\n </span>\n );\n}\n\nSpinner.displayName = 'Spinner';\n"]}