@allxsmith/bestax-bulma 5.62.0 → 5.63.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 (64) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/EmptyState.js +2 -6
  4. package/dist/esm/components/EmptyState.js.map +1 -1
  5. package/dist/esm/components/Timeline.js +5 -9
  6. package/dist/esm/components/Timeline.js.map +1 -1
  7. package/dist/esm/components/TreeView.js +3 -7
  8. package/dist/esm/components/TreeView.js.map +1 -1
  9. package/dist/esm/elements/Buttons.js +2 -0
  10. package/dist/esm/elements/Buttons.js.map +1 -1
  11. package/dist/esm/elements/CopyButton.js +132 -0
  12. package/dist/esm/elements/CopyButton.js.map +1 -0
  13. package/dist/esm/elements/DescriptionList.js +1 -5
  14. package/dist/esm/elements/DescriptionList.js.map +1 -1
  15. package/dist/esm/elements/Stat.js +196 -0
  16. package/dist/esm/elements/Stat.js.map +1 -0
  17. package/dist/esm/elements/Stats.js +48 -0
  18. package/dist/esm/elements/Stats.js.map +1 -0
  19. package/dist/esm/elements/statContext.js +10 -0
  20. package/dist/esm/elements/statContext.js.map +1 -0
  21. package/dist/esm/form/Combobox.js +2 -1
  22. package/dist/esm/form/Combobox.js.map +1 -1
  23. package/dist/esm/helpers/checkIcon.js +20 -0
  24. package/dist/esm/helpers/checkIcon.js.map +1 -0
  25. package/dist/esm/helpers/isGiven.js +13 -0
  26. package/dist/esm/helpers/isGiven.js.map +1 -0
  27. package/dist/esm/helpers/statusRegion.js +3 -3
  28. package/dist/esm/helpers/useClipboard.js +176 -0
  29. package/dist/esm/helpers/useClipboard.js.map +1 -0
  30. package/dist/extras.css +1 -1
  31. package/dist/extras.css.map +1 -1
  32. package/dist/index.cjs +4946 -4428
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.esm.js +4 -0
  35. package/dist/index.esm.js.map +1 -1
  36. package/dist/types/elements/Buttons.d.ts +1 -0
  37. package/dist/types/elements/CopyButton.d.ts +105 -0
  38. package/dist/types/elements/Stat.d.ts +242 -0
  39. package/dist/types/elements/Stats.d.ts +40 -0
  40. package/dist/types/elements/statContext.d.ts +18 -0
  41. package/dist/types/helpers/checkIcon.d.ts +10 -0
  42. package/dist/types/helpers/isGiven.d.ts +7 -0
  43. package/dist/types/helpers/useClipboard.d.ts +65 -0
  44. package/dist/types/index.d.ts +5 -0
  45. package/dist/types-cjs/elements/Buttons.d.ts +1 -0
  46. package/dist/types-cjs/elements/CopyButton.d.ts +105 -0
  47. package/dist/types-cjs/elements/Stat.d.ts +242 -0
  48. package/dist/types-cjs/elements/Stats.d.ts +40 -0
  49. package/dist/types-cjs/elements/statContext.d.ts +18 -0
  50. package/dist/types-cjs/helpers/checkIcon.d.ts +10 -0
  51. package/dist/types-cjs/helpers/isGiven.d.ts +7 -0
  52. package/dist/types-cjs/helpers/useClipboard.d.ts +65 -0
  53. package/dist/types-cjs/index.d.ts +5 -0
  54. package/dist/versions/bestax-no-dark-mode.css +1 -1
  55. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  56. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  57. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  58. package/dist/versions/bestax-no-helpers.css +1 -1
  59. package/dist/versions/bestax-no-helpers.css.map +1 -1
  60. package/dist/versions/bestax-prefixed.css +1 -1
  61. package/dist/versions/bestax-prefixed.css.map +1 -1
  62. package/package.json +1 -1
  63. package/src/scss/elements/_index.scss +1 -0
  64. package/src/scss/elements/_stat.scss +153 -0
@@ -13,6 +13,7 @@ import { warnOnce } from '../helpers/devWarnings.js';
13
13
  import { useLocaleMatcher } from '../helpers/localeFormat.js';
14
14
  import { useAnchoredPosition, marginGap } from '../helpers/useAnchoredPosition.js';
15
15
  import { spokenText, StatusRegion } from '../helpers/statusRegion.js';
16
+ import { CheckIcon } from '../helpers/checkIcon.js';
16
17
  import { useComboboxEngine } from '../helpers/useComboboxEngine.js';
17
18
  import { Field } from './Field.js';
18
19
  import { Input } from './Input.js';
@@ -372,7 +373,7 @@ const ComboboxItem = ({ value, disabled = false, checked = false, children, clas
372
373
  onPointerMove?.(event);
373
374
  if (!disabled && !highlighted)
374
375
  engine.hover(value);
375
- }, children: [checked && (jsx("span", { className: checkClass, "aria-hidden": "true", children: jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", width: "1em", height: "1em", focusable: "false", children: jsx("polyline", { points: "3 8.5 6.5 12 13 4.5" }) }) })), children] }));
376
+ }, children: [checked && (jsx("span", { className: checkClass, "aria-hidden": "true", children: jsx(CheckIcon, {}) })), children] }));
376
377
  };
377
378
  ComboboxItem.displayName = 'ComboboxItem';
378
379
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox.js","sources":["../../../src/form/Combobox.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { Portal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { flattenChildren } from '../helpers/flattenChildren';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { useLocaleMatcher } from '../helpers/localeFormat';\nimport {\n AnchoredPosition,\n marginGap,\n useAnchoredPosition,\n} from '../helpers/useAnchoredPosition';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport {\n ComboboxEngine,\n useComboboxEngine,\n} from '../helpers/useComboboxEngine';\nimport type { PopoverPosition } from '../components/Popover';\nimport { Field } from './Field';\nimport { Input, InputProps } from './Input';\nimport { FormFieldProps } from './fieldProps';\nimport {\n rendersOwnField,\n useFieldsetDisabled,\n useInsideControl,\n useInsideField,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { useControlLoading } from './controlLoading';\nimport { HiddenValues, ValueTags, tagIds } from './_selectInternals/ValueTags';\n\nconst validComboboxSizes = ['small', 'medium', 'large'] as const;\n\n// What the status region announces: the `Combobox.Empty` content, as the one\n// item it's handed while that content is on screen because of the user's\n// typing.\nconst typedNoMatches = [{ id: 'empty' }];\nconst nothingToAnnounce: Array<{ id: string }> = [];\n\n/**\n * One item in a Combobox's `data`. A string there is an item whose label is\n * its value.\n */\nexport interface ComboboxItemData {\n /**\n * What `onSelect` and `onChange` hand back, and what `name` posts. Unique\n * within the Combobox.\n */\n value: string;\n /** What the item shows, and what typing matches. The `value` when it's left out. */\n label?: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it.\n */\n disabled?: boolean;\n /**\n * The heading the item goes under. Groups show in the order `data` first\n * names them, and the items with no group show together where the first of\n * them is.\n */\n group?: string;\n}\n\n/** What a Combobox takes whether it's given `data` or built from parts. */\ninterface ComboboxBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'onChange' | 'onSelect' | 'defaultValue'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /**\n * The field's label, which names `Combobox.Input` through `htmlFor`, and\n * the list through `aria-labelledby`. Dropped inside an outer `Field`,\n * whose label names both instead when it points at the field. When\n * `Combobox.Input` has an `id` of its own, server markup names the field\n * through `aria-labelledby` until the page hydrates and the label's `for`\n * catches up.\n */\n label?: React.ReactNode;\n /**\n * Props for the label element. An explicit `htmlFor` takes over the\n * association: give `Combobox.Input` the same `id`, and the list is still\n * named after the label.\n */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /**\n * Controlled open state. When set, opening and closing only report\n * through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the open state asked for: `true` from typing, a click in\n * the field or Down Arrow, and `false` from Escape, Tab, a pick with one\n * value, focus leaving or a press outside. Fires in controlled and\n * uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called with an item's `value` when it's picked with Enter or a click.\n * A disabled item is never picked. With `data`, `onChange` reports the\n * value that follows. Built from parts, the Combobox keeps no value and\n * doesn't change the text in the field: update yours here.\n */\n onSelect?: (value: string) => void;\n /**\n * Highlights the first enabled item whenever the list opens or its\n * items change, so Enter picks the top match. It only highlights:\n * leaving the field still picks nothing, and so does Tab.\n * @defaultValue false\n */\n keepFirst?: boolean;\n /**\n * The list is always on screen, in the flow under the field, as in a\n * Popover or a page panel. There's no menu, so nothing closes it, and\n * Escape goes to whatever is around it.\n * @defaultValue false\n */\n inline?: boolean;\n /**\n * Where the menu opens against the field: below (`bottom-*`) or above\n * (`top-*`), lined up with its left or right edge. `auto` picks the one\n * that keeps the list in the viewport, preferring below. The same union\n * Popover takes.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Renders the menu through `Portal`, into the `portalContainer` a\n * `ConfigProvider` sets, `document.body` by default, fixed to the viewport\n * at the field, so a container that clips its overflow can't cut it off.\n * It then shows from the commit after hydration, never in server markup.\n * Theming variables set on an ancestor reach it only when the portal's\n * container is inside that ancestor, as with Popover. In a `Modal`, point\n * `portalContainer` inside the modal, so the list stays in the dialog for\n * assistive tech.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /** Sizes the field and the items together. */\n size?: 'small' | 'medium' | 'large';\n}\n\n/** What a Combobox given `data` takes, with one value or several. */\ninterface ComboboxDataBaseProps extends ComboboxBaseProps {\n /** The field's placeholder, with `data`. */\n placeholder?: string;\n /**\n * A form field name, with `data`. A hidden input posts the value, empty\n * while there's none, and with `multiple` a hidden input posts each value.\n */\n name?: string;\n /**\n * What the menu shows in place of the list, with `data`, when nothing\n * matches the typing, such as \"No countries match\". It's announced the way\n * `Combobox.Empty` is. Without it, the menu closes while nothing matches.\n */\n empty?: React.ReactNode;\n /**\n * Renders an item's content, with `data`, in place of its label. It's\n * handed the item from `data`, a string there arriving as\n * `{ value, label }`.\n */\n itemTemplate?: (item: ComboboxItemData) => React.ReactNode;\n /**\n * The field can't be used, with `data`: it can't be focused or typed in,\n * its items can't be picked, its tags lose their buttons, and its hidden\n * inputs don't post, the way a disabled field's value doesn't.\n */\n disabled?: boolean;\n /**\n * A value is needed, with `data`. The field is `required` while nothing is\n * picked, so the browser's own check stops the form the way it does for\n * Autocomplete's field, and it's `aria-required` the whole time. The check\n * reads the field's text, which Enter, the list closing or leaving the\n * field puts back to the pick.\n */\n required?: boolean;\n /**\n * The id of the form the value posts with, with `data`, for a field\n * outside it. It goes on the hidden inputs, and on the field so that form\n * checks `required` too.\n */\n form?: string;\n /**\n * The field's `id`, with `data`, which the label then points at, and so\n * can a label of your own. Built from parts, it lands on `div.combobox`, so\n * give `Combobox.Input` the `id` instead.\n */\n id?: string;\n /**\n * Names the field and the list, with `data`, in place of a `label`. Built\n * from parts, it lands on `div.combobox`, so put it on `Combobox.Input`.\n */\n 'aria-label'?: string;\n /**\n * The ids of what names the field and the list, with `data`, in place of\n * a `label`. Built from parts, it lands on `div.combobox`, so put it on\n * `Combobox.Input`.\n */\n 'aria-labelledby'?: string;\n /** @internal With `data`, the Combobox renders its own parts. */\n children?: never;\n}\n\n/** Props for a Combobox given `data`, with one value. */\nexport interface ComboboxSingleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders the field, the menu, the list,\n * the groups and the empty message itself. A string is an item whose label\n * is its value, and an object is `{ value, label?, disabled?, group? }`.\n * Typing filters the items by label, ignoring case, and inside a\n * `LocaleProvider` with a `locale`, ignoring accents too where that\n * language does, so \"cafe\" finds \"Café\". The Combobox keeps the value. Leave it out to build the Combobox from parts.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`. With `data`, the value is an array, and the picks show\n * as tags under the field, inside its Field, each with a button that takes\n * it off. The field's description lists them, since its text is the\n * search.\n * @defaultValue false\n */\n multiple?: false;\n /**\n * The value, controlled, with `data`: the picked item's `value`, or `null`\n * for none, and with `multiple` an array of them. With one value, the\n * field shows the picked item's label while you aren't typing in it, and\n * the list closing or the field being left puts it back over any typing.\n * A field emptied and left like that clears the value.\n */\n value?: string | null;\n /** The value to start with when uncontrolled, with `data`. */\n defaultValue?: string | null;\n /**\n * Called with the new value, with `data`, when a pick, a tag's button or\n * a field left empty changes it: an item's `value` or `null`, or with\n * `multiple` the array.\n */\n onChange?: (value: string | null) => void;\n /** @internal With one value there are no tags to name. */\n ariaCloseLabel?: never;\n}\n\n/** Props for a Combobox given `data`, with several values. */\nexport interface ComboboxMultipleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders itself. A string is an item whose\n * label is its value, and an object is `{ value, label?, disabled?, group? }`.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked: the value is an array, and the picks show\n * as tags under the field, each with a button that takes it off. The\n * field's description lists them.\n */\n multiple: true;\n /** The values, controlled: the picked items' `value`s. */\n value?: string[];\n /** The values to start with when uncontrolled. */\n defaultValue?: string[];\n /** Called with the new array when a pick or a tag's button changes it. */\n onChange?: (value: string[]) => void;\n /**\n * Names each tag's button, in place of \"Remove\" and the item's label, as\n * Taginput's does. The button is then described by its tag's label, so it\n * still says which tag it takes off.\n */\n ariaCloseLabel?: string;\n}\n\n/** Props for a Combobox given `data`. */\ntype ComboboxDataProps = ComboboxSingleDataProps | ComboboxMultipleDataProps;\n\n/** Props for a Combobox built from parts. */\nexport interface ComboboxPartsProps extends ComboboxBaseProps {\n /**\n * The parts, in order: `Combobox.Input`, then `Combobox.Menu` with\n * `Combobox.List` and `Combobox.Empty` in it. With `inline`, the\n * `Combobox.List` and `Combobox.Empty` go straight in. Render\n * `Combobox.List` while there are items and `Combobox.Empty` while\n * there aren't: the empty message sits beside the list, not in it. With\n * `data` there are none to give: children given with it are ignored, with\n * a warning in development.\n */\n children?: React.ReactNode;\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`.\n * @defaultValue false\n */\n multiple?: boolean;\n /** @internal Built from parts, there's no `data`. */\n data?: never;\n /** @internal Built from parts, the app keeps the value. */\n value?: never;\n /** @internal Built from parts, the app keeps the value. */\n defaultValue?: never;\n /** @internal Built from parts, `onSelect` reports a pick. */\n onChange?: never;\n /** @internal Built from parts, `Combobox.Input` takes the placeholder. */\n placeholder?: never;\n /** @internal Built from parts, the app posts the value. */\n name?: never;\n /** @internal Built from parts, `Combobox.Empty` is the empty message. */\n empty?: never;\n /** @internal Built from parts, `Combobox.Item` renders its own content. */\n itemTemplate?: never;\n /** @internal Built from parts, `Combobox.Input` takes `disabled`. */\n disabled?: never;\n /** @internal Built from parts, `Combobox.Input` takes `required`. */\n required?: never;\n /** @internal Built from parts, the app posts the value. */\n form?: never;\n}\n\n/**\n * Props for the Combobox component: given `data`, it renders itself and\n * keeps the value, and without it, it's built from parts. The helper props,\n * the other attributes and the `ref` land on the `div.combobox` around the\n * field and the list. It renders the `Field` and the label itself, unless an\n * outer `Field` already does.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the `div.combobox` around the field and the list.\n */\nexport type ComboboxProps =\n ComboboxSingleDataProps | ComboboxMultipleDataProps | ComboboxPartsProps;\n\n/**\n * Props for Combobox.Input, the text field. It renders `Input`, so its icons,\n * `isLoading` and `color` work as they do there. The Field props go on the\n * Combobox, and the size comes from it. The field is `autoComplete=\"off\"`,\n * so the browser's own suggestions don't open over the list, and that isn't\n * yours to set.\n */\nexport type ComboboxInputProps = Omit<\n InputProps,\n // By name, since the docs read only names out of an Omit, and\n // `__typetests__/combobox.tsx` fails if one goes missing. The Field props:\n | 'label'\n | 'labelSize'\n | 'labelProps'\n | 'horizontal'\n | 'message'\n | 'messageColor'\n | 'fieldClassName'\n // And what the Combobox sets on the field itself:\n | 'size'\n | 'role'\n | 'autoComplete'\n>;\n\n/** Props for Combobox.Menu, the floating panel under the field. */\nexport interface ComboboxMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * What the panel shows: `Combobox.List` while there are items, and\n * `Combobox.Empty` while there aren't. Children that are all `null`,\n * `false` or `''`, or empty Fragments, keep the panel shut, so write the\n * conditional here. A component that renders nothing, or a\n * `Combobox.List` with no items in it, still counts, and shows an\n * empty panel.\n */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.List, the list. Its `id` is the one the field's\n * `aria-controls` names, so it isn't yours to set.\n */\nexport interface ComboboxListProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'id'\n> {\n /** `Combobox.Item`s and `Combobox.Group`s, in the order they're shown. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.Item, one choice in the list. Its `id` follows from\n * its `value`, since the field's `aria-activedescendant` names it, so it\n * isn't yours to set.\n */\nexport interface ComboboxItemProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'onSelect' | 'id'\n> {\n /** What `onSelect` hands back. Unique within the Combobox. */\n value: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it, and it's never `aria-selected`.\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * It's the value, or one of them. It shows a check mark, the list opens\n * with the highlight on it, and with `multiple` it's the `aria-selected`.\n * @defaultValue false\n */\n checked?: boolean;\n /** What the item shows: text, or text with an avatar, a tag or a hint. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Group, items under a heading. */\nexport interface ComboboxGroupProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role'\n> {\n /**\n * The heading, which also names the group for assistive tech, unless you\n * give the group an `aria-label` or `aria-labelledby` of its own.\n */\n label: React.ReactNode;\n /** The group's `Combobox.Item`s. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Empty, the message shown in place of the list. */\nexport interface ComboboxEmptyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The message, such as \"No countries match\". Its text is announced when\n * typing brings it on screen and isn't read again while it stays, so a\n * message that names the query is heard for the first query only.\n */\n children?: React.ReactNode;\n}\n\n/** What the Combobox hands its parts. */\ninterface ComboboxContextValue {\n engine: ComboboxEngine;\n /** The id the field takes when it's given none. */\n inputId: string | undefined;\n /** Tells the Combobox the id the field was given, so the label follows it. */\n reportInputId: (id: string | undefined) => void;\n /** The id of the label that names the field, which names the list too. */\n labelId: string | undefined;\n /**\n * The id of the label the Combobox renders itself, when it names the field.\n * The field points at it while its own `id` hasn't reached the label yet.\n */\n ownLabelId: string | undefined;\n /** Tells the Combobox the field's `isLoading`, which holds the empty message's announcement. */\n reportLoading: (loading: boolean) => void;\n /** Records the empty message while it's on screen. Returns the function that forgets it. */\n reportEmpty: (element: HTMLElement) => () => void;\n /** A change to the field's value, which is the user typing. */\n onFieldChange: (value: string) => void;\n /**\n * Records the menu's panel while it's on screen, so it's placed and\n * counts as inside. Returns the function that forgets it.\n */\n reportPanel: (element: HTMLElement) => () => void;\n /** Where the panel goes against the field. */\n placement: AnchoredPosition;\n size?: ComboboxProps['size'];\n multiple: boolean;\n inline: boolean;\n appendToBody: boolean;\n}\n\nconst noop = () => {};\nconst registerNothing = () => noop;\n\n// What a part rendered outside a Combobox reads: closed, with nothing to\n// report to, so it renders its markup and does nothing.\nconst standalone: ComboboxContextValue = {\n engine: {\n open: false,\n expanded: false,\n highlighted: null,\n typed: false,\n listboxId: '',\n itemId: () => '',\n rootRef: { current: null },\n inputRef: { current: null },\n listboxRef: { current: null },\n registerPopup: registerNothing,\n registerItem: registerNothing,\n onKeyDown: noop,\n onChange: noop,\n onClick: noop,\n onBlur: noop,\n hover: noop,\n pick: noop,\n keepFocus: noop,\n markInside: noop,\n },\n inputId: undefined,\n reportInputId: noop,\n labelId: undefined,\n ownLabelId: undefined,\n reportLoading: noop,\n reportEmpty: registerNothing,\n onFieldChange: noop,\n reportPanel: registerNothing,\n placement: { position: 'bottom-left' },\n multiple: false,\n inline: false,\n appendToBody: false,\n};\n\nconst ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nconst useCombobox = () => useContext(ComboboxContext) ?? standalone;\n\n/** Hands a node to a forwarded ref and to one of the component's own. */\nfunction setRefs<T>(\n node: T | null,\n own: React.MutableRefObject<T | null>,\n forwarded: React.ForwardedRef<T>\n) {\n own.current = node;\n if (typeof forwarded === 'function') forwarded(node);\n else if (forwarded) forwarded.current = node;\n}\n\n/**\n * The Combobox built from parts: the field, the menu, the list and the\n * keys, with the data, the filtering and the value left to the app.\n */\n/** What the parts root takes from the Combobox given `data`, beyond the parts' props. */\ninterface ComboboxPartsRootProps extends ComboboxPartsProps {\n /**\n * Shown under the Combobox, inside its Field and ahead of the message: the\n * tags of several values. While it's given, the two share a wrapper, so\n * they stay together in a horizontal Field's body.\n */\n below?: React.ReactNode;\n /**\n * Called when Enter goes on to the form with nothing to pick, so the\n * Combobox given `data` can put the field's text back first, `inline`\n * included, where nothing closes.\n */\n onSettle?: () => void;\n}\n\nconst ComboboxParts = forwardRef<HTMLDivElement, ComboboxPartsRootProps>(\n (\n {\n children,\n below,\n onSettle,\n open,\n defaultOpen = false,\n onOpenChange,\n onSelect,\n keepFirst = false,\n multiple = false,\n inline = false,\n position = 'bottom-left',\n appendToBody = false,\n size,\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Combobox', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n // The field's own `id`, when `Combobox.Input` was given one, which the\n // label then points at.\n const [givenInputId, setGivenInputId] = useState<string | undefined>();\n const {\n controlId,\n fieldLabelProps,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id: givenInputId,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: true,\n });\n const engine = useComboboxEngine({\n open,\n defaultOpen,\n onOpenChange,\n onSelect,\n onSettle,\n keepFirst,\n multiple,\n inline,\n // A portaled panel has no server markup to point at.\n deferred: appendToBody && !inline,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const validSize = (validComboboxSizes as readonly string[]).includes(\n size as string\n )\n ? size\n : undefined;\n const rootClass = usePrefixedClassNames('combobox', {\n [`is-${validSize}`]: !!validSize,\n 'is-inline': inline,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // A polite status region, in the page from the start so it's there\n // before anything is written into it, announces `Combobox.Empty` when\n // the user's typing leaves it on screen: once each time that happens,\n // not again on each keystroke while it stays. An empty field isn't a\n // search, so it stays quiet then. While the field's `isLoading`, or a\n // loading Control around the Combobox, says results are on their way, it\n // waits, and it's said once loading ends with the message still there.\n const [inputLoading, setInputLoading] = useState(false);\n const controlLoading = useControlLoading();\n const [hasText, setHasText] = useState(false);\n const emptyRef = useRef<HTMLElement | null>(null);\n const [emptyShown, setEmptyShown] = useState(false);\n const announced =\n engine.typed && hasText && emptyShown && !inputLoading && !controlLoading\n ? typedNoMatches\n : nothingToAnnounce;\n // The region reads the text on screen, whatever the message 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 const reportEmpty = useCallback((element: HTMLElement) => {\n emptyRef.current = element;\n setEmptyShown(true);\n return () => {\n emptyRef.current = null;\n setEmptyShown(false);\n };\n }, []);\n // The menu is placed from here rather than from the part, since this\n // is where the field's element is known by the time the panel mounts.\n const panelRef = useRef<HTMLElement | null>(null);\n const [panelShown, setPanelShown] = useState(false);\n const placement = useAnchoredPosition(engine.rootRef, panelRef, {\n active: panelShown,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-combobox-menu-offset` as a margin, so\n // the coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n matchWidth: true,\n // The list filters as the user types, so the menu's height changes.\n followContent: true,\n });\n const { registerPopup } = engine;\n const reportPanel = useCallback(\n (element: HTMLElement) => {\n const forget = registerPopup(element);\n panelRef.current = element;\n setPanelShown(true);\n return () => {\n forget();\n panelRef.current = null;\n setPanelShown(false);\n };\n },\n [registerPopup]\n );\n\n const onFieldChange = (value: string) => {\n setHasText(value !== '');\n engine.onChange();\n };\n\n // A new value each render: the engine's state and handlers are, and the\n // parts read the highlight and the open state from it.\n const context: ComboboxContextValue = {\n engine,\n inputId: controlId,\n reportInputId: setGivenInputId,\n labelId: listLabelId,\n ownLabelId: label && ownField ? listLabelId : undefined,\n reportLoading: setInputLoading,\n reportEmpty,\n onFieldChange,\n reportPanel,\n placement,\n size: validSize,\n multiple,\n inline,\n appendToBody,\n };\n\n const { rootRef } = engine;\n const rootRefs = useCallback(\n (node: HTMLDivElement | null) => setRefs(node, rootRef, ref),\n [rootRef, ref]\n );\n\n const comboboxElement = (\n // The ref after the spread, so the element stays the Combobox's.\n <div\n className={classNames(rootClass, bulmaHelperClasses, className)}\n {...rest}\n ref={rootRefs}\n >\n <ComboboxContext.Provider value={context}>\n {children}\n </ComboboxContext.Provider>\n <StatusRegion items={announced} describe={describeEmpty} />\n </div>\n );\n const fieldElement =\n below === undefined ? (\n comboboxElement\n ) : (\n <div>\n {comboboxElement}\n {/* Part of the Combobox, as the menu is: a press here keeps focus\n in the field and doesn't count as outside, so the list and the\n search stay put. */}\n <div\n onPointerDownCapture={engine.markInside}\n onMouseDown={engine.keepFocus}\n >\n {below}\n </div>\n </div>\n );\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {fieldElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fieldElement}\n {messageEl}\n </>\n );\n }\n);\nComboboxParts.displayName = 'ComboboxParts';\n\n/**\n * The text field, with the combobox role and the keys, rendered as an `Input`.\n *\n * @function\n * @param {ComboboxInputProps} props - Props for the Combobox.Input component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the `<input>`.\n * @returns {JSX.Element} The field in its Control.\n */\nexport const ComboboxInput = forwardRef<HTMLInputElement, ComboboxInputProps>(\n (\n {\n id,\n isLoading,\n controlSize,\n onKeyDown,\n onChange,\n onClick,\n onBlur,\n 'aria-autocomplete': ariaAutocomplete,\n ...props\n },\n ref\n ) => {\n const context = useCombobox();\n const { engine, reportInputId, reportLoading } = context;\n // Inside a caller's Control the field renders none of its own, so the\n // Combobox's size isn't handed to one there.\n const insideControl = useInsideControl();\n useClientLayoutEffect(() => {\n reportInputId(id);\n return () => reportInputId(undefined);\n }, [reportInputId, id]);\n useClientLayoutEffect(() => {\n reportLoading(!!isLoading);\n return () => reportLoading(false);\n }, [reportLoading, isLoading]);\n const { inputRef } = engine;\n const inputRefs = useCallback(\n (node: HTMLInputElement | null) => setRefs(node, inputRef, ref),\n [inputRef, ref]\n );\n const { expanded, highlighted } = engine;\n // An `id` of the field's own reaches the label from a layout effect, so\n // in server markup, and the first render, the label's `for` still names\n // the generated id. Until then the field points at the label itself,\n // unless the caller named it.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n const labelledBy = callerNamed\n ? props['aria-labelledby']\n : id !== undefined && id !== context.inputId\n ? context.ownLabelId\n : undefined;\n\n return (\n // The attributes the Combobox owns after the caller's, so a stray\n // `aria-expanded` never wins.\n <Input\n {...props}\n ref={inputRefs}\n id={id ?? context.inputId}\n aria-labelledby={labelledBy}\n isLoading={isLoading}\n size={context.size}\n controlSize={controlSize ?? (insideControl ? undefined : context.size)}\n role=\"combobox\"\n aria-autocomplete={ariaAutocomplete ?? 'list'}\n aria-haspopup=\"listbox\"\n aria-expanded={expanded}\n aria-controls={expanded ? engine.listboxId : undefined}\n aria-activedescendant={\n expanded && highlighted !== null\n ? engine.itemId(highlighted)\n : undefined\n }\n autoComplete=\"off\"\n onKeyDown={event => {\n onKeyDown?.(event);\n engine.onKeyDown(event);\n }}\n onChange={event => {\n onChange?.(event);\n context.onFieldChange(event.target.value);\n }}\n onClick={event => {\n onClick?.(event);\n if (!event.defaultPrevented) engine.onClick();\n }}\n onBlur={event => {\n onBlur?.(event);\n engine.onBlur(event);\n }}\n />\n );\n }\n);\nComboboxInput.displayName = 'ComboboxInput';\n\n/**\n * The floating panel under the field, on screen while the list is open and its children aren't all empty.\n *\n * @function\n * @param {ComboboxMenuProps} props - Props for the Combobox.Menu component.\n * @returns {JSX.Element | null} The panel, or nothing while the list is closed or its children are all empty.\n */\nexport const ComboboxMenu: React.FC<ComboboxMenuProps> = ({\n children,\n className,\n style,\n onMouseDown,\n onPointerDownCapture,\n ...props\n}) => {\n const { engine, inline, appendToBody, placement, reportPanel, size } =\n useCombobox();\n // Children that are all `null`, `false` or `''` leave no panel, whatever\n // `open` says. This reads the elements it's handed, not what they render.\n const hasContent = flattenChildren(children).some(child => child !== '');\n const shown = engine.open && !inline && hasContent;\n // A portaled panel has no server markup, so it only exists from the\n // commit after hydration. Everything that measures it waits for that.\n const hydrated = useIsHydrated();\n const mounted = shown && (hydrated || !appendToBody);\n const panelRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(() => {\n const panel = panelRef.current;\n return mounted && panel ? reportPanel(panel) : undefined;\n }, [mounted, reportPanel]);\n\n const menuClass = usePrefixedClassNames('dropdown-menu', 'combobox-menu', {\n [`is-${placement.position}`]: true,\n 'is-portal': appendToBody,\n [`is-${size}`]: !!size,\n });\n const contentClass = usePrefixedClassNames('dropdown-content');\n\n // Inline, the list is in the flow already.\n if (inline) return <>{children}</>;\n if (!shown) return null;\n\n return (\n <Portal disabled={!appendToBody}>\n <div\n {...props}\n ref={panelRef}\n className={classNames(menuClass, className)}\n style={\n appendToBody\n ? {\n ...style,\n position: 'fixed',\n top: placement.top,\n left: placement.left,\n minWidth: placement.minWidth,\n }\n : style\n }\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n onPointerDownCapture={event => {\n onPointerDownCapture?.(event);\n engine.markInside(event);\n }}\n >\n <div className={contentClass}>{children}</div>\n </div>\n </Portal>\n );\n};\nComboboxMenu.displayName = 'ComboboxMenu';\n\n/**\n * The list of items, a `listbox` named by the label that names the field.\n *\n * @function\n * @param {ComboboxListProps} props - Props for the Combobox.List component.\n * @returns {JSX.Element} The listbox.\n */\nexport const ComboboxList: React.FC<ComboboxListProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, labelId, multiple } = useCombobox();\n const { listboxRef, listboxId, keepFocus } = engine;\n const listClass = usePrefixedClassNames('combobox-list');\n // A name the caller gave the list wins over the label's.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(listClass, className)}\n {...props}\n ref={listboxRef}\n id={listboxId || undefined}\n role=\"listbox\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n aria-label={\n callerNamed ? props['aria-label'] : labelId ? undefined : 'Suggestions'\n }\n aria-multiselectable={multiple || undefined}\n onMouseDown={event => {\n onMouseDown?.(event);\n keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxList.displayName = 'ComboboxList';\n\n/**\n * One choice in the list, with a check mark while it's `checked`.\n *\n * @function\n * @param {ComboboxItemProps} props - Props for the Combobox.Item component.\n * @returns {JSX.Element} The item.\n */\nexport const ComboboxItem: React.FC<ComboboxItemProps> = ({\n value,\n disabled = false,\n checked = false,\n children,\n className,\n onClick,\n onPointerMove,\n ...props\n}) => {\n const { engine, multiple } = useCombobox();\n const itemRef = useRef<HTMLDivElement>(null);\n const { registerItem } = engine;\n useClientLayoutEffect(\n () =>\n registerItem(itemRef.current as HTMLDivElement, {\n value,\n disabled,\n checked,\n }),\n [registerItem, value, disabled, checked]\n );\n const highlighted = engine.highlighted === value;\n const itemClass = usePrefixedClassNames('dropdown-item', 'combobox-item', {\n 'is-active': highlighted,\n 'is-checked': checked,\n 'is-disabled': disabled,\n });\n const checkClass = usePrefixedClassNames('combobox-check');\n // One value: the highlighted option, as the ARIA Authoring Practices'\n // combobox has it, and no attribute on the rest. Several: each option says\n // whether it's chosen. Never a disabled option.\n const selected = disabled\n ? undefined\n : multiple\n ? checked\n : highlighted || undefined;\n\n return (\n <div\n className={classNames(itemClass, className)}\n {...props}\n ref={itemRef}\n id={engine.itemId(value) || undefined}\n role=\"option\"\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n onClick={event => {\n onClick?.(event);\n if (!disabled && !event.defaultPrevented) engine.pick(value);\n }}\n onPointerMove={event => {\n onPointerMove?.(event);\n if (!disabled && !highlighted) engine.hover(value);\n }}\n >\n {checked && (\n <span className={checkClass} aria-hidden=\"true\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n width=\"1em\"\n height=\"1em\"\n focusable=\"false\"\n >\n <polyline points=\"3 8.5 6.5 12 13 4.5\" />\n </svg>\n </span>\n )}\n {children}\n </div>\n );\n};\nComboboxItem.displayName = 'ComboboxItem';\n\n/**\n * Items under a heading, a `group` named by it.\n *\n * @function\n * @param {ComboboxGroupProps} props - Props for the Combobox.Group component.\n * @returns {JSX.Element} The group and its heading.\n */\nexport const ComboboxGroup: React.FC<ComboboxGroupProps> = ({\n label,\n children,\n className,\n ...props\n}) => {\n const labelId = useId();\n const groupClass = usePrefixedClassNames('combobox-group');\n const labelClass = usePrefixedClassNames('combobox-group-label');\n // A name the caller gave the group wins over its heading's, as on the list.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(groupClass, className)}\n {...props}\n role=\"group\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n >\n <div className={labelClass} id={labelId}>\n {label}\n </div>\n {children}\n </div>\n );\n};\nComboboxGroup.displayName = 'ComboboxGroup';\n\n/**\n * The message shown in place of the list when nothing matches, announced when typing brings it on screen.\n *\n * @function\n * @param {ComboboxEmptyProps} props - Props for the Combobox.Empty component.\n * @returns {JSX.Element} The message.\n */\nexport const ComboboxEmpty: React.FC<ComboboxEmptyProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, reportEmpty } = useCombobox();\n const emptyRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(\n () => reportEmpty(emptyRef.current as HTMLDivElement),\n [reportEmpty]\n );\n const emptyClass = usePrefixedClassNames('combobox-empty');\n return (\n <div\n className={classNames(emptyClass, className)}\n {...props}\n ref={emptyRef}\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxEmpty.displayName = 'ComboboxEmpty';\n\n/** An entry in `data` as an item: a string is its own label. */\nconst toItem = (entry: string | ComboboxItemData): ComboboxItemData =>\n typeof entry === 'string' ? { value: entry, label: entry } : entry;\n\nconst labelOf = (item: ComboboxItemData): string => item.label ?? item.value;\n\n/** One value or several, as a list: one value is a list of none or one. */\nconst asList = (value: string | string[] | null | undefined): string[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n\n/**\n * The Combobox given `data`. It renders the parts itself, filters the items\n * by label as the user types, and keeps the value, so a pick goes through\n * the same parts, keys and ARIA as one built by hand.\n */\nconst ComboboxFromData = forwardRef<HTMLDivElement, ComboboxDataProps>(\n (props, ref) => {\n const {\n data,\n value,\n defaultValue,\n // Called below through `props`, which knows which value it takes.\n onChange: _onChange,\n multiple = false,\n placeholder,\n name,\n empty,\n itemTemplate,\n onSelect,\n onOpenChange,\n inline = false,\n disabled: disabledProp,\n required = false,\n form,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ariaCloseLabel,\n children,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n // A name given in place of a label is the field's and the list's, not\n // the wrapper's. Only the ones given are passed, since an\n // `aria-labelledby` that's there at all, even undefined, keeps the\n // label's name off the field.\n const named = {\n ...(ariaLabel !== undefined && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy !== undefined && {\n 'aria-labelledby': ariaLabelledBy,\n }),\n };\n if (flattenChildren(children).length > 0) {\n warnOnce(\n 'Combobox:data-children',\n '[bestax-bulma] <Combobox data> renders its own field, menu and ' +\n 'items, so its children are ignored. Give it data or build it ' +\n 'from parts, not both.'\n );\n }\n const items = data.map(toItem);\n const labelFor = (picked: string) => {\n const item = items.find(entry => entry.value === picked);\n return item ? labelOf(item) : picked;\n };\n\n const controlled = value !== undefined;\n const [ownValue, setOwnValue] = useState(() => asList(defaultValue));\n const matchText = useLocaleMatcher();\n const picked = controlled ? asList(value) : ownValue;\n const change = (next: string[]) => {\n if (!controlled) setOwnValue(next);\n if (props.multiple === true) props.onChange?.(next);\n else props.onChange?.(next[0] ?? null);\n };\n\n // What's typed, or `null` while the field shows the value instead. The\n // ref holds it as it is now, since a pick sets it and the list's closing\n // reads it in the same event, before a render.\n const [query, setQueryState] = useState<string | null>(null);\n const queryRef = useRef<string | null>(null);\n const setQuery = (next: string | null) => {\n queryRef.current = next;\n setQueryState(next);\n };\n // Once the list closes or the field is left, the field shows the value\n // again: typed text goes back to the pick, and with one value a field\n // left empty clears it.\n const settle = () => {\n if (!multiple && queryRef.current === '' && picked.length > 0) {\n change([]);\n }\n setQuery(null);\n };\n const typed = (query ?? '').trim();\n const term = typed.toLowerCase();\n const shown = items.filter(item =>\n matchText\n ? matchText(labelOf(item), typed)\n : labelOf(item).toLowerCase().includes(term)\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n const select = (pick: string) => {\n onSelect?.(pick);\n if (multiple) {\n change(\n picked.includes(pick)\n ? picked.filter(v => v !== pick)\n : [...picked, pick]\n );\n } else {\n if (picked[0] !== pick) change([pick]);\n setQuery(null);\n }\n };\n const remove = (pick: string) => {\n change(picked.filter(v => v !== pick));\n inputRef.current?.focus();\n };\n // The picks, for the field's description, since its text is the search.\n const tagsId = useId();\n const ids = tagIds(tagsId, picked);\n\n // Each group where `data` first names it, and the items with none\n // together where the first of them is.\n const sections = new Map<string, ComboboxItemData[]>();\n for (const item of shown) {\n const group = item.group ?? '';\n sections.set(group, [...(sections.get(group) ?? []), item]);\n }\n const renderItem = (item: ComboboxItemData) => (\n <ComboboxItem\n key={item.value}\n value={item.value}\n disabled={disabled || item.disabled}\n checked={picked.includes(item.value)}\n >\n {itemTemplate ? itemTemplate(item) : labelOf(item)}\n </ComboboxItem>\n );\n const list =\n shown.length > 0 ? (\n <ComboboxList {...named}>\n {Array.from(sections, ([group, members]) =>\n group ? (\n <ComboboxGroup key={group} label={group}>\n {members.map(renderItem)}\n </ComboboxGroup>\n ) : (\n members.map(renderItem)\n )\n )}\n </ComboboxList>\n ) : empty ? (\n <ComboboxEmpty>{empty}</ComboboxEmpty>\n ) : null;\n\n return (\n <ComboboxParts\n {...rest}\n ref={ref}\n multiple={multiple}\n inline={inline}\n onSelect={select}\n onSettle={settle}\n onOpenChange={next => {\n if (!next) settle();\n onOpenChange?.(next);\n }}\n below={\n multiple ? (\n <ValueTags\n values={picked}\n ids={ids}\n labelFor={labelFor}\n disabled={disabled}\n ariaCloseLabel={ariaCloseLabel}\n onRemove={remove}\n />\n ) : undefined\n }\n >\n <ComboboxInput\n {...named}\n ref={inputRef}\n id={id}\n disabled={disabled}\n // The browser's check reads the field's text, and only a pick\n // fills it for good, so it's required until there is one.\n required={required && picked.length === 0}\n aria-required={required || undefined}\n form={form}\n aria-describedby={\n multiple && picked.length > 0 ? ids.join(' ') : undefined\n }\n placeholder={placeholder}\n value={\n query ??\n (multiple || picked.length === 0 ? '' : labelFor(picked[0]))\n }\n onChange={event => setQuery(event.target.value)}\n onBlur={settle}\n />\n {inline ? list : <ComboboxMenu>{list}</ComboboxMenu>}\n <HiddenValues\n name={name}\n values={multiple ? picked : [picked[0] ?? '']}\n form={form}\n disabled={disabled}\n />\n </ComboboxParts>\n );\n }\n);\nComboboxFromData.displayName = 'ComboboxFromData';\n\n/**\n * The `Combobox` component is a text field with a list to pick from under it, for a searchable select, a multi-select with tags, grouped items or a server search: given `data` it does the rest, and built from parts it leaves the data to you.\n *\n * Given `data`, it's one element. It renders the field, the menu, the list,\n * the groups and the empty message, filters the items by label as the user\n * types, and keeps the value, which `onChange` reports. With `multiple`, the\n * picks show as tags under the field.\n *\n * Built from parts, the app owns the data: what's in the list, how it's\n * filtered, and the value. A pick calls `onSelect` with the item's `value`,\n * and the Combobox keeps no value and never changes the text in the field,\n * so the app sets both there. Nothing filters the items either, so a\n * server's answer shows as it came. For a free-text field with suggestions,\n * `Autocomplete` is the simpler choice.\n *\n * Either way, focus stays in the field, and the highlighted item is its\n * `aria-activedescendant`. With one value, the highlighted item is the\n * `aria-selected` one, as the ARIA Authoring Practices' combobox does it, and\n * a `checked` item shows a check mark and takes the highlight when the list\n * opens. With `multiple`, `checked` is each item's `aria-selected`. Tab and\n * focus leaving close the menu without picking.\n *\n * When typing leaves the empty message on screen, its text is announced\n * through a polite status region, once, after any loading ends. Result\n * counts aren't announced: a screen reader reads the list's size from the\n * markup, and a count on every keystroke talks over the typing. Show one in\n * a `role=\"status\"` line beside the field when it matters.\n *\n * @function\n * @param {ComboboxProps} props - Props for the Combobox component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the `div.combobox`.\n * @returns {JSX.Element} The field and its list, in a `Field` with the label unless one is around it.\n *\n * @example\n * <Combobox\n * label=\"Country\"\n * data={['Canada', 'France', 'Japan']}\n * placeholder=\"Pick a country\"\n * empty=\"No countries match\"\n * />\n *\n * @example\n * <Combobox label=\"Country\" onSelect={pick}>\n * <Combobox.Input value={query} onChange={e => setQuery(e.target.value)} />\n * <Combobox.Menu>\n * {matches.length > 0 ? (\n * <Combobox.List>\n * {matches.map(c => (\n * <Combobox.Item key={c} value={c} checked={c === value}>\n * {c}\n * </Combobox.Item>\n * ))}\n * </Combobox.List>\n * ) : (\n * <Combobox.Empty>No countries match</Combobox.Empty>\n * )}\n * </Combobox.Menu>\n * </Combobox>\n */\nconst ComboboxRoot = forwardRef<HTMLDivElement, ComboboxProps>((props, ref) =>\n props.data === undefined ? (\n <ComboboxParts {...props} ref={ref} />\n ) : (\n <ComboboxFromData {...props} ref={ref} />\n )\n);\n\n/** Combobox with Input, Menu, List, Item, Group and Empty sub-components. */\nexport const Combobox = withSubComponents(\n ComboboxRoot,\n {\n Input: ComboboxInput,\n Menu: ComboboxMenu,\n List: ComboboxList,\n Item: ComboboxItem,\n Group: ComboboxGroup,\n Empty: ComboboxEmpty,\n },\n 'Combobox'\n);\n\nexport default Combobox;\n"],"names":["noop","standalone","setRefs","_jsxs","_jsx","_Fragment","asList"],"mappings":"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"}
1
+ {"version":3,"file":"Combobox.js","sources":["../../../src/form/Combobox.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useId,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { Portal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { flattenChildren } from '../helpers/flattenChildren';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { useLocaleMatcher } from '../helpers/localeFormat';\nimport {\n AnchoredPosition,\n marginGap,\n useAnchoredPosition,\n} from '../helpers/useAnchoredPosition';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport { CheckIcon } from '../helpers/checkIcon';\nimport {\n ComboboxEngine,\n useComboboxEngine,\n} from '../helpers/useComboboxEngine';\nimport type { PopoverPosition } from '../components/Popover';\nimport { Field } from './Field';\nimport { Input, InputProps } from './Input';\nimport { FormFieldProps } from './fieldProps';\nimport {\n rendersOwnField,\n useFieldsetDisabled,\n useInsideControl,\n useInsideField,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { useControlLoading } from './controlLoading';\nimport { HiddenValues, ValueTags, tagIds } from './_selectInternals/ValueTags';\n\nconst validComboboxSizes = ['small', 'medium', 'large'] as const;\n\n// What the status region announces: the `Combobox.Empty` content, as the one\n// item it's handed while that content is on screen because of the user's\n// typing.\nconst typedNoMatches = [{ id: 'empty' }];\nconst nothingToAnnounce: Array<{ id: string }> = [];\n\n/**\n * One item in a Combobox's `data`. A string there is an item whose label is\n * its value.\n */\nexport interface ComboboxItemData {\n /**\n * What `onSelect` and `onChange` hand back, and what `name` posts. Unique\n * within the Combobox.\n */\n value: string;\n /** What the item shows, and what typing matches. The `value` when it's left out. */\n label?: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it.\n */\n disabled?: boolean;\n /**\n * The heading the item goes under. Groups show in the order `data` first\n * names them, and the items with no group show together where the first of\n * them is.\n */\n group?: string;\n}\n\n/** What a Combobox takes whether it's given `data` or built from parts. */\ninterface ComboboxBaseProps\n extends\n Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'color' | 'onChange' | 'onSelect' | 'defaultValue'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /**\n * The field's label, which names `Combobox.Input` through `htmlFor`, and\n * the list through `aria-labelledby`. Dropped inside an outer `Field`,\n * whose label names both instead when it points at the field. When\n * `Combobox.Input` has an `id` of its own, server markup names the field\n * through `aria-labelledby` until the page hydrates and the label's `for`\n * catches up.\n */\n label?: React.ReactNode;\n /**\n * Props for the label element. An explicit `htmlFor` takes over the\n * association: give `Combobox.Input` the same `id`, and the list is still\n * named after the label.\n */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /**\n * Controlled open state. When set, opening and closing only report\n * through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the open state asked for: `true` from typing, a click in\n * the field or Down Arrow, and `false` from Escape, Tab, a pick with one\n * value, focus leaving or a press outside. Fires in controlled and\n * uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Called with an item's `value` when it's picked with Enter or a click.\n * A disabled item is never picked. With `data`, `onChange` reports the\n * value that follows. Built from parts, the Combobox keeps no value and\n * doesn't change the text in the field: update yours here.\n */\n onSelect?: (value: string) => void;\n /**\n * Highlights the first enabled item whenever the list opens or its\n * items change, so Enter picks the top match. It only highlights:\n * leaving the field still picks nothing, and so does Tab.\n * @defaultValue false\n */\n keepFirst?: boolean;\n /**\n * The list is always on screen, in the flow under the field, as in a\n * Popover or a page panel. There's no menu, so nothing closes it, and\n * Escape goes to whatever is around it.\n * @defaultValue false\n */\n inline?: boolean;\n /**\n * Where the menu opens against the field: below (`bottom-*`) or above\n * (`top-*`), lined up with its left or right edge. `auto` picks the one\n * that keeps the list in the viewport, preferring below. The same union\n * Popover takes.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Renders the menu through `Portal`, into the `portalContainer` a\n * `ConfigProvider` sets, `document.body` by default, fixed to the viewport\n * at the field, so a container that clips its overflow can't cut it off.\n * It then shows from the commit after hydration, never in server markup.\n * Theming variables set on an ancestor reach it only when the portal's\n * container is inside that ancestor, as with Popover. In a `Modal`, point\n * `portalContainer` inside the modal, so the list stays in the dialog for\n * assistive tech.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /** Sizes the field and the items together. */\n size?: 'small' | 'medium' | 'large';\n}\n\n/** What a Combobox given `data` takes, with one value or several. */\ninterface ComboboxDataBaseProps extends ComboboxBaseProps {\n /** The field's placeholder, with `data`. */\n placeholder?: string;\n /**\n * A form field name, with `data`. A hidden input posts the value, empty\n * while there's none, and with `multiple` a hidden input posts each value.\n */\n name?: string;\n /**\n * What the menu shows in place of the list, with `data`, when nothing\n * matches the typing, such as \"No countries match\". It's announced the way\n * `Combobox.Empty` is. Without it, the menu closes while nothing matches.\n */\n empty?: React.ReactNode;\n /**\n * Renders an item's content, with `data`, in place of its label. It's\n * handed the item from `data`, a string there arriving as\n * `{ value, label }`.\n */\n itemTemplate?: (item: ComboboxItemData) => React.ReactNode;\n /**\n * The field can't be used, with `data`: it can't be focused or typed in,\n * its items can't be picked, its tags lose their buttons, and its hidden\n * inputs don't post, the way a disabled field's value doesn't.\n */\n disabled?: boolean;\n /**\n * A value is needed, with `data`. The field is `required` while nothing is\n * picked, so the browser's own check stops the form the way it does for\n * Autocomplete's field, and it's `aria-required` the whole time. The check\n * reads the field's text, which Enter, the list closing or leaving the\n * field puts back to the pick.\n */\n required?: boolean;\n /**\n * The id of the form the value posts with, with `data`, for a field\n * outside it. It goes on the hidden inputs, and on the field so that form\n * checks `required` too.\n */\n form?: string;\n /**\n * The field's `id`, with `data`, which the label then points at, and so\n * can a label of your own. Built from parts, it lands on `div.combobox`, so\n * give `Combobox.Input` the `id` instead.\n */\n id?: string;\n /**\n * Names the field and the list, with `data`, in place of a `label`. Built\n * from parts, it lands on `div.combobox`, so put it on `Combobox.Input`.\n */\n 'aria-label'?: string;\n /**\n * The ids of what names the field and the list, with `data`, in place of\n * a `label`. Built from parts, it lands on `div.combobox`, so put it on\n * `Combobox.Input`.\n */\n 'aria-labelledby'?: string;\n /** @internal With `data`, the Combobox renders its own parts. */\n children?: never;\n}\n\n/** Props for a Combobox given `data`, with one value. */\nexport interface ComboboxSingleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders the field, the menu, the list,\n * the groups and the empty message itself. A string is an item whose label\n * is its value, and an object is `{ value, label?, disabled?, group? }`.\n * Typing filters the items by label, ignoring case, and inside a\n * `LocaleProvider` with a `locale`, ignoring accents too where that\n * language does, so \"cafe\" finds \"Café\". The Combobox keeps the value. Leave it out to build the Combobox from parts.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`. With `data`, the value is an array, and the picks show\n * as tags under the field, inside its Field, each with a button that takes\n * it off. The field's description lists them, since its text is the\n * search.\n * @defaultValue false\n */\n multiple?: false;\n /**\n * The value, controlled, with `data`: the picked item's `value`, or `null`\n * for none, and with `multiple` an array of them. With one value, the\n * field shows the picked item's label while you aren't typing in it, and\n * the list closing or the field being left puts it back over any typing.\n * A field emptied and left like that clears the value.\n */\n value?: string | null;\n /** The value to start with when uncontrolled, with `data`. */\n defaultValue?: string | null;\n /**\n * Called with the new value, with `data`, when a pick, a tag's button or\n * a field left empty changes it: an item's `value` or `null`, or with\n * `multiple` the array.\n */\n onChange?: (value: string | null) => void;\n /** @internal With one value there are no tags to name. */\n ariaCloseLabel?: never;\n}\n\n/** Props for a Combobox given `data`, with several values. */\nexport interface ComboboxMultipleDataProps extends ComboboxDataBaseProps {\n /**\n * The items, for a Combobox that renders itself. A string is an item whose\n * label is its value, and an object is `{ value, label?, disabled?, group? }`.\n */\n data: (string | ComboboxItemData)[];\n /**\n * Several values can be picked: the value is an array, and the picks show\n * as tags under the field, each with a button that takes it off. The\n * field's description lists them.\n */\n multiple: true;\n /** The values, controlled: the picked items' `value`s. */\n value?: string[];\n /** The values to start with when uncontrolled. */\n defaultValue?: string[];\n /** Called with the new array when a pick or a tag's button changes it. */\n onChange?: (value: string[]) => void;\n /**\n * Names each tag's button, in place of \"Remove\" and the item's label, as\n * Taginput's does. The button is then described by its tag's label, so it\n * still says which tag it takes off.\n */\n ariaCloseLabel?: string;\n}\n\n/** Props for a Combobox given `data`. */\ntype ComboboxDataProps = ComboboxSingleDataProps | ComboboxMultipleDataProps;\n\n/** Props for a Combobox built from parts. */\nexport interface ComboboxPartsProps extends ComboboxBaseProps {\n /**\n * The parts, in order: `Combobox.Input`, then `Combobox.Menu` with\n * `Combobox.List` and `Combobox.Empty` in it. With `inline`, the\n * `Combobox.List` and `Combobox.Empty` go straight in. Render\n * `Combobox.List` while there are items and `Combobox.Empty` while\n * there aren't: the empty message sits beside the list, not in it. With\n * `data` there are none to give: children given with it are ignored, with\n * a warning in development.\n */\n children?: React.ReactNode;\n /**\n * Several values can be picked. The list stays open after a pick, it's\n * `aria-multiselectable`, and each item's `checked` is its\n * `aria-selected`.\n * @defaultValue false\n */\n multiple?: boolean;\n /** @internal Built from parts, there's no `data`. */\n data?: never;\n /** @internal Built from parts, the app keeps the value. */\n value?: never;\n /** @internal Built from parts, the app keeps the value. */\n defaultValue?: never;\n /** @internal Built from parts, `onSelect` reports a pick. */\n onChange?: never;\n /** @internal Built from parts, `Combobox.Input` takes the placeholder. */\n placeholder?: never;\n /** @internal Built from parts, the app posts the value. */\n name?: never;\n /** @internal Built from parts, `Combobox.Empty` is the empty message. */\n empty?: never;\n /** @internal Built from parts, `Combobox.Item` renders its own content. */\n itemTemplate?: never;\n /** @internal Built from parts, `Combobox.Input` takes `disabled`. */\n disabled?: never;\n /** @internal Built from parts, `Combobox.Input` takes `required`. */\n required?: never;\n /** @internal Built from parts, the app posts the value. */\n form?: never;\n}\n\n/**\n * Props for the Combobox component: given `data`, it renders itself and\n * keeps the value, and without it, it's built from parts. The helper props,\n * the other attributes and the `ref` land on the `div.combobox` around the\n * field and the list. It renders the `Field` and the label itself, unless an\n * outer `Field` already does.\n *\n * @extraProp {React.Ref<HTMLDivElement>} [ref] - Ref forwarded to the `div.combobox` around the field and the list.\n */\nexport type ComboboxProps =\n ComboboxSingleDataProps | ComboboxMultipleDataProps | ComboboxPartsProps;\n\n/**\n * Props for Combobox.Input, the text field. It renders `Input`, so its icons,\n * `isLoading` and `color` work as they do there. The Field props go on the\n * Combobox, and the size comes from it. The field is `autoComplete=\"off\"`,\n * so the browser's own suggestions don't open over the list, and that isn't\n * yours to set.\n */\nexport type ComboboxInputProps = Omit<\n InputProps,\n // By name, since the docs read only names out of an Omit, and\n // `__typetests__/combobox.tsx` fails if one goes missing. The Field props:\n | 'label'\n | 'labelSize'\n | 'labelProps'\n | 'horizontal'\n | 'message'\n | 'messageColor'\n | 'fieldClassName'\n // And what the Combobox sets on the field itself:\n | 'size'\n | 'role'\n | 'autoComplete'\n>;\n\n/** Props for Combobox.Menu, the floating panel under the field. */\nexport interface ComboboxMenuProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * What the panel shows: `Combobox.List` while there are items, and\n * `Combobox.Empty` while there aren't. Children that are all `null`,\n * `false` or `''`, or empty Fragments, keep the panel shut, so write the\n * conditional here. A component that renders nothing, or a\n * `Combobox.List` with no items in it, still counts, and shows an\n * empty panel.\n */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.List, the list. Its `id` is the one the field's\n * `aria-controls` names, so it isn't yours to set.\n */\nexport interface ComboboxListProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'id'\n> {\n /** `Combobox.Item`s and `Combobox.Group`s, in the order they're shown. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for Combobox.Item, one choice in the list. Its `id` follows from\n * its `value`, since the field's `aria-activedescendant` names it, so it\n * isn't yours to set.\n */\nexport interface ComboboxItemProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role' | 'onSelect' | 'id'\n> {\n /** What `onSelect` hands back. Unique within the Combobox. */\n value: string;\n /**\n * Can't be picked. The arrows still reach it, so a screen reader user\n * finds it, and it's never `aria-selected`.\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * It's the value, or one of them. It shows a check mark, the list opens\n * with the highlight on it, and with `multiple` it's the `aria-selected`.\n * @defaultValue false\n */\n checked?: boolean;\n /** What the item shows: text, or text with an avatar, a tag or a hint. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Group, items under a heading. */\nexport interface ComboboxGroupProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'role'\n> {\n /**\n * The heading, which also names the group for assistive tech, unless you\n * give the group an `aria-label` or `aria-labelledby` of its own.\n */\n label: React.ReactNode;\n /** The group's `Combobox.Item`s. */\n children?: React.ReactNode;\n}\n\n/** Props for Combobox.Empty, the message shown in place of the list. */\nexport interface ComboboxEmptyProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The message, such as \"No countries match\". Its text is announced when\n * typing brings it on screen and isn't read again while it stays, so a\n * message that names the query is heard for the first query only.\n */\n children?: React.ReactNode;\n}\n\n/** What the Combobox hands its parts. */\ninterface ComboboxContextValue {\n engine: ComboboxEngine;\n /** The id the field takes when it's given none. */\n inputId: string | undefined;\n /** Tells the Combobox the id the field was given, so the label follows it. */\n reportInputId: (id: string | undefined) => void;\n /** The id of the label that names the field, which names the list too. */\n labelId: string | undefined;\n /**\n * The id of the label the Combobox renders itself, when it names the field.\n * The field points at it while its own `id` hasn't reached the label yet.\n */\n ownLabelId: string | undefined;\n /** Tells the Combobox the field's `isLoading`, which holds the empty message's announcement. */\n reportLoading: (loading: boolean) => void;\n /** Records the empty message while it's on screen. Returns the function that forgets it. */\n reportEmpty: (element: HTMLElement) => () => void;\n /** A change to the field's value, which is the user typing. */\n onFieldChange: (value: string) => void;\n /**\n * Records the menu's panel while it's on screen, so it's placed and\n * counts as inside. Returns the function that forgets it.\n */\n reportPanel: (element: HTMLElement) => () => void;\n /** Where the panel goes against the field. */\n placement: AnchoredPosition;\n size?: ComboboxProps['size'];\n multiple: boolean;\n inline: boolean;\n appendToBody: boolean;\n}\n\nconst noop = () => {};\nconst registerNothing = () => noop;\n\n// What a part rendered outside a Combobox reads: closed, with nothing to\n// report to, so it renders its markup and does nothing.\nconst standalone: ComboboxContextValue = {\n engine: {\n open: false,\n expanded: false,\n highlighted: null,\n typed: false,\n listboxId: '',\n itemId: () => '',\n rootRef: { current: null },\n inputRef: { current: null },\n listboxRef: { current: null },\n registerPopup: registerNothing,\n registerItem: registerNothing,\n onKeyDown: noop,\n onChange: noop,\n onClick: noop,\n onBlur: noop,\n hover: noop,\n pick: noop,\n keepFocus: noop,\n markInside: noop,\n },\n inputId: undefined,\n reportInputId: noop,\n labelId: undefined,\n ownLabelId: undefined,\n reportLoading: noop,\n reportEmpty: registerNothing,\n onFieldChange: noop,\n reportPanel: registerNothing,\n placement: { position: 'bottom-left' },\n multiple: false,\n inline: false,\n appendToBody: false,\n};\n\nconst ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nconst useCombobox = () => useContext(ComboboxContext) ?? standalone;\n\n/** Hands a node to a forwarded ref and to one of the component's own. */\nfunction setRefs<T>(\n node: T | null,\n own: React.MutableRefObject<T | null>,\n forwarded: React.ForwardedRef<T>\n) {\n own.current = node;\n if (typeof forwarded === 'function') forwarded(node);\n else if (forwarded) forwarded.current = node;\n}\n\n/**\n * The Combobox built from parts: the field, the menu, the list and the\n * keys, with the data, the filtering and the value left to the app.\n */\n/** What the parts root takes from the Combobox given `data`, beyond the parts' props. */\ninterface ComboboxPartsRootProps extends ComboboxPartsProps {\n /**\n * Shown under the Combobox, inside its Field and ahead of the message: the\n * tags of several values. While it's given, the two share a wrapper, so\n * they stay together in a horizontal Field's body.\n */\n below?: React.ReactNode;\n /**\n * Called when Enter goes on to the form with nothing to pick, so the\n * Combobox given `data` can put the field's text back first, `inline`\n * included, where nothing closes.\n */\n onSettle?: () => void;\n}\n\nconst ComboboxParts = forwardRef<HTMLDivElement, ComboboxPartsRootProps>(\n (\n {\n children,\n below,\n onSettle,\n open,\n defaultOpen = false,\n onOpenChange,\n onSelect,\n keepFirst = false,\n multiple = false,\n inline = false,\n position = 'bottom-left',\n appendToBody = false,\n size,\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Combobox', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n // The field's own `id`, when `Combobox.Input` was given one, which the\n // label then points at.\n const [givenInputId, setGivenInputId] = useState<string | undefined>();\n const {\n controlId,\n fieldLabelProps,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id: givenInputId,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: true,\n });\n const engine = useComboboxEngine({\n open,\n defaultOpen,\n onOpenChange,\n onSelect,\n onSettle,\n keepFirst,\n multiple,\n inline,\n // A portaled panel has no server markup to point at.\n deferred: appendToBody && !inline,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const validSize = (validComboboxSizes as readonly string[]).includes(\n size as string\n )\n ? size\n : undefined;\n const rootClass = usePrefixedClassNames('combobox', {\n [`is-${validSize}`]: !!validSize,\n 'is-inline': inline,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // A polite status region, in the page from the start so it's there\n // before anything is written into it, announces `Combobox.Empty` when\n // the user's typing leaves it on screen: once each time that happens,\n // not again on each keystroke while it stays. An empty field isn't a\n // search, so it stays quiet then. While the field's `isLoading`, or a\n // loading Control around the Combobox, says results are on their way, it\n // waits, and it's said once loading ends with the message still there.\n const [inputLoading, setInputLoading] = useState(false);\n const controlLoading = useControlLoading();\n const [hasText, setHasText] = useState(false);\n const emptyRef = useRef<HTMLElement | null>(null);\n const [emptyShown, setEmptyShown] = useState(false);\n const announced =\n engine.typed && hasText && emptyShown && !inputLoading && !controlLoading\n ? typedNoMatches\n : nothingToAnnounce;\n // The region reads the text on screen, whatever the message 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 const reportEmpty = useCallback((element: HTMLElement) => {\n emptyRef.current = element;\n setEmptyShown(true);\n return () => {\n emptyRef.current = null;\n setEmptyShown(false);\n };\n }, []);\n // The menu is placed from here rather than from the part, since this\n // is where the field's element is known by the time the panel mounts.\n const panelRef = useRef<HTMLElement | null>(null);\n const [panelShown, setPanelShown] = useState(false);\n const placement = useAnchoredPosition(engine.rootRef, panelRef, {\n active: panelShown,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-combobox-menu-offset` as a margin, so\n // the coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n matchWidth: true,\n // The list filters as the user types, so the menu's height changes.\n followContent: true,\n });\n const { registerPopup } = engine;\n const reportPanel = useCallback(\n (element: HTMLElement) => {\n const forget = registerPopup(element);\n panelRef.current = element;\n setPanelShown(true);\n return () => {\n forget();\n panelRef.current = null;\n setPanelShown(false);\n };\n },\n [registerPopup]\n );\n\n const onFieldChange = (value: string) => {\n setHasText(value !== '');\n engine.onChange();\n };\n\n // A new value each render: the engine's state and handlers are, and the\n // parts read the highlight and the open state from it.\n const context: ComboboxContextValue = {\n engine,\n inputId: controlId,\n reportInputId: setGivenInputId,\n labelId: listLabelId,\n ownLabelId: label && ownField ? listLabelId : undefined,\n reportLoading: setInputLoading,\n reportEmpty,\n onFieldChange,\n reportPanel,\n placement,\n size: validSize,\n multiple,\n inline,\n appendToBody,\n };\n\n const { rootRef } = engine;\n const rootRefs = useCallback(\n (node: HTMLDivElement | null) => setRefs(node, rootRef, ref),\n [rootRef, ref]\n );\n\n const comboboxElement = (\n // The ref after the spread, so the element stays the Combobox's.\n <div\n className={classNames(rootClass, bulmaHelperClasses, className)}\n {...rest}\n ref={rootRefs}\n >\n <ComboboxContext.Provider value={context}>\n {children}\n </ComboboxContext.Provider>\n <StatusRegion items={announced} describe={describeEmpty} />\n </div>\n );\n const fieldElement =\n below === undefined ? (\n comboboxElement\n ) : (\n <div>\n {comboboxElement}\n {/* Part of the Combobox, as the menu is: a press here keeps focus\n in the field and doesn't count as outside, so the list and the\n search stay put. */}\n <div\n onPointerDownCapture={engine.markInside}\n onMouseDown={engine.keepFocus}\n >\n {below}\n </div>\n </div>\n );\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {fieldElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fieldElement}\n {messageEl}\n </>\n );\n }\n);\nComboboxParts.displayName = 'ComboboxParts';\n\n/**\n * The text field, with the combobox role and the keys, rendered as an `Input`.\n *\n * @function\n * @param {ComboboxInputProps} props - Props for the Combobox.Input component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the `<input>`.\n * @returns {JSX.Element} The field in its Control.\n */\nexport const ComboboxInput = forwardRef<HTMLInputElement, ComboboxInputProps>(\n (\n {\n id,\n isLoading,\n controlSize,\n onKeyDown,\n onChange,\n onClick,\n onBlur,\n 'aria-autocomplete': ariaAutocomplete,\n ...props\n },\n ref\n ) => {\n const context = useCombobox();\n const { engine, reportInputId, reportLoading } = context;\n // Inside a caller's Control the field renders none of its own, so the\n // Combobox's size isn't handed to one there.\n const insideControl = useInsideControl();\n useClientLayoutEffect(() => {\n reportInputId(id);\n return () => reportInputId(undefined);\n }, [reportInputId, id]);\n useClientLayoutEffect(() => {\n reportLoading(!!isLoading);\n return () => reportLoading(false);\n }, [reportLoading, isLoading]);\n const { inputRef } = engine;\n const inputRefs = useCallback(\n (node: HTMLInputElement | null) => setRefs(node, inputRef, ref),\n [inputRef, ref]\n );\n const { expanded, highlighted } = engine;\n // An `id` of the field's own reaches the label from a layout effect, so\n // in server markup, and the first render, the label's `for` still names\n // the generated id. Until then the field points at the label itself,\n // unless the caller named it.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n const labelledBy = callerNamed\n ? props['aria-labelledby']\n : id !== undefined && id !== context.inputId\n ? context.ownLabelId\n : undefined;\n\n return (\n // The attributes the Combobox owns after the caller's, so a stray\n // `aria-expanded` never wins.\n <Input\n {...props}\n ref={inputRefs}\n id={id ?? context.inputId}\n aria-labelledby={labelledBy}\n isLoading={isLoading}\n size={context.size}\n controlSize={controlSize ?? (insideControl ? undefined : context.size)}\n role=\"combobox\"\n aria-autocomplete={ariaAutocomplete ?? 'list'}\n aria-haspopup=\"listbox\"\n aria-expanded={expanded}\n aria-controls={expanded ? engine.listboxId : undefined}\n aria-activedescendant={\n expanded && highlighted !== null\n ? engine.itemId(highlighted)\n : undefined\n }\n autoComplete=\"off\"\n onKeyDown={event => {\n onKeyDown?.(event);\n engine.onKeyDown(event);\n }}\n onChange={event => {\n onChange?.(event);\n context.onFieldChange(event.target.value);\n }}\n onClick={event => {\n onClick?.(event);\n if (!event.defaultPrevented) engine.onClick();\n }}\n onBlur={event => {\n onBlur?.(event);\n engine.onBlur(event);\n }}\n />\n );\n }\n);\nComboboxInput.displayName = 'ComboboxInput';\n\n/**\n * The floating panel under the field, on screen while the list is open and its children aren't all empty.\n *\n * @function\n * @param {ComboboxMenuProps} props - Props for the Combobox.Menu component.\n * @returns {JSX.Element | null} The panel, or nothing while the list is closed or its children are all empty.\n */\nexport const ComboboxMenu: React.FC<ComboboxMenuProps> = ({\n children,\n className,\n style,\n onMouseDown,\n onPointerDownCapture,\n ...props\n}) => {\n const { engine, inline, appendToBody, placement, reportPanel, size } =\n useCombobox();\n // Children that are all `null`, `false` or `''` leave no panel, whatever\n // `open` says. This reads the elements it's handed, not what they render.\n const hasContent = flattenChildren(children).some(child => child !== '');\n const shown = engine.open && !inline && hasContent;\n // A portaled panel has no server markup, so it only exists from the\n // commit after hydration. Everything that measures it waits for that.\n const hydrated = useIsHydrated();\n const mounted = shown && (hydrated || !appendToBody);\n const panelRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(() => {\n const panel = panelRef.current;\n return mounted && panel ? reportPanel(panel) : undefined;\n }, [mounted, reportPanel]);\n\n const menuClass = usePrefixedClassNames('dropdown-menu', 'combobox-menu', {\n [`is-${placement.position}`]: true,\n 'is-portal': appendToBody,\n [`is-${size}`]: !!size,\n });\n const contentClass = usePrefixedClassNames('dropdown-content');\n\n // Inline, the list is in the flow already.\n if (inline) return <>{children}</>;\n if (!shown) return null;\n\n return (\n <Portal disabled={!appendToBody}>\n <div\n {...props}\n ref={panelRef}\n className={classNames(menuClass, className)}\n style={\n appendToBody\n ? {\n ...style,\n position: 'fixed',\n top: placement.top,\n left: placement.left,\n minWidth: placement.minWidth,\n }\n : style\n }\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n onPointerDownCapture={event => {\n onPointerDownCapture?.(event);\n engine.markInside(event);\n }}\n >\n <div className={contentClass}>{children}</div>\n </div>\n </Portal>\n );\n};\nComboboxMenu.displayName = 'ComboboxMenu';\n\n/**\n * The list of items, a `listbox` named by the label that names the field.\n *\n * @function\n * @param {ComboboxListProps} props - Props for the Combobox.List component.\n * @returns {JSX.Element} The listbox.\n */\nexport const ComboboxList: React.FC<ComboboxListProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, labelId, multiple } = useCombobox();\n const { listboxRef, listboxId, keepFocus } = engine;\n const listClass = usePrefixedClassNames('combobox-list');\n // A name the caller gave the list wins over the label's.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(listClass, className)}\n {...props}\n ref={listboxRef}\n id={listboxId || undefined}\n role=\"listbox\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n aria-label={\n callerNamed ? props['aria-label'] : labelId ? undefined : 'Suggestions'\n }\n aria-multiselectable={multiple || undefined}\n onMouseDown={event => {\n onMouseDown?.(event);\n keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxList.displayName = 'ComboboxList';\n\n/**\n * One choice in the list, with a check mark while it's `checked`.\n *\n * @function\n * @param {ComboboxItemProps} props - Props for the Combobox.Item component.\n * @returns {JSX.Element} The item.\n */\nexport const ComboboxItem: React.FC<ComboboxItemProps> = ({\n value,\n disabled = false,\n checked = false,\n children,\n className,\n onClick,\n onPointerMove,\n ...props\n}) => {\n const { engine, multiple } = useCombobox();\n const itemRef = useRef<HTMLDivElement>(null);\n const { registerItem } = engine;\n useClientLayoutEffect(\n () =>\n registerItem(itemRef.current as HTMLDivElement, {\n value,\n disabled,\n checked,\n }),\n [registerItem, value, disabled, checked]\n );\n const highlighted = engine.highlighted === value;\n const itemClass = usePrefixedClassNames('dropdown-item', 'combobox-item', {\n 'is-active': highlighted,\n 'is-checked': checked,\n 'is-disabled': disabled,\n });\n const checkClass = usePrefixedClassNames('combobox-check');\n // One value: the highlighted option, as the ARIA Authoring Practices'\n // combobox has it, and no attribute on the rest. Several: each option says\n // whether it's chosen. Never a disabled option.\n const selected = disabled\n ? undefined\n : multiple\n ? checked\n : highlighted || undefined;\n\n return (\n <div\n className={classNames(itemClass, className)}\n {...props}\n ref={itemRef}\n id={engine.itemId(value) || undefined}\n role=\"option\"\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n onClick={event => {\n onClick?.(event);\n if (!disabled && !event.defaultPrevented) engine.pick(value);\n }}\n onPointerMove={event => {\n onPointerMove?.(event);\n if (!disabled && !highlighted) engine.hover(value);\n }}\n >\n {checked && (\n <span className={checkClass} aria-hidden=\"true\">\n <CheckIcon />\n </span>\n )}\n {children}\n </div>\n );\n};\nComboboxItem.displayName = 'ComboboxItem';\n\n/**\n * Items under a heading, a `group` named by it.\n *\n * @function\n * @param {ComboboxGroupProps} props - Props for the Combobox.Group component.\n * @returns {JSX.Element} The group and its heading.\n */\nexport const ComboboxGroup: React.FC<ComboboxGroupProps> = ({\n label,\n children,\n className,\n ...props\n}) => {\n const labelId = useId();\n const groupClass = usePrefixedClassNames('combobox-group');\n const labelClass = usePrefixedClassNames('combobox-group-label');\n // A name the caller gave the group wins over its heading's, as on the list.\n const callerNamed = !!props['aria-label'] || 'aria-labelledby' in props;\n return (\n <div\n className={classNames(groupClass, className)}\n {...props}\n role=\"group\"\n aria-labelledby={callerNamed ? props['aria-labelledby'] : labelId}\n >\n <div className={labelClass} id={labelId}>\n {label}\n </div>\n {children}\n </div>\n );\n};\nComboboxGroup.displayName = 'ComboboxGroup';\n\n/**\n * The message shown in place of the list when nothing matches, announced when typing brings it on screen.\n *\n * @function\n * @param {ComboboxEmptyProps} props - Props for the Combobox.Empty component.\n * @returns {JSX.Element} The message.\n */\nexport const ComboboxEmpty: React.FC<ComboboxEmptyProps> = ({\n children,\n className,\n onMouseDown,\n ...props\n}) => {\n const { engine, reportEmpty } = useCombobox();\n const emptyRef = useRef<HTMLDivElement>(null);\n useClientLayoutEffect(\n () => reportEmpty(emptyRef.current as HTMLDivElement),\n [reportEmpty]\n );\n const emptyClass = usePrefixedClassNames('combobox-empty');\n return (\n <div\n className={classNames(emptyClass, className)}\n {...props}\n ref={emptyRef}\n onMouseDown={event => {\n onMouseDown?.(event);\n engine.keepFocus(event);\n }}\n >\n {children}\n </div>\n );\n};\nComboboxEmpty.displayName = 'ComboboxEmpty';\n\n/** An entry in `data` as an item: a string is its own label. */\nconst toItem = (entry: string | ComboboxItemData): ComboboxItemData =>\n typeof entry === 'string' ? { value: entry, label: entry } : entry;\n\nconst labelOf = (item: ComboboxItemData): string => item.label ?? item.value;\n\n/** One value or several, as a list: one value is a list of none or one. */\nconst asList = (value: string | string[] | null | undefined): string[] =>\n value == null ? [] : Array.isArray(value) ? value : [value];\n\n/**\n * The Combobox given `data`. It renders the parts itself, filters the items\n * by label as the user types, and keeps the value, so a pick goes through\n * the same parts, keys and ARIA as one built by hand.\n */\nconst ComboboxFromData = forwardRef<HTMLDivElement, ComboboxDataProps>(\n (props, ref) => {\n const {\n data,\n value,\n defaultValue,\n // Called below through `props`, which knows which value it takes.\n onChange: _onChange,\n multiple = false,\n placeholder,\n name,\n empty,\n itemTemplate,\n onSelect,\n onOpenChange,\n inline = false,\n disabled: disabledProp,\n required = false,\n form,\n id,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ariaCloseLabel,\n children,\n ...rest\n } = props;\n const disabled = useFieldsetDisabled(disabledProp);\n // A name given in place of a label is the field's and the list's, not\n // the wrapper's. Only the ones given are passed, since an\n // `aria-labelledby` that's there at all, even undefined, keeps the\n // label's name off the field.\n const named = {\n ...(ariaLabel !== undefined && { 'aria-label': ariaLabel }),\n ...(ariaLabelledBy !== undefined && {\n 'aria-labelledby': ariaLabelledBy,\n }),\n };\n if (flattenChildren(children).length > 0) {\n warnOnce(\n 'Combobox:data-children',\n '[bestax-bulma] <Combobox data> renders its own field, menu and ' +\n 'items, so its children are ignored. Give it data or build it ' +\n 'from parts, not both.'\n );\n }\n const items = data.map(toItem);\n const labelFor = (picked: string) => {\n const item = items.find(entry => entry.value === picked);\n return item ? labelOf(item) : picked;\n };\n\n const controlled = value !== undefined;\n const [ownValue, setOwnValue] = useState(() => asList(defaultValue));\n const matchText = useLocaleMatcher();\n const picked = controlled ? asList(value) : ownValue;\n const change = (next: string[]) => {\n if (!controlled) setOwnValue(next);\n if (props.multiple === true) props.onChange?.(next);\n else props.onChange?.(next[0] ?? null);\n };\n\n // What's typed, or `null` while the field shows the value instead. The\n // ref holds it as it is now, since a pick sets it and the list's closing\n // reads it in the same event, before a render.\n const [query, setQueryState] = useState<string | null>(null);\n const queryRef = useRef<string | null>(null);\n const setQuery = (next: string | null) => {\n queryRef.current = next;\n setQueryState(next);\n };\n // Once the list closes or the field is left, the field shows the value\n // again: typed text goes back to the pick, and with one value a field\n // left empty clears it.\n const settle = () => {\n if (!multiple && queryRef.current === '' && picked.length > 0) {\n change([]);\n }\n setQuery(null);\n };\n const typed = (query ?? '').trim();\n const term = typed.toLowerCase();\n const shown = items.filter(item =>\n matchText\n ? matchText(labelOf(item), typed)\n : labelOf(item).toLowerCase().includes(term)\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n const select = (pick: string) => {\n onSelect?.(pick);\n if (multiple) {\n change(\n picked.includes(pick)\n ? picked.filter(v => v !== pick)\n : [...picked, pick]\n );\n } else {\n if (picked[0] !== pick) change([pick]);\n setQuery(null);\n }\n };\n const remove = (pick: string) => {\n change(picked.filter(v => v !== pick));\n inputRef.current?.focus();\n };\n // The picks, for the field's description, since its text is the search.\n const tagsId = useId();\n const ids = tagIds(tagsId, picked);\n\n // Each group where `data` first names it, and the items with none\n // together where the first of them is.\n const sections = new Map<string, ComboboxItemData[]>();\n for (const item of shown) {\n const group = item.group ?? '';\n sections.set(group, [...(sections.get(group) ?? []), item]);\n }\n const renderItem = (item: ComboboxItemData) => (\n <ComboboxItem\n key={item.value}\n value={item.value}\n disabled={disabled || item.disabled}\n checked={picked.includes(item.value)}\n >\n {itemTemplate ? itemTemplate(item) : labelOf(item)}\n </ComboboxItem>\n );\n const list =\n shown.length > 0 ? (\n <ComboboxList {...named}>\n {Array.from(sections, ([group, members]) =>\n group ? (\n <ComboboxGroup key={group} label={group}>\n {members.map(renderItem)}\n </ComboboxGroup>\n ) : (\n members.map(renderItem)\n )\n )}\n </ComboboxList>\n ) : empty ? (\n <ComboboxEmpty>{empty}</ComboboxEmpty>\n ) : null;\n\n return (\n <ComboboxParts\n {...rest}\n ref={ref}\n multiple={multiple}\n inline={inline}\n onSelect={select}\n onSettle={settle}\n onOpenChange={next => {\n if (!next) settle();\n onOpenChange?.(next);\n }}\n below={\n multiple ? (\n <ValueTags\n values={picked}\n ids={ids}\n labelFor={labelFor}\n disabled={disabled}\n ariaCloseLabel={ariaCloseLabel}\n onRemove={remove}\n />\n ) : undefined\n }\n >\n <ComboboxInput\n {...named}\n ref={inputRef}\n id={id}\n disabled={disabled}\n // The browser's check reads the field's text, and only a pick\n // fills it for good, so it's required until there is one.\n required={required && picked.length === 0}\n aria-required={required || undefined}\n form={form}\n aria-describedby={\n multiple && picked.length > 0 ? ids.join(' ') : undefined\n }\n placeholder={placeholder}\n value={\n query ??\n (multiple || picked.length === 0 ? '' : labelFor(picked[0]))\n }\n onChange={event => setQuery(event.target.value)}\n onBlur={settle}\n />\n {inline ? list : <ComboboxMenu>{list}</ComboboxMenu>}\n <HiddenValues\n name={name}\n values={multiple ? picked : [picked[0] ?? '']}\n form={form}\n disabled={disabled}\n />\n </ComboboxParts>\n );\n }\n);\nComboboxFromData.displayName = 'ComboboxFromData';\n\n/**\n * The `Combobox` component is a text field with a list to pick from under it, for a searchable select, a multi-select with tags, grouped items or a server search: given `data` it does the rest, and built from parts it leaves the data to you.\n *\n * Given `data`, it's one element. It renders the field, the menu, the list,\n * the groups and the empty message, filters the items by label as the user\n * types, and keeps the value, which `onChange` reports. With `multiple`, the\n * picks show as tags under the field.\n *\n * Built from parts, the app owns the data: what's in the list, how it's\n * filtered, and the value. A pick calls `onSelect` with the item's `value`,\n * and the Combobox keeps no value and never changes the text in the field,\n * so the app sets both there. Nothing filters the items either, so a\n * server's answer shows as it came. For a free-text field with suggestions,\n * `Autocomplete` is the simpler choice.\n *\n * Either way, focus stays in the field, and the highlighted item is its\n * `aria-activedescendant`. With one value, the highlighted item is the\n * `aria-selected` one, as the ARIA Authoring Practices' combobox does it, and\n * a `checked` item shows a check mark and takes the highlight when the list\n * opens. With `multiple`, `checked` is each item's `aria-selected`. Tab and\n * focus leaving close the menu without picking.\n *\n * When typing leaves the empty message on screen, its text is announced\n * through a polite status region, once, after any loading ends. Result\n * counts aren't announced: a screen reader reads the list's size from the\n * markup, and a count on every keystroke talks over the typing. Show one in\n * a `role=\"status\"` line beside the field when it matters.\n *\n * @function\n * @param {ComboboxProps} props - Props for the Combobox component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the `div.combobox`.\n * @returns {JSX.Element} The field and its list, in a `Field` with the label unless one is around it.\n *\n * @example\n * <Combobox\n * label=\"Country\"\n * data={['Canada', 'France', 'Japan']}\n * placeholder=\"Pick a country\"\n * empty=\"No countries match\"\n * />\n *\n * @example\n * <Combobox label=\"Country\" onSelect={pick}>\n * <Combobox.Input value={query} onChange={e => setQuery(e.target.value)} />\n * <Combobox.Menu>\n * {matches.length > 0 ? (\n * <Combobox.List>\n * {matches.map(c => (\n * <Combobox.Item key={c} value={c} checked={c === value}>\n * {c}\n * </Combobox.Item>\n * ))}\n * </Combobox.List>\n * ) : (\n * <Combobox.Empty>No countries match</Combobox.Empty>\n * )}\n * </Combobox.Menu>\n * </Combobox>\n */\nconst ComboboxRoot = forwardRef<HTMLDivElement, ComboboxProps>((props, ref) =>\n props.data === undefined ? (\n <ComboboxParts {...props} ref={ref} />\n ) : (\n <ComboboxFromData {...props} ref={ref} />\n )\n);\n\n/** Combobox with Input, Menu, List, Item, Group and Empty sub-components. */\nexport const Combobox = withSubComponents(\n ComboboxRoot,\n {\n Input: ComboboxInput,\n Menu: ComboboxMenu,\n List: ComboboxList,\n Item: ComboboxItem,\n Group: ComboboxGroup,\n Empty: ComboboxEmpty,\n },\n 'Combobox'\n);\n\nexport default Combobox;\n"],"names":["noop","standalone","setRefs","_jsxs","_jsx","_Fragment","asList"],"mappings":"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"}
@@ -0,0 +1,20 @@
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
+
5
+ // INTERNAL: deliberately not exported from src/index.ts.
6
+ /**
7
+ * A check mark, 1em square and drawn in `currentColor`, so it takes the text
8
+ * color around it, the system's in forced colors included. Combobox draws it
9
+ * beside a chosen item, and CopyButton after a copy. It's decorative: put it
10
+ * inside something `aria-hidden`.
11
+ *
12
+ * @function CheckIcon
13
+ * @returns The check mark's `<svg>`.
14
+ */
15
+ function CheckIcon$1() {
16
+ return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", width: "1em", height: "1em", focusable: "false", children: jsx("polyline", { points: "3 8.5 6.5 12 13 4.5" }) }));
17
+ }
18
+
19
+ export { CheckIcon$1 as CheckIcon };
20
+ //# sourceMappingURL=checkIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkIcon.js","sources":["../../../src/helpers/checkIcon.tsx"],"sourcesContent":["// INTERNAL: deliberately not exported from src/index.ts.\n\n/**\n * A check mark, 1em square and drawn in `currentColor`, so it takes the text\n * color around it, the system's in forced colors included. Combobox draws it\n * beside a chosen item, and CopyButton after a copy. It's decorative: put it\n * inside something `aria-hidden`.\n *\n * @function CheckIcon\n * @returns The check mark's `<svg>`.\n */\nexport function CheckIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n width=\"1em\"\n height=\"1em\"\n focusable=\"false\"\n >\n <polyline points=\"3 8.5 6.5 12 13 4.5\" />\n </svg>\n );\n}\n"],"names":["CheckIcon","_jsx"],"mappings":";;;;AAAA;AAEA;;;;;;;;AAQG;SACaA,WAAS,GAAA;IACvB,QACEC,aACE,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,KAAK,EAAC,KAAK,EACX,MAAM,EAAC,KAAK,EACZ,SAAS,EAAC,OAAO,EAAA,QAAA,EAEjBA,GAAA,CAAA,UAAA,EAAA,EAAU,MAAM,EAAC,qBAAqB,EAAA,CAAG,EAAA,CACrC;AAEV;;"}
@@ -0,0 +1,13 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ /**
3
+ * INTERNAL, deliberately not exported from `src/index.ts`. Whether a prop
4
+ * was given something to render: `undefined`, `null`, a boolean and `''`
5
+ * weren't, and `0` was, since React renders it.
6
+ */
7
+ const isGiven = (node) => node !== undefined &&
8
+ node !== null &&
9
+ typeof node !== 'boolean' &&
10
+ node !== '';
11
+
12
+ export { isGiven };
13
+ //# sourceMappingURL=isGiven.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isGiven.js","sources":["../../../src/helpers/isGiven.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\n/**\n * INTERNAL, deliberately not exported from `src/index.ts`. Whether a prop\n * was given something to render: `undefined`, `null`, a boolean and `''`\n * weren't, and `0` was, since React renders it.\n */\nexport const isGiven = (node: ReactNode) =>\n node !== undefined &&\n node !== null &&\n typeof node !== 'boolean' &&\n node !== '';\n"],"names":[],"mappings":";AAEA;;;;AAIG;AACI,MAAM,OAAO,GAAG,CAAC,IAAe,KACrC,IAAI,KAAK,SAAS;AAClB,IAAA,IAAI,KAAK,IAAI;IACb,OAAO,IAAI,KAAK,SAAS;IACzB,IAAI,KAAK;;"}
@@ -17,11 +17,11 @@ const announceDelay = 100;
17
17
  * again.
18
18
  */
19
19
  const announcementLifetime = 1000;
20
- const noAnnouncements$1 = [];
20
+ const noAnnouncements$2 = [];
21
21
  const nothingWritten = [];
22
22
  const noAnnouncementsYet = {
23
23
  key: 0,
24
- waiting: noAnnouncements$1,
24
+ waiting: noAnnouncements$2,
25
25
  written: nothingWritten,
26
26
  };
27
27
  // Hides the region with inline styles rather than a class, so it needs no
@@ -123,7 +123,7 @@ function useAnnouncements(items, describe) {
123
123
  setAnnouncements(current => current.key === key
124
124
  ? {
125
125
  ...current,
126
- waiting: noAnnouncements$1,
126
+ waiting: noAnnouncements$2,
127
127
  written: [
128
128
  ...current.written,
129
129
  ...current.waiting
@@ -0,0 +1,176 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ 'use client';
3
+ import { useState, useRef, useEffect, useCallback } from 'react';
4
+ import { useLatestRef } from './useLatestRef.js';
5
+
6
+ /** How long `copied` lasts when `duration` doesn't say, in ms. */
7
+ const defaultDuration = 2000;
8
+ /**
9
+ * The longest delay `setTimeout` takes, in ms. A longer one, `Infinity`
10
+ * included, runs at once.
11
+ */
12
+ const longestDelay = 2 ** 31 - 1;
13
+ /**
14
+ * `duration` as a delay `setTimeout` keeps, or `null` for no timer: `null`
15
+ * for `0`, as on Toast, the default when it's missing or `NaN` (or a
16
+ * JavaScript caller's `null`), `0` for a negative one, which ends `copied` at
17
+ * once, and the longest delay for `Infinity` or anything longer.
18
+ */
19
+ const delayOf = (duration) => {
20
+ if (duration === 0)
21
+ return null;
22
+ return duration == null || Number.isNaN(duration)
23
+ ? defaultDuration
24
+ : Math.min(Math.max(duration, 0), longestDelay);
25
+ };
26
+ /** The error a copy reports when nothing could write and nothing said why. */
27
+ const cannotCopy = 'The Clipboard API is missing or refused, and the copy command copied nothing.';
28
+ /**
29
+ * Copies `text` the way browsers did before the Clipboard API: it runs the
30
+ * `copy` command and puts the text on the `copy` event that command fires.
31
+ * Success is the event having fired, not the command's return value, which
32
+ * WebKit reports as `false` for a copy that happened.
33
+ *
34
+ * This is the library's only call to the deprecated `document.execCommand`,
35
+ * so it can go when browsers drop it. Until then it's what writes on a page
36
+ * without the Clipboard API, such as one served over plain `http://`.
37
+ *
38
+ * @param text - The text to copy.
39
+ * @returns Whether the `copy` event fired and took the text.
40
+ */
41
+ function copyWithCommand(text) {
42
+ let written = false;
43
+ // WebKit enables the copy command only when something is selected or a
44
+ // `beforecopy` listener cancels that event, and nothing is selected here.
45
+ const enable = (event) => event.preventDefault();
46
+ // On `window` while capturing, so it runs before the page's listeners on
47
+ // the document and its elements. The copy is this hook's own, so it's
48
+ // stopped there: a page's own copy handler, such as one that adds a
49
+ // credit line to whatever is copied, never sees it to rewrite it.
50
+ const onCopy = (event) => {
51
+ if (!event.clipboardData)
52
+ return;
53
+ event.clipboardData.setData('text/plain', text);
54
+ event.preventDefault();
55
+ event.stopImmediatePropagation();
56
+ written = true;
57
+ };
58
+ window.addEventListener('beforecopy', enable, true);
59
+ window.addEventListener('copy', onCopy, true);
60
+ try {
61
+ document.execCommand('copy');
62
+ }
63
+ catch {
64
+ // An engine that refuses, or no longer has the command, can throw, and
65
+ // the event not firing already says so.
66
+ }
67
+ finally {
68
+ window.removeEventListener('beforecopy', enable, true);
69
+ window.removeEventListener('copy', onCopy, true);
70
+ }
71
+ return written;
72
+ }
73
+ /**
74
+ * Writes `text` through the Clipboard API, and through the copy command when
75
+ * that's missing or refuses. Where it's missing, the copy command runs before
76
+ * the first `await`, so it's still inside the click that called it. After a
77
+ * refusal it runs once the refusal arrives, which writes only where the
78
+ * browser still counts the click by then, and only if no later copy has
79
+ * started in the meantime, which it would otherwise write over.
80
+ *
81
+ * @param text - The text to write.
82
+ * @param isLatest - Whether this is still the latest copy.
83
+ * @returns `null` once it's written, or why it couldn't be.
84
+ */
85
+ async function writeToClipboard(text, isLatest) {
86
+ let refusal = null;
87
+ // Read at the click, never while rendering, so there's always a navigator.
88
+ const { clipboard } = navigator;
89
+ if (clipboard?.writeText) {
90
+ try {
91
+ await clipboard.writeText(text);
92
+ return null;
93
+ }
94
+ catch (reason) {
95
+ refusal = reason;
96
+ }
97
+ }
98
+ if (isLatest() && copyWithCommand(text))
99
+ return null;
100
+ return refusal instanceof Error ? refusal : new Error(cannotCopy);
101
+ }
102
+ /**
103
+ * Copies text to the clipboard through the Clipboard API, falling back to the copy command where that's missing or refused, and keeps a `copied` flag for `duration` after a copy.
104
+ *
105
+ * It announces nothing. A trigger of your own says "Copied" in a
106
+ * `role="status"` region that's in the page before the click; `CopyButton`
107
+ * is this hook with the button, the label and the announcement built in.
108
+ *
109
+ * A failed copy sets `error`, calls `onCopyError`, and ends `copied` if a
110
+ * copy before it had set it. When copies overlap, only the latest one's
111
+ * outcome sets the state and fires the callbacks, whichever finishes first.
112
+ * Nothing changes and no callback fires once the component using it has
113
+ * unmounted, though a write already under way still finishes.
114
+ *
115
+ * @function useClipboard
116
+ * @param options - How long `copied` lasts, and the callbacks.
117
+ * @returns `copy`, which writes, and the `copied` and `error` state.
118
+ *
119
+ * @example
120
+ * const { copy, copied } = useClipboard();
121
+ * <Button onClick={() => copy(url)}>{copied ? 'Copied' : 'Copy link'}</Button>
122
+ */
123
+ function useClipboard(options = {}) {
124
+ const [copied, setCopied] = useState(false);
125
+ const [error, setError] = useState(null);
126
+ const optionsRef = useLatestRef(options);
127
+ const copiedRef = useRef(false);
128
+ const timerRef = useRef(undefined);
129
+ const mountedRef = useRef(false);
130
+ // Counts the calls to `copy`, so only the latest one's outcome is kept.
131
+ const latestCallRef = useRef(0);
132
+ useEffect(() => {
133
+ mountedRef.current = true;
134
+ return () => {
135
+ mountedRef.current = false;
136
+ clearTimeout(timerRef.current);
137
+ };
138
+ }, []);
139
+ const copy = useCallback(async (text) => {
140
+ latestCallRef.current += 1;
141
+ const call = latestCallRef.current;
142
+ const isLatest = () => call === latestCallRef.current;
143
+ const failure = await writeToClipboard(text, isLatest);
144
+ // A write overtaken by a later copy, which may finish first, reports
145
+ // through its promise only.
146
+ if (!mountedRef.current || !isLatest()) {
147
+ return failure === null;
148
+ }
149
+ clearTimeout(timerRef.current);
150
+ const { duration, onCopiedChange, onCopyError } = optionsRef.current;
151
+ const wasCopied = copiedRef.current;
152
+ copiedRef.current = failure === null;
153
+ setCopied(failure === null);
154
+ setError(failure);
155
+ if (failure) {
156
+ if (wasCopied)
157
+ onCopiedChange?.(false);
158
+ onCopyError?.(failure);
159
+ return false;
160
+ }
161
+ onCopiedChange?.(true);
162
+ const delay = delayOf(duration);
163
+ if (delay !== null) {
164
+ timerRef.current = setTimeout(() => {
165
+ copiedRef.current = false;
166
+ setCopied(false);
167
+ optionsRef.current.onCopiedChange?.(false);
168
+ }, delay);
169
+ }
170
+ return true;
171
+ }, [optionsRef]);
172
+ return { copy, copied, error };
173
+ }
174
+
175
+ export { useClipboard };
176
+ //# sourceMappingURL=useClipboard.js.map