@allxsmith/bestax-bulma 5.67.2 → 5.67.4

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 (96) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Card.js +3 -14
  4. package/dist/esm/components/Card.js.map +1 -1
  5. package/dist/esm/components/Command.js +14 -3
  6. package/dist/esm/components/Command.js.map +1 -1
  7. package/dist/esm/components/ContextMenu.js +10 -10
  8. package/dist/esm/components/ContextMenu.js.map +1 -1
  9. package/dist/esm/components/Dialog.js +7 -3
  10. package/dist/esm/components/Dialog.js.map +1 -1
  11. package/dist/esm/components/HoverCard.js +2 -2
  12. package/dist/esm/components/HoverCard.js.map +1 -1
  13. package/dist/esm/components/Menu.js +2 -1
  14. package/dist/esm/components/Menu.js.map +1 -1
  15. package/dist/esm/components/Modal.js +11 -9
  16. package/dist/esm/components/Modal.js.map +1 -1
  17. package/dist/esm/components/Popover.js +2 -2
  18. package/dist/esm/components/Popover.js.map +1 -1
  19. package/dist/esm/components/Tabs.js +4 -3
  20. package/dist/esm/components/Tabs.js.map +1 -1
  21. package/dist/esm/elements/CopyButton.js +6 -3
  22. package/dist/esm/elements/CopyButton.js.map +1 -1
  23. package/dist/esm/elements/IconButton.js +3 -2
  24. package/dist/esm/elements/IconButton.js.map +1 -1
  25. package/dist/esm/elements/Stat.js +3 -2
  26. package/dist/esm/elements/Stat.js.map +1 -1
  27. package/dist/esm/form/ColorInputBase.js.map +1 -1
  28. package/dist/esm/form/Combobox.js +2 -2
  29. package/dist/esm/form/Combobox.js.map +1 -1
  30. package/dist/esm/form/DateInputBase.js.map +1 -1
  31. package/dist/esm/form/DateRangeInputBase.js.map +1 -1
  32. package/dist/esm/form/DateTimeInputBase.js.map +1 -1
  33. package/dist/esm/form/Field.js +6 -6
  34. package/dist/esm/form/Field.js.map +1 -1
  35. package/dist/esm/form/TimeInputBase.js.map +1 -1
  36. package/dist/esm/form/TreeSelect.js.map +1 -1
  37. package/dist/esm/form/_pickerInternals/Calendar.js +19 -12
  38. package/dist/esm/form/_pickerInternals/Calendar.js.map +1 -1
  39. package/dist/esm/form/_pickerInternals/PickerPopover.js +3 -3
  40. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
  41. package/dist/esm/helpers/Config.js.map +1 -1
  42. package/dist/esm/helpers/elementType.js +42 -0
  43. package/dist/esm/helpers/elementType.js.map +1 -0
  44. package/dist/esm/helpers/portal.js +57 -1
  45. package/dist/esm/helpers/portal.js.map +1 -1
  46. package/dist/esm/helpers/useAnchoredPosition.js +23 -12
  47. package/dist/esm/helpers/useAnchoredPosition.js.map +1 -1
  48. package/dist/esm/helpers/withSubComponents.js +1 -1
  49. package/dist/esm/helpers/withSubComponents.js.map +1 -1
  50. package/dist/esm/layout/AppFrame.js +4 -3
  51. package/dist/esm/layout/AppFrame.js.map +1 -1
  52. package/dist/esm/layout/Splitter.js +3 -2
  53. package/dist/esm/layout/Splitter.js.map +1 -1
  54. package/dist/extras.css +1 -1
  55. package/dist/extras.css.map +1 -1
  56. package/dist/index.cjs +196 -81
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/types/components/HoverCard.d.ts +9 -8
  59. package/dist/types/components/Popover.d.ts +6 -5
  60. package/dist/types/form/ColorInputBase.d.ts +2 -1
  61. package/dist/types/form/Combobox.d.ts +6 -7
  62. package/dist/types/form/DateInputBase.d.ts +6 -2
  63. package/dist/types/form/DateRangeInputBase.d.ts +6 -2
  64. package/dist/types/form/DateTimeInputBase.d.ts +6 -2
  65. package/dist/types/form/TimeInputBase.d.ts +2 -1
  66. package/dist/types/form/TreeSelect.d.ts +1 -1
  67. package/dist/types/helpers/Config.d.ts +6 -3
  68. package/dist/types/helpers/elementType.d.ts +20 -0
  69. package/dist/types/helpers/portal.d.ts +44 -0
  70. package/dist/types/helpers/useAnchoredPosition.d.ts +3 -1
  71. package/dist/types/helpers/withSubComponents.d.ts +1 -1
  72. package/dist/types-cjs/components/HoverCard.d.ts +9 -8
  73. package/dist/types-cjs/components/Popover.d.ts +6 -5
  74. package/dist/types-cjs/form/ColorInputBase.d.ts +2 -1
  75. package/dist/types-cjs/form/Combobox.d.ts +6 -7
  76. package/dist/types-cjs/form/DateInputBase.d.ts +6 -2
  77. package/dist/types-cjs/form/DateRangeInputBase.d.ts +6 -2
  78. package/dist/types-cjs/form/DateTimeInputBase.d.ts +6 -2
  79. package/dist/types-cjs/form/TimeInputBase.d.ts +2 -1
  80. package/dist/types-cjs/form/TreeSelect.d.ts +1 -1
  81. package/dist/types-cjs/helpers/Config.d.ts +6 -3
  82. package/dist/types-cjs/helpers/elementType.d.ts +20 -0
  83. package/dist/types-cjs/helpers/portal.d.ts +44 -0
  84. package/dist/types-cjs/helpers/useAnchoredPosition.d.ts +3 -1
  85. package/dist/types-cjs/helpers/withSubComponents.d.ts +1 -1
  86. package/dist/versions/bestax-no-dark-mode.css +1 -1
  87. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  88. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  89. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  90. package/dist/versions/bestax-no-helpers.css +1 -1
  91. package/dist/versions/bestax-no-helpers.css.map +1 -1
  92. package/dist/versions/bestax-prefixed.css +1 -1
  93. package/dist/versions/bestax-prefixed.css.map +1 -1
  94. package/package.json +1 -1
  95. package/src/scss/components/_menu.scss +16 -2
  96. package/src/scss/form/_dateinput.scss +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TreeSelect.js","sources":["../../../src/form/TreeSelect.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { usePrefixedClassNames } from '../helpers/classNames';\nimport type { BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { useLocaleMatcher } from '../helpers/localeFormat';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport {\n TreeViewHiddenContext,\n readChecks,\n toggledList,\n} from '../helpers/useTreeView';\nimport { useControlled } from '../helpers/useControlled';\nimport {\n checkRecords,\n checkedByStrategy,\n childNodes,\n indexTree,\n isParentNode,\n nodeLabel,\n searchTree,\n} from '../helpers/treeData';\nimport { TreeView } from '../components/TreeView';\nimport type { FormFieldProps } from './fieldProps';\nimport { useFieldsetDisabled } from './FormContext';\nimport type { PickerPosition } from './_pickerInternals/pickerTypes';\nimport { DialogSelect } from './_selectInternals/DialogSelect';\nimport { ValueTags, tagIds } from './_selectInternals/ValueTags';\n\n/**\n * One node in a TreeSelect's `data`: Combobox's item fields plus\n * TreeView.Item's, with `children` for the nodes under it.\n */\nexport interface TreeItemData {\n /** **Required.** What the value holds and `name` posts. Unique in the whole tree. */\n value: string;\n /** What the row, the field and the tags show, and what search matches. The `value` when it's left out. */\n label?: string;\n /** Reachable, but never picked, checked, opened or closed. */\n disabled?: boolean;\n /** A picture before the label: an `Icon` name, or a node. Hidden from assistive tech. */\n icon?: React.ReactNode;\n /** The nodes under this one. */\n children?: TreeItemData[];\n /** Shows the node as a parent before its children are known, for a branch that loads when it opens. */\n hasChildren?: boolean;\n /** Its children are on their way: an open branch ends in a row that says so, and the live region says it too. */\n isLoading?: boolean;\n /** Its children didn't load: an open branch ends in this message, with a Retry button when there's an `onRetry`. */\n loadError?: React.ReactNode;\n /** Called by the Retry button on a failed load's row. Set `isLoading` while the retry runs. */\n onRetry?: () => void;\n}\n\n/** What a checked branch puts in the value a check makes. */\nexport type TreeSelectCheckedStrategy = 'child' | 'parent' | 'all';\n\n/** The visible and accessible strings, in your app's language. */\nexport interface TreeSelectLabels {\n /**\n * Names the panel and the tree in it.\n * @defaultValue the field's label\n */\n choose?: string;\n /**\n * Names the search box.\n * @defaultValue 'Search'\n */\n search?: string;\n /**\n * Names the clear button.\n * @defaultValue 'Clear'\n */\n clear?: string;\n /**\n * What a loading branch's row says, as on TreeView.\n * @defaultValue 'Loading…'\n */\n loading?: string;\n /**\n * The Retry button's text on a failed load's row, as on TreeView.\n * @defaultValue 'Retry'\n */\n retry?: string;\n /**\n * What the live region says when an open branch starts loading, built\n * from its name, as on TreeView.\n * @defaultValue name => `Loading ${name}`\n */\n loadingAnnouncement?: (name: string) => string;\n /**\n * What the live region says when that load finishes, as on TreeView.\n * @defaultValue name => `${name} loaded`\n */\n loadedAnnouncement?: (name: string) => string;\n}\n\n/**\n * What every TreeSelect takes. The helper props and the other attributes\n * land on the root `<div>`, as Combobox's do, and the `ref` on the field.\n */\ninterface TreeSelectBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'onChange' | 'defaultValue' | 'children'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** **Required.** The tree, as nodes nested through `children`. */\n data: TreeItemData[];\n /**\n * The field's label, which names the field through `htmlFor`, and the\n * panel and the tree in it through `aria-labelledby`. Dropped inside an\n * outer `Field`, whose label names them instead.\n */\n label?: React.ReactNode;\n /** The field's `id`, which the label then points at. The panel's is this one with `-panel` after it. */\n id?: string;\n /** Names the field, and the panel and the tree, in place of a `label`. */\n 'aria-label'?: string;\n /** The ids of what names the field, and the panel and the tree, in place of a `label`. */\n 'aria-labelledby'?: string;\n /** The ids of what describes the field, ahead of the tags. */\n 'aria-describedby'?: string;\n /** The open branches' values when you hold the state, as TreeView's `expanded`. */\n expanded?: string[];\n /** The branches open to begin with, when TreeSelect holds its own state. */\n defaultExpanded?: string[];\n /**\n * Called with the new list whenever a branch opens or closes, opening the\n * panel on the picked item's branch included. Fetch a lazy branch's\n * children from here. The branches a search opens aren't in it.\n */\n onExpandedChange?: (expanded: string[]) => void;\n /** Whether the panel is open, controlled: opening and closing then only call `onOpenChange`. */\n open?: boolean;\n /** The panel is open to begin with. */\n defaultOpen?: boolean;\n /** Called with the new state when the panel opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Puts a search box at the top of the panel. It matches labels, keeps a\n * match's ancestors and the nodes under it, and opens every branch with a\n * match. A printable key on the field opens the panel with it in the box,\n * and the search empties when the panel closes.\n */\n searchable?: boolean;\n /** The search text when you hold the state. */\n query?: string;\n /** The search text to begin with. */\n defaultQuery?: string;\n /** Called with the search text as it changes. */\n onQueryChange?: (query: string) => void;\n /**\n * Whether a node matches the search, in place of the locale-aware match on\n * its label. It's handed the search text trimmed, the node, and its path\n * from the top node down, the node last, as Cascader's `filter` is. A\n * match's ancestors stay either way. The search runs again when the search\n * text or `data` changes, not when only this does, so one written inline\n * costs nothing.\n */\n filter?: (query: string, item: TreeItemData, path: TreeItemData[]) => boolean;\n /** What the panel shows when the search matches nothing, such as \"No folders match\". Announced once. */\n empty?: React.ReactNode;\n /** Renders a row's content in place of its label. The field and the tags still show the label. */\n itemTemplate?: (item: TreeItemData) => React.ReactNode;\n /** What the field shows while nothing is picked. */\n placeholder?: string;\n /** A form field name. A hidden input posts the value, or one per value in the checkbox modes. */\n name?: string;\n /** The id of the form the hidden inputs belong to, when it isn't an ancestor. */\n form?: string;\n /**\n * A value is needed: the field is `aria-required`, and the form won't\n * submit while nothing is picked. The browser's message points at the\n * field, which shows focus, and the next key goes to it.\n */\n required?: boolean;\n /** The field can't be used: it can't be focused or opened, its tags lose their buttons, and its hidden inputs don't post. */\n disabled?: boolean;\n /**\n * Shows a clear button at the field's inline end while something it can\n * take off is picked. It leaves checked disabled items, which no control\n * unchecks.\n */\n clearable?: boolean;\n /** Bulma color modifier for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** The field's size, which the tree in the panel follows. */\n size?: 'small' | 'medium' | 'large';\n /** Rounds the field's corners (Bulma's `is-rounded`). */\n isRounded?: boolean;\n /**\n * Where the panel opens against the field, as on the pickers. Left out, it\n * opens below and lines up with the field's start edge, which is its right\n * edge on a right-to-left page. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges either way.\n * @defaultValue 'bottom-left'\n */\n position?: PickerPosition;\n /** Renders the panel through a portal, into a `ConfigProvider`'s `portalContainer`, `document.body` by default. */\n appendToBody?: boolean;\n /** The visible and accessible strings, in your app's language. */\n labels?: TreeSelectLabels;\n}\n\n/** Props for a TreeSelect that picks one item. */\nexport interface TreeSelectSingleProps extends TreeSelectBaseProps {\n /**\n * `'single'`: one item, picked with Enter, Space or a click on its row.\n * `'checkbox'`: any number, with a box on every item. A check reaches every\n * enabled item under it, and a parent with some of them checked is mixed.\n * `'checkbox-independent'`: any number, each box checking its own item, so\n * a parent means the parent alone (Mantine's and Ant Design's\n * `checkStrictly`). The checkbox modes show the value as tags.\n */\n selectionMode?: 'single';\n /**\n * The value when you hold the state: in `'single'` the picked item's\n * value, or `null` for none, and in the checkbox modes the checked values.\n * In `'checkbox'` a parent's value checks its whole branch, so the list any\n * `checkedStrategy` gives checks the same boxes.\n */\n value?: string | null;\n /** The value to begin with, when TreeSelect holds its own state: a value or `null`, or a list in the checkbox modes. */\n defaultValue?: string | null;\n /**\n * Called with the new value: in `'single'` the picked item's value, or\n * `null` when it's cleared, and in the checkbox modes the new list, after a\n * check, an uncheck, a tag's button or the clear button, each shaped by\n * `checkedStrategy`. A reset of the field's form calls it too, with\n * `defaultValue` as it was given, or with `null` or `[]` when you hold\n * the value, for you to set.\n */\n onChange?: (value: string | null) => void;\n /**\n * A parent's row picks the parent. `false` makes the row, Enter and Space\n * open it instead, so only leaves are picked.\n * @defaultValue true\n */\n parentsSelectable?: boolean;\n /**\n * Closes the panel after a pick and puts focus back on the field.\n * @defaultValue true\n */\n closeOnSelect?: boolean;\n /** Read with the checkbox modes only. */\n checkedStrategy?: never;\n /** Read with the checkbox modes only. */\n ariaCloseLabel?: never;\n}\n\n/** Props for a TreeSelect with a box on every item. */\nexport interface TreeSelectCheckboxProps extends TreeSelectBaseProps {\n /**\n * `'checkbox'`: a check reaches every enabled item under it, and a parent\n * with some of them checked is mixed. `'checkbox-independent'`: each box\n * checks its own item, so a parent means the parent alone.\n */\n selectionMode: 'checkbox' | 'checkbox-independent';\n /**\n * The checked values when you hold the state. In `'checkbox'`, a parent's\n * value checks its whole branch, so the list any `checkedStrategy` gives\n * checks the same boxes.\n */\n value?: string[];\n /** The values checked to begin with, when TreeSelect holds its own state. */\n defaultValue?: string[];\n /**\n * Called with the new list after a check, an uncheck, a tag's button or\n * the clear button, shaped by `checkedStrategy`, and after a reset of the\n * field's form, with `defaultValue` as given, or `[]` when you hold the\n * value.\n */\n onChange?: (value: string[]) => void;\n /**\n * What a checked branch puts in the value, in `'checkbox'`: `'child'` its\n * leaves, `'parent'` its topmost checked item, `'all'` every checked item,\n * parents included. A checked disabled item is in all three, since only\n * its own value checks it. It shapes the value a check, an uncheck, a\n * tag's button or the clear button makes, which `onChange` reports, and\n * not `defaultValue`, a value you pass or the one a form reset puts back.\n * The tags and the hidden\n * inputs show the value as it's held, so a value you pass shows as you\n * pass it, and a branch that loads later changes nothing the form posts.\n * `'checkbox-independent'` always reports exactly the checked items.\n * @defaultValue 'child'\n */\n checkedStrategy?: TreeSelectCheckedStrategy;\n /** Names each tag's button, in place of \"Remove\" and the item's label, as on Combobox. */\n ariaCloseLabel?: string;\n /** Read with `'single'` only. */\n parentsSelectable?: never;\n /** Read with `'single'` only: the panel stays open while boxes are checked. */\n closeOnSelect?: never;\n}\n\n/**\n * Props for the TreeSelect component. The helper props and the other\n * attributes land on the `div.tree-select` around the field, and the `ref`\n * on the field. It renders the `Field` and the label itself, unless an outer\n * `Field` already does.\n *\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the field, the read-only `<input role=\"combobox\">`.\n */\nexport type TreeSelectProps = TreeSelectSingleProps | TreeSelectCheckboxProps;\n\nconst NOTHING_HIDDEN: ReadonlySet<string> = new Set();\nconst noMatches = [{ id: 'empty' }];\nconst nothingToSay: Array<{ id: string }> = [];\n/** What takes focus as the panel opens. */\nconst INITIAL_FOCUS = '[data-initial-focus]';\n\n/** One value or several, as a list. */\nconst asList = (value: string | string[] | null | undefined): string[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n\n/** Whether two lists hold the same values, whatever their order and repeats. */\nconst sameValues = (a: string[], b: string[]): boolean => {\n const inA = new Set(a);\n const inB = new Set(b);\n return inA.size === inB.size && [...inA].every(value => inB.has(value));\n};\n\n/** The list with every value of `more` it doesn't have added at the end. */\nconst withAll = (list: string[], more: string[]): string[] => [\n ...list,\n ...more.filter(value => !list.includes(value)),\n];\n\n/**\n * The `TreeSelect` component is a form field whose options are a tree, such as categories, places or teams: it opens a panel holding a real `TreeView`, picks one item or checks a branch at a time, and searches labels.\n *\n * The field is a read-only `role=\"combobox\"` that opens a dialog, wired as\n * DateInput's is, so focus moves into the tree for real and the tree keeps\n * TreeView's keys, type-ahead and spoken output. The tree is given as `data`,\n * so the field and the tags can name what's picked while the panel is shut,\n * and on the server.\n *\n * `selectionMode` picks the kind. `'single'` picks one item and closes. With\n * `'checkbox'`, a check reaches every enabled item under it, closed or hidden\n * by a search, and `checkedStrategy` decides what the value holds: the\n * leaves, the topmost checked items or every one. With\n * `'checkbox-independent'`, each box is its own item's, so a parent means\n * itself alone (Mantine's and Ant Design's `checkStrictly`). The value shows\n * as tags under the field.\n *\n * A value no node has is kept and shown as it is, with a warning in\n * development, so a value under a branch that hasn't loaded survives until\n * it does.\n *\n * @function\n * @param {TreeSelectProps} props - Props for the TreeSelect component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the field.\n * @returns {JSX.Element} The field, its tags and its panel, in a `Field` with the label unless one is around it.\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ | APG Combobox Pattern}\n *\n * @example\n * <TreeSelect\n * label=\"Save to\"\n * data={[\n * { value: 'docs', label: 'Documents', children: [{ value: 'invoices', label: 'Invoices' }] },\n * { value: 'photos', label: 'Photos' },\n * ]}\n * searchable\n * />\n *\n * @example\n * <TreeSelect label=\"Regions\" selectionMode=\"checkbox\" checkedStrategy=\"parent\" data={regions} />\n */\nexport const TreeSelect = forwardRef<HTMLInputElement, TreeSelectProps>(\n (props, ref) => {\n const {\n data,\n expanded: expandedProp,\n defaultExpanded = [],\n onExpandedChange,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n searchable = false,\n query: queryProp,\n defaultQuery = '',\n onQueryChange,\n filter,\n empty,\n itemTemplate,\n disabled: disabledProp,\n clearable = false,\n size,\n labels,\n selectionMode = 'single',\n value: valueProp,\n defaultValue,\n // Called below through `props`, which knows which value it takes.\n onChange: _onChange,\n parentsSelectable = true,\n closeOnSelect = true,\n checkedStrategy = 'child',\n ariaCloseLabel,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n const single = selectionMode === 'single';\n const cascade = selectionMode === 'checkbox';\n\n const index = useMemo(() => indexTree(data), [data]);\n const records = useMemo(() => checkRecords(index), [index]);\n const labelFor = (value: string) => {\n const entry = index.get(value);\n return entry ? nodeLabel(entry.node) : value;\n };\n\n // The value, as a list: none or one in `single`.\n const [held, setHeld] = useControlled<string | string[] | null>(\n valueProp,\n defaultValue ?? null\n );\n const listed = asList(held);\n const change = (next: string[]) => {\n const value = single ? (next[0] ?? null) : next;\n setHeld(value);\n // The mode decides which of the two `onChange` takes.\n const report = props.onChange as\n ((value: string | string[] | null) => void) | undefined;\n report?.(value);\n };\n // What the field, the tags and the hidden inputs show: the value as it's\n // held. `checkedStrategy` shapes a new value as a check makes it, so a\n // branch that loads later changes nothing the form posts.\n const picked = single ? listed.slice(0, 1) : Array.from(new Set(listed));\n\n const unknown = picked.find(value => !index.has(value));\n useEffect(() => {\n if (unknown !== undefined) {\n warnOnce(\n 'TreeSelect:unknown-value',\n `[bestax-bulma] <TreeSelect> was given the value \"${unknown}\", ` +\n 'which no node in its data has. It is kept and shown as it is, ' +\n 'as it should be for a node under a branch that has not loaded ' +\n 'yet. Otherwise, check the value against the data.'\n );\n }\n }, [unknown]);\n\n const [expanded, setExpanded] = useControlled(\n expandedProp,\n defaultExpanded\n );\n const changeExpanded = (next: string[]) => {\n setExpanded(next);\n onExpandedChange?.(next);\n };\n\n // The picked item focus goes to: the first in the tree's order.\n const pickedSet = new Set(picked);\n const target = Array.from(index.keys()).find(value => pickedSet.has(value));\n\n const [query, setQueryState] = useControlled(queryProp, defaultQuery);\n const setQuery = (next: string) => {\n if (next === query) return;\n setQueryState(next);\n onQueryChange?.(next);\n };\n\n const [isOpen, setOpenState] = useControlled(openProp, defaultOpen);\n const setOpen = (next: boolean) => {\n if (next === isOpen) return;\n if (next) {\n // Opening shows the picked item, its branch open.\n const path = (target !== undefined && index.get(target)?.path) || [];\n if (path.some(value => !expanded.includes(value))) {\n changeExpanded(withAll(expanded, path));\n }\n } else {\n setQuery('');\n }\n setOpenState(next);\n onOpenChange?.(next);\n };\n\n const matchText = useLocaleMatcher();\n const typed = searchable ? query.trim() : '';\n // Every item reads the hidden set, so it's only built again when the\n // search text or the data changes.\n const search = useMemo(\n () =>\n typed\n ? searchTree(data, (node, path) => {\n if (filter) return filter(typed, node, path);\n const text = nodeLabel(node);\n return matchText\n ? matchText(text, typed)\n : text.toLowerCase().includes(typed.toLowerCase());\n })\n : null,\n // `filter` is read as it is when the text or the data changes: one\n // written inline is a new function every render, and listing it would\n // search again on each.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [data, typed, matchText]\n );\n // The branches a search opened that were closed during it, for the\n // search text they were closed under: any new text, from the box or\n // from a held `query`, starts over.\n const [searchClosed, setSearchClosed] = useState({\n query: typed,\n values: [] as string[],\n });\n if (searchClosed.query !== typed) {\n setSearchClosed({ query: typed, values: [] });\n }\n const closedHere = searchClosed.query === typed ? searchClosed.values : [];\n // The branches a search opens show open over the ones you opened, and\n // close again once it's cleared.\n const forced = search\n ? search.open.filter(value => !closedHere.includes(value))\n : [];\n const shownExpanded = withAll(expanded, forced);\n // TreeView's click on a row selects it and opens it. A pick by click, as\n // a pick by Enter, only picks, so the open the tree asks for right after\n // one on a parent is dropped, and a lazy parent isn't fetched to be\n // picked.\n const clickPickedRef = useRef(false);\n const onTreeExpandedChange = (next: string[]) => {\n if (clickPickedRef.current) {\n clickPickedRef.current = false;\n return;\n }\n const closed = shownExpanded.filter(value => !next.includes(value));\n const opened = next.filter(value => !shownExpanded.includes(value));\n const closedForced = closed.filter(value => forced.includes(value));\n if (closedForced.length > 0) {\n setSearchClosed({\n query: typed,\n values: [...closedHere, ...closedForced],\n });\n }\n if (opened.length > 0 || closed.some(value => expanded.includes(value))) {\n changeExpanded([\n ...expanded.filter(value => !closed.includes(value)),\n ...opened,\n ]);\n }\n };\n\n // Whether an item is on the page with the panel open: every branch\n // above it open, and the search not hiding it.\n const visible = (value: string) =>\n !search?.hidden.has(value) &&\n index.get(value)!.path.every(above => shownExpanded.includes(above));\n const focusTarget =\n target !== undefined && visible(target)\n ? target\n : data.find(node => visible(node.value))?.value;\n\n // Picking in `single`. TreeView shows `selected`, held here, and the\n // picks are made from the rows' own keys and clicks, so a parent can\n // open instead and a pick of the picked item still closes.\n const pickable = (node: TreeItemData) =>\n !node.disabled && (parentsSelectable || !isParentNode(node));\n const pick = (value: string) => {\n if (listed.length !== 1 || listed[0] !== value) change([value]);\n if (closeOnSelect) setOpen(false);\n };\n const toggleClass = usePrefixedClassNames('tree-view-toggle');\n const rowHandlers = (node: TreeItemData) =>\n single\n ? {\n onKeyDown: (event: React.KeyboardEvent<HTMLLIElement>) => {\n if (\n event.target !== event.currentTarget ||\n event.repeat ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n (event.key !== 'Enter' && event.key !== ' ')\n ) {\n return;\n }\n if (pickable(node)) {\n pick(node.value);\n } else if (!node.disabled && isParentNode(node)) {\n // TreeView leaves a key that's been used alone.\n event.preventDefault();\n onTreeExpandedChange(\n shownExpanded.includes(node.value)\n ? shownExpanded.filter(value => value !== node.value)\n : [...shownExpanded, node.value]\n );\n }\n },\n onClick: (event: React.MouseEvent<HTMLLIElement>) => {\n const item = event.currentTarget;\n const target = event.target as Element;\n // A click in this item's own row, where TreeView reads one,\n // not one in the group of items inside it, and not on its\n // chevron, which only opens it.\n const inRow =\n target === item || item.firstElementChild!.contains(target);\n const onChevron =\n isParentNode(node) && !!target.closest(`.${toggleClass}`);\n if (inRow && !onChevron && pickable(node)) {\n // TreeView opens a parent it's handed this click on, in\n // this same click: the flag goes once the click is over.\n clickPickedRef.current = isParentNode(node);\n queueMicrotask(() => {\n clickPickedRef.current = false;\n });\n pick(node.value);\n }\n },\n }\n : undefined;\n\n const renderNode = (node: TreeItemData): React.ReactNode => (\n <TreeView.Item\n key={node.value}\n value={node.value}\n label={itemTemplate ? itemTemplate(node) : nodeLabel(node)}\n icon={node.icon}\n hasChildren={node.hasChildren}\n isLoading={node.isLoading}\n loadError={node.loadError}\n onRetry={node.onRetry}\n disabled={node.disabled}\n data-initial-focus={\n !searchable && node.value === focusTarget ? '' : undefined\n }\n {...rowHandlers(node)}\n >\n {childNodes(node).map(renderNode)}\n </TreeView.Item>\n );\n\n // In `checkbox`, TreeView reports every checked item, read here into\n // the list `checkedStrategy` gives.\n const shaped = (next: string[]) =>\n cascade ? checkedByStrategy(records, next, checkedStrategy) : next;\n const onCheckedChange = (next: string[]) => change(shaped(next));\n // Every item's check state, read once a render, which the clear button\n // and the tags' buttons decide from. Only `checkbox` reads TreeView's\n // rules: in `checkbox-independent` a listed item is a checked one.\n const listedKey = JSON.stringify(listed);\n const checks = useMemo(\n () => (cascade ? readChecks(records, new Set(listed)) : null),\n // `listed` by what it holds, since a held list is a new array each\n // render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [cascade, records, listedKey]\n );\n const isDisabled = (value: string) => !!index.get(value)?.node.disabled;\n // Read in `checkbox` only, where there are states to read.\n const isChecked = (value: string) => checks!.states.get(value) === true;\n // What a control can uncheck. In `checkbox`, that's each checked end no\n // checked disabled item above it keeps checked, and every item above it,\n // which takes it along; elsewhere it's each listed item that isn't\n // disabled. A disabled item is checked only by its own value, so nothing\n // unchecks it, or what it keeps checked.\n const uncheckable = new Set<string>();\n if (checks) {\n for (const end of checks.ends) {\n const { path } = index.get(end)!;\n if (\n isChecked(end) &&\n !path.some(above => isDisabled(above) && isChecked(above))\n ) {\n uncheckable.add(end);\n path.forEach(above => uncheckable.add(above));\n }\n }\n } else if (!single) {\n picked.forEach(value => !isDisabled(value) && uncheckable.add(value));\n }\n // A tag's button takes its value off where that changes what's checked,\n // the way its box would. A value no node has can always go.\n const removable = (value: string) =>\n !index.has(value) || (!isDisabled(value) && uncheckable.has(value));\n const without = (value: string) =>\n cascade && records.has(value)\n ? shaped(toggledList(records, listed, value))\n : listed.filter(item => item !== value);\n // What the clear button leaves: the checked disabled items, and in\n // `checkbox` what they keep checked, shaped as a check's value is.\n const cleared = single\n ? []\n : shaped(\n checks\n ? Array.from(records.keys()).filter(\n value => isDisabled(value) && isChecked(value)\n )\n : picked.filter(isDisabled)\n );\n const canClear = single\n ? picked.length > 0\n : uncheckable.size > 0 || picked.some(value => !index.has(value));\n const inputRef = useRef<HTMLInputElement | null>(null);\n // A forwarded callback's cleanup, which React 19 lets it return, run on\n // detach in place of a call with `null`, on React 18 as well.\n const refCleanupRef = useRef<(() => void) | null>(null);\n const fieldRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') {\n if (node === null) {\n const cleanup = refCleanupRef.current;\n refCleanupRef.current = null;\n if (cleanup) cleanup();\n else ref(null);\n return;\n }\n const cleanup: unknown = ref(node);\n refCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n const tagsId = useId();\n const ids = tagIds(tagsId, picked);\n\n const searchClass = usePrefixedClassNames('input', 'tree-select-search', {\n [`is-${size}`]: !!size,\n });\n const emptyClass = usePrefixedClassNames('tree-select-empty');\n const treeRef = useRef<HTMLUListElement>(null);\n const emptyRef = useRef<HTMLDivElement>(null);\n const nothingFound = !!search && !search.found;\n // The region reads the text on screen, whatever `empty` renders.\n const describeEmpty = useCallback(() => {\n const node = emptyRef.current;\n /* istanbul ignore if: it's only announced while it's on screen */\n if (!node) return null;\n return spokenText(node);\n }, []);\n\n return (\n <DialogSelect\n {...rest}\n component=\"TreeSelect\"\n rootClass=\"tree-select\"\n panelClass=\"tree-select-panel\"\n text={single && picked.length > 0 ? labelFor(picked[0]) : ''}\n values={single ? [picked[0] ?? ''] : picked}\n hasValue={picked.length > 0}\n open={isOpen}\n onOpenChange={setOpen}\n onPrintableKey={\n searchable\n ? key => {\n setQuery(key);\n setOpen(true);\n return true;\n }\n : undefined\n }\n onClear={() => change(cleared)}\n clearable={clearable && canClear}\n onFormReset={() => {\n // Back to `defaultValue`, or to nothing for a held value, which\n // its owner sets from `onChange`.\n const back = valueProp === undefined ? asList(defaultValue) : [];\n if (!sameValues(back, listed)) change(back);\n }}\n clearLabel={labels?.clear || 'Clear'}\n chooseLabel={labels?.choose}\n disabled={disabled}\n size={size}\n inputRef={inputRef}\n fieldRef={fieldRef}\n describedBy={single ? undefined : ids.join(' ')}\n below={\n single ? undefined : (\n <ValueTags\n values={picked}\n ids={ids}\n labelFor={labelFor}\n disabled={disabled}\n ariaCloseLabel={ariaCloseLabel}\n removable={removable}\n onRemove={value => {\n change(without(value));\n inputRef.current?.focus();\n }}\n />\n )\n }\n initialFocusSelector={INITIAL_FOCUS}\n >\n {panelName => (\n <>\n {searchable && (\n <input\n className={searchClass}\n type=\"search\"\n aria-label={labels?.search || 'Search'}\n autoComplete=\"off\"\n value={query}\n data-initial-focus=\"\"\n onChange={event => setQuery(event.target.value)}\n onFocus={event => {\n // A key that opened the panel is in the box: type after it.\n const { length } = event.currentTarget.value;\n event.currentTarget.setSelectionRange(length, length);\n }}\n onKeyDown={event => {\n if (event.key === 'Enter') {\n // The search box's Enter would submit the form.\n event.preventDefault();\n } else if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n const tree = treeRef.current;\n (\n tree?.querySelector<HTMLElement>(\n '[role=\"treeitem\"][tabindex=\"0\"]'\n ) ?? tree?.querySelector<HTMLElement>('[role=\"treeitem\"]')\n )?.focus();\n }\n }}\n />\n )}\n {nothingFound ? (\n empty && (\n <div className={emptyClass} ref={emptyRef}>\n {empty}\n </div>\n )\n ) : (\n <TreeViewHiddenContext.Provider\n value={search?.hidden ?? NOTHING_HIDDEN}\n >\n <TreeView\n {...panelName}\n ref={treeRef}\n // It scrolls, and Firefox makes a scroller a Tab stop of\n // its own: the roving one on its items is the tree's.\n tabIndex={-1}\n selectionMode={selectionMode}\n size={size}\n selected={single ? (picked[0] ?? null) : undefined}\n checked={single ? undefined : listed}\n onCheckedChange={onCheckedChange}\n expanded={shownExpanded}\n onExpandedChange={onTreeExpandedChange}\n loadingLabel={labels?.loading}\n retryLabel={labels?.retry}\n loadingAnnouncement={labels?.loadingAnnouncement}\n loadedAnnouncement={labels?.loadedAnnouncement}\n >\n {data.map(renderNode)}\n </TreeView>\n </TreeViewHiddenContext.Provider>\n )}\n <StatusRegion\n items={nothingFound && empty ? noMatches : nothingToSay}\n describe={describeEmpty}\n />\n </>\n )}\n </DialogSelect>\n );\n }\n);\n\nTreeSelect.displayName = 'TreeSelect';\n\nexport default TreeSelect;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"TreeSelect.js","sources":["../../../src/form/TreeSelect.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { usePrefixedClassNames } from '../helpers/classNames';\nimport type { BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { useLocaleMatcher } from '../helpers/localeFormat';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport {\n TreeViewHiddenContext,\n readChecks,\n toggledList,\n} from '../helpers/useTreeView';\nimport { useControlled } from '../helpers/useControlled';\nimport {\n checkRecords,\n checkedByStrategy,\n childNodes,\n indexTree,\n isParentNode,\n nodeLabel,\n searchTree,\n} from '../helpers/treeData';\nimport { TreeView } from '../components/TreeView';\nimport type { FormFieldProps } from './fieldProps';\nimport { useFieldsetDisabled } from './FormContext';\nimport type { PickerPosition } from './_pickerInternals/pickerTypes';\nimport { DialogSelect } from './_selectInternals/DialogSelect';\nimport { ValueTags, tagIds } from './_selectInternals/ValueTags';\n\n/**\n * One node in a TreeSelect's `data`: Combobox's item fields plus\n * TreeView.Item's, with `children` for the nodes under it.\n */\nexport interface TreeItemData {\n /** **Required.** What the value holds and `name` posts. Unique in the whole tree. */\n value: string;\n /** What the row, the field and the tags show, and what search matches. The `value` when it's left out. */\n label?: string;\n /** Reachable, but never picked, checked, opened or closed. */\n disabled?: boolean;\n /** A picture before the label: an `Icon` name, or a node. Hidden from assistive tech. */\n icon?: React.ReactNode;\n /** The nodes under this one. */\n children?: TreeItemData[];\n /** Shows the node as a parent before its children are known, for a branch that loads when it opens. */\n hasChildren?: boolean;\n /** Its children are on their way: an open branch ends in a row that says so, and the live region says it too. */\n isLoading?: boolean;\n /** Its children didn't load: an open branch ends in this message, with a Retry button when there's an `onRetry`. */\n loadError?: React.ReactNode;\n /** Called by the Retry button on a failed load's row. Set `isLoading` while the retry runs. */\n onRetry?: () => void;\n}\n\n/** What a checked branch puts in the value a check makes. */\nexport type TreeSelectCheckedStrategy = 'child' | 'parent' | 'all';\n\n/** The visible and accessible strings, in your app's language. */\nexport interface TreeSelectLabels {\n /**\n * Names the panel and the tree in it.\n * @defaultValue the field's label\n */\n choose?: string;\n /**\n * Names the search box.\n * @defaultValue 'Search'\n */\n search?: string;\n /**\n * Names the clear button.\n * @defaultValue 'Clear'\n */\n clear?: string;\n /**\n * What a loading branch's row says, as on TreeView.\n * @defaultValue 'Loading…'\n */\n loading?: string;\n /**\n * The Retry button's text on a failed load's row, as on TreeView.\n * @defaultValue 'Retry'\n */\n retry?: string;\n /**\n * What the live region says when an open branch starts loading, built\n * from its name, as on TreeView.\n * @defaultValue name => `Loading ${name}`\n */\n loadingAnnouncement?: (name: string) => string;\n /**\n * What the live region says when that load finishes, as on TreeView.\n * @defaultValue name => `${name} loaded`\n */\n loadedAnnouncement?: (name: string) => string;\n}\n\n/**\n * What every TreeSelect takes. The helper props and the other attributes\n * land on the root `<div>`, as Combobox's do, and the `ref` on the field.\n */\ninterface TreeSelectBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'onChange' | 'defaultValue' | 'children'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** **Required.** The tree, as nodes nested through `children`. */\n data: TreeItemData[];\n /**\n * The field's label, which names the field through `htmlFor`, and the\n * panel and the tree in it through `aria-labelledby`. Dropped inside an\n * outer `Field`, whose label names them instead.\n */\n label?: React.ReactNode;\n /** The field's `id`, which the label then points at. The panel's is this one with `-panel` after it. */\n id?: string;\n /** Names the field, and the panel and the tree, in place of a `label`. */\n 'aria-label'?: string;\n /** The ids of what names the field, and the panel and the tree, in place of a `label`. */\n 'aria-labelledby'?: string;\n /** The ids of what describes the field, ahead of the tags. */\n 'aria-describedby'?: string;\n /** The open branches' values when you hold the state, as TreeView's `expanded`. */\n expanded?: string[];\n /** The branches open to begin with, when TreeSelect holds its own state. */\n defaultExpanded?: string[];\n /**\n * Called with the new list whenever a branch opens or closes, opening the\n * panel on the picked item's branch included. Fetch a lazy branch's\n * children from here. The branches a search opens aren't in it.\n */\n onExpandedChange?: (expanded: string[]) => void;\n /** Whether the panel is open, controlled: opening and closing then only call `onOpenChange`. */\n open?: boolean;\n /** The panel is open to begin with. */\n defaultOpen?: boolean;\n /** Called with the new state when the panel opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Puts a search box at the top of the panel. It matches labels, keeps a\n * match's ancestors and the nodes under it, and opens every branch with a\n * match. A printable key on the field opens the panel with it in the box,\n * and the search empties when the panel closes.\n */\n searchable?: boolean;\n /** The search text when you hold the state. */\n query?: string;\n /** The search text to begin with. */\n defaultQuery?: string;\n /** Called with the search text as it changes. */\n onQueryChange?: (query: string) => void;\n /**\n * Whether a node matches the search, in place of the locale-aware match on\n * its label. It's handed the search text trimmed, the node, and its path\n * from the top node down, the node last, as Cascader's `filter` is. A\n * match's ancestors stay either way. The search runs again when the search\n * text or `data` changes, not when only this does, so one written inline\n * costs nothing.\n */\n filter?: (query: string, item: TreeItemData, path: TreeItemData[]) => boolean;\n /** What the panel shows when the search matches nothing, such as \"No folders match\". Announced once. */\n empty?: React.ReactNode;\n /** Renders a row's content in place of its label. The field and the tags still show the label. */\n itemTemplate?: (item: TreeItemData) => React.ReactNode;\n /** What the field shows while nothing is picked. */\n placeholder?: string;\n /** A form field name. A hidden input posts the value, or one per value in the checkbox modes. */\n name?: string;\n /** The id of the form the hidden inputs belong to, when it isn't an ancestor. */\n form?: string;\n /**\n * A value is needed: the field is `aria-required`, and the form won't\n * submit while nothing is picked. The browser's message points at the\n * field, which shows focus, and the next key goes to it.\n */\n required?: boolean;\n /** The field can't be used: it can't be focused or opened, its tags lose their buttons, and its hidden inputs don't post. */\n disabled?: boolean;\n /**\n * Shows a clear button at the field's inline end while something it can\n * take off is picked. It leaves checked disabled items, which no control\n * unchecks.\n */\n clearable?: boolean;\n /** Bulma color modifier for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** The field's size, which the tree in the panel follows. */\n size?: 'small' | 'medium' | 'large';\n /** Rounds the field's corners (Bulma's `is-rounded`). */\n isRounded?: boolean;\n /**\n * Where the panel opens against the field, as on the pickers. Left out, it\n * opens below and lines up with the field's start edge, which is its right\n * edge on a right-to-left page. A corner you pass stays physical, so\n * `bottom-left` lines up the left edges either way.\n * @defaultValue 'bottom-left'\n */\n position?: PickerPosition;\n /** Renders the panel through a portal, into a `ConfigProvider`'s `portalContainer`, else the `Modal`, `Dialog` or `Command.Dialog` it's in, else `document.body`. */\n appendToBody?: boolean;\n /** The visible and accessible strings, in your app's language. */\n labels?: TreeSelectLabels;\n}\n\n/** Props for a TreeSelect that picks one item. */\nexport interface TreeSelectSingleProps extends TreeSelectBaseProps {\n /**\n * `'single'`: one item, picked with Enter, Space or a click on its row.\n * `'checkbox'`: any number, with a box on every item. A check reaches every\n * enabled item under it, and a parent with some of them checked is mixed.\n * `'checkbox-independent'`: any number, each box checking its own item, so\n * a parent means the parent alone (Mantine's and Ant Design's\n * `checkStrictly`). The checkbox modes show the value as tags.\n */\n selectionMode?: 'single';\n /**\n * The value when you hold the state: in `'single'` the picked item's\n * value, or `null` for none, and in the checkbox modes the checked values.\n * In `'checkbox'` a parent's value checks its whole branch, so the list any\n * `checkedStrategy` gives checks the same boxes.\n */\n value?: string | null;\n /** The value to begin with, when TreeSelect holds its own state: a value or `null`, or a list in the checkbox modes. */\n defaultValue?: string | null;\n /**\n * Called with the new value: in `'single'` the picked item's value, or\n * `null` when it's cleared, and in the checkbox modes the new list, after a\n * check, an uncheck, a tag's button or the clear button, each shaped by\n * `checkedStrategy`. A reset of the field's form calls it too, with\n * `defaultValue` as it was given, or with `null` or `[]` when you hold\n * the value, for you to set.\n */\n onChange?: (value: string | null) => void;\n /**\n * A parent's row picks the parent. `false` makes the row, Enter and Space\n * open it instead, so only leaves are picked.\n * @defaultValue true\n */\n parentsSelectable?: boolean;\n /**\n * Closes the panel after a pick and puts focus back on the field.\n * @defaultValue true\n */\n closeOnSelect?: boolean;\n /** Read with the checkbox modes only. */\n checkedStrategy?: never;\n /** Read with the checkbox modes only. */\n ariaCloseLabel?: never;\n}\n\n/** Props for a TreeSelect with a box on every item. */\nexport interface TreeSelectCheckboxProps extends TreeSelectBaseProps {\n /**\n * `'checkbox'`: a check reaches every enabled item under it, and a parent\n * with some of them checked is mixed. `'checkbox-independent'`: each box\n * checks its own item, so a parent means the parent alone.\n */\n selectionMode: 'checkbox' | 'checkbox-independent';\n /**\n * The checked values when you hold the state. In `'checkbox'`, a parent's\n * value checks its whole branch, so the list any `checkedStrategy` gives\n * checks the same boxes.\n */\n value?: string[];\n /** The values checked to begin with, when TreeSelect holds its own state. */\n defaultValue?: string[];\n /**\n * Called with the new list after a check, an uncheck, a tag's button or\n * the clear button, shaped by `checkedStrategy`, and after a reset of the\n * field's form, with `defaultValue` as given, or `[]` when you hold the\n * value.\n */\n onChange?: (value: string[]) => void;\n /**\n * What a checked branch puts in the value, in `'checkbox'`: `'child'` its\n * leaves, `'parent'` its topmost checked item, `'all'` every checked item,\n * parents included. A checked disabled item is in all three, since only\n * its own value checks it. It shapes the value a check, an uncheck, a\n * tag's button or the clear button makes, which `onChange` reports, and\n * not `defaultValue`, a value you pass or the one a form reset puts back.\n * The tags and the hidden\n * inputs show the value as it's held, so a value you pass shows as you\n * pass it, and a branch that loads later changes nothing the form posts.\n * `'checkbox-independent'` always reports exactly the checked items.\n * @defaultValue 'child'\n */\n checkedStrategy?: TreeSelectCheckedStrategy;\n /** Names each tag's button, in place of \"Remove\" and the item's label, as on Combobox. */\n ariaCloseLabel?: string;\n /** Read with `'single'` only. */\n parentsSelectable?: never;\n /** Read with `'single'` only: the panel stays open while boxes are checked. */\n closeOnSelect?: never;\n}\n\n/**\n * Props for the TreeSelect component. The helper props and the other\n * attributes land on the `div.tree-select` around the field, and the `ref`\n * on the field. It renders the `Field` and the label itself, unless an outer\n * `Field` already does.\n *\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the field, the read-only `<input role=\"combobox\">`.\n */\nexport type TreeSelectProps = TreeSelectSingleProps | TreeSelectCheckboxProps;\n\nconst NOTHING_HIDDEN: ReadonlySet<string> = new Set();\nconst noMatches = [{ id: 'empty' }];\nconst nothingToSay: Array<{ id: string }> = [];\n/** What takes focus as the panel opens. */\nconst INITIAL_FOCUS = '[data-initial-focus]';\n\n/** One value or several, as a list. */\nconst asList = (value: string | string[] | null | undefined): string[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n\n/** Whether two lists hold the same values, whatever their order and repeats. */\nconst sameValues = (a: string[], b: string[]): boolean => {\n const inA = new Set(a);\n const inB = new Set(b);\n return inA.size === inB.size && [...inA].every(value => inB.has(value));\n};\n\n/** The list with every value of `more` it doesn't have added at the end. */\nconst withAll = (list: string[], more: string[]): string[] => [\n ...list,\n ...more.filter(value => !list.includes(value)),\n];\n\n/**\n * The `TreeSelect` component is a form field whose options are a tree, such as categories, places or teams: it opens a panel holding a real `TreeView`, picks one item or checks a branch at a time, and searches labels.\n *\n * The field is a read-only `role=\"combobox\"` that opens a dialog, wired as\n * DateInput's is, so focus moves into the tree for real and the tree keeps\n * TreeView's keys, type-ahead and spoken output. The tree is given as `data`,\n * so the field and the tags can name what's picked while the panel is shut,\n * and on the server.\n *\n * `selectionMode` picks the kind. `'single'` picks one item and closes. With\n * `'checkbox'`, a check reaches every enabled item under it, closed or hidden\n * by a search, and `checkedStrategy` decides what the value holds: the\n * leaves, the topmost checked items or every one. With\n * `'checkbox-independent'`, each box is its own item's, so a parent means\n * itself alone (Mantine's and Ant Design's `checkStrictly`). The value shows\n * as tags under the field.\n *\n * A value no node has is kept and shown as it is, with a warning in\n * development, so a value under a branch that hasn't loaded survives until\n * it does.\n *\n * @function\n * @param {TreeSelectProps} props - Props for the TreeSelect component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the field.\n * @returns {JSX.Element} The field, its tags and its panel, in a `Field` with the label unless one is around it.\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ | APG Combobox Pattern}\n *\n * @example\n * <TreeSelect\n * label=\"Save to\"\n * data={[\n * { value: 'docs', label: 'Documents', children: [{ value: 'invoices', label: 'Invoices' }] },\n * { value: 'photos', label: 'Photos' },\n * ]}\n * searchable\n * />\n *\n * @example\n * <TreeSelect label=\"Regions\" selectionMode=\"checkbox\" checkedStrategy=\"parent\" data={regions} />\n */\nexport const TreeSelect = forwardRef<HTMLInputElement, TreeSelectProps>(\n (props, ref) => {\n const {\n data,\n expanded: expandedProp,\n defaultExpanded = [],\n onExpandedChange,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n searchable = false,\n query: queryProp,\n defaultQuery = '',\n onQueryChange,\n filter,\n empty,\n itemTemplate,\n disabled: disabledProp,\n clearable = false,\n size,\n labels,\n selectionMode = 'single',\n value: valueProp,\n defaultValue,\n // Called below through `props`, which knows which value it takes.\n onChange: _onChange,\n parentsSelectable = true,\n closeOnSelect = true,\n checkedStrategy = 'child',\n ariaCloseLabel,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n const single = selectionMode === 'single';\n const cascade = selectionMode === 'checkbox';\n\n const index = useMemo(() => indexTree(data), [data]);\n const records = useMemo(() => checkRecords(index), [index]);\n const labelFor = (value: string) => {\n const entry = index.get(value);\n return entry ? nodeLabel(entry.node) : value;\n };\n\n // The value, as a list: none or one in `single`.\n const [held, setHeld] = useControlled<string | string[] | null>(\n valueProp,\n defaultValue ?? null\n );\n const listed = asList(held);\n const change = (next: string[]) => {\n const value = single ? (next[0] ?? null) : next;\n setHeld(value);\n // The mode decides which of the two `onChange` takes.\n const report = props.onChange as\n ((value: string | string[] | null) => void) | undefined;\n report?.(value);\n };\n // What the field, the tags and the hidden inputs show: the value as it's\n // held. `checkedStrategy` shapes a new value as a check makes it, so a\n // branch that loads later changes nothing the form posts.\n const picked = single ? listed.slice(0, 1) : Array.from(new Set(listed));\n\n const unknown = picked.find(value => !index.has(value));\n useEffect(() => {\n if (unknown !== undefined) {\n warnOnce(\n 'TreeSelect:unknown-value',\n `[bestax-bulma] <TreeSelect> was given the value \"${unknown}\", ` +\n 'which no node in its data has. It is kept and shown as it is, ' +\n 'as it should be for a node under a branch that has not loaded ' +\n 'yet. Otherwise, check the value against the data.'\n );\n }\n }, [unknown]);\n\n const [expanded, setExpanded] = useControlled(\n expandedProp,\n defaultExpanded\n );\n const changeExpanded = (next: string[]) => {\n setExpanded(next);\n onExpandedChange?.(next);\n };\n\n // The picked item focus goes to: the first in the tree's order.\n const pickedSet = new Set(picked);\n const target = Array.from(index.keys()).find(value => pickedSet.has(value));\n\n const [query, setQueryState] = useControlled(queryProp, defaultQuery);\n const setQuery = (next: string) => {\n if (next === query) return;\n setQueryState(next);\n onQueryChange?.(next);\n };\n\n const [isOpen, setOpenState] = useControlled(openProp, defaultOpen);\n const setOpen = (next: boolean) => {\n if (next === isOpen) return;\n if (next) {\n // Opening shows the picked item, its branch open.\n const path = (target !== undefined && index.get(target)?.path) || [];\n if (path.some(value => !expanded.includes(value))) {\n changeExpanded(withAll(expanded, path));\n }\n } else {\n setQuery('');\n }\n setOpenState(next);\n onOpenChange?.(next);\n };\n\n const matchText = useLocaleMatcher();\n const typed = searchable ? query.trim() : '';\n // Every item reads the hidden set, so it's only built again when the\n // search text or the data changes.\n const search = useMemo(\n () =>\n typed\n ? searchTree(data, (node, path) => {\n if (filter) return filter(typed, node, path);\n const text = nodeLabel(node);\n return matchText\n ? matchText(text, typed)\n : text.toLowerCase().includes(typed.toLowerCase());\n })\n : null,\n // `filter` is read as it is when the text or the data changes: one\n // written inline is a new function every render, and listing it would\n // search again on each.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [data, typed, matchText]\n );\n // The branches a search opened that were closed during it, for the\n // search text they were closed under: any new text, from the box or\n // from a held `query`, starts over.\n const [searchClosed, setSearchClosed] = useState({\n query: typed,\n values: [] as string[],\n });\n if (searchClosed.query !== typed) {\n setSearchClosed({ query: typed, values: [] });\n }\n const closedHere = searchClosed.query === typed ? searchClosed.values : [];\n // The branches a search opens show open over the ones you opened, and\n // close again once it's cleared.\n const forced = search\n ? search.open.filter(value => !closedHere.includes(value))\n : [];\n const shownExpanded = withAll(expanded, forced);\n // TreeView's click on a row selects it and opens it. A pick by click, as\n // a pick by Enter, only picks, so the open the tree asks for right after\n // one on a parent is dropped, and a lazy parent isn't fetched to be\n // picked.\n const clickPickedRef = useRef(false);\n const onTreeExpandedChange = (next: string[]) => {\n if (clickPickedRef.current) {\n clickPickedRef.current = false;\n return;\n }\n const closed = shownExpanded.filter(value => !next.includes(value));\n const opened = next.filter(value => !shownExpanded.includes(value));\n const closedForced = closed.filter(value => forced.includes(value));\n if (closedForced.length > 0) {\n setSearchClosed({\n query: typed,\n values: [...closedHere, ...closedForced],\n });\n }\n if (opened.length > 0 || closed.some(value => expanded.includes(value))) {\n changeExpanded([\n ...expanded.filter(value => !closed.includes(value)),\n ...opened,\n ]);\n }\n };\n\n // Whether an item is on the page with the panel open: every branch\n // above it open, and the search not hiding it.\n const visible = (value: string) =>\n !search?.hidden.has(value) &&\n index.get(value)!.path.every(above => shownExpanded.includes(above));\n const focusTarget =\n target !== undefined && visible(target)\n ? target\n : data.find(node => visible(node.value))?.value;\n\n // Picking in `single`. TreeView shows `selected`, held here, and the\n // picks are made from the rows' own keys and clicks, so a parent can\n // open instead and a pick of the picked item still closes.\n const pickable = (node: TreeItemData) =>\n !node.disabled && (parentsSelectable || !isParentNode(node));\n const pick = (value: string) => {\n if (listed.length !== 1 || listed[0] !== value) change([value]);\n if (closeOnSelect) setOpen(false);\n };\n const toggleClass = usePrefixedClassNames('tree-view-toggle');\n const rowHandlers = (node: TreeItemData) =>\n single\n ? {\n onKeyDown: (event: React.KeyboardEvent<HTMLLIElement>) => {\n if (\n event.target !== event.currentTarget ||\n event.repeat ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n (event.key !== 'Enter' && event.key !== ' ')\n ) {\n return;\n }\n if (pickable(node)) {\n pick(node.value);\n } else if (!node.disabled && isParentNode(node)) {\n // TreeView leaves a key that's been used alone.\n event.preventDefault();\n onTreeExpandedChange(\n shownExpanded.includes(node.value)\n ? shownExpanded.filter(value => value !== node.value)\n : [...shownExpanded, node.value]\n );\n }\n },\n onClick: (event: React.MouseEvent<HTMLLIElement>) => {\n const item = event.currentTarget;\n const target = event.target as Element;\n // A click in this item's own row, where TreeView reads one,\n // not one in the group of items inside it, and not on its\n // chevron, which only opens it.\n const inRow =\n target === item || item.firstElementChild!.contains(target);\n const onChevron =\n isParentNode(node) && !!target.closest(`.${toggleClass}`);\n if (inRow && !onChevron && pickable(node)) {\n // TreeView opens a parent it's handed this click on, in\n // this same click: the flag goes once the click is over.\n clickPickedRef.current = isParentNode(node);\n queueMicrotask(() => {\n clickPickedRef.current = false;\n });\n pick(node.value);\n }\n },\n }\n : undefined;\n\n const renderNode = (node: TreeItemData): React.ReactNode => (\n <TreeView.Item\n key={node.value}\n value={node.value}\n label={itemTemplate ? itemTemplate(node) : nodeLabel(node)}\n icon={node.icon}\n hasChildren={node.hasChildren}\n isLoading={node.isLoading}\n loadError={node.loadError}\n onRetry={node.onRetry}\n disabled={node.disabled}\n data-initial-focus={\n !searchable && node.value === focusTarget ? '' : undefined\n }\n {...rowHandlers(node)}\n >\n {childNodes(node).map(renderNode)}\n </TreeView.Item>\n );\n\n // In `checkbox`, TreeView reports every checked item, read here into\n // the list `checkedStrategy` gives.\n const shaped = (next: string[]) =>\n cascade ? checkedByStrategy(records, next, checkedStrategy) : next;\n const onCheckedChange = (next: string[]) => change(shaped(next));\n // Every item's check state, read once a render, which the clear button\n // and the tags' buttons decide from. Only `checkbox` reads TreeView's\n // rules: in `checkbox-independent` a listed item is a checked one.\n const listedKey = JSON.stringify(listed);\n const checks = useMemo(\n () => (cascade ? readChecks(records, new Set(listed)) : null),\n // `listed` by what it holds, since a held list is a new array each\n // render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [cascade, records, listedKey]\n );\n const isDisabled = (value: string) => !!index.get(value)?.node.disabled;\n // Read in `checkbox` only, where there are states to read.\n const isChecked = (value: string) => checks!.states.get(value) === true;\n // What a control can uncheck. In `checkbox`, that's each checked end no\n // checked disabled item above it keeps checked, and every item above it,\n // which takes it along; elsewhere it's each listed item that isn't\n // disabled. A disabled item is checked only by its own value, so nothing\n // unchecks it, or what it keeps checked.\n const uncheckable = new Set<string>();\n if (checks) {\n for (const end of checks.ends) {\n const { path } = index.get(end)!;\n if (\n isChecked(end) &&\n !path.some(above => isDisabled(above) && isChecked(above))\n ) {\n uncheckable.add(end);\n path.forEach(above => uncheckable.add(above));\n }\n }\n } else if (!single) {\n picked.forEach(value => !isDisabled(value) && uncheckable.add(value));\n }\n // A tag's button takes its value off where that changes what's checked,\n // the way its box would. A value no node has can always go.\n const removable = (value: string) =>\n !index.has(value) || (!isDisabled(value) && uncheckable.has(value));\n const without = (value: string) =>\n cascade && records.has(value)\n ? shaped(toggledList(records, listed, value))\n : listed.filter(item => item !== value);\n // What the clear button leaves: the checked disabled items, and in\n // `checkbox` what they keep checked, shaped as a check's value is.\n const cleared = single\n ? []\n : shaped(\n checks\n ? Array.from(records.keys()).filter(\n value => isDisabled(value) && isChecked(value)\n )\n : picked.filter(isDisabled)\n );\n const canClear = single\n ? picked.length > 0\n : uncheckable.size > 0 || picked.some(value => !index.has(value));\n const inputRef = useRef<HTMLInputElement | null>(null);\n // A forwarded callback's cleanup, which React 19 lets it return, run on\n // detach in place of a call with `null`, on React 18 as well.\n const refCleanupRef = useRef<(() => void) | null>(null);\n const fieldRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') {\n if (node === null) {\n const cleanup = refCleanupRef.current;\n refCleanupRef.current = null;\n if (cleanup) cleanup();\n else ref(null);\n return;\n }\n const cleanup: unknown = ref(node);\n refCleanupRef.current =\n typeof cleanup === 'function' ? (cleanup as () => void) : null;\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n const tagsId = useId();\n const ids = tagIds(tagsId, picked);\n\n const searchClass = usePrefixedClassNames('input', 'tree-select-search', {\n [`is-${size}`]: !!size,\n });\n const emptyClass = usePrefixedClassNames('tree-select-empty');\n const treeRef = useRef<HTMLUListElement>(null);\n const emptyRef = useRef<HTMLDivElement>(null);\n const nothingFound = !!search && !search.found;\n // The region reads the text on screen, whatever `empty` renders.\n const describeEmpty = useCallback(() => {\n const node = emptyRef.current;\n /* istanbul ignore if: it's only announced while it's on screen */\n if (!node) return null;\n return spokenText(node);\n }, []);\n\n return (\n <DialogSelect\n {...rest}\n component=\"TreeSelect\"\n rootClass=\"tree-select\"\n panelClass=\"tree-select-panel\"\n text={single && picked.length > 0 ? labelFor(picked[0]) : ''}\n values={single ? [picked[0] ?? ''] : picked}\n hasValue={picked.length > 0}\n open={isOpen}\n onOpenChange={setOpen}\n onPrintableKey={\n searchable\n ? key => {\n setQuery(key);\n setOpen(true);\n return true;\n }\n : undefined\n }\n onClear={() => change(cleared)}\n clearable={clearable && canClear}\n onFormReset={() => {\n // Back to `defaultValue`, or to nothing for a held value, which\n // its owner sets from `onChange`.\n const back = valueProp === undefined ? asList(defaultValue) : [];\n if (!sameValues(back, listed)) change(back);\n }}\n clearLabel={labels?.clear || 'Clear'}\n chooseLabel={labels?.choose}\n disabled={disabled}\n size={size}\n inputRef={inputRef}\n fieldRef={fieldRef}\n describedBy={single ? undefined : ids.join(' ')}\n below={\n single ? undefined : (\n <ValueTags\n values={picked}\n ids={ids}\n labelFor={labelFor}\n disabled={disabled}\n ariaCloseLabel={ariaCloseLabel}\n removable={removable}\n onRemove={value => {\n change(without(value));\n inputRef.current?.focus();\n }}\n />\n )\n }\n initialFocusSelector={INITIAL_FOCUS}\n >\n {panelName => (\n <>\n {searchable && (\n <input\n className={searchClass}\n type=\"search\"\n aria-label={labels?.search || 'Search'}\n autoComplete=\"off\"\n value={query}\n data-initial-focus=\"\"\n onChange={event => setQuery(event.target.value)}\n onFocus={event => {\n // A key that opened the panel is in the box: type after it.\n const { length } = event.currentTarget.value;\n event.currentTarget.setSelectionRange(length, length);\n }}\n onKeyDown={event => {\n if (event.key === 'Enter') {\n // The search box's Enter would submit the form.\n event.preventDefault();\n } else if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n const tree = treeRef.current;\n (\n tree?.querySelector<HTMLElement>(\n '[role=\"treeitem\"][tabindex=\"0\"]'\n ) ?? tree?.querySelector<HTMLElement>('[role=\"treeitem\"]')\n )?.focus();\n }\n }}\n />\n )}\n {nothingFound ? (\n empty && (\n <div className={emptyClass} ref={emptyRef}>\n {empty}\n </div>\n )\n ) : (\n <TreeViewHiddenContext.Provider\n value={search?.hidden ?? NOTHING_HIDDEN}\n >\n <TreeView\n {...panelName}\n ref={treeRef}\n // It scrolls, and Firefox makes a scroller a Tab stop of\n // its own: the roving one on its items is the tree's.\n tabIndex={-1}\n selectionMode={selectionMode}\n size={size}\n selected={single ? (picked[0] ?? null) : undefined}\n checked={single ? undefined : listed}\n onCheckedChange={onCheckedChange}\n expanded={shownExpanded}\n onExpandedChange={onTreeExpandedChange}\n loadingLabel={labels?.loading}\n retryLabel={labels?.retry}\n loadingAnnouncement={labels?.loadingAnnouncement}\n loadedAnnouncement={labels?.loadedAnnouncement}\n >\n {data.map(renderNode)}\n </TreeView>\n </TreeViewHiddenContext.Provider>\n )}\n <StatusRegion\n items={nothingFound && empty ? noMatches : nothingToSay}\n describe={describeEmpty}\n />\n </>\n )}\n </DialogSelect>\n );\n }\n);\n\nTreeSelect.displayName = 'TreeSelect';\n\nexport default TreeSelect;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -109,6 +109,11 @@ const inWeeks = (days, className) => {
109
109
  }
110
110
  return rows;
111
111
  };
112
+ /** Sunday-first weekday names, starting from `firstDayOfWeek` instead. */
113
+ const fromFirstDay = (sundayFirst, firstDayOfWeek) => [
114
+ ...sundayFirst.slice(firstDayOfWeek),
115
+ ...sundayFirst.slice(0, firstDayOfWeek),
116
+ ];
112
117
  /** A date's time, or `null` for none, for comparing ranges by value. */
113
118
  const timeOf = (d) => d ? d.getTime() : null;
114
119
  /**
@@ -152,15 +157,18 @@ const Calendar = ({ value, focusedDate, onSelect: onSelectProp, onFocusedDateCha
152
157
  const [view, setView] = useState(baseView);
153
158
  // Nothing before year 1 can be picked or reached, as in HTML's date inputs.
154
159
  const min = useMemo(() => floorMin(minProp), [minProp]);
155
- const computedDayNames = useMemo(() => {
156
- if (dayNames && dayNames.length === 7)
157
- return dayNames;
158
- const sundayFirst = getDayNames(locale, 'short');
159
- return [
160
- ...sundayFirst.slice(firstDayOfWeek),
161
- ...sundayFirst.slice(0, firstDayOfWeek),
162
- ];
163
- }, [dayNames, locale, firstDayOfWeek]);
160
+ const customDayNames = dayNames && dayNames.length === 7 ? dayNames : null;
161
+ const computedDayNames = useMemo(() => customDayNames ??
162
+ fromFirstDay(getDayNames(locale, 'short'), firstDayOfWeek), [customDayNames, locale, firstDayOfWeek]);
163
+ // Each weekday column is named by its full weekday in the locale, so a
164
+ // screen reader names the column as focus moves across the grid. A server
165
+ // and a browser can spell those names differently, so they're added only
166
+ // once the page has hydrated, and never beside day names the caller gave,
167
+ // which name the columns themselves.
168
+ const hydrated = useIsHydrated();
169
+ const weekdayNames = useMemo(() => hydrated && !customDayNames
170
+ ? fromFirstDay(getDayNames(locale, 'long'), firstDayOfWeek)
171
+ : null, [hydrated, customDayNames, locale, firstDayOfWeek]);
164
172
  const computedMonthNames = useMemo(() => {
165
173
  if (monthNames && monthNames.length === 12)
166
174
  return monthNames;
@@ -447,7 +455,6 @@ const Calendar = ({ value, focusedDate, onSelect: onSelectProp, onFocusedDateCha
447
455
  // server render and the render hydrating it mark no day, month or year,
448
456
  // and the commit after marks the browser's own. A calendar mounted after
449
457
  // hydration marks it from its first render.
450
- const hydrated = useIsHydrated();
451
458
  const today = hydrated ? new Date() : null;
452
459
  const todayYear = today?.getFullYear();
453
460
  // The header steps a month at a time over the day grid and a year at a
@@ -656,7 +663,7 @@ const Calendar = ({ value, focusedDate, onSelect: onSelectProp, onFocusedDateCha
656
663
  return (jsxs("div", { className: classNames(calendarClass, className), id: id, children: [jsxs("div", { className: headerClass, children: [isYearGranularity ? (jsx("span", { className: monthLabelClass, id: labelId, children: monthLabel })) : (jsxs("button", { type: "button", className: monthTriggerClass, "aria-haspopup": "listbox", "aria-expanded": view === 'years', disabled: calendarDisabled, onClick: () => {
657
664
  setNavYear(null);
658
665
  setView(v => (v === 'years' ? baseView : 'years'));
659
- }, children: [jsx("span", { className: monthLabelClass, id: labelId, "aria-live": "polite", children: monthLabel }), jsx("svg", { className: monthCaretClass, viewBox: "0 0 12 12", width: "10", height: "10", "aria-hidden": "true", children: jsx("path", { d: "M2 4l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })] })), !isYearGranularity && (jsxs("div", { className: navGroupClass, children: [jsx("button", { type: "button", className: navPrevClass, "aria-label": isDayGranularity ? t.prevMonth : t.prevYear, disabled: calendarDisabled || prevDisabled || view !== baseView, onClick: () => onFocusedDateChange(prevAnchor), children: navArrow('M10 3l-5 5 5 5') }), jsx("button", { type: "button", className: navNextClass, "aria-label": isDayGranularity ? t.nextMonth : t.nextYear, disabled: calendarDisabled || nextDisabled || view !== baseView, onClick: () => onFocusedDateChange(nextAnchor), children: navArrow('M6 3l5 5-5 5') })] }))] }), view === 'days' && (jsxs(Fragment, { children: [jsx("div", { className: dayNamesRowClass, "aria-hidden": "true", children: computedDayNames.map((name, i) => (jsx("div", { className: dayNameClass, children: name }, i))) }), jsx("div", { ref: gridRef, role: "grid", "aria-labelledby": labelId, "aria-multiselectable": rangeMode || undefined, "aria-describedby": rangeMode ? rangeSummaryId : undefined, "aria-disabled": calendarDisabled || undefined, "aria-readonly": readOnly || undefined, className: gridClass, onKeyDown: handleKeyDown, onMouseLeave: anchor ? () => setHoverDate(null) : undefined, ...gridFocusHandlers, children: inWeeks(cells.map(cell => {
666
+ }, children: [jsx("span", { className: monthLabelClass, id: labelId, "aria-live": "polite", children: monthLabel }), jsx("svg", { className: monthCaretClass, viewBox: "0 0 12 12", width: "10", height: "10", "aria-hidden": "true", children: jsx("path", { d: "M2 4l4 4 4-4", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }) })] })), !isYearGranularity && (jsxs("div", { className: navGroupClass, children: [jsx("button", { type: "button", className: navPrevClass, "aria-label": isDayGranularity ? t.prevMonth : t.prevYear, disabled: calendarDisabled || prevDisabled || view !== baseView, onClick: () => onFocusedDateChange(prevAnchor), children: navArrow('M10 3l-5 5 5 5') }), jsx("button", { type: "button", className: navNextClass, "aria-label": isDayGranularity ? t.nextMonth : t.nextYear, disabled: calendarDisabled || nextDisabled || view !== baseView, onClick: () => onFocusedDateChange(nextAnchor), children: navArrow('M6 3l5 5-5 5') })] }))] }), view === 'days' && (jsx(Fragment, { children: jsxs("div", { ref: gridRef, role: "grid", "aria-labelledby": labelId, "aria-multiselectable": rangeMode || undefined, "aria-describedby": rangeMode ? rangeSummaryId : undefined, "aria-disabled": calendarDisabled || undefined, "aria-readonly": readOnly || undefined, className: gridClass, onKeyDown: handleKeyDown, onMouseLeave: anchor ? () => setHoverDate(null) : undefined, ...gridFocusHandlers, children: [jsx("div", { role: "row", className: dayNamesRowClass, children: computedDayNames.map((name, i) => (jsx("div", { role: "columnheader", "aria-label": weekdayNames?.[i], className: dayNameClass, children: name }, i))) }), inWeeks(cells.map(cell => {
660
667
  const disabled = calendarDisabled || isDateUnselectable(cell.date);
661
668
  const time = cell.date.getTime();
662
669
  // Range mode. The range on show has its ends filled. Every day
@@ -719,7 +726,7 @@ const Calendar = ({ value, focusedDate, onSelect: onSelectProp, onFocusedDateCha
719
726
  else
720
727
  onSelect?.(cell.date);
721
728
  }, style: !display ? { visibility: 'hidden' } : undefined, children: cell.date.getDate() }, cell.date.toISOString()));
722
- }), weekClass) })] })), view === 'months' && (jsx("div", { ref: monthGridRef, role: "grid", "aria-labelledby": labelId, "aria-disabled": calendarDisabled || undefined, "aria-readonly": readOnly || undefined, className: monthsGridClass, onKeyDown: handleMonthKeyDown, ...gridFocusHandlers, children: MONTH_ROWS.map(row => (jsx("div", { role: "row", className: monthsRowClass, children: row.map(month => {
729
+ }), weekClass)] }) })), view === 'months' && (jsx("div", { ref: monthGridRef, role: "grid", "aria-labelledby": labelId, "aria-disabled": calendarDisabled || undefined, "aria-readonly": readOnly || undefined, className: monthsGridClass, onKeyDown: handleMonthKeyDown, ...gridFocusHandlers, children: MONTH_ROWS.map(row => (jsx("div", { role: "row", className: monthsRowClass, children: row.map(month => {
723
730
  const date = makeDate(focusedYear, month);
724
731
  const disabled = calendarDisabled || disabledMonths[month];
725
732
  const isSelected = !!value && isSameMonth(value, date);