@allxsmith/bestax-bulma 5.57.5 → 5.59.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 (112) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Avatars.js +2 -2
  4. package/dist/esm/components/Avatars.js.map +1 -1
  5. package/dist/esm/components/Badge.js +2 -2
  6. package/dist/esm/components/Badge.js.map +1 -1
  7. package/dist/esm/components/Pagination.js +2 -2
  8. package/dist/esm/components/Pagination.js.map +1 -1
  9. package/dist/esm/components/Steps.js +2 -2
  10. package/dist/esm/components/Steps.js.map +1 -1
  11. package/dist/esm/components/TreeView.js +7 -5
  12. package/dist/esm/components/TreeView.js.map +1 -1
  13. package/dist/esm/components/useDataTable.js +2 -2
  14. package/dist/esm/components/useDataTable.js.map +1 -1
  15. package/dist/esm/elements/Buttons.js +2 -0
  16. package/dist/esm/elements/Buttons.js.map +1 -1
  17. package/dist/esm/elements/IconButton.js +114 -0
  18. package/dist/esm/elements/IconButton.js.map +1 -0
  19. package/dist/esm/elements/NumberFormatter.js +42 -0
  20. package/dist/esm/elements/NumberFormatter.js.map +1 -0
  21. package/dist/esm/elements/RingProgress.js +2 -2
  22. package/dist/esm/elements/RingProgress.js.map +1 -1
  23. package/dist/esm/form/Dropzone.js +2 -2
  24. package/dist/esm/form/Dropzone.js.map +1 -1
  25. package/dist/esm/form/File.js +2 -2
  26. package/dist/esm/form/File.js.map +1 -1
  27. package/dist/esm/form/Rate.js +2 -2
  28. package/dist/esm/form/Rate.js.map +1 -1
  29. package/dist/esm/form/Slider.js +2 -2
  30. package/dist/esm/form/Slider.js.map +1 -1
  31. package/dist/esm/form/Taginput.js +2 -2
  32. package/dist/esm/form/Taginput.js.map +1 -1
  33. package/dist/esm/form/_colorInternals/pickerState.js +2 -2
  34. package/dist/esm/form/_colorInternals/pickerState.js.map +1 -1
  35. package/dist/esm/helpers/LocaleProvider.js +13 -6
  36. package/dist/esm/helpers/LocaleProvider.js.map +1 -1
  37. package/dist/esm/helpers/containerBreakpoints.js +14 -0
  38. package/dist/esm/helpers/containerBreakpoints.js.map +1 -0
  39. package/dist/esm/helpers/localeFormat.js +196 -36
  40. package/dist/esm/helpers/localeFormat.js.map +1 -1
  41. package/dist/esm/helpers/polymorphic.js.map +1 -1
  42. package/dist/esm/helpers/stackLayout.js +30 -0
  43. package/dist/esm/helpers/stackLayout.js.map +1 -0
  44. package/dist/esm/helpers/useBulmaClasses.js +8 -2
  45. package/dist/esm/helpers/useBulmaClasses.js.map +1 -1
  46. package/dist/esm/helpers/useFlexboxClasses.js +17 -4
  47. package/dist/esm/helpers/useFlexboxClasses.js.map +1 -1
  48. package/dist/esm/helpers/useTreeView.js +54 -20
  49. package/dist/esm/helpers/useTreeView.js.map +1 -1
  50. package/dist/esm/layout/Center.js +33 -0
  51. package/dist/esm/layout/Center.js.map +1 -0
  52. package/dist/esm/layout/Container.js +2 -6
  53. package/dist/esm/layout/Container.js.map +1 -1
  54. package/dist/esm/layout/Flex.js +34 -0
  55. package/dist/esm/layout/Flex.js.map +1 -0
  56. package/dist/esm/layout/Group.js +43 -0
  57. package/dist/esm/layout/Group.js.map +1 -0
  58. package/dist/esm/layout/Stack.js +34 -0
  59. package/dist/esm/layout/Stack.js.map +1 -0
  60. package/dist/extras.css +1 -1
  61. package/dist/extras.css.map +1 -1
  62. package/dist/index.cjs +712 -212
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.esm.js +7 -0
  65. package/dist/index.esm.js.map +1 -1
  66. package/dist/types/components/TreeView.d.ts +20 -11
  67. package/dist/types/elements/Buttons.d.ts +1 -0
  68. package/dist/types/elements/IconButton.d.ts +110 -0
  69. package/dist/types/elements/NumberFormatter.d.ts +62 -0
  70. package/dist/types/helpers/LocaleProvider.d.ts +7 -0
  71. package/dist/types/helpers/containerBreakpoints.d.ts +2 -0
  72. package/dist/types/helpers/localeFormat.d.ts +30 -8
  73. package/dist/types/helpers/polymorphic.d.ts +19 -0
  74. package/dist/types/helpers/stackLayout.d.ts +62 -0
  75. package/dist/types/helpers/useBulmaClasses.d.ts +8 -2
  76. package/dist/types/helpers/useFlexboxClasses.d.ts +26 -3
  77. package/dist/types/helpers/useTreeView.d.ts +12 -6
  78. package/dist/types/index.d.ts +10 -1
  79. package/dist/types/layout/Center.d.ts +54 -0
  80. package/dist/types/layout/Flex.d.ts +92 -0
  81. package/dist/types/layout/Group.d.ts +86 -0
  82. package/dist/types/layout/Stack.d.ts +63 -0
  83. package/dist/types-cjs/components/TreeView.d.ts +20 -11
  84. package/dist/types-cjs/elements/Buttons.d.ts +1 -0
  85. package/dist/types-cjs/elements/IconButton.d.ts +110 -0
  86. package/dist/types-cjs/elements/NumberFormatter.d.ts +62 -0
  87. package/dist/types-cjs/helpers/LocaleProvider.d.ts +7 -0
  88. package/dist/types-cjs/helpers/containerBreakpoints.d.ts +2 -0
  89. package/dist/types-cjs/helpers/localeFormat.d.ts +30 -8
  90. package/dist/types-cjs/helpers/polymorphic.d.ts +19 -0
  91. package/dist/types-cjs/helpers/stackLayout.d.ts +62 -0
  92. package/dist/types-cjs/helpers/useBulmaClasses.d.ts +8 -2
  93. package/dist/types-cjs/helpers/useFlexboxClasses.d.ts +26 -3
  94. package/dist/types-cjs/helpers/useTreeView.d.ts +12 -6
  95. package/dist/types-cjs/index.d.ts +10 -1
  96. package/dist/types-cjs/layout/Center.d.ts +54 -0
  97. package/dist/types-cjs/layout/Flex.d.ts +92 -0
  98. package/dist/types-cjs/layout/Group.d.ts +86 -0
  99. package/dist/types-cjs/layout/Stack.d.ts +63 -0
  100. package/dist/versions/bestax-no-dark-mode.css +1 -1
  101. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  102. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  103. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  104. package/dist/versions/bestax-no-helpers.css +1 -1
  105. package/dist/versions/bestax-no-helpers.css.map +1 -1
  106. package/dist/versions/bestax-prefixed.css +1 -1
  107. package/dist/versions/bestax-prefixed.css.map +1 -1
  108. package/package.json +1 -1
  109. package/src/scss/elements/_iconbutton.scss +36 -0
  110. package/src/scss/elements/_index.scss +1 -0
  111. package/src/scss/layout/_index.scss +1 -0
  112. package/src/scss/layout/_stack.scss +145 -0
@@ -6,15 +6,23 @@ import { getActiveElementInTree } from './shadowDom.js';
6
6
  import { useTypeahead, typeaheadMatch, typeaheadText } from './typeahead.js';
7
7
 
8
8
  // INTERNAL: deliberately not exported from src/index.ts.
9
+ /** The keys and clicks of both checkbox modes, which differ only in what a check reaches. */
10
+ const CHECKBOX_ACTIONS = {
11
+ enter: ['open'],
12
+ space: ['check'],
13
+ click: ['check'],
14
+ };
9
15
  /**
10
16
  * What Enter, Space and a click on the row do in each mode, from the tables
11
- * in #1096. `open` opens or closes a parent and does nothing on a leaf. A
12
- * click on the chevron only ever opens or closes.
17
+ * in #1096, with `checkbox-independent` from #1430. `open` opens or closes a
18
+ * parent and does nothing on a leaf. A click on the chevron only ever opens
19
+ * or closes.
13
20
  */
14
21
  const MODES = {
15
22
  none: { enter: ['open'], space: ['open'], click: ['open'] },
16
23
  single: { enter: ['select'], space: ['select'], click: ['select', 'open'] },
17
- checkbox: { enter: ['open'], space: ['check'], click: ['check'] },
24
+ checkbox: CHECKBOX_ACTIONS,
25
+ 'checkbox-independent': CHECKBOX_ACTIONS,
18
26
  };
19
27
  /** Left and Right, swapped for a right-to-left page. */
20
28
  const MIRRORED = {
@@ -155,6 +163,13 @@ function useControlled(controlled, initial) {
155
163
  };
156
164
  return [isControlled ? controlled : own, set];
157
165
  }
166
+ /**
167
+ * The list with `value` added at the end, or, when it's `present`, with
168
+ * every copy of it taken out. Everything else stays as it was, in its order.
169
+ */
170
+ function addedOrRemoved(list, value, present) {
171
+ return present ? list.filter(v => v !== value) : [...list, value];
172
+ }
158
173
  /**
159
174
  * The open state, the selection, the keys, the tab stop, the positions and
160
175
  * the registry of a TreeView (#1096). Focus moves for real, with a roving
@@ -163,10 +178,12 @@ function useControlled(controlled, initial) {
163
178
  * browser (#1171), read off the page once the tree has mounted.
164
179
  *
165
180
  * Every item registers its value, its parent and whether it's disabled from
166
- * a layout effect. In a checkbox tree a closed item's children still render
167
- * and register while drawing nothing, so the registry knows every item and a
168
- * check reaches all of them. The keys read the items on the page, in
169
- * document order, each time they need them.
181
+ * a layout effect. In a `checkbox` tree a closed item's children still
182
+ * render and register while drawing nothing, so the registry knows every item
183
+ * and a check reaches all of them. A `checkbox-independent` tree reads each
184
+ * box off the checked list alone, so a check adds or takes out its own value
185
+ * and nothing else. The keys read the items on the page, in document order,
186
+ * each time they need them.
170
187
  *
171
188
  * @function useTreeView
172
189
  * @param options - The TreeView's props.
@@ -182,9 +199,15 @@ function useTreeView(options) {
182
199
  const [expanded, setExpanded] = useControlled(options.expanded, options.defaultExpanded);
183
200
  const [selection, setSelection] = useControlled(options.selected, options.defaultSelected);
184
201
  const [checkedList, setChecked] = useControlled(options.checked, options.defaultChecked);
202
+ // In a `checkbox` tree a check reaches the items under it, by the rules. In
203
+ // a `checkbox-independent` one each box is its own item's, read off the list.
204
+ const cascade = mode === 'checkbox';
205
+ const independent = mode === 'checkbox-independent';
206
+ // A box on every item, in either checkbox tree.
207
+ const boxed = cascade || independent;
185
208
  // Each is read in its own mode only.
186
209
  const selected = mode === 'single' ? selection : null;
187
- const listed = new Set(mode === 'checkbox' ? checkedList : []);
210
+ const listed = new Set(boxed ? checkedList : []);
188
211
  const treeRef = useRef(null);
189
212
  const registryRef = useRef({
190
213
  records: new Map(),
@@ -205,21 +228,28 @@ function useTreeView(options) {
205
228
  // Each item's place among the items beside it, by its key.
206
229
  const [positions, setPositions] = useState(NO_POSITIONS);
207
230
  const { records } = registryRef.current;
208
- const checks = mode === 'checkbox'
231
+ const checks = cascade
209
232
  ? // eslint-disable-next-line react-hooks/refs -- read in render on purpose: items write the registry from their layout effects and then ask for this render with `refresh`
210
233
  readChecks(records, listed).states
211
234
  : undefined;
212
235
  const tabStop = focused ?? (resting === undefined ? selected : resting);
236
+ // An item's box, decided here alone, so the box drawn, the tab stop and a
237
+ // toggle agree: off the list in a `checkbox-independent` tree, and by the
238
+ // rules in a `checkbox` one, where it's `undefined` until the item
239
+ // registers. `undefined` in a tree with no boxes.
240
+ const checkOf = (value) => independent ? listed.has(value) : checks?.get(value);
213
241
  const isOpen = (value) => expanded.includes(value);
214
242
  const stateOf = (value, path, disabled) => {
215
243
  if (mode === 'single') {
216
244
  return disabled ? {} : { selected: value === selected };
217
245
  }
218
- if (checks) {
219
- // Until the items register, a value stands for its branch, and a
220
- // parent can't know it's mixed.
221
- const fromList = listed.has(value) || (!disabled && path.some(v => listed.has(v)));
222
- return { checked: checks.get(value) ?? fromList };
246
+ if (boxed) {
247
+ // Until the items register in a `checkbox` tree, a value stands for
248
+ // its branch, and a parent can't know it's mixed.
249
+ return {
250
+ checked: checkOf(value) ??
251
+ (listed.has(value) || (!disabled && path.some(v => listed.has(v)))),
252
+ };
223
253
  }
224
254
  return {};
225
255
  };
@@ -229,9 +259,8 @@ function useTreeView(options) {
229
259
  };
230
260
  const run = {
231
261
  open: ({ value, isParent, open }) => {
232
- if (isParent) {
233
- changeOpen(open ? expanded.filter(v => v !== value) : [...expanded, value]);
234
- }
262
+ if (isParent)
263
+ changeOpen(addedOrRemoved(expanded, value, open));
235
264
  },
236
265
  select: ({ value }) => {
237
266
  if (value === selected)
@@ -240,7 +269,11 @@ function useTreeView(options) {
240
269
  options.onSelectedChange?.(value);
241
270
  },
242
271
  check: ({ value }) => {
243
- const next = toggledList(records, checkedList, value);
272
+ // A `checkbox-independent` box is its own item's alone, so its value
273
+ // comes or goes and the rest of the list stays as it was.
274
+ const next = independent
275
+ ? addedOrRemoved(checkedList, value, checkOf(value) === true)
276
+ : toggledList(records, checkedList, value);
244
277
  setChecked(next);
245
278
  options.onCheckedChange?.(next);
246
279
  },
@@ -289,7 +322,7 @@ function useTreeView(options) {
289
322
  }
290
323
  if (focused !== null && !isShown(focused))
291
324
  setFocused(null);
292
- const preferred = onPage.find(value => value === selected || checks?.get(value) === true);
325
+ const preferred = onPage.find(value => value === selected || checkOf(value) === true);
293
326
  const next = preferred ?? (isShown(resting) ? resting : heir(restingPathRef.current));
294
327
  if (next !== resting) {
295
328
  setResting(next);
@@ -428,7 +461,8 @@ function useTreeView(options) {
428
461
  };
429
462
  return {
430
463
  treeRef,
431
- rendersClosed: mode === 'checkbox',
464
+ rendersClosed: cascade,
465
+ multiselectable: boxed,
432
466
  tabStop,
433
467
  isOpen,
434
468
  stateOf,
@@ -1 +1 @@
1
- {"version":3,"file":"useTreeView.js","sources":["../../../src/helpers/useTreeView.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport { useCallback, useEffect, useReducer, useRef, useState } from 'react';\nimport type React from 'react';\nimport type { TreeViewSelectionMode } from '../components/TreeView';\nimport { useClientLayoutEffect } from './useClientLayoutEffect';\nimport { getActiveElementInTree } from './shadowDom';\nimport { typeaheadMatch, typeaheadText, useTypeahead } from './typeahead';\n\n/** What an item tells the tree about itself when it registers. */\nexport interface TreeViewItemRecord {\n /** The value of the item it's in, or `null` at the top. */\n parent: string | null;\n disabled: boolean;\n /** It has children, or `hasChildren` says it will. */\n isParent: boolean;\n}\n\n/** An item as a key or a click on it sees it. */\nexport interface TreeViewItemInfo extends TreeViewItemRecord {\n value: string;\n open: boolean;\n /**\n * A failed load's row: what Enter, Space and a click on it do, in place of\n * what the mode says.\n */\n retry?: () => void;\n}\n\n/** A box's state: checked, unchecked or mixed. */\nexport type TreeViewCheckState = boolean | 'mixed';\n\n/**\n * Where an item sits among the items beside it, for its `aria-posinset` and\n * `aria-setsize`: its number, from 1, and how many there are.\n */\nexport interface TreeViewPosition {\n posinset: number;\n setsize: number;\n}\n\n/**\n * What an item shows of the selection: `selected` in a `single` tree,\n * `checked` in a `checkbox` tree, and neither with `none`.\n */\nexport interface TreeViewItemState {\n selected?: boolean;\n checked?: TreeViewCheckState;\n}\n\ntype Action = 'open' | 'select' | 'check';\n\n/**\n * What Enter, Space and a click on the row do in each mode, from the tables\n * in #1096. `open` opens or closes a parent and does nothing on a leaf. A\n * click on the chevron only ever opens or closes.\n */\nconst MODES: Record<\n TreeViewSelectionMode,\n { enter: Action[]; space: Action[]; click: Action[] }\n> = {\n none: { enter: ['open'], space: ['open'], click: ['open'] },\n single: { enter: ['select'], space: ['select'], click: ['select', 'open'] },\n checkbox: { enter: ['open'], space: ['check'], click: ['check'] },\n};\n\n/** Left and Right, swapped for a right-to-left page. */\nconst MIRRORED: Record<string, string> = {\n ArrowLeft: 'ArrowRight',\n ArrowRight: 'ArrowLeft',\n};\n\n/** An IME is composing, so the key belongs to it (`keyCode` 229 is Safari's word for it). */\nconst isComposing = (event: React.KeyboardEvent): boolean =>\n event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229;\n\n/**\n * The items a tree knows, and their elements while they're on the page. A\n * loading item's row, or a failed load's, hands over its element under a key\n * of its own and has no record, so the keys reach it and nothing else counts it.\n */\ninterface Registry {\n records: Map<string, TreeViewItemRecord>;\n // By value, for an item whose ref lets go, which hands over no element.\n elements: Map<string, HTMLLIElement>;\n // Weak, so an element that leaves the page needn't be forgotten by hand.\n values: WeakMap<Element, string>;\n}\n\n/** The registry's items on the page, in document order. */\nconst shownIn = (tree: Element, { values }: Registry): HTMLElement[] =>\n Array.from(tree.querySelectorAll<HTMLElement>('[role=\"treeitem\"]')).filter(\n element => values.has(element)\n );\n\n/** The item an item on the page sits in: its group's `<li>`, or none at the top. */\nfunction parentItemOf(element: Element): HTMLElement | null {\n const group = element.parentElement!;\n return group.getAttribute('role') === 'group' ? group.parentElement : null;\n}\n\n/** No positions: on the server, and until the tree has mounted. */\nconst NO_POSITIONS = new Map<string, TreeViewPosition>();\n\n/**\n * Each item's place among the items beside it, by its key, read off the\n * items on the page: the ones in the same group, or at the top. A loading or\n * failed load's row counts, as it does for a browser that works positions\n * out for itself, so the declared ones say what a browser would.\n */\nfunction positionsOf(\n shown: HTMLElement[],\n { values }: Registry\n): Map<string, TreeViewPosition> {\n const sets = new Map<Element | null, HTMLElement[]>();\n shown.forEach(element => {\n const set = sets.get(element.parentElement);\n if (set) set.push(element);\n else sets.set(element.parentElement, [element]);\n });\n const positions = new Map<string, TreeViewPosition>();\n sets.forEach(set =>\n set.forEach((element, at) =>\n positions.set(values.get(element)!, {\n posinset: at + 1,\n setsize: set.length,\n })\n )\n );\n return positions;\n}\n\n/** Whether two sets of positions say the same for every item. */\nfunction samePositions(\n a: Map<string, TreeViewPosition>,\n b: Map<string, TreeViewPosition>\n): boolean {\n return (\n a.size === b.size &&\n Array.from(a).every(([key, { posinset, setsize }]) => {\n const other = b.get(key);\n return other?.posinset === posinset && other.setsize === setsize;\n })\n );\n}\n\n/** The values of the items an item on the page is in, from the top. */\nfunction pathOf(element: Element, { values }: Registry): string[] {\n const path: string[] = [];\n for (let at = parentItemOf(element); at; at = parentItemOf(at)) {\n path.unshift(values.get(at)!);\n }\n return path;\n}\n\n/**\n * Every known item's check state, by the rules in #1096:\n *\n * - a disabled item is checked only when its own value is listed;\n * - an enabled item with no enabled items anywhere under it is checked when\n * it, or any item above it, is listed;\n * - any other enabled item follows the items of that second kind in its\n * branch: checked when they all are, unchecked when none is, mixed between.\n *\n * Also returns the items of the second kind, which are what a toggle sets.\n */\nfunction readChecks(\n records: Map<string, TreeViewItemRecord>,\n listed: Set<string>\n): { states: Map<string, TreeViewCheckState>; ends: string[] } {\n const kids = new Map<string | null, string[]>();\n records.forEach(({ parent }, value) => {\n kids.set(parent, [...(kids.get(parent) ?? []), value]);\n });\n const states = new Map<string, TreeViewCheckState>();\n const ends: string[] = [];\n // How many enabled ends the branch holds, and how many are checked.\n const visit = (value: string, above: boolean): [number, number] => {\n const marked = above || listed.has(value);\n let total = 0;\n let on = 0;\n for (const kid of kids.get(value) ?? []) {\n const [t, o] = visit(kid, marked);\n total += t;\n on += o;\n }\n if (records.get(value)!.disabled) {\n states.set(value, listed.has(value));\n return [total, on];\n }\n if (total === 0) {\n states.set(value, marked);\n ends.push(value);\n return [1, marked ? 1 : 0];\n }\n states.set(value, on === total ? true : on > 0 && 'mixed');\n return [total, on];\n };\n for (const top of kids.get(null) ?? []) visit(top, false);\n return { states, ends };\n}\n\n/**\n * The list a toggle of `value` leaves: it and every enabled item under it\n * take the opposite of its state (a mixed one checks), and the rest is read\n * back by the rules. That's every item that shows checked, parents\n * included, plus any listed value no item has.\n */\nfunction toggledList(\n records: Map<string, TreeViewItemRecord>,\n list: string[],\n value: string\n): string[] {\n const { states, ends } = readChecks(records, new Set(list));\n const to = states.get(value) !== true;\n // An end was reached from the top, so everything above it is known.\n const under = (end: string) => {\n for (let at: string | null = end; at !== null;) {\n if (at === value) return true;\n at = records.get(at)!.parent;\n }\n return false;\n };\n const seed = new Set(\n ends.filter(end => (under(end) ? to : states.get(end) === true))\n );\n records.forEach(({ disabled }, item) => {\n if (disabled && states.get(item) === true) seed.add(item);\n });\n const after = readChecks(records, seed).states;\n return [\n ...Array.from(after)\n .filter(([, state]) => state === true)\n .map(([item]) => item),\n ...list.filter(item => !records.has(item)),\n ];\n}\n\n/** A value the caller holds, or one this hook holds when the caller doesn't. */\nfunction useControlled<T>(controlled: T | undefined, initial: T) {\n const [own, setOwn] = useState(initial);\n const isControlled = controlled !== undefined;\n const set = (next: T) => {\n if (!isControlled) setOwn(next);\n };\n return [isControlled ? controlled : own, set] as const;\n}\n\n/** Options for `useTreeView`: the TreeView's own props. */\nexport interface TreeViewOptions {\n mode: TreeViewSelectionMode;\n selected?: string | null;\n defaultSelected: string | null;\n onSelectedChange?: (value: string) => void;\n checked?: string[];\n defaultChecked: string[];\n onCheckedChange?: (checked: string[]) => void;\n expanded?: string[];\n defaultExpanded: string[];\n onExpandedChange?: (expanded: string[]) => void;\n}\n\n/** What `useTreeView` hands the root and its items. */\nexport interface TreeViewEngine {\n /** For the `<ul role=\"tree\">`. */\n treeRef: React.MutableRefObject<HTMLUListElement | null>;\n /**\n * Whether a closed item still renders its children, drawing nothing, so a\n * check knows everything under it. Only a checkbox tree needs to.\n */\n rendersClosed: boolean;\n /** The item that holds `tabIndex={0}`. */\n tabStop: string | null;\n isOpen: (value: string) => boolean;\n /**\n * What the item shows of the selection. `path` is the values of the items\n * above it, which decide its box until the items have registered, as on\n * the server.\n */\n stateOf: (\n value: string,\n path: string[],\n disabled: boolean\n ) => TreeViewItemState;\n /**\n * Where the item with this key sits among the items beside it, read off\n * the page after each render and whenever items move. Nothing until the\n * tree has mounted, as on the server.\n */\n positionOf: (key: string) => TreeViewPosition | undefined;\n /** Records an item from its layout effect. Returns the function that forgets it. */\n register: (value: string, record: TreeViewItemRecord) => () => void;\n /** For each item's `<li>` ref: records it, and notices focus leaving with it. */\n setElement: (value: string, element: HTMLLIElement | null) => void;\n /** Focus arrived on the item's own `<li>`. */\n onFocus: (value: string, element: HTMLLIElement) => void;\n /** Focus left the item's own `<li>`. */\n onBlur: () => void;\n /** A key on the item's `<li>`, after its own `onKeyDown`. */\n onKeyDown: (\n event: React.KeyboardEvent<HTMLLIElement>,\n item: TreeViewItemInfo\n ) => void;\n /**\n * A click on the item's row, or with `onToggle` on its chevron. Focus and\n * the tab stop move to the item.\n */\n onClick: (\n element: HTMLLIElement,\n item: TreeViewItemInfo,\n onToggle: boolean\n ) => void;\n}\n\n/**\n * The open state, the selection, the keys, the tab stop, the positions and\n * the registry of a TreeView (#1096). Focus moves for real, with a roving\n * tabindex, rather than through `aria-activedescendant`. Each item's\n * position among the items beside it is declared rather than left to the\n * browser (#1171), read off the page once the tree has mounted.\n *\n * Every item registers its value, its parent and whether it's disabled from\n * a layout effect. In a checkbox tree a closed item's children still render\n * and register while drawing nothing, so the registry knows every item and a\n * check reaches all of them. The keys read the items on the page, in\n * document order, each time they need them.\n *\n * @function useTreeView\n * @param options - The TreeView's props.\n * @returns The state and handlers the root and its items wire up.\n */\nexport function useTreeView(options: TreeViewOptions): TreeViewEngine {\n // An own key only, so a name every object inherits, like `toString`, is a\n // mode the tree doesn't know too.\n const mode = Object.prototype.hasOwnProperty.call(MODES, options.mode)\n ? options.mode\n : 'none';\n const actions = MODES[mode];\n\n const [expanded, setExpanded] = useControlled(\n options.expanded,\n options.defaultExpanded\n );\n const [selection, setSelection] = useControlled(\n options.selected,\n options.defaultSelected\n );\n const [checkedList, setChecked] = useControlled(\n options.checked,\n options.defaultChecked\n );\n // Each is read in its own mode only.\n const selected = mode === 'single' ? selection : null;\n const listed = new Set(mode === 'checkbox' ? checkedList : []);\n\n const treeRef = useRef<HTMLUListElement | null>(null);\n const registryRef = useRef<Registry>({\n records: new Map(),\n elements: new Map(),\n values: new WeakMap(),\n });\n // Items register from their own effects, so they ask for a render to be read.\n const [, refresh] = useReducer((n: number) => n + 1, 0);\n const typeahead = useTypeahead();\n\n // The item with focus, and where the stop rests while focus is elsewhere:\n // `undefined` until the tree has mounted. With the values above it, for\n // when it goes away.\n const [focused, setFocused] = useState<string | null>(null);\n const [resting, setResting] = useState<string | null | undefined>();\n const restingPathRef = useRef<string[]>([]);\n // The values above an item that left the page with focus in it.\n const lostRef = useRef<string[] | null>(null);\n // Each item's place among the items beside it, by its key.\n const [positions, setPositions] = useState(NO_POSITIONS);\n\n const { records } = registryRef.current;\n const checks =\n mode === 'checkbox'\n ? // eslint-disable-next-line react-hooks/refs -- read in render on purpose: items write the registry from their layout effects and then ask for this render with `refresh`\n readChecks(records, listed).states\n : undefined;\n const tabStop = focused ?? (resting === undefined ? selected : resting);\n\n const isOpen = (value: string) => expanded.includes(value);\n\n const stateOf = (\n value: string,\n path: string[],\n disabled: boolean\n ): TreeViewItemState => {\n if (mode === 'single') {\n return disabled ? {} : { selected: value === selected };\n }\n if (checks) {\n // Until the items register, a value stands for its branch, and a\n // parent can't know it's mixed.\n const fromList =\n listed.has(value) || (!disabled && path.some(v => listed.has(v)));\n return { checked: checks.get(value) ?? fromList };\n }\n return {};\n };\n\n const changeOpen = (next: string[]) => {\n setExpanded(next);\n options.onExpandedChange?.(next);\n };\n\n const run: Record<Action, (item: TreeViewItemInfo) => void> = {\n open: ({ value, isParent, open }) => {\n if (isParent) {\n changeOpen(\n open ? expanded.filter(v => v !== value) : [...expanded, value]\n );\n }\n },\n select: ({ value }) => {\n if (value === selected) return;\n setSelection(value);\n options.onSelectedChange?.(value);\n },\n check: ({ value }) => {\n const next = toggledList(records, checkedList, value);\n setChecked(next);\n options.onCheckedChange?.(next);\n },\n };\n\n /** Disabled items are never selected, checked, opened or closed. */\n const act = (item: TreeViewItemInfo, list: Action[]) => {\n if (!item.disabled) list.forEach(action => run[action](item));\n };\n\n /** Enter, Space and a click on the row: a failed load's row retries. */\n const press = (item: TreeViewItemInfo, list: Action[]) => {\n if (item.retry) item.retry();\n else act(item, list);\n };\n\n // After every render, read each item's position off the page, and put the\n // stop where it belongs. While focus is in the tree it's the focused item.\n // Otherwise it's the selected item, or the first checked one on the page,\n // and failing that it stays where it was. An item that goes away hands it\n // to its nearest ancestor on the page, or to the first item, and focus goes\n // with it if it had focus.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose: it reads the page, and sets state only when what it reads has changed\n useClientLayoutEffect(() => {\n const tree = treeRef.current!;\n const registry = registryRef.current;\n // Each item's element is read off the page with its value, rather than\n // out of `elements`, which holds one element per value: two items\n // sharing a value, which they shouldn't, can leave it without one the\n // page still has.\n const shown = shownIn(tree, registry);\n const placed = positionsOf(shown, registry);\n if (!samePositions(positions, placed)) setPositions(placed);\n const onPage = shown.map(element => registry.values.get(element)!);\n const elementOf = (value: string) => shown[onPage.indexOf(value)];\n const isShown = (value: string | null | undefined): value is string =>\n value != null && onPage.includes(value);\n const heir = (path: string[]) =>\n [...path].reverse().find(isShown) ?? onPage[0] ?? null;\n\n const lost = lostRef.current;\n lostRef.current = null;\n if (lost && !tree.contains(getActiveElementInTree(tree))) {\n const to = heir(lost);\n if (to) elementOf(to).focus();\n return;\n }\n if (focused !== null && !isShown(focused)) setFocused(null);\n\n const preferred = onPage.find(\n value => value === selected || checks?.get(value) === true\n );\n const next =\n preferred ?? (isShown(resting) ? resting : heir(restingPathRef.current));\n if (next !== resting) {\n setResting(next);\n restingPathRef.current = next ? pathOf(elementOf(next), registry) : [];\n }\n });\n\n // Items can also move without the tree rendering, such as children that a\n // component of the app sorts with state of its own. That changes no record,\n // so the page is watched for items coming, going and moving, and the\n // positions are read again.\n useEffect(() => {\n const tree = treeRef.current!;\n const observer = new MutationObserver(() => {\n const registry = registryRef.current;\n const placed = positionsOf(shownIn(tree, registry), registry);\n setPositions(current =>\n samePositions(current, placed) ? current : placed\n );\n });\n observer.observe(tree, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, []);\n\n const register = useCallback((value: string, record: TreeViewItemRecord) => {\n const { records: known } = registryRef.current;\n known.set(value, record);\n refresh();\n return () => {\n if (known.get(value) !== record) return;\n known.delete(value);\n refresh();\n };\n }, []);\n\n const setElement = useCallback(\n (value: string, element: HTMLLIElement | null) => {\n const registry = registryRef.current;\n if (element) {\n registry.elements.set(value, element);\n registry.values.set(element, value);\n return;\n }\n const gone = registry.elements.get(value);\n if (!gone) return;\n // The ref lets go before the element leaves the page, so it can still\n // say whether focus was in it, and where it sat.\n if (!lostRef.current && gone.contains(getActiveElementInTree(gone))) {\n lostRef.current = [...pathOf(gone, registry), value];\n }\n registry.elements.delete(value);\n },\n []\n );\n\n const onFocus = (value: string, element: HTMLLIElement) => {\n setFocused(value);\n setResting(value);\n restingPathRef.current = pathOf(element, registryRef.current);\n };\n\n const onBlur = () => setFocused(null);\n\n const onKeyDown = (\n event: React.KeyboardEvent<HTMLLIElement>,\n item: TreeViewItemInfo\n ) => {\n const element = event.currentTarget;\n // A key on an item inside this one bubbles here too, and is its own.\n if (\n event.target !== element ||\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n isComposing(event)\n ) {\n return;\n }\n const registry = registryRef.current;\n const items = shownIn(treeRef.current!, registry);\n const at = items.indexOf(element);\n const rtl = getComputedStyle(element).direction === 'rtl';\n const key = (rtl && MIRRORED[event.key]) || event.key;\n\n switch (key) {\n case 'ArrowDown':\n items[at + 1]?.focus();\n break;\n case 'ArrowUp':\n items[at - 1]?.focus();\n break;\n case 'Home':\n items[0].focus();\n break;\n case 'End':\n items[items.length - 1].focus();\n break;\n case 'ArrowRight': {\n const next = items[at + 1];\n if (!item.open) act(item, ['open']);\n else if (next && parentItemOf(next) === element) next.focus();\n break;\n }\n case 'ArrowLeft':\n if (item.open && !item.disabled) act(item, ['open']);\n else parentItemOf(element)?.focus();\n break;\n // A held key acts once.\n case 'Enter':\n if (!event.repeat) press(item, actions.enter);\n break;\n case ' ':\n if (!event.repeat) press(item, actions.space);\n break;\n case '*': {\n const closed: string[] = [];\n registry.records.forEach((record, value) => {\n if (\n record.parent === item.parent &&\n record.isParent &&\n !record.disabled &&\n !expanded.includes(value)\n ) {\n closed.push(value);\n }\n });\n if (closed.length) changeOpen([...expanded, ...closed]);\n break;\n }\n default:\n // Type-ahead takes a printable character. Anything else, Escape and\n // Tab included, is left to whatever is around the tree.\n if (event.key.length !== 1) return;\n typeaheadMatch(items, typeahead.type(event.key), at, el =>\n typeaheadText(el.firstElementChild!)\n )?.focus();\n }\n event.preventDefault();\n };\n\n const onClick = (\n element: HTMLLIElement,\n item: TreeViewItemInfo,\n onToggle: boolean\n ) => {\n element.focus();\n if (onToggle) act(item, ['open']);\n else press(item, actions.click);\n };\n\n return {\n treeRef,\n rendersClosed: mode === 'checkbox',\n tabStop,\n isOpen,\n stateOf,\n positionOf: key => positions.get(key),\n register,\n setElement,\n onFocus,\n onBlur,\n onKeyDown,\n onClick,\n };\n}\n"],"names":["isComposing"],"mappings":"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"}
1
+ {"version":3,"file":"useTreeView.js","sources":["../../../src/helpers/useTreeView.ts"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\nimport { useCallback, useEffect, useReducer, useRef, useState } from 'react';\nimport type React from 'react';\nimport type { TreeViewSelectionMode } from '../components/TreeView';\nimport { useClientLayoutEffect } from './useClientLayoutEffect';\nimport { getActiveElementInTree } from './shadowDom';\nimport { typeaheadMatch, typeaheadText, useTypeahead } from './typeahead';\n\n/** What an item tells the tree about itself when it registers. */\nexport interface TreeViewItemRecord {\n /** The value of the item it's in, or `null` at the top. */\n parent: string | null;\n disabled: boolean;\n /** It has children, or `hasChildren` says it will. */\n isParent: boolean;\n}\n\n/** An item as a key or a click on it sees it. */\nexport interface TreeViewItemInfo extends TreeViewItemRecord {\n value: string;\n open: boolean;\n /**\n * A failed load's row: what Enter, Space and a click on it do, in place of\n * what the mode says.\n */\n retry?: () => void;\n}\n\n/** A box's state: checked, unchecked or mixed. */\nexport type TreeViewCheckState = boolean | 'mixed';\n\n/**\n * Where an item sits among the items beside it, for its `aria-posinset` and\n * `aria-setsize`: its number, from 1, and how many there are.\n */\nexport interface TreeViewPosition {\n posinset: number;\n setsize: number;\n}\n\n/**\n * What an item shows of the selection: `selected` in a `single` tree,\n * `checked` in a `checkbox` or `checkbox-independent` tree, and neither with\n * `none`.\n */\nexport interface TreeViewItemState {\n selected?: boolean;\n checked?: TreeViewCheckState;\n}\n\ntype Action = 'open' | 'select' | 'check';\n\n/** What Enter, Space and a click on the row do in a mode. */\ninterface ModeActions {\n enter: Action[];\n space: Action[];\n click: Action[];\n}\n\n/** The keys and clicks of both checkbox modes, which differ only in what a check reaches. */\nconst CHECKBOX_ACTIONS: ModeActions = {\n enter: ['open'],\n space: ['check'],\n click: ['check'],\n};\n\n/**\n * What Enter, Space and a click on the row do in each mode, from the tables\n * in #1096, with `checkbox-independent` from #1430. `open` opens or closes a\n * parent and does nothing on a leaf. A click on the chevron only ever opens\n * or closes.\n */\nconst MODES: Record<TreeViewSelectionMode, ModeActions> = {\n none: { enter: ['open'], space: ['open'], click: ['open'] },\n single: { enter: ['select'], space: ['select'], click: ['select', 'open'] },\n checkbox: CHECKBOX_ACTIONS,\n 'checkbox-independent': CHECKBOX_ACTIONS,\n};\n\n/** Left and Right, swapped for a right-to-left page. */\nconst MIRRORED: Record<string, string> = {\n ArrowLeft: 'ArrowRight',\n ArrowRight: 'ArrowLeft',\n};\n\n/** An IME is composing, so the key belongs to it (`keyCode` 229 is Safari's word for it). */\nconst isComposing = (event: React.KeyboardEvent): boolean =>\n event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229;\n\n/**\n * The items a tree knows, and their elements while they're on the page. A\n * loading item's row, or a failed load's, hands over its element under a key\n * of its own and has no record, so the keys reach it and nothing else counts it.\n */\ninterface Registry {\n records: Map<string, TreeViewItemRecord>;\n // By value, for an item whose ref lets go, which hands over no element.\n elements: Map<string, HTMLLIElement>;\n // Weak, so an element that leaves the page needn't be forgotten by hand.\n values: WeakMap<Element, string>;\n}\n\n/** The registry's items on the page, in document order. */\nconst shownIn = (tree: Element, { values }: Registry): HTMLElement[] =>\n Array.from(tree.querySelectorAll<HTMLElement>('[role=\"treeitem\"]')).filter(\n element => values.has(element)\n );\n\n/** The item an item on the page sits in: its group's `<li>`, or none at the top. */\nfunction parentItemOf(element: Element): HTMLElement | null {\n const group = element.parentElement!;\n return group.getAttribute('role') === 'group' ? group.parentElement : null;\n}\n\n/** No positions: on the server, and until the tree has mounted. */\nconst NO_POSITIONS = new Map<string, TreeViewPosition>();\n\n/**\n * Each item's place among the items beside it, by its key, read off the\n * items on the page: the ones in the same group, or at the top. A loading or\n * failed load's row counts, as it does for a browser that works positions\n * out for itself, so the declared ones say what a browser would.\n */\nfunction positionsOf(\n shown: HTMLElement[],\n { values }: Registry\n): Map<string, TreeViewPosition> {\n const sets = new Map<Element | null, HTMLElement[]>();\n shown.forEach(element => {\n const set = sets.get(element.parentElement);\n if (set) set.push(element);\n else sets.set(element.parentElement, [element]);\n });\n const positions = new Map<string, TreeViewPosition>();\n sets.forEach(set =>\n set.forEach((element, at) =>\n positions.set(values.get(element)!, {\n posinset: at + 1,\n setsize: set.length,\n })\n )\n );\n return positions;\n}\n\n/** Whether two sets of positions say the same for every item. */\nfunction samePositions(\n a: Map<string, TreeViewPosition>,\n b: Map<string, TreeViewPosition>\n): boolean {\n return (\n a.size === b.size &&\n Array.from(a).every(([key, { posinset, setsize }]) => {\n const other = b.get(key);\n return other?.posinset === posinset && other.setsize === setsize;\n })\n );\n}\n\n/** The values of the items an item on the page is in, from the top. */\nfunction pathOf(element: Element, { values }: Registry): string[] {\n const path: string[] = [];\n for (let at = parentItemOf(element); at; at = parentItemOf(at)) {\n path.unshift(values.get(at)!);\n }\n return path;\n}\n\n/**\n * Every known item's check state, by the rules in #1096:\n *\n * - a disabled item is checked only when its own value is listed;\n * - an enabled item with no enabled items anywhere under it is checked when\n * it, or any item above it, is listed;\n * - any other enabled item follows the items of that second kind in its\n * branch: checked when they all are, unchecked when none is, mixed between.\n *\n * Also returns the items of the second kind, which are what a toggle sets.\n */\nfunction readChecks(\n records: Map<string, TreeViewItemRecord>,\n listed: Set<string>\n): { states: Map<string, TreeViewCheckState>; ends: string[] } {\n const kids = new Map<string | null, string[]>();\n records.forEach(({ parent }, value) => {\n kids.set(parent, [...(kids.get(parent) ?? []), value]);\n });\n const states = new Map<string, TreeViewCheckState>();\n const ends: string[] = [];\n // How many enabled ends the branch holds, and how many are checked.\n const visit = (value: string, above: boolean): [number, number] => {\n const marked = above || listed.has(value);\n let total = 0;\n let on = 0;\n for (const kid of kids.get(value) ?? []) {\n const [t, o] = visit(kid, marked);\n total += t;\n on += o;\n }\n if (records.get(value)!.disabled) {\n states.set(value, listed.has(value));\n return [total, on];\n }\n if (total === 0) {\n states.set(value, marked);\n ends.push(value);\n return [1, marked ? 1 : 0];\n }\n states.set(value, on === total ? true : on > 0 && 'mixed');\n return [total, on];\n };\n for (const top of kids.get(null) ?? []) visit(top, false);\n return { states, ends };\n}\n\n/**\n * The list a toggle of `value` leaves: it and every enabled item under it\n * take the opposite of its state (a mixed one checks), and the rest is read\n * back by the rules. That's every item that shows checked, parents\n * included, plus any listed value no item has.\n */\nfunction toggledList(\n records: Map<string, TreeViewItemRecord>,\n list: string[],\n value: string\n): string[] {\n const { states, ends } = readChecks(records, new Set(list));\n const to = states.get(value) !== true;\n // An end was reached from the top, so everything above it is known.\n const under = (end: string) => {\n for (let at: string | null = end; at !== null;) {\n if (at === value) return true;\n at = records.get(at)!.parent;\n }\n return false;\n };\n const seed = new Set(\n ends.filter(end => (under(end) ? to : states.get(end) === true))\n );\n records.forEach(({ disabled }, item) => {\n if (disabled && states.get(item) === true) seed.add(item);\n });\n const after = readChecks(records, seed).states;\n return [\n ...Array.from(after)\n .filter(([, state]) => state === true)\n .map(([item]) => item),\n ...list.filter(item => !records.has(item)),\n ];\n}\n\n/** A value the caller holds, or one this hook holds when the caller doesn't. */\nfunction useControlled<T>(controlled: T | undefined, initial: T) {\n const [own, setOwn] = useState(initial);\n const isControlled = controlled !== undefined;\n const set = (next: T) => {\n if (!isControlled) setOwn(next);\n };\n return [isControlled ? controlled : own, set] as const;\n}\n\n/**\n * The list with `value` added at the end, or, when it's `present`, with\n * every copy of it taken out. Everything else stays as it was, in its order.\n */\nfunction addedOrRemoved(\n list: string[],\n value: string,\n present: boolean\n): string[] {\n return present ? list.filter(v => v !== value) : [...list, value];\n}\n\n/** Options for `useTreeView`: the TreeView's own props. */\nexport interface TreeViewOptions {\n mode: TreeViewSelectionMode;\n selected?: string | null;\n defaultSelected: string | null;\n onSelectedChange?: (value: string) => void;\n checked?: string[];\n defaultChecked: string[];\n onCheckedChange?: (checked: string[]) => void;\n expanded?: string[];\n defaultExpanded: string[];\n onExpandedChange?: (expanded: string[]) => void;\n}\n\n/** What `useTreeView` hands the root and its items. */\nexport interface TreeViewEngine {\n /** For the `<ul role=\"tree\">`. */\n treeRef: React.MutableRefObject<HTMLUListElement | null>;\n /**\n * Whether a closed item still renders its children, drawing nothing, so a\n * check knows everything under it. Only a `checkbox` tree needs to: a check\n * in a `checkbox-independent` tree reaches nothing under it.\n */\n rendersClosed: boolean;\n /** Whether any number of items can be checked, in either checkbox mode. */\n multiselectable: boolean;\n /** The item that holds `tabIndex={0}`. */\n tabStop: string | null;\n isOpen: (value: string) => boolean;\n /**\n * What the item shows of the selection. `path` is the values of the items\n * above it, which decide its box until the items have registered, as on\n * the server.\n */\n stateOf: (\n value: string,\n path: string[],\n disabled: boolean\n ) => TreeViewItemState;\n /**\n * Where the item with this key sits among the items beside it, read off\n * the page after each render and whenever items move. Nothing until the\n * tree has mounted, as on the server.\n */\n positionOf: (key: string) => TreeViewPosition | undefined;\n /** Records an item from its layout effect. Returns the function that forgets it. */\n register: (value: string, record: TreeViewItemRecord) => () => void;\n /** For each item's `<li>` ref: records it, and notices focus leaving with it. */\n setElement: (value: string, element: HTMLLIElement | null) => void;\n /** Focus arrived on the item's own `<li>`. */\n onFocus: (value: string, element: HTMLLIElement) => void;\n /** Focus left the item's own `<li>`. */\n onBlur: () => void;\n /** A key on the item's `<li>`, after its own `onKeyDown`. */\n onKeyDown: (\n event: React.KeyboardEvent<HTMLLIElement>,\n item: TreeViewItemInfo\n ) => void;\n /**\n * A click on the item's row, or with `onToggle` on its chevron. Focus and\n * the tab stop move to the item.\n */\n onClick: (\n element: HTMLLIElement,\n item: TreeViewItemInfo,\n onToggle: boolean\n ) => void;\n}\n\n/**\n * The open state, the selection, the keys, the tab stop, the positions and\n * the registry of a TreeView (#1096). Focus moves for real, with a roving\n * tabindex, rather than through `aria-activedescendant`. Each item's\n * position among the items beside it is declared rather than left to the\n * browser (#1171), read off the page once the tree has mounted.\n *\n * Every item registers its value, its parent and whether it's disabled from\n * a layout effect. In a `checkbox` tree a closed item's children still\n * render and register while drawing nothing, so the registry knows every item\n * and a check reaches all of them. A `checkbox-independent` tree reads each\n * box off the checked list alone, so a check adds or takes out its own value\n * and nothing else. The keys read the items on the page, in document order,\n * each time they need them.\n *\n * @function useTreeView\n * @param options - The TreeView's props.\n * @returns The state and handlers the root and its items wire up.\n */\nexport function useTreeView(options: TreeViewOptions): TreeViewEngine {\n // An own key only, so a name every object inherits, like `toString`, is a\n // mode the tree doesn't know too.\n const mode = Object.prototype.hasOwnProperty.call(MODES, options.mode)\n ? options.mode\n : 'none';\n const actions = MODES[mode];\n\n const [expanded, setExpanded] = useControlled(\n options.expanded,\n options.defaultExpanded\n );\n const [selection, setSelection] = useControlled(\n options.selected,\n options.defaultSelected\n );\n const [checkedList, setChecked] = useControlled(\n options.checked,\n options.defaultChecked\n );\n // In a `checkbox` tree a check reaches the items under it, by the rules. In\n // a `checkbox-independent` one each box is its own item's, read off the list.\n const cascade = mode === 'checkbox';\n const independent = mode === 'checkbox-independent';\n // A box on every item, in either checkbox tree.\n const boxed = cascade || independent;\n // Each is read in its own mode only.\n const selected = mode === 'single' ? selection : null;\n const listed = new Set(boxed ? checkedList : []);\n\n const treeRef = useRef<HTMLUListElement | null>(null);\n const registryRef = useRef<Registry>({\n records: new Map(),\n elements: new Map(),\n values: new WeakMap(),\n });\n // Items register from their own effects, so they ask for a render to be read.\n const [, refresh] = useReducer((n: number) => n + 1, 0);\n const typeahead = useTypeahead();\n\n // The item with focus, and where the stop rests while focus is elsewhere:\n // `undefined` until the tree has mounted. With the values above it, for\n // when it goes away.\n const [focused, setFocused] = useState<string | null>(null);\n const [resting, setResting] = useState<string | null | undefined>();\n const restingPathRef = useRef<string[]>([]);\n // The values above an item that left the page with focus in it.\n const lostRef = useRef<string[] | null>(null);\n // Each item's place among the items beside it, by its key.\n const [positions, setPositions] = useState(NO_POSITIONS);\n\n const { records } = registryRef.current;\n const checks = cascade\n ? // eslint-disable-next-line react-hooks/refs -- read in render on purpose: items write the registry from their layout effects and then ask for this render with `refresh`\n readChecks(records, listed).states\n : undefined;\n const tabStop = focused ?? (resting === undefined ? selected : resting);\n\n // An item's box, decided here alone, so the box drawn, the tab stop and a\n // toggle agree: off the list in a `checkbox-independent` tree, and by the\n // rules in a `checkbox` one, where it's `undefined` until the item\n // registers. `undefined` in a tree with no boxes.\n const checkOf = (value: string): TreeViewCheckState | undefined =>\n independent ? listed.has(value) : checks?.get(value);\n\n const isOpen = (value: string) => expanded.includes(value);\n\n const stateOf = (\n value: string,\n path: string[],\n disabled: boolean\n ): TreeViewItemState => {\n if (mode === 'single') {\n return disabled ? {} : { selected: value === selected };\n }\n if (boxed) {\n // Until the items register in a `checkbox` tree, a value stands for\n // its branch, and a parent can't know it's mixed.\n return {\n checked:\n checkOf(value) ??\n (listed.has(value) || (!disabled && path.some(v => listed.has(v)))),\n };\n }\n return {};\n };\n\n const changeOpen = (next: string[]) => {\n setExpanded(next);\n options.onExpandedChange?.(next);\n };\n\n const run: Record<Action, (item: TreeViewItemInfo) => void> = {\n open: ({ value, isParent, open }) => {\n if (isParent) changeOpen(addedOrRemoved(expanded, value, open));\n },\n select: ({ value }) => {\n if (value === selected) return;\n setSelection(value);\n options.onSelectedChange?.(value);\n },\n check: ({ value }) => {\n // A `checkbox-independent` box is its own item's alone, so its value\n // comes or goes and the rest of the list stays as it was.\n const next = independent\n ? addedOrRemoved(checkedList, value, checkOf(value) === true)\n : toggledList(records, checkedList, value);\n setChecked(next);\n options.onCheckedChange?.(next);\n },\n };\n\n /** Disabled items are never selected, checked, opened or closed. */\n const act = (item: TreeViewItemInfo, list: Action[]) => {\n if (!item.disabled) list.forEach(action => run[action](item));\n };\n\n /** Enter, Space and a click on the row: a failed load's row retries. */\n const press = (item: TreeViewItemInfo, list: Action[]) => {\n if (item.retry) item.retry();\n else act(item, list);\n };\n\n // After every render, read each item's position off the page, and put the\n // stop where it belongs. While focus is in the tree it's the focused item.\n // Otherwise it's the selected item, or the first checked one on the page,\n // and failing that it stays where it was. An item that goes away hands it\n // to its nearest ancestor on the page, or to the first item, and focus goes\n // with it if it had focus.\n // eslint-disable-next-line react-hooks/exhaustive-deps -- after every render on purpose: it reads the page, and sets state only when what it reads has changed\n useClientLayoutEffect(() => {\n const tree = treeRef.current!;\n const registry = registryRef.current;\n // Each item's element is read off the page with its value, rather than\n // out of `elements`, which holds one element per value: two items\n // sharing a value, which they shouldn't, can leave it without one the\n // page still has.\n const shown = shownIn(tree, registry);\n const placed = positionsOf(shown, registry);\n if (!samePositions(positions, placed)) setPositions(placed);\n const onPage = shown.map(element => registry.values.get(element)!);\n const elementOf = (value: string) => shown[onPage.indexOf(value)];\n const isShown = (value: string | null | undefined): value is string =>\n value != null && onPage.includes(value);\n const heir = (path: string[]) =>\n [...path].reverse().find(isShown) ?? onPage[0] ?? null;\n\n const lost = lostRef.current;\n lostRef.current = null;\n if (lost && !tree.contains(getActiveElementInTree(tree))) {\n const to = heir(lost);\n if (to) elementOf(to).focus();\n return;\n }\n if (focused !== null && !isShown(focused)) setFocused(null);\n\n const preferred = onPage.find(\n value => value === selected || checkOf(value) === true\n );\n const next =\n preferred ?? (isShown(resting) ? resting : heir(restingPathRef.current));\n if (next !== resting) {\n setResting(next);\n restingPathRef.current = next ? pathOf(elementOf(next), registry) : [];\n }\n });\n\n // Items can also move without the tree rendering, such as children that a\n // component of the app sorts with state of its own. That changes no record,\n // so the page is watched for items coming, going and moving, and the\n // positions are read again.\n useEffect(() => {\n const tree = treeRef.current!;\n const observer = new MutationObserver(() => {\n const registry = registryRef.current;\n const placed = positionsOf(shownIn(tree, registry), registry);\n setPositions(current =>\n samePositions(current, placed) ? current : placed\n );\n });\n observer.observe(tree, { childList: true, subtree: true });\n return () => observer.disconnect();\n }, []);\n\n const register = useCallback((value: string, record: TreeViewItemRecord) => {\n const { records: known } = registryRef.current;\n known.set(value, record);\n refresh();\n return () => {\n if (known.get(value) !== record) return;\n known.delete(value);\n refresh();\n };\n }, []);\n\n const setElement = useCallback(\n (value: string, element: HTMLLIElement | null) => {\n const registry = registryRef.current;\n if (element) {\n registry.elements.set(value, element);\n registry.values.set(element, value);\n return;\n }\n const gone = registry.elements.get(value);\n if (!gone) return;\n // The ref lets go before the element leaves the page, so it can still\n // say whether focus was in it, and where it sat.\n if (!lostRef.current && gone.contains(getActiveElementInTree(gone))) {\n lostRef.current = [...pathOf(gone, registry), value];\n }\n registry.elements.delete(value);\n },\n []\n );\n\n const onFocus = (value: string, element: HTMLLIElement) => {\n setFocused(value);\n setResting(value);\n restingPathRef.current = pathOf(element, registryRef.current);\n };\n\n const onBlur = () => setFocused(null);\n\n const onKeyDown = (\n event: React.KeyboardEvent<HTMLLIElement>,\n item: TreeViewItemInfo\n ) => {\n const element = event.currentTarget;\n // A key on an item inside this one bubbles here too, and is its own.\n if (\n event.target !== element ||\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n isComposing(event)\n ) {\n return;\n }\n const registry = registryRef.current;\n const items = shownIn(treeRef.current!, registry);\n const at = items.indexOf(element);\n const rtl = getComputedStyle(element).direction === 'rtl';\n const key = (rtl && MIRRORED[event.key]) || event.key;\n\n switch (key) {\n case 'ArrowDown':\n items[at + 1]?.focus();\n break;\n case 'ArrowUp':\n items[at - 1]?.focus();\n break;\n case 'Home':\n items[0].focus();\n break;\n case 'End':\n items[items.length - 1].focus();\n break;\n case 'ArrowRight': {\n const next = items[at + 1];\n if (!item.open) act(item, ['open']);\n else if (next && parentItemOf(next) === element) next.focus();\n break;\n }\n case 'ArrowLeft':\n if (item.open && !item.disabled) act(item, ['open']);\n else parentItemOf(element)?.focus();\n break;\n // A held key acts once.\n case 'Enter':\n if (!event.repeat) press(item, actions.enter);\n break;\n case ' ':\n if (!event.repeat) press(item, actions.space);\n break;\n case '*': {\n const closed: string[] = [];\n registry.records.forEach((record, value) => {\n if (\n record.parent === item.parent &&\n record.isParent &&\n !record.disabled &&\n !expanded.includes(value)\n ) {\n closed.push(value);\n }\n });\n if (closed.length) changeOpen([...expanded, ...closed]);\n break;\n }\n default:\n // Type-ahead takes a printable character. Anything else, Escape and\n // Tab included, is left to whatever is around the tree.\n if (event.key.length !== 1) return;\n typeaheadMatch(items, typeahead.type(event.key), at, el =>\n typeaheadText(el.firstElementChild!)\n )?.focus();\n }\n event.preventDefault();\n };\n\n const onClick = (\n element: HTMLLIElement,\n item: TreeViewItemInfo,\n onToggle: boolean\n ) => {\n element.focus();\n if (onToggle) act(item, ['open']);\n else press(item, actions.click);\n };\n\n return {\n treeRef,\n rendersClosed: cascade,\n multiselectable: boxed,\n tabStop,\n isOpen,\n stateOf,\n positionOf: key => positions.get(key),\n register,\n setElement,\n onFocus,\n onBlur,\n onKeyDown,\n onClick,\n };\n}\n"],"names":["isComposing"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ 'use client';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { forwardRef } from 'react';
5
+ import { StackLayout } from '../helpers/stackLayout.js';
6
+
7
+ /**
8
+ * The `Center` component centers its content on both axes.
9
+ *
10
+ * Use it for a loader, an icon or an empty state in the middle of a box, a
11
+ * card or a section. Give it a height, or put it in something that has one,
12
+ * to center down the middle as well as across. Several children sit side by
13
+ * side in the middle, with no gap unless you set one.
14
+ *
15
+ * @function
16
+ * @param {CenterProps} props - Props for the Center component.
17
+ * @param {React.Ref} ref - Forwarded ref to the element `as` renders.
18
+ * @returns {JSX.Element} The rendered center.
19
+ *
20
+ * @example
21
+ * <Center p="6">
22
+ * <Loader />
23
+ * </Center>
24
+ */
25
+ const Center = forwardRef(function Center(props, ref) {
26
+ return (jsx(StackLayout, { ref: ref, ...props,
27
+ // Centered both ways, in the children's own order.
28
+ flexDirection: undefined, modifiers: { 'is-centered': true } }));
29
+ });
30
+ Center.displayName = 'Center';
31
+
32
+ export { Center };
33
+ //# sourceMappingURL=Center.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Center.js","sources":["../../../src/layout/Center.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport type { ConstrainedPolymorphicComponent } from '../helpers/polymorphic';\nimport {\n StackLayout,\n type LayoutElement,\n type LayoutOwnProps,\n type StackLayoutProps,\n} from '../helpers/stackLayout';\nimport type { BulmaGapStep, validDisplays } from '../helpers/useBulmaClasses';\n\n/**\n * The Center component's own props, beside the attributes of the element\n * `as` renders.\n */\nexport interface CenterOwnProps extends LayoutOwnProps {\n /**\n * Space between children, when there are several. None by default. Needs\n * Bulma's helper classes: under `bestax-no-helpers.css` the default stays.\n */\n gap?: BulmaGapStep;\n /**\n * `'inline-flex'` sizes it to its content, to center something inside a line\n * of text. Needs Bulma's helper classes: under `bestax-no-helpers.css` the\n * default stays.\n */\n display?: (typeof validDisplays)[number] | 'none';\n}\n\n/**\n * Props for the Center component. The attributes and the `ref` follow `as`.\n *\n * @extraProp {PolymorphicRef<LayoutElement>} [ref] - Ref forwarded to the element `as` renders.\n */\nexport type CenterProps<T extends LayoutElement = LayoutElement> =\n CenterOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof CenterOwnProps | 'as'> & {\n /**\n * The element to render. With `ul` or `ol`, give it `li` children: it\n * restates `role=\"list\"`, which Bulma's list reset takes away in Safari.\n * @defaultValue 'div'\n */\n as?: T;\n };\n\n/**\n * The `Center` component centers its content on both axes.\n *\n * Use it for a loader, an icon or an empty state in the middle of a box, a\n * card or a section. Give it a height, or put it in something that has one,\n * to center down the middle as well as across. Several children sit side by\n * side in the middle, with no gap unless you set one.\n *\n * @function\n * @param {CenterProps} props - Props for the Center component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered center.\n *\n * @example\n * <Center p=\"6\">\n * <Loader />\n * </Center>\n */\nexport const Center = forwardRef(function Center(\n props: CenterProps,\n ref: React.Ref<HTMLElement>\n) {\n return (\n <StackLayout\n ref={ref}\n {...(props as StackLayoutProps)}\n // Centered both ways, in the children's own order.\n flexDirection={undefined}\n modifiers={{ 'is-centered': true }}\n />\n );\n}) as ConstrainedPolymorphicComponent<CenterOwnProps, LayoutElement, 'div'>;\n\nCenter.displayName = 'Center';\n\nexport default Center;\n"],"names":["_jsx"],"mappings":";;;;;;AA4CA;;;;;;;;;;;;;;;;;AAiBG;AACI,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,MAAM,CAC9C,KAAkB,EAClB,GAA2B,EAAA;IAE3B,QACEA,IAAC,WAAW,EAAA,EACV,GAAG,EAAE,GAAG,KACH,KAA0B;;AAE/B,QAAA,aAAa,EAAE,SAAS,EACxB,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAA,CAClC;AAEN,CAAC;AAED,MAAM,CAAC,WAAW,GAAG,QAAQ;;"}
@@ -4,6 +4,7 @@ import { jsx } from 'react/jsx-runtime';
4
4
  import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
5
  import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
6
  import { mergeBulmaStyles } from '../helpers/mergeBulmaStyles.js';
7
+ import { CONTAINER_BREAKPOINTS } from '../helpers/containerBreakpoints.js';
7
8
 
8
9
  /**
9
10
  * The `Container` component provides a responsive and flexible layout wrapper for your Bulma React UI.
@@ -20,14 +21,9 @@ const Container = ({ as: Tag = 'div', className, textColor, color, bgColor, flui
20
21
  ...props,
21
22
  });
22
23
  // Only allow isMax for supported breakpoints
23
- const validMaxBreakpoints = [
24
- 'tablet',
25
- 'desktop',
26
- 'widescreen',
27
- ];
28
24
  let breakpointClass;
29
25
  if (breakpoint) {
30
- if (isMax && validMaxBreakpoints.includes(breakpoint)) {
26
+ if (isMax && CONTAINER_BREAKPOINTS.includes(breakpoint)) {
31
27
  breakpointClass = `is-max-${breakpoint}`;
32
28
  }
33
29
  else if (!isMax) {
@@ -1 +1 @@
1
- {"version":3,"file":"Container.js","sources":["../../../src/layout/Container.tsx"],"sourcesContent":["import React from 'react';\nimport classNames, { usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n validSchemeColors,\n} from '../helpers/useBulmaClasses';\nimport { mergeBulmaStyles } from '../helpers/mergeBulmaStyles';\n\n/**\n * Bulma container breakpoints.\n */\nexport type ContainerBreakpoint = 'tablet' | 'desktop' | 'widescreen';\n\n/**\n * Props for the Container component.\n */\nexport interface ContainerProps\n extends\n React.HTMLAttributes<HTMLElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * HTML element to render (default: `div`). Bulma pages often put the\n * container on a landmark, such as `<main class=\"container\">` or\n * `<footer class=\"container\">`. A page has only one visible `main`, and a\n * `section` is a `region` landmark only once it has an accessible name\n * (`aria-label`, or `aria-labelledby` pointing at its heading).\n */\n as?:\n | 'div'\n | 'main'\n | 'section'\n | 'article'\n | 'aside'\n | 'header'\n | 'footer'\n | 'nav';\n /** Additional CSS classes. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Text color alias: renders `has-text-<color>`, exactly like `textColor`.\n * Not a filled variant (no `.container.is-<color>` CSS exists). Prefer\n * `textColor`, which takes precedence when both are set; use `bgColor` for\n * a colored surface.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /**\n * Background color helper. `scheme-*` values render as a dark-mode-safe\n * inline `background-color: var(--bulma-scheme-*)` instead of a class. The\n * `scheme-invert*` values do not change text color — pair them with a\n * contrasting foreground.\n */\n bgColor?:\n | (typeof validColors)[number]\n | (typeof validSchemeColors)[number]\n | 'inherit'\n | 'current';\n /** Makes the container full-width with a 32px gap on each side. */\n fluid?: boolean;\n /** Makes the container full-width until the `widescreen` breakpoint. */\n widescreen?: boolean;\n /** Makes the container full-width until the `fullhd` breakpoint. */\n fullhd?: boolean;\n /** Responsive breakpoint for container (`is-tablet`, `is-desktop`, `is-widescreen`). */\n breakpoint?: ContainerBreakpoint;\n /** Uses Bulma's `is-max-*` class for the specified breakpoint, limiting max width. */\n isMax?: boolean;\n /** Content inside the container. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Container` component provides a responsive and flexible layout wrapper for your Bulma React UI.\n *\n * @function\n * @param {ContainerProps} props - Props for the Container component.\n * @returns {JSX.Element} The rendered container.\n * @see {@link https://bulma.io/documentation/layout/container/ | Bulma Container documentation}\n */\nexport const Container: React.FC<ContainerProps> = ({\n as: Tag = 'div',\n className,\n textColor,\n color,\n bgColor,\n fluid,\n widescreen,\n fullhd,\n breakpoint,\n isMax,\n children,\n style,\n ...props\n}) => {\n const { bulmaHelperClasses, bulmaHelperStyles, rest } = useBulmaClasses({\n color: textColor ?? color,\n backgroundColor: bgColor,\n ...props,\n });\n\n // Only allow isMax for supported breakpoints\n const validMaxBreakpoints: ContainerBreakpoint[] = [\n 'tablet',\n 'desktop',\n 'widescreen',\n ];\n let breakpointClass: string | undefined;\n if (breakpoint) {\n if (isMax && validMaxBreakpoints.includes(breakpoint)) {\n breakpointClass = `is-max-${breakpoint}`;\n } else if (!isMax) {\n breakpointClass = `is-${breakpoint}`;\n }\n }\n\n const mainClass = usePrefixedClassNames('container');\n const containerModifiers = usePrefixedClassNames('', {\n 'is-fluid': fluid,\n 'is-widescreen': widescreen,\n 'is-fullhd': fullhd,\n });\n const prefixedBreakpointClass = usePrefixedClassNames(breakpointClass || '');\n\n const containerClasses = classNames(\n mainClass,\n containerModifiers,\n prefixedBreakpointClass,\n className,\n bulmaHelperClasses\n );\n\n return (\n <Tag\n className={containerClasses}\n style={mergeBulmaStyles(bulmaHelperStyles, style)}\n {...rest}\n >\n {children}\n </Tag>\n );\n};\n\nexport default Container;\n"],"names":["_jsx"],"mappings":";;;;;;;AA0EA;;;;;;;AAOG;AACI,MAAM,SAAS,GAA6B,CAAC,EAClD,EAAE,EAAE,GAAG,GAAG,KAAK,EACf,SAAS,EACT,SAAS,EACT,KAAK,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,MAAM,EACN,UAAU,EACV,KAAK,EACL,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACT,KAAI;IACH,MAAM,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;QACtE,KAAK,EAAE,SAAS,IAAI,KAAK;AACzB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;;AAGF,IAAA,MAAM,mBAAmB,GAA0B;QACjD,QAAQ;QACR,SAAS;QACT,YAAY;KACb;AACD,IAAA,IAAI,eAAmC;IACvC,IAAI,UAAU,EAAE;QACd,IAAI,KAAK,IAAI,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;AACrD,YAAA,eAAe,GAAG,CAAA,OAAA,EAAU,UAAU,CAAA,CAAE;QAC1C;aAAO,IAAI,CAAC,KAAK,EAAE;AACjB,YAAA,eAAe,GAAG,CAAA,GAAA,EAAM,UAAU,CAAA,CAAE;QACtC;IACF;AAEA,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,WAAW,CAAC;AACpD,IAAA,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,EAAE,EAAE;AACnD,QAAA,UAAU,EAAE,KAAK;AACjB,QAAA,eAAe,EAAE,UAAU;AAC3B,QAAA,WAAW,EAAE,MAAM;AACpB,KAAA,CAAC;IACF,MAAM,uBAAuB,GAAG,qBAAqB,CAAC,eAAe,IAAI,EAAE,CAAC;AAE5E,IAAA,MAAM,gBAAgB,GAAG,UAAU,CACjC,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,SAAS,EACT,kBAAkB,CACnB;IAED,QACEA,IAAC,GAAG,EAAA,EACF,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,gBAAgB,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAA,GAC7C,IAAI,EAAA,QAAA,EAEP,QAAQ,EAAA,CACL;AAEV;;"}
1
+ {"version":3,"file":"Container.js","sources":["../../../src/layout/Container.tsx"],"sourcesContent":["import React from 'react';\nimport classNames, { usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n validSchemeColors,\n} from '../helpers/useBulmaClasses';\nimport { mergeBulmaStyles } from '../helpers/mergeBulmaStyles';\nimport { CONTAINER_BREAKPOINTS } from '../helpers/containerBreakpoints';\n\n/**\n * Bulma container breakpoints.\n */\nexport type ContainerBreakpoint = 'tablet' | 'desktop' | 'widescreen';\n\n/**\n * Props for the Container component.\n */\nexport interface ContainerProps\n extends\n React.HTMLAttributes<HTMLElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * HTML element to render (default: `div`). Bulma pages often put the\n * container on a landmark, such as `<main class=\"container\">` or\n * `<footer class=\"container\">`. A page has only one visible `main`, and a\n * `section` is a `region` landmark only once it has an accessible name\n * (`aria-label`, or `aria-labelledby` pointing at its heading).\n */\n as?:\n | 'div'\n | 'main'\n | 'section'\n | 'article'\n | 'aside'\n | 'header'\n | 'footer'\n | 'nav';\n /** Additional CSS classes. */\n className?: string;\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /**\n * Text color alias: renders `has-text-<color>`, exactly like `textColor`.\n * Not a filled variant (no `.container.is-<color>` CSS exists). Prefer\n * `textColor`, which takes precedence when both are set; use `bgColor` for\n * a colored surface.\n */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /**\n * Background color helper. `scheme-*` values render as a dark-mode-safe\n * inline `background-color: var(--bulma-scheme-*)` instead of a class. The\n * `scheme-invert*` values do not change text color — pair them with a\n * contrasting foreground.\n */\n bgColor?:\n | (typeof validColors)[number]\n | (typeof validSchemeColors)[number]\n | 'inherit'\n | 'current';\n /** Makes the container full-width with a 32px gap on each side. */\n fluid?: boolean;\n /** Makes the container full-width until the `widescreen` breakpoint. */\n widescreen?: boolean;\n /** Makes the container full-width until the `fullhd` breakpoint. */\n fullhd?: boolean;\n /** Responsive breakpoint for container (`is-tablet`, `is-desktop`, `is-widescreen`). */\n breakpoint?: ContainerBreakpoint;\n /** Uses Bulma's `is-max-*` class for the specified breakpoint, limiting max width. */\n isMax?: boolean;\n /** Content inside the container. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Container` component provides a responsive and flexible layout wrapper for your Bulma React UI.\n *\n * @function\n * @param {ContainerProps} props - Props for the Container component.\n * @returns {JSX.Element} The rendered container.\n * @see {@link https://bulma.io/documentation/layout/container/ | Bulma Container documentation}\n */\nexport const Container: React.FC<ContainerProps> = ({\n as: Tag = 'div',\n className,\n textColor,\n color,\n bgColor,\n fluid,\n widescreen,\n fullhd,\n breakpoint,\n isMax,\n children,\n style,\n ...props\n}) => {\n const { bulmaHelperClasses, bulmaHelperStyles, rest } = useBulmaClasses({\n color: textColor ?? color,\n backgroundColor: bgColor,\n ...props,\n });\n\n // Only allow isMax for supported breakpoints\n let breakpointClass: string | undefined;\n if (breakpoint) {\n if (isMax && CONTAINER_BREAKPOINTS.includes(breakpoint)) {\n breakpointClass = `is-max-${breakpoint}`;\n } else if (!isMax) {\n breakpointClass = `is-${breakpoint}`;\n }\n }\n\n const mainClass = usePrefixedClassNames('container');\n const containerModifiers = usePrefixedClassNames('', {\n 'is-fluid': fluid,\n 'is-widescreen': widescreen,\n 'is-fullhd': fullhd,\n });\n const prefixedBreakpointClass = usePrefixedClassNames(breakpointClass || '');\n\n const containerClasses = classNames(\n mainClass,\n containerModifiers,\n prefixedBreakpointClass,\n className,\n bulmaHelperClasses\n );\n\n return (\n <Tag\n className={containerClasses}\n style={mergeBulmaStyles(bulmaHelperStyles, style)}\n {...rest}\n >\n {children}\n </Tag>\n );\n};\n\nexport default Container;\n"],"names":["_jsx"],"mappings":";;;;;;;;AA2EA;;;;;;;AAOG;AACI,MAAM,SAAS,GAA6B,CAAC,EAClD,EAAE,EAAE,GAAG,GAAG,KAAK,EACf,SAAS,EACT,SAAS,EACT,KAAK,EACL,OAAO,EACP,KAAK,EACL,UAAU,EACV,MAAM,EACN,UAAU,EACV,KAAK,EACL,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACT,KAAI;IACH,MAAM,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;QACtE,KAAK,EAAE,SAAS,IAAI,KAAK;AACzB,QAAA,eAAe,EAAE,OAAO;AACxB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;;AAGF,IAAA,IAAI,eAAmC;IACvC,IAAI,UAAU,EAAE;QACd,IAAI,KAAK,IAAI,qBAAqB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;AACvD,YAAA,eAAe,GAAG,CAAA,OAAA,EAAU,UAAU,CAAA,CAAE;QAC1C;aAAO,IAAI,CAAC,KAAK,EAAE;AACjB,YAAA,eAAe,GAAG,CAAA,GAAA,EAAM,UAAU,CAAA,CAAE;QACtC;IACF;AAEA,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,WAAW,CAAC;AACpD,IAAA,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,EAAE,EAAE;AACnD,QAAA,UAAU,EAAE,KAAK;AACjB,QAAA,eAAe,EAAE,UAAU;AAC3B,QAAA,WAAW,EAAE,MAAM;AACpB,KAAA,CAAC;IACF,MAAM,uBAAuB,GAAG,qBAAqB,CAAC,eAAe,IAAI,EAAE,CAAC;AAE5E,IAAA,MAAM,gBAAgB,GAAG,UAAU,CACjC,SAAS,EACT,kBAAkB,EAClB,uBAAuB,EACvB,SAAS,EACT,kBAAkB,CACnB;IAED,QACEA,IAAC,GAAG,EAAA,EACF,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,gBAAgB,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAA,GAC7C,IAAI,EAAA,QAAA,EAEP,QAAQ,EAAA,CACL;AAEV;;"}
@@ -0,0 +1,34 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ 'use client';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { forwardRef } from 'react';
5
+ import { StackLayout } from '../helpers/stackLayout.js';
6
+
7
+ /**
8
+ * The `Flex` component is a flex container with CSS's own defaults, taking the flex container's properties as props.
9
+ *
10
+ * It's a row that doesn't wrap, with its children stretched across it and no
11
+ * gap, until you set otherwise. Use it for a layout of your own, such as a
12
+ * fixed side beside a growing one, with `flexGrow` and `flexShrink` on the
13
+ * children. Its children's own block margins are zeroed, so the gap is the
14
+ * only space. For a column of blocks or a row of controls with Bulma's
15
+ * spacing already in place, `Stack` and `Group` start closer.
16
+ *
17
+ * @function
18
+ * @param {FlexProps} props - Props for the Flex component.
19
+ * @param {React.Ref} ref - Forwarded ref to the element `as` renders.
20
+ * @returns {JSX.Element} The rendered flex container.
21
+ *
22
+ * @example
23
+ * <Flex gap="4" alignItems="flex-start">
24
+ * <Box flexShrink="0">…</Box>
25
+ * <Box flexGrow="1">…</Box>
26
+ * </Flex>
27
+ */
28
+ const Flex = forwardRef(function Flex(props, ref) {
29
+ return jsx(StackLayout, { ref: ref, ...props });
30
+ });
31
+ Flex.displayName = 'Flex';
32
+
33
+ export { Flex };
34
+ //# sourceMappingURL=Flex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Flex.js","sources":["../../../src/layout/Flex.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport type { ConstrainedPolymorphicComponent } from '../helpers/polymorphic';\nimport {\n StackLayout,\n type LayoutElement,\n type LayoutOwnProps,\n type StackLayoutProps,\n} from '../helpers/stackLayout';\nimport type {\n BulmaGapStep,\n validAlignContents,\n validAlignItems,\n validFlexDirections,\n validFlexWraps,\n validJustifyContents,\n} from '../helpers/useBulmaClasses';\n\n/**\n * The Flex component's own props, beside the attributes of the element `as`\n * renders.\n */\nexport interface FlexOwnProps extends LayoutOwnProps {\n /**\n * The main axis. `row-reverse` and `column-reverse` change only what's seen:\n * reading and Tab order still follow the children's order (WCAG 1.3.2 and\n * 2.4.3). Needs Bulma's helper classes: under `bestax-no-helpers.css` the\n * default stays.\n * @defaultValue 'row'\n */\n flexDirection?: (typeof validFlexDirections)[number];\n /**\n * Whether children move to a new line when they don't fit. Needs Bulma's\n * helper classes: under `bestax-no-helpers.css` the default stays.\n * @defaultValue 'nowrap'\n */\n flexWrap?: (typeof validFlexWraps)[number];\n /**\n * How each child sits across the main axis. Needs Bulma's helper classes:\n * under `bestax-no-helpers.css` the default stays.\n * @defaultValue 'stretch'\n */\n alignItems?: (typeof validAlignItems)[number];\n /**\n * Where the children sit along the main axis. Needs Bulma's helper classes:\n * under `bestax-no-helpers.css` the default stays.\n */\n justifyContent?: (typeof validJustifyContents)[number];\n /**\n * How wrapped lines share the space across the main axis. Needs Bulma's\n * helper classes: under `bestax-no-helpers.css` the default stays.\n */\n alignContent?: (typeof validAlignContents)[number];\n /**\n * Space between children, a step of Bulma's gap scale. None by default. Needs\n * Bulma's helper classes: under `bestax-no-helpers.css` the default stays.\n */\n gap?: BulmaGapStep;\n /**\n * Space between wrapped lines, when it differs from `gap`. Needs Bulma's\n * helper classes: under `bestax-no-helpers.css` the default stays.\n */\n rowGap?: BulmaGapStep;\n /**\n * Space between children along a row, when it differs from `gap`. Needs\n * Bulma's helper classes: under `bestax-no-helpers.css` the default stays.\n */\n columnGap?: BulmaGapStep;\n}\n\n/**\n * Props for the Flex component. The attributes and the `ref` follow `as`, so\n * `as=\"form\"` takes `action` and `as=\"fieldset\"` takes `disabled`.\n *\n * @extraProp {PolymorphicRef<LayoutElement>} [ref] - Ref forwarded to the element `as` renders.\n */\nexport type FlexProps<T extends LayoutElement = LayoutElement> = FlexOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof FlexOwnProps | 'as'> & {\n /**\n * The element to render. With `ul` or `ol`, give it `li` children: it\n * restates `role=\"list\"`, which Bulma's list reset takes away in Safari.\n * @defaultValue 'div'\n */\n as?: T;\n };\n\n/**\n * The `Flex` component is a flex container with CSS's own defaults, taking the flex container's properties as props.\n *\n * It's a row that doesn't wrap, with its children stretched across it and no\n * gap, until you set otherwise. Use it for a layout of your own, such as a\n * fixed side beside a growing one, with `flexGrow` and `flexShrink` on the\n * children. Its children's own block margins are zeroed, so the gap is the\n * only space. For a column of blocks or a row of controls with Bulma's\n * spacing already in place, `Stack` and `Group` start closer.\n *\n * @function\n * @param {FlexProps} props - Props for the Flex component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered flex container.\n *\n * @example\n * <Flex gap=\"4\" alignItems=\"flex-start\">\n * <Box flexShrink=\"0\">…</Box>\n * <Box flexGrow=\"1\">…</Box>\n * </Flex>\n */\nexport const Flex = forwardRef(function Flex(\n props: FlexProps,\n ref: React.Ref<HTMLElement>\n) {\n return <StackLayout ref={ref} {...(props as StackLayoutProps)} />;\n}) as ConstrainedPolymorphicComponent<FlexOwnProps, LayoutElement, 'div'>;\n\nFlex.displayName = 'Flex';\n\nexport default Flex;\n"],"names":["_jsx"],"mappings":";;;;;;AAqFA;;;;;;;;;;;;;;;;;;;;AAoBG;AACI,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,IAAI,CAC1C,KAAgB,EAChB,GAA2B,EAAA;IAE3B,OAAOA,GAAA,CAAC,WAAW,EAAA,EAAC,GAAG,EAAE,GAAG,EAAA,GAAO,KAA0B,EAAA,CAAI;AACnE,CAAC;AAED,IAAI,CAAC,WAAW,GAAG,MAAM;;"}
@@ -0,0 +1,43 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ 'use client';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { forwardRef } from 'react';
5
+ import { StackLayout } from '../helpers/stackLayout.js';
6
+ import { CONTAINER_BREAKPOINTS } from '../helpers/containerBreakpoints.js';
7
+
8
+ /**
9
+ * The `Group` component lays its children out in a row that wraps, centered on each other, with half of Bulma's block spacing between them.
10
+ *
11
+ * Use it for a row of buttons, tags or avatars beside some text, or a toolbar
12
+ * with `justifyContent="space-between"` pushing its ends apart. The children's
13
+ * own block margins are zeroed, so the gap is the only space. With
14
+ * `breakpoint`, it's a column on narrow screens and a row from that
15
+ * breakpoint up. For controls joined into one, with no gap and shared
16
+ * borders, use `hasAddons` on Field or Buttons instead.
17
+ *
18
+ * @function
19
+ * @param {GroupProps} props - Props for the Group component.
20
+ * @param {React.Ref} ref - Forwarded ref to the element `as` renders.
21
+ * @returns {JSX.Element} The rendered group.
22
+ *
23
+ * @example
24
+ * <Group justifyContent="space-between">
25
+ * <Title as="h2" size="4">Invoices</Title>
26
+ * <Button color="primary">New invoice</Button>
27
+ * </Group>
28
+ */
29
+ const Group = forwardRef(function Group(props, ref) {
30
+ const { isFullwidth, breakpoint, ...rest } = props;
31
+ return (jsx(StackLayout, { ref: ref, ...rest,
32
+ // A row always, or a column below `breakpoint`: never reversed, so
33
+ // reading and Tab order follow what's seen.
34
+ flexDirection: undefined, modifiers: {
35
+ 'is-horizontal': true,
36
+ 'is-fullwidth': isFullwidth,
37
+ [`is-${breakpoint}`]: !!breakpoint && CONTAINER_BREAKPOINTS.includes(breakpoint),
38
+ } }));
39
+ });
40
+ Group.displayName = 'Group';
41
+
42
+ export { Group };
43
+ //# sourceMappingURL=Group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Group.js","sources":["../../../src/layout/Group.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport type { ConstrainedPolymorphicComponent } from '../helpers/polymorphic';\nimport {\n StackLayout,\n type LayoutElement,\n type LayoutOwnProps,\n type StackLayoutProps,\n} from '../helpers/stackLayout';\nimport type {\n BulmaGapStep,\n validAlignItems,\n validFlexWraps,\n validJustifyContents,\n} from '../helpers/useBulmaClasses';\nimport type { ContainerBreakpoint } from './Container';\nimport { CONTAINER_BREAKPOINTS } from '../helpers/containerBreakpoints';\n\n/**\n * The Group component's own props, beside the attributes of the element `as`\n * renders.\n */\nexport interface GroupOwnProps extends LayoutOwnProps {\n /**\n * Space between children, a step of Bulma's gap scale. Unset, it's\n * `--bulma-stack-horizontal-gap`, half of Bulma's block spacing. Needs\n * Bulma's helper classes: under `bestax-no-helpers.css` the default stays.\n */\n gap?: BulmaGapStep;\n /**\n * How each child sits across the row. While `breakpoint` stacks them, it's\n * where each sits across the column. Needs Bulma's helper classes: under\n * `bestax-no-helpers.css` the default stays.\n * @defaultValue 'center'\n */\n alignItems?: (typeof validAlignItems)[number];\n /**\n * Where the children sit along the row: `'space-between'` pushes the ends\n * apart. Needs Bulma's helper classes: under `bestax-no-helpers.css` the\n * default stays.\n */\n justifyContent?: (typeof validJustifyContents)[number];\n /**\n * Whether children move to a new row when they don't fit. Needs Bulma's\n * helper classes: under `bestax-no-helpers.css` the default stays.\n * @defaultValue 'wrap'\n */\n flexWrap?: (typeof validFlexWraps)[number];\n /**\n * The children share the row equally, and fill the column while\n * `breakpoint` stacks them (Bulma's `is-fullwidth`).\n */\n isFullwidth?: boolean;\n /**\n * Stacks the children below this Bulma breakpoint and sets them in a row\n * from it up, the breakpoints Container's `breakpoint` takes. Unset, a row\n * at every width. It's the job Columns and Level do with booleans:\n * `'tablet'` is where they turn into a row by default, `'desktop'` is\n * Columns' `isDesktop`, and leaving it unset is their `isMobile`.\n */\n breakpoint?: ContainerBreakpoint;\n}\n\n/**\n * Props for the Group component. The attributes and the `ref` follow `as`, so\n * `as=\"form\"` takes `action` and `as=\"fieldset\"` takes `disabled`.\n *\n * @extraProp {PolymorphicRef<LayoutElement>} [ref] - Ref forwarded to the element `as` renders.\n */\nexport type GroupProps<T extends LayoutElement = LayoutElement> =\n GroupOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof GroupOwnProps | 'as'> & {\n /**\n * The element to render. With `ul` or `ol`, give it `li` children: it\n * restates `role=\"list\"`, which Bulma's list reset takes away in Safari.\n * @defaultValue 'div'\n */\n as?: T;\n };\n\n/**\n * The `Group` component lays its children out in a row that wraps, centered on each other, with half of Bulma's block spacing between them.\n *\n * Use it for a row of buttons, tags or avatars beside some text, or a toolbar\n * with `justifyContent=\"space-between\"` pushing its ends apart. The children's\n * own block margins are zeroed, so the gap is the only space. With\n * `breakpoint`, it's a column on narrow screens and a row from that\n * breakpoint up. For controls joined into one, with no gap and shared\n * borders, use `hasAddons` on Field or Buttons instead.\n *\n * @function\n * @param {GroupProps} props - Props for the Group component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered group.\n *\n * @example\n * <Group justifyContent=\"space-between\">\n * <Title as=\"h2\" size=\"4\">Invoices</Title>\n * <Button color=\"primary\">New invoice</Button>\n * </Group>\n */\nexport const Group = forwardRef(function Group(\n props: GroupProps,\n ref: React.Ref<HTMLElement>\n) {\n const { isFullwidth, breakpoint, ...rest } = props as GroupOwnProps &\n StackLayoutProps;\n return (\n <StackLayout\n ref={ref}\n {...rest}\n // A row always, or a column below `breakpoint`: never reversed, so\n // reading and Tab order follow what's seen.\n flexDirection={undefined}\n modifiers={{\n 'is-horizontal': true,\n 'is-fullwidth': isFullwidth,\n [`is-${breakpoint}`]:\n !!breakpoint && CONTAINER_BREAKPOINTS.includes(breakpoint),\n }}\n />\n );\n}) as ConstrainedPolymorphicComponent<GroupOwnProps, LayoutElement, 'div'>;\n\nGroup.displayName = 'Group';\n\nexport default Group;\n"],"names":["_jsx"],"mappings":";;;;;;;AA+EA;;;;;;;;;;;;;;;;;;;;AAoBG;AACI,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,KAAK,CAC5C,KAAiB,EACjB,GAA2B,EAAA;IAE3B,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,KAC3B;IAClB,QACEA,IAAC,WAAW,EAAA,EACV,GAAG,EAAE,GAAG,KACJ,IAAI;;;AAGR,QAAA,aAAa,EAAE,SAAS,EACxB,SAAS,EAAE;AACT,YAAA,eAAe,EAAE,IAAI;AACrB,YAAA,cAAc,EAAE,WAAW;AAC3B,YAAA,CAAC,CAAA,GAAA,EAAM,UAAU,CAAA,CAAE,GACjB,CAAC,CAAC,UAAU,IAAI,qBAAqB,CAAC,QAAQ,CAAC,UAAU,CAAC;AAC7D,SAAA,EAAA,CACD;AAEN,CAAC;AAED,KAAK,CAAC,WAAW,GAAG,OAAO;;"}
@@ -0,0 +1,34 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ 'use client';
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { forwardRef } from 'react';
5
+ import { StackLayout } from '../helpers/stackLayout.js';
6
+
7
+ /**
8
+ * The `Stack` component lays its children out in a column, with Bulma's block spacing between them and the margins Bulma gives them zeroed.
9
+ *
10
+ * A Stack of Boxes, Cards or Notifications looks like Bulma's own stacked
11
+ * blocks, spaced by the gap alone, so there are no margins to undo. A `gap`
12
+ * step replaces the default spacing. It's always a column, top to bottom.
13
+ *
14
+ * @function
15
+ * @param {StackProps} props - Props for the Stack component.
16
+ * @param {React.Ref} ref - Forwarded ref to the element `as` renders.
17
+ * @returns {JSX.Element} The rendered stack.
18
+ *
19
+ * @example
20
+ * <Stack>
21
+ * <Notification color="info">Your changes are saved.</Notification>
22
+ * <Box>…</Box>
23
+ * </Stack>
24
+ */
25
+ const Stack = forwardRef(function Stack(props, ref) {
26
+ return (jsx(StackLayout, { ref: ref, ...props,
27
+ // A column always: reading and Tab order follow the children's order,
28
+ // and a reversed column would show them in another.
29
+ flexDirection: undefined, modifiers: { 'is-vertical': true } }));
30
+ });
31
+ Stack.displayName = 'Stack';
32
+
33
+ export { Stack };
34
+ //# sourceMappingURL=Stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stack.js","sources":["../../../src/layout/Stack.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport type { ConstrainedPolymorphicComponent } from '../helpers/polymorphic';\nimport {\n StackLayout,\n type LayoutElement,\n type LayoutOwnProps,\n type StackLayoutProps,\n} from '../helpers/stackLayout';\nimport type {\n BulmaGapStep,\n validAlignItems,\n validJustifyContents,\n} from '../helpers/useBulmaClasses';\n\n/**\n * The Stack component's own props, beside the attributes of the element `as`\n * renders.\n */\nexport interface StackOwnProps extends LayoutOwnProps {\n /**\n * Space between children, a step of Bulma's gap scale (`'2'` is 1rem). Unset,\n * it's `--bulma-stack-gap`, Bulma's block spacing. Needs Bulma's helper\n * classes: under `bestax-no-helpers.css` the default stays.\n */\n gap?: BulmaGapStep;\n /**\n * How each child sits across the column. `'stretch'` makes each as wide as\n * the Stack. Needs Bulma's helper classes: under `bestax-no-helpers.css` the\n * default stays.\n * @defaultValue 'stretch'\n */\n alignItems?: (typeof validAlignItems)[number];\n /**\n * Where the children sit down the column, when it's taller than they are.\n * Needs Bulma's helper classes: under `bestax-no-helpers.css` the default\n * stays.\n */\n justifyContent?: (typeof validJustifyContents)[number];\n}\n\n/**\n * Props for the Stack component. The attributes and the `ref` follow `as`, so\n * `as=\"form\"` takes `action` and `as=\"fieldset\"` takes `disabled`.\n *\n * @extraProp {PolymorphicRef<LayoutElement>} [ref] - Ref forwarded to the element `as` renders.\n */\nexport type StackProps<T extends LayoutElement = LayoutElement> =\n StackOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof StackOwnProps | 'as'> & {\n /**\n * The element to render. With `ul` or `ol`, give it `li` children: it\n * restates `role=\"list\"`, which Bulma's list reset takes away in Safari.\n * @defaultValue 'div'\n */\n as?: T;\n };\n\n/**\n * The `Stack` component lays its children out in a column, with Bulma's block spacing between them and the margins Bulma gives them zeroed.\n *\n * A Stack of Boxes, Cards or Notifications looks like Bulma's own stacked\n * blocks, spaced by the gap alone, so there are no margins to undo. A `gap`\n * step replaces the default spacing. It's always a column, top to bottom.\n *\n * @function\n * @param {StackProps} props - Props for the Stack component.\n * @param {React.Ref} ref - Forwarded ref to the element `as` renders.\n * @returns {JSX.Element} The rendered stack.\n *\n * @example\n * <Stack>\n * <Notification color=\"info\">Your changes are saved.</Notification>\n * <Box>…</Box>\n * </Stack>\n */\nexport const Stack = forwardRef(function Stack(\n props: StackProps,\n ref: React.Ref<HTMLElement>\n) {\n return (\n <StackLayout\n ref={ref}\n {...(props as StackLayoutProps)}\n // A column always: reading and Tab order follow the children's order,\n // and a reversed column would show them in another.\n flexDirection={undefined}\n modifiers={{ 'is-vertical': true }}\n />\n );\n}) as ConstrainedPolymorphicComponent<StackOwnProps, LayoutElement, 'div'>;\n\nStack.displayName = 'Stack';\n\nexport default Stack;\n"],"names":["_jsx"],"mappings":";;;;;;AAyDA;;;;;;;;;;;;;;;;;AAiBG;AACI,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,KAAK,CAC5C,KAAiB,EACjB,GAA2B,EAAA;IAE3B,QACEA,IAAC,WAAW,EAAA,EACV,GAAG,EAAE,GAAG,KACH,KAA0B;;;AAG/B,QAAA,aAAa,EAAE,SAAS,EACxB,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAA,CAClC;AAEN,CAAC;AAED,KAAK,CAAC,WAAW,GAAG,OAAO;;"}