@allxsmith/bestax-bulma 5.45.1 → 5.47.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 (42) hide show
  1. package/dist/esm/components/TreeView.js +5 -2
  2. package/dist/esm/components/TreeView.js.map +1 -1
  3. package/dist/esm/form/Checkbox.js.map +1 -1
  4. package/dist/esm/form/File.js.map +1 -1
  5. package/dist/esm/form/Numberinput.js.map +1 -1
  6. package/dist/esm/form/PinInput.js.map +1 -1
  7. package/dist/esm/form/Radio.js.map +1 -1
  8. package/dist/esm/form/SelectBase.js.map +1 -1
  9. package/dist/esm/form/Slider.js.map +1 -1
  10. package/dist/esm/form/Switch.js.map +1 -1
  11. package/dist/esm/helpers/Theme.js +191 -49
  12. package/dist/esm/helpers/Theme.js.map +1 -1
  13. package/dist/esm/helpers/useTreeView.js +64 -9
  14. package/dist/esm/helpers/useTreeView.js.map +1 -1
  15. package/dist/esm/helpers/useVisibilityClasses.js.map +1 -1
  16. package/dist/index.cjs +258 -59
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/types/components/TreeView.d.ts +2 -0
  19. package/dist/types/form/Checkbox.d.ts +3 -0
  20. package/dist/types/form/File.d.ts +3 -0
  21. package/dist/types/form/Numberinput.d.ts +2 -0
  22. package/dist/types/form/PinInput.d.ts +3 -0
  23. package/dist/types/form/Radio.d.ts +3 -0
  24. package/dist/types/form/SelectBase.d.ts +3 -0
  25. package/dist/types/form/Slider.d.ts +3 -0
  26. package/dist/types/form/Switch.d.ts +2 -0
  27. package/dist/types/helpers/Theme.d.ts +37 -10
  28. package/dist/types/helpers/useTreeView.d.ts +19 -3
  29. package/dist/types/helpers/useVisibilityClasses.d.ts +5 -1
  30. package/dist/types-cjs/components/TreeView.d.ts +2 -0
  31. package/dist/types-cjs/form/Checkbox.d.ts +3 -0
  32. package/dist/types-cjs/form/File.d.ts +3 -0
  33. package/dist/types-cjs/form/Numberinput.d.ts +2 -0
  34. package/dist/types-cjs/form/PinInput.d.ts +3 -0
  35. package/dist/types-cjs/form/Radio.d.ts +3 -0
  36. package/dist/types-cjs/form/SelectBase.d.ts +3 -0
  37. package/dist/types-cjs/form/Slider.d.ts +3 -0
  38. package/dist/types-cjs/form/Switch.d.ts +2 -0
  39. package/dist/types-cjs/helpers/Theme.d.ts +37 -10
  40. package/dist/types-cjs/helpers/useTreeView.d.ts +19 -3
  41. package/dist/types-cjs/helpers/useVisibilityClasses.d.ts +5 -1
  42. package/package.json +2 -1
@@ -213,7 +213,9 @@ const TreeViewItem = forwardRef(function TreeViewItem({ value, label, icon, chil
213
213
  if (branch.hidden)
214
214
  return jsx(Fragment, { children: items });
215
215
  const info = { value, parent, disabled, isParent, open };
216
- return (jsxs("li", { ...props, ref: setRefs, className: classNames(itemClass, className), role: "treeitem", "aria-labelledby": labelId, "aria-level": branch.path.length + 1, "aria-expanded": isParent ? open : undefined, "aria-disabled": disabled || undefined, "aria-selected": selected, "aria-checked": checked, tabIndex: tree.tabStop === value ? 0 : -1, onKeyDown: event => {
216
+ // A position the caller gives wins, for a set the page holds only part of.
217
+ const position = tree.positionOf(value);
218
+ return (jsxs("li", { ...props, ref: setRefs, className: classNames(itemClass, className), role: "treeitem", "aria-labelledby": labelId, "aria-level": branch.path.length + 1, "aria-posinset": props['aria-posinset'] ?? position?.posinset, "aria-setsize": props['aria-setsize'] ?? position?.setsize, "aria-expanded": isParent ? open : undefined, "aria-disabled": disabled || undefined, "aria-selected": selected, "aria-checked": checked, tabIndex: tree.tabStop === value ? 0 : -1, onKeyDown: event => {
217
219
  onKeyDown?.(event);
218
220
  tree.onKeyDown(event, info);
219
221
  }, onFocus: event => {
@@ -283,7 +285,8 @@ function StatusRow({ kind, parent, level, message, onRetry, labelRef, }) {
283
285
  open: false,
284
286
  retry,
285
287
  };
286
- return (jsx("li", { ref: setRef, className: itemClass, role: "treeitem", "aria-labelledby": retry ? `${labelId} ${retryId}` : labelId, "aria-level": level, "aria-disabled": !retry || undefined, tabIndex: tree.tabStop === labelId ? 0 : -1, onKeyDown: event => tree.onKeyDown(event, info), onFocus: event => {
288
+ const position = tree.positionOf(labelId);
289
+ return (jsx("li", { ref: setRef, className: itemClass, role: "treeitem", "aria-labelledby": retry ? `${labelId} ${retryId}` : labelId, "aria-level": level, "aria-posinset": position?.posinset, "aria-setsize": position?.setsize, "aria-disabled": !retry || undefined, tabIndex: tree.tabStop === labelId ? 0 : -1, onKeyDown: event => tree.onKeyDown(event, info), onFocus: event => {
287
290
  // Focus in something the message holds isn't the row's.
288
291
  if (event.target === event.currentTarget) {
289
292
  tree.onFocus(labelId, event.currentTarget);
@@ -1 +1 @@
1
- {"version":3,"file":"TreeView.js","sources":["../../../src/components/TreeView.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\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 { warnOnce } from '../helpers/devWarnings';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useTreeView, type TreeViewEngine } from '../helpers/useTreeView';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport { Checkbox } from '../form/Checkbox';\nimport { Icon } from '../elements/Icon';\n\n/**\n * How items are picked: `none`, nothing is; `single`, one item at a time;\n * `checkbox`, any number, with a box on every item and mixed parents.\n */\nexport type TreeViewSelectionMode = 'none' | 'single' | 'checkbox';\n\nconst validTreeViewSizes = ['small', 'medium', 'large'] as const;\n\n/** What an open item's load says in the tree's live region. */\ninterface LoadAnnouncement {\n /** The item's key, so what it says next replaces this. */\n key: string;\n /** The key and the kind: the region says it once each time it appears. */\n id: string;\n kind: 'loading' | 'loaded' | 'error';\n /** The item's name, read off its label. */\n name: string;\n /** A failed load's message, read off its row. */\n message: string;\n}\n\n/** What the root hands its items: the engine, the live region, and the rows' words. */\ninterface TreeContextValue extends TreeViewEngine {\n /** Puts what an item's load says in the live region, or takes it out with `null`. */\n announce: (key: string, announcement: LoadAnnouncement | null) => void;\n loadingLabel: string;\n retryLabel: string;\n}\n\n// Not exported, so they stay out of the public API that `index.ts` re-exports.\nconst TreeViewContext = createContext<TreeContextValue | null>(null);\n\nconst sayLoading = (name: string) => `Loading ${name}`;\nconst sayLoaded = (name: string) => `${name} loaded`;\n\n/** Where an item sits: the values of the items above it, and whether one of them is closed. */\ninterface Branch {\n path: string[];\n hidden: boolean;\n}\n\nconst TOP: Branch = { path: [], hidden: false };\nconst BranchContext = createContext<Branch>(TOP);\n\n/** The box's input lets the row's click toggle it, so a change on its own does nothing. */\nconst ignoreChange = () => {};\n\n/** Whether an `icon` was given something to render. */\nconst isGiven = (node: React.ReactNode) =>\n node !== undefined &&\n node !== null &&\n typeof node !== 'boolean' &&\n node !== '';\n\n/**\n * Props for the TreeView component. The helper props, the other attributes\n * and the `ref` land on the `<ul role=\"tree\">`.\n *\n * @extraProp {string} [aria-label] - Names the tree, such as \"Files\". A tree needs a name, so pass this or `aria-labelledby`, and a development build warns when it has neither.\n * @extraProp {string} [aria-labelledby] - The id of a visible heading or label that names the tree, in place of `aria-label`.\n * @extraProp {React.Ref<HTMLUListElement>} [ref] - Ref forwarded to the `<ul>`.\n */\nexport interface TreeViewProps\n extends\n Omit<\n React.HTMLAttributes<HTMLUListElement>,\n | keyof BulmaClassesProps\n | 'role'\n | 'onSelect'\n | 'defaultValue'\n | 'defaultChecked'\n >,\n BulmaClassesProps {\n /**\n * `TreeView.Item`s, nested inside each other for their children. Render\n * an item's children whenever you have them, open or not: the tree hides\n * them while it's closed.\n */\n children?: React.ReactNode;\n /**\n * `none`: nothing is picked, and Enter and Space open and close a parent.\n * `single`: one item, picked with Enter, Space or a click.\n * `checkbox`: any number, checked with Space or a click. A check reaches\n * every enabled item under it, and a parent with some of them checked is mixed.\n */\n selectionMode?: TreeViewSelectionMode;\n /**\n * The selected item's value when you hold the state, or `null` for none.\n * Read with `single` only. Picking an item then only calls\n * `onSelectedChange`, and nothing changes until you pass the new value.\n */\n selected?: string | null;\n /** The item selected to begin with, when the tree holds its own state. Read with `single` only. */\n defaultSelected?: string | null;\n /**\n * Called with the value of the item picked. Not called for the one\n * already selected, and moving focus never calls it.\n */\n onSelectedChange?: (value: string) => void;\n /**\n * The checked items' values when you hold the state. Read with `checkbox`\n * only. A value checks its item, and an enabled item also counts as checked\n * when any item above it is in the list, so a parent's value stands for its\n * whole branch, loaded or not. A disabled item is checked only by its own value.\n */\n checked?: string[];\n /** The values checked to begin with, when the tree holds its own state. Read with `checkbox` only. */\n defaultChecked?: string[];\n /**\n * Called after a check or an uncheck with every item that now shows\n * checked, parents included, plus any earlier value that matches no item\n * the tree knows, left as it was. The order means nothing. Passed back as\n * `checked`, the list shows the same boxes.\n */\n onCheckedChange?: (checked: string[]) => void;\n /**\n * The open items' values when you hold the state. A value stays in the\n * list while its item's parent is closed, so the item reopens as it was.\n */\n expanded?: string[];\n /** The items open to begin with, when the tree holds its own state. */\n defaultExpanded?: string[];\n /** Called with the new list whenever an item opens or closes, `*` included. */\n onExpandedChange?: (expanded: string[]) => void;\n /** The text size, as Bulma's menu sizes it. The rows, the indent and the chevron scale with it. */\n size?: 'small' | 'medium' | 'large';\n /** What the row in a loading item's group says. In your app's language. */\n loadingLabel?: string;\n /** The Retry button's text on a failed load's row. In your app's language. */\n retryLabel?: string;\n /**\n * What the live region says when an open item starts loading, built from\n * the item's name. In your app's language. Default: `` `Loading ${name}` ``.\n */\n loadingAnnouncement?: (name: string) => string;\n /**\n * What the live region says when that load finishes. In your app's\n * language. Default: `` `${name} loaded` ``.\n */\n loadedAnnouncement?: (name: string) => string;\n}\n\n/**\n * Props for TreeView.Item, one row and, nested in it, its children. The other\n * attributes and the `ref` land on its `<li role=\"treeitem\">`.\n *\n * @extraProp {React.Ref<HTMLLIElement>} [ref] - Ref forwarded to the `<li>`.\n */\nexport interface TreeViewItemProps extends Omit<\n React.LiHTMLAttributes<HTMLLIElement>,\n 'role' | 'value' | 'onSelect' | 'children'\n> {\n /** **Required.** Identifies the item in `selected`, `checked` and `expanded`. Unique in the tree. */\n value: string;\n /**\n * **Required.** What the row shows, and the item's name for assistive\n * tech. Nothing in it should be a link or a button: a tree item does one\n * thing, and nothing else in its row takes focus.\n */\n label: React.ReactNode;\n /** A picture before the label: an `Icon` name, or a node. Hidden from assistive tech. */\n icon?: React.ReactNode;\n /**\n * `TreeView.Item`s under this one. Render them whenever you have them,\n * open or not: the tree hides them while it's closed, and a checkbox tree\n * needs them to know what a check reaches.\n */\n children?: React.ReactNode;\n /** Shows the item as a parent before its children are known, such as a folder that loads when it opens. */\n hasChildren?: boolean;\n /**\n * Its children are on their way. While it's open, its group ends in a row\n * that says so, and the tree's live region says it's loading, then that\n * it's loaded once this goes back to `false`. A parent only: pair it with\n * `hasChildren`, or with the children it already has.\n */\n isLoading?: boolean;\n /**\n * Its children didn't load. While it's open, its group ends in a row with\n * this message, and a Retry button when there's an `onRetry`, and the live\n * region reads the message out, so name the item in it (\"Couldn't load\n * src\"), then says it's loaded once this goes with the item still open. A\n * parent only, like `isLoading`. Nothing in it should be a link or a\n * button: the row is what's pressed. `isLoading` wins while both are given.\n */\n loadError?: React.ReactNode;\n /**\n * Called by the Retry button on a failed load's row, and by Enter or Space\n * there. Set `isLoading` while the retry runs, so the live region says it's\n * loading, and reads the message out again if it fails again. The same\n * message passed a second time with no loading between is no change the\n * tree can see.\n */\n onRetry?: () => void;\n /**\n * Reachable with the arrow keys, Home, End and type-ahead, so a screen\n * reader finds it, but never selected, checked, opened or closed. One\n * that's already open stays open.\n */\n disabled?: boolean;\n}\n\n/**\n * The `TreeView` component renders a tree of items you browse and pick from, the way a file explorer works: one tab stop, the arrow keys to move, and Right and Left to open and close.\n *\n * It's the APG Tree View pattern, drawn to look like Bulma's menu. It isn't\n * for site navigation: items aren't links, and a sidebar whose sections open\n * and close is `Menu`'s job. The root owns which items are open, through\n * `expanded`, `defaultExpanded` and `onExpandedChange`.\n *\n * `selectionMode` picks one of three trees. With `none`, nothing is picked.\n * With `single`, one item is, and `selected` says which. With `checkbox`,\n * each item has a box, a check reaches every enabled item under it, closed\n * branches included, and a parent with some of its items checked is mixed.\n * `selected` is read in a `single` tree only, and `checked` in a `checkbox`\n * tree only. Selection never follows focus.\n *\n * Disabled items stay reachable from the keys, so a screen reader finds\n * them. The tree needs a name, from `aria-label` or `aria-labelledby`, and a\n * development build warns when it has neither.\n *\n * @function\n * @param {TreeViewProps} props - Props for the TreeView component.\n * @param {React.Ref<HTMLUListElement>} ref - Forwarded ref to the `<ul>`.\n * @returns {JSX.Element} The rendered tree.\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ | APG Tree View Pattern}\n *\n * @example\n * <TreeView aria-label=\"Files\" selectionMode=\"single\" defaultExpanded={['src']}>\n * <TreeView.Item value=\"src\" label=\"src\" icon=\"folder\">\n * <TreeView.Item value=\"src/index.ts\" label=\"index.ts\" icon=\"file\" />\n * </TreeView.Item>\n * <TreeView.Item value=\"package.json\" label=\"package.json\" icon=\"file\" />\n * </TreeView>\n */\nconst TreeViewRoot = forwardRef<HTMLUListElement, TreeViewProps>(\n function TreeView(\n {\n children,\n selectionMode = 'none',\n selected,\n defaultSelected = null,\n onSelectedChange,\n checked,\n defaultChecked = [],\n onCheckedChange,\n expanded,\n defaultExpanded = [],\n onExpandedChange,\n size,\n loadingLabel = 'Loading…',\n retryLabel = 'Retry',\n loadingAnnouncement,\n loadedAnnouncement,\n className,\n ...props\n },\n ref\n ) {\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n const engine = useTreeView({\n mode: selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n checked,\n defaultChecked,\n onCheckedChange,\n expanded,\n defaultExpanded,\n onExpandedChange,\n });\n\n const { treeRef } = engine;\n const setRefs = useCallback(\n (node: HTMLUListElement | null) => {\n treeRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref, treeRef]\n );\n\n const named = Boolean(rest['aria-label'] || rest['aria-labelledby']);\n useEffect(() => {\n if (!named) {\n warnOnce(\n 'TreeView:unnamed',\n '[bestax-bulma] <TreeView> has no accessible name. Pass ' +\n 'aria-label or aria-labelledby, so a screen reader can say what ' +\n 'the tree holds.'\n );\n }\n }, [named]);\n\n const rootClass = usePrefixedClassNames('tree-view', {\n [`is-${size}`]:\n !!size && (validTreeViewSizes as readonly string[]).includes(size),\n });\n\n // What each open item's load says, in the order they started saying it.\n const [announcements, setAnnouncements] = useState<LoadAnnouncement[]>([]);\n const announce = useCallback(\n (key: string, announcement: LoadAnnouncement | null) => {\n setAnnouncements(current => {\n const others = current.filter(said => said.key !== key);\n return announcement ? [...others, announcement] : others;\n });\n },\n []\n );\n const describe = useCallback(\n ({ kind, name, message }: LoadAnnouncement) => {\n if (kind === 'error') return message;\n const say =\n kind === 'loading'\n ? (loadingAnnouncement ?? sayLoading)\n : (loadedAnnouncement ?? sayLoaded);\n return say(name);\n },\n [loadingAnnouncement, loadedAnnouncement]\n );\n\n // The props are spread first, so the role and the attributes the tree\n // owns win over anything a caller passes along. The live region sits\n // beside the tree, since a tree holds items and groups only, and it's\n // there from the start, so a screen reader is listening to it before\n // anything is written into it.\n return (\n <TreeViewContext.Provider\n value={{ ...engine, announce, loadingLabel, retryLabel }}\n >\n <BranchContext.Provider value={TOP}>\n <ul\n {...rest}\n ref={setRefs}\n className={classNames(rootClass, bulmaHelperClasses, className)}\n role=\"tree\"\n aria-multiselectable={engine.rendersClosed || undefined}\n >\n {children}\n </ul>\n </BranchContext.Provider>\n <StatusRegion items={announcements} describe={describe} />\n </TreeViewContext.Provider>\n );\n }\n);\n\n/**\n * One item in the tree: a row with its chevron, its box, its icon and its label, and, while it's open, a group of the items under it.\n *\n * @function\n * @param {TreeViewItemProps} props - Props for TreeView.Item.\n * @param {React.Ref<HTMLLIElement>} ref - Forwarded ref to the `<li>`.\n * @returns {JSX.Element | null} The rendered item, or nothing under a closed one.\n */\nexport const TreeViewItem = forwardRef<HTMLLIElement, TreeViewItemProps>(\n function TreeViewItem(\n {\n value,\n label,\n icon,\n children,\n hasChildren = false,\n isLoading = false,\n loadError,\n onRetry,\n disabled = false,\n className,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ...props\n },\n ref\n ) {\n const tree = useContext(TreeViewContext);\n const branch = useContext(BranchContext);\n // Also the item's key in the live region.\n const labelId = useId();\n const hasItems = React.Children.toArray(children).length > 0;\n const isParent = hasItems || hasChildren;\n const open = isParent && !!tree?.isOpen(value);\n const parent = branch.path[branch.path.length - 1] ?? null;\n\n // The row at the end of its group, while it's open and on the page.\n const shown = open && !branch.hidden;\n const status = !shown\n ? null\n : isLoading\n ? 'loading'\n : isGiven(loadError)\n ? 'error'\n : null;\n const labelRef = useRef<HTMLSpanElement | null>(null);\n const statusLabelRef = useRef<HTMLSpanElement | null>(null);\n\n // What the live region says follows the row: it's loading, or it failed,\n // while the row says so, and it's loaded once the row goes with the item\n // still open, whichever row it was, until the item closes or loads again.\n // A closed item says nothing, loading or not.\n const phase = shown ? (status ?? 'open') : 'closed';\n const lastPhaseRef = useRef(phase);\n const announce = tree?.announce;\n useEffect(() => {\n const was = lastPhaseRef.current;\n lastPhaseRef.current = phase;\n const kind =\n phase === 'loading' || phase === 'error'\n ? phase\n : phase === 'open' && (was === 'loading' || was === 'error')\n ? 'loaded'\n : null;\n if (!kind) return undefined;\n // Only an item inside a tree can be open.\n announce!(labelId, {\n key: labelId,\n id: `${labelId}:${kind}`,\n kind,\n name: spokenText(labelRef.current!),\n message: kind === 'error' ? spokenText(statusLabelRef.current!) : '',\n });\n return () => announce!(labelId, null);\n }, [phase, announce, labelId]);\n\n const itemClass = usePrefixedClassNames('tree-view-item');\n const groupClass = usePrefixedClassNames('tree-view-group');\n const toggleClass = usePrefixedClassNames('tree-view-toggle');\n const checkClass = usePrefixedClassNames('tree-view-check');\n const iconClass = usePrefixedClassNames('tree-view-icon');\n const labelClass = usePrefixedClassNames('tree-view-label');\n\n const register = tree?.register;\n useClientLayoutEffect(() => {\n if (!register) {\n warnOnce(\n 'TreeView.Item:outside',\n '[bestax-bulma] <TreeView.Item> is outside a <TreeView>, so it ' +\n 'renders nothing. Put it inside one.'\n );\n return undefined;\n }\n return register(value, { parent, disabled, isParent });\n }, [register, value, parent, disabled, isParent]);\n\n const setElement = tree?.setElement;\n const setRefs = useCallback(\n (node: HTMLLIElement | null) => {\n // Only an item inside a tree renders an element to hand over.\n setElement!(value, node);\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [setElement, value, ref]\n );\n const rowRef = useRef<HTMLDivElement | null>(null);\n const toggleRef = useRef<HTMLSpanElement | null>(null);\n\n const childBranch = useMemo(\n () => ({\n path: [...branch.path, value],\n hidden: branch.hidden || !open,\n }),\n [branch, value, open]\n );\n\n const { selected, checked } =\n tree?.stateOf(value, branch.path, disabled) ?? {};\n const rowClass = usePrefixedClassNames('tree-view-row', {\n 'is-selected': selected,\n 'is-disabled': disabled,\n });\n\n if (!tree) return null;\n\n // While it's open the children render in its group. In a checkbox tree\n // they render while it's closed too, drawing nothing, so a check knows\n // what's under it.\n const items = (open || tree.rendersClosed) && (\n <BranchContext.Provider value={childBranch}>\n {children}\n </BranchContext.Provider>\n );\n if (branch.hidden) return <>{items}</>;\n\n const info = { value, parent, disabled, isParent, open };\n\n return (\n <li\n {...props}\n ref={setRefs}\n className={classNames(itemClass, className)}\n role=\"treeitem\"\n aria-labelledby={labelId}\n aria-level={branch.path.length + 1}\n aria-expanded={isParent ? open : undefined}\n aria-disabled={disabled || undefined}\n aria-selected={selected}\n aria-checked={checked}\n tabIndex={tree.tabStop === value ? 0 : -1}\n onKeyDown={event => {\n onKeyDown?.(event);\n tree.onKeyDown(event, info);\n }}\n onFocus={event => {\n onFocus?.(event);\n if (event.target === event.currentTarget) {\n tree.onFocus(value, event.currentTarget);\n }\n }}\n onBlur={event => {\n onBlur?.(event);\n if (event.target === event.currentTarget) tree.onBlur();\n }}\n onClick={event => {\n onClick?.(event);\n // A click in its row is its own, and so is one on the item itself,\n // as a test's click on the treeitem is. One in its group belongs\n // to the item inside it, or to nothing. The chevron's box is on\n // every row, but it's a chevron only on a parent: on a leaf it's\n // more of the row.\n const target = event.target as Node;\n if (\n target === event.currentTarget ||\n rowRef.current!.contains(target)\n ) {\n tree.onClick(\n event.currentTarget,\n info,\n isParent && toggleRef.current!.contains(target)\n );\n }\n }}\n >\n <div className={rowClass} ref={rowRef}>\n <span className={toggleClass} aria-hidden=\"true\" ref={toggleRef} />\n {checked !== undefined && (\n <span\n className={checkClass}\n aria-hidden=\"true\"\n onClick={event => {\n // A click on the box's label is followed by one on its\n // input, and both reach the item. The label's is cancelled,\n // so the item toggles once.\n if (!(event.target instanceof HTMLInputElement)) {\n event.preventDefault();\n }\n }}\n >\n <Checkbox\n tabIndex={-1}\n checked={checked === true}\n indeterminate={checked === 'mixed'}\n disabled={disabled}\n onChange={ignoreChange}\n />\n </span>\n )}\n {isGiven(icon) && (\n <span className={iconClass} aria-hidden=\"true\">\n {typeof icon === 'string' ? <Icon name={icon} /> : icon}\n </span>\n )}\n <span className={labelClass} id={labelId} ref={labelRef}>\n {label}\n </span>\n </div>\n {open && (hasItems || status) ? (\n <ul className={groupClass} role=\"group\">\n {items}\n {status && (\n <StatusRow\n kind={status}\n parent={value}\n level={branch.path.length + 2}\n message={loadError}\n onRetry={onRetry}\n labelRef={statusLabelRef}\n />\n )}\n </ul>\n ) : (\n items\n )}\n </li>\n );\n }\n);\n\nTreeViewItem.displayName = 'TreeView.Item';\n\n/** Props for the row at the end of a loading item's group, or a failed load's. */\ninterface StatusRowProps {\n /** `loading`, or `error` for a load that failed. */\n kind: 'loading' | 'error';\n /** The value of the item it's in. */\n parent: string;\n /** Its `aria-level`, one under the item it's in. */\n level: number;\n /** A failed load's message. */\n message: React.ReactNode;\n /** Retries a failed load. */\n onRetry?: () => void;\n /** For its label, which the item reads a failed load's message off. */\n labelRef: React.Ref<HTMLSpanElement>;\n}\n\n/**\n * The row at the end of a loading item's group, or of one whose load failed.\n * It's a `treeitem` the keys reach, the way they reach a disabled item, so a\n * screen reader finds it. It has no value and no record, so it's never\n * selected or checked, and a check never counts it. A failed load's row with\n * `onRetry` retries with Enter, Space or a click, and any other is disabled.\n * The Retry button is drawn, hidden from assistive tech and out of the tab\n * order, the way an item's box is: the row is what's pressed, and its name\n * says so. Rendered in one place, a failed load's row that starts loading\n * again is the same element, so focus stays on it.\n */\nfunction StatusRow({\n kind,\n parent,\n level,\n message,\n onRetry,\n labelRef,\n}: StatusRowProps) {\n // Only an item inside a tree renders a group.\n const tree = useContext(TreeViewContext)!;\n // Also its key in the registry and for the tab stop, where an item has its value.\n const labelId = useId();\n const retryId = useId();\n const retry = kind === 'error' ? onRetry : undefined;\n\n const itemClass = usePrefixedClassNames('tree-view-item');\n const rowClass = usePrefixedClassNames('tree-view-row', {\n 'is-disabled': !retry,\n });\n const toggleClass = usePrefixedClassNames('tree-view-toggle');\n const labelClass = usePrefixedClassNames('tree-view-label');\n const loaderClass = usePrefixedClassNames('loader');\n const retryClass = usePrefixedClassNames('button', { 'is-small': true });\n\n const { setElement } = tree;\n const setRef = useCallback(\n (node: HTMLLIElement | null) => setElement(labelId, node),\n [setElement, labelId]\n );\n const info = {\n value: labelId,\n parent,\n disabled: !retry,\n isParent: false,\n open: false,\n retry,\n };\n\n return (\n <li\n ref={setRef}\n className={itemClass}\n role=\"treeitem\"\n aria-labelledby={retry ? `${labelId} ${retryId}` : labelId}\n aria-level={level}\n aria-disabled={!retry || undefined}\n tabIndex={tree.tabStop === labelId ? 0 : -1}\n onKeyDown={event => tree.onKeyDown(event, info)}\n onFocus={event => {\n // Focus in something the message holds isn't the row's.\n if (event.target === event.currentTarget) {\n tree.onFocus(labelId, event.currentTarget);\n }\n }}\n onBlur={event => {\n if (event.target === event.currentTarget) tree.onBlur();\n }}\n onClick={event => tree.onClick(event.currentTarget, info, false)}\n >\n <div className={rowClass}>\n <span className={toggleClass} aria-hidden=\"true\">\n {kind === 'loading' && <span className={loaderClass} />}\n </span>\n <span className={labelClass} id={labelId} ref={labelRef}>\n {kind === 'loading' ? tree.loadingLabel : message}\n </span>\n {retry && (\n <span className={retryClass} id={retryId} aria-hidden=\"true\">\n {tree.retryLabel}\n </span>\n )}\n </div>\n </li>\n );\n}\n\nexport const TreeView = withSubComponents(\n TreeViewRoot,\n { Item: TreeViewItem },\n 'TreeView'\n);\n\nexport default TreeView;\n"],"names":["_jsxs","_jsx","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"TreeView.js","sources":["../../../src/components/TreeView.tsx"],"sourcesContent":["import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\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 { warnOnce } from '../helpers/devWarnings';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useTreeView, type TreeViewEngine } from '../helpers/useTreeView';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\nimport { Checkbox } from '../form/Checkbox';\nimport { Icon } from '../elements/Icon';\n\n/**\n * How items are picked: `none`, nothing is; `single`, one item at a time;\n * `checkbox`, any number, with a box on every item and mixed parents.\n */\nexport type TreeViewSelectionMode = 'none' | 'single' | 'checkbox';\n\nconst validTreeViewSizes = ['small', 'medium', 'large'] as const;\n\n/** What an open item's load says in the tree's live region. */\ninterface LoadAnnouncement {\n /** The item's key, so what it says next replaces this. */\n key: string;\n /** The key and the kind: the region says it once each time it appears. */\n id: string;\n kind: 'loading' | 'loaded' | 'error';\n /** The item's name, read off its label. */\n name: string;\n /** A failed load's message, read off its row. */\n message: string;\n}\n\n/** What the root hands its items: the engine, the live region, and the rows' words. */\ninterface TreeContextValue extends TreeViewEngine {\n /** Puts what an item's load says in the live region, or takes it out with `null`. */\n announce: (key: string, announcement: LoadAnnouncement | null) => void;\n loadingLabel: string;\n retryLabel: string;\n}\n\n// Not exported, so they stay out of the public API that `index.ts` re-exports.\nconst TreeViewContext = createContext<TreeContextValue | null>(null);\n\nconst sayLoading = (name: string) => `Loading ${name}`;\nconst sayLoaded = (name: string) => `${name} loaded`;\n\n/** Where an item sits: the values of the items above it, and whether one of them is closed. */\ninterface Branch {\n path: string[];\n hidden: boolean;\n}\n\nconst TOP: Branch = { path: [], hidden: false };\nconst BranchContext = createContext<Branch>(TOP);\n\n/** The box's input lets the row's click toggle it, so a change on its own does nothing. */\nconst ignoreChange = () => {};\n\n/** Whether an `icon` was given something to render. */\nconst isGiven = (node: React.ReactNode) =>\n node !== undefined &&\n node !== null &&\n typeof node !== 'boolean' &&\n node !== '';\n\n/**\n * Props for the TreeView component. The helper props, the other attributes\n * and the `ref` land on the `<ul role=\"tree\">`.\n *\n * @extraProp {string} [aria-label] - Names the tree, such as \"Files\". A tree needs a name, so pass this or `aria-labelledby`, and a development build warns when it has neither.\n * @extraProp {string} [aria-labelledby] - The id of a visible heading or label that names the tree, in place of `aria-label`.\n * @extraProp {React.Ref<HTMLUListElement>} [ref] - Ref forwarded to the `<ul>`.\n */\nexport interface TreeViewProps\n extends\n Omit<\n React.HTMLAttributes<HTMLUListElement>,\n | keyof BulmaClassesProps\n | 'role'\n | 'onSelect'\n | 'defaultValue'\n | 'defaultChecked'\n >,\n BulmaClassesProps {\n /**\n * `TreeView.Item`s, nested inside each other for their children. Render\n * an item's children whenever you have them, open or not: the tree hides\n * them while it's closed.\n */\n children?: React.ReactNode;\n /**\n * `none`: nothing is picked, and Enter and Space open and close a parent.\n * `single`: one item, picked with Enter, Space or a click.\n * `checkbox`: any number, checked with Space or a click. A check reaches\n * every enabled item under it, and a parent with some of them checked is mixed.\n */\n selectionMode?: TreeViewSelectionMode;\n /**\n * The selected item's value when you hold the state, or `null` for none.\n * Read with `single` only. Picking an item then only calls\n * `onSelectedChange`, and nothing changes until you pass the new value.\n */\n selected?: string | null;\n /** The item selected to begin with, when the tree holds its own state. Read with `single` only. */\n defaultSelected?: string | null;\n /**\n * Called with the value of the item picked. Not called for the one\n * already selected, and moving focus never calls it.\n */\n onSelectedChange?: (value: string) => void;\n /**\n * The checked items' values when you hold the state. Read with `checkbox`\n * only. A value checks its item, and an enabled item also counts as checked\n * when any item above it is in the list, so a parent's value stands for its\n * whole branch, loaded or not. A disabled item is checked only by its own value.\n */\n checked?: string[];\n /** The values checked to begin with, when the tree holds its own state. Read with `checkbox` only. */\n defaultChecked?: string[];\n /**\n * Called after a check or an uncheck with every item that now shows\n * checked, parents included, plus any earlier value that matches no item\n * the tree knows, left as it was. The order means nothing. Passed back as\n * `checked`, the list shows the same boxes.\n */\n onCheckedChange?: (checked: string[]) => void;\n /**\n * The open items' values when you hold the state. A value stays in the\n * list while its item's parent is closed, so the item reopens as it was.\n */\n expanded?: string[];\n /** The items open to begin with, when the tree holds its own state. */\n defaultExpanded?: string[];\n /** Called with the new list whenever an item opens or closes, `*` included. */\n onExpandedChange?: (expanded: string[]) => void;\n /** The text size, as Bulma's menu sizes it. The rows, the indent and the chevron scale with it. */\n size?: 'small' | 'medium' | 'large';\n /** What the row in a loading item's group says. In your app's language. */\n loadingLabel?: string;\n /** The Retry button's text on a failed load's row. In your app's language. */\n retryLabel?: string;\n /**\n * What the live region says when an open item starts loading, built from\n * the item's name. In your app's language. Default: `` `Loading ${name}` ``.\n */\n loadingAnnouncement?: (name: string) => string;\n /**\n * What the live region says when that load finishes. In your app's\n * language. Default: `` `${name} loaded` ``.\n */\n loadedAnnouncement?: (name: string) => string;\n}\n\n/**\n * Props for TreeView.Item, one row and, nested in it, its children. The other\n * attributes and the `ref` land on its `<li role=\"treeitem\">`.\n *\n * @extraProp {number} [aria-posinset] - The item's number among the items beside it. The tree declares it, and `aria-setsize`, from the items on the page once it mounts. When the page holds only part of a set, such as the first page of a long folder, pass both on every item of that set: yours win, and the tree's own stay on any item without them.\n * @extraProp {number} [aria-setsize] - How many items sit beside it, itself included. Declared by the tree like `aria-posinset`, and `-1` says the count isn't known.\n * @extraProp {React.Ref<HTMLLIElement>} [ref] - Ref forwarded to the `<li>`.\n */\nexport interface TreeViewItemProps extends Omit<\n React.LiHTMLAttributes<HTMLLIElement>,\n 'role' | 'value' | 'onSelect' | 'children'\n> {\n /** **Required.** Identifies the item in `selected`, `checked` and `expanded`. Unique in the tree. */\n value: string;\n /**\n * **Required.** What the row shows, and the item's name for assistive\n * tech. Nothing in it should be a link or a button: a tree item does one\n * thing, and nothing else in its row takes focus.\n */\n label: React.ReactNode;\n /** A picture before the label: an `Icon` name, or a node. Hidden from assistive tech. */\n icon?: React.ReactNode;\n /**\n * `TreeView.Item`s under this one. Render them whenever you have them,\n * open or not: the tree hides them while it's closed, and a checkbox tree\n * needs them to know what a check reaches.\n */\n children?: React.ReactNode;\n /** Shows the item as a parent before its children are known, such as a folder that loads when it opens. */\n hasChildren?: boolean;\n /**\n * Its children are on their way. While it's open, its group ends in a row\n * that says so, and the tree's live region says it's loading, then that\n * it's loaded once this goes back to `false`. A parent only: pair it with\n * `hasChildren`, or with the children it already has.\n */\n isLoading?: boolean;\n /**\n * Its children didn't load. While it's open, its group ends in a row with\n * this message, and a Retry button when there's an `onRetry`, and the live\n * region reads the message out, so name the item in it (\"Couldn't load\n * src\"), then says it's loaded once this goes with the item still open. A\n * parent only, like `isLoading`. Nothing in it should be a link or a\n * button: the row is what's pressed. `isLoading` wins while both are given.\n */\n loadError?: React.ReactNode;\n /**\n * Called by the Retry button on a failed load's row, and by Enter or Space\n * there. Set `isLoading` while the retry runs, so the live region says it's\n * loading, and reads the message out again if it fails again. The same\n * message passed a second time with no loading between is no change the\n * tree can see.\n */\n onRetry?: () => void;\n /**\n * Reachable with the arrow keys, Home, End and type-ahead, so a screen\n * reader finds it, but never selected, checked, opened or closed. One\n * that's already open stays open.\n */\n disabled?: boolean;\n}\n\n/**\n * The `TreeView` component renders a tree of items you browse and pick from, the way a file explorer works: one tab stop, the arrow keys to move, and Right and Left to open and close.\n *\n * It's the APG Tree View pattern, drawn to look like Bulma's menu. It isn't\n * for site navigation: items aren't links, and a sidebar whose sections open\n * and close is `Menu`'s job. The root owns which items are open, through\n * `expanded`, `defaultExpanded` and `onExpandedChange`.\n *\n * `selectionMode` picks one of three trees. With `none`, nothing is picked.\n * With `single`, one item is, and `selected` says which. With `checkbox`,\n * each item has a box, a check reaches every enabled item under it, closed\n * branches included, and a parent with some of its items checked is mixed.\n * `selected` is read in a `single` tree only, and `checked` in a `checkbox`\n * tree only. Selection never follows focus.\n *\n * Disabled items stay reachable from the keys, so a screen reader finds\n * them. The tree needs a name, from `aria-label` or `aria-labelledby`, and a\n * development build warns when it has neither.\n *\n * @function\n * @param {TreeViewProps} props - Props for the TreeView component.\n * @param {React.Ref<HTMLUListElement>} ref - Forwarded ref to the `<ul>`.\n * @returns {JSX.Element} The rendered tree.\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ | APG Tree View Pattern}\n *\n * @example\n * <TreeView aria-label=\"Files\" selectionMode=\"single\" defaultExpanded={['src']}>\n * <TreeView.Item value=\"src\" label=\"src\" icon=\"folder\">\n * <TreeView.Item value=\"src/index.ts\" label=\"index.ts\" icon=\"file\" />\n * </TreeView.Item>\n * <TreeView.Item value=\"package.json\" label=\"package.json\" icon=\"file\" />\n * </TreeView>\n */\nconst TreeViewRoot = forwardRef<HTMLUListElement, TreeViewProps>(\n function TreeView(\n {\n children,\n selectionMode = 'none',\n selected,\n defaultSelected = null,\n onSelectedChange,\n checked,\n defaultChecked = [],\n onCheckedChange,\n expanded,\n defaultExpanded = [],\n onExpandedChange,\n size,\n loadingLabel = 'Loading…',\n retryLabel = 'Retry',\n loadingAnnouncement,\n loadedAnnouncement,\n className,\n ...props\n },\n ref\n ) {\n const { bulmaHelperClasses, rest } = useBulmaClasses({ ...props });\n const engine = useTreeView({\n mode: selectionMode,\n selected,\n defaultSelected,\n onSelectedChange,\n checked,\n defaultChecked,\n onCheckedChange,\n expanded,\n defaultExpanded,\n onExpandedChange,\n });\n\n const { treeRef } = engine;\n const setRefs = useCallback(\n (node: HTMLUListElement | null) => {\n treeRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref, treeRef]\n );\n\n const named = Boolean(rest['aria-label'] || rest['aria-labelledby']);\n useEffect(() => {\n if (!named) {\n warnOnce(\n 'TreeView:unnamed',\n '[bestax-bulma] <TreeView> has no accessible name. Pass ' +\n 'aria-label or aria-labelledby, so a screen reader can say what ' +\n 'the tree holds.'\n );\n }\n }, [named]);\n\n const rootClass = usePrefixedClassNames('tree-view', {\n [`is-${size}`]:\n !!size && (validTreeViewSizes as readonly string[]).includes(size),\n });\n\n // What each open item's load says, in the order they started saying it.\n const [announcements, setAnnouncements] = useState<LoadAnnouncement[]>([]);\n const announce = useCallback(\n (key: string, announcement: LoadAnnouncement | null) => {\n setAnnouncements(current => {\n const others = current.filter(said => said.key !== key);\n return announcement ? [...others, announcement] : others;\n });\n },\n []\n );\n const describe = useCallback(\n ({ kind, name, message }: LoadAnnouncement) => {\n if (kind === 'error') return message;\n const say =\n kind === 'loading'\n ? (loadingAnnouncement ?? sayLoading)\n : (loadedAnnouncement ?? sayLoaded);\n return say(name);\n },\n [loadingAnnouncement, loadedAnnouncement]\n );\n\n // The props are spread first, so the role and the attributes the tree\n // owns win over anything a caller passes along. The live region sits\n // beside the tree, since a tree holds items and groups only, and it's\n // there from the start, so a screen reader is listening to it before\n // anything is written into it.\n return (\n <TreeViewContext.Provider\n value={{ ...engine, announce, loadingLabel, retryLabel }}\n >\n <BranchContext.Provider value={TOP}>\n <ul\n {...rest}\n ref={setRefs}\n className={classNames(rootClass, bulmaHelperClasses, className)}\n role=\"tree\"\n aria-multiselectable={engine.rendersClosed || undefined}\n >\n {children}\n </ul>\n </BranchContext.Provider>\n <StatusRegion items={announcements} describe={describe} />\n </TreeViewContext.Provider>\n );\n }\n);\n\n/**\n * One item in the tree: a row with its chevron, its box, its icon and its label, and, while it's open, a group of the items under it.\n *\n * @function\n * @param {TreeViewItemProps} props - Props for TreeView.Item.\n * @param {React.Ref<HTMLLIElement>} ref - Forwarded ref to the `<li>`.\n * @returns {JSX.Element | null} The rendered item, or nothing under a closed one.\n */\nexport const TreeViewItem = forwardRef<HTMLLIElement, TreeViewItemProps>(\n function TreeViewItem(\n {\n value,\n label,\n icon,\n children,\n hasChildren = false,\n isLoading = false,\n loadError,\n onRetry,\n disabled = false,\n className,\n onClick,\n onKeyDown,\n onFocus,\n onBlur,\n ...props\n },\n ref\n ) {\n const tree = useContext(TreeViewContext);\n const branch = useContext(BranchContext);\n // Also the item's key in the live region.\n const labelId = useId();\n const hasItems = React.Children.toArray(children).length > 0;\n const isParent = hasItems || hasChildren;\n const open = isParent && !!tree?.isOpen(value);\n const parent = branch.path[branch.path.length - 1] ?? null;\n\n // The row at the end of its group, while it's open and on the page.\n const shown = open && !branch.hidden;\n const status = !shown\n ? null\n : isLoading\n ? 'loading'\n : isGiven(loadError)\n ? 'error'\n : null;\n const labelRef = useRef<HTMLSpanElement | null>(null);\n const statusLabelRef = useRef<HTMLSpanElement | null>(null);\n\n // What the live region says follows the row: it's loading, or it failed,\n // while the row says so, and it's loaded once the row goes with the item\n // still open, whichever row it was, until the item closes or loads again.\n // A closed item says nothing, loading or not.\n const phase = shown ? (status ?? 'open') : 'closed';\n const lastPhaseRef = useRef(phase);\n const announce = tree?.announce;\n useEffect(() => {\n const was = lastPhaseRef.current;\n lastPhaseRef.current = phase;\n const kind =\n phase === 'loading' || phase === 'error'\n ? phase\n : phase === 'open' && (was === 'loading' || was === 'error')\n ? 'loaded'\n : null;\n if (!kind) return undefined;\n // Only an item inside a tree can be open.\n announce!(labelId, {\n key: labelId,\n id: `${labelId}:${kind}`,\n kind,\n name: spokenText(labelRef.current!),\n message: kind === 'error' ? spokenText(statusLabelRef.current!) : '',\n });\n return () => announce!(labelId, null);\n }, [phase, announce, labelId]);\n\n const itemClass = usePrefixedClassNames('tree-view-item');\n const groupClass = usePrefixedClassNames('tree-view-group');\n const toggleClass = usePrefixedClassNames('tree-view-toggle');\n const checkClass = usePrefixedClassNames('tree-view-check');\n const iconClass = usePrefixedClassNames('tree-view-icon');\n const labelClass = usePrefixedClassNames('tree-view-label');\n\n const register = tree?.register;\n useClientLayoutEffect(() => {\n if (!register) {\n warnOnce(\n 'TreeView.Item:outside',\n '[bestax-bulma] <TreeView.Item> is outside a <TreeView>, so it ' +\n 'renders nothing. Put it inside one.'\n );\n return undefined;\n }\n return register(value, { parent, disabled, isParent });\n }, [register, value, parent, disabled, isParent]);\n\n const setElement = tree?.setElement;\n const setRefs = useCallback(\n (node: HTMLLIElement | null) => {\n // Only an item inside a tree renders an element to hand over.\n setElement!(value, node);\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [setElement, value, ref]\n );\n const rowRef = useRef<HTMLDivElement | null>(null);\n const toggleRef = useRef<HTMLSpanElement | null>(null);\n\n const childBranch = useMemo(\n () => ({\n path: [...branch.path, value],\n hidden: branch.hidden || !open,\n }),\n [branch, value, open]\n );\n\n const { selected, checked } =\n tree?.stateOf(value, branch.path, disabled) ?? {};\n const rowClass = usePrefixedClassNames('tree-view-row', {\n 'is-selected': selected,\n 'is-disabled': disabled,\n });\n\n if (!tree) return null;\n\n // While it's open the children render in its group. In a checkbox tree\n // they render while it's closed too, drawing nothing, so a check knows\n // what's under it.\n const items = (open || tree.rendersClosed) && (\n <BranchContext.Provider value={childBranch}>\n {children}\n </BranchContext.Provider>\n );\n if (branch.hidden) return <>{items}</>;\n\n const info = { value, parent, disabled, isParent, open };\n // A position the caller gives wins, for a set the page holds only part of.\n const position = tree.positionOf(value);\n\n return (\n <li\n {...props}\n ref={setRefs}\n className={classNames(itemClass, className)}\n role=\"treeitem\"\n aria-labelledby={labelId}\n aria-level={branch.path.length + 1}\n aria-posinset={props['aria-posinset'] ?? position?.posinset}\n aria-setsize={props['aria-setsize'] ?? position?.setsize}\n aria-expanded={isParent ? open : undefined}\n aria-disabled={disabled || undefined}\n aria-selected={selected}\n aria-checked={checked}\n tabIndex={tree.tabStop === value ? 0 : -1}\n onKeyDown={event => {\n onKeyDown?.(event);\n tree.onKeyDown(event, info);\n }}\n onFocus={event => {\n onFocus?.(event);\n if (event.target === event.currentTarget) {\n tree.onFocus(value, event.currentTarget);\n }\n }}\n onBlur={event => {\n onBlur?.(event);\n if (event.target === event.currentTarget) tree.onBlur();\n }}\n onClick={event => {\n onClick?.(event);\n // A click in its row is its own, and so is one on the item itself,\n // as a test's click on the treeitem is. One in its group belongs\n // to the item inside it, or to nothing. The chevron's box is on\n // every row, but it's a chevron only on a parent: on a leaf it's\n // more of the row.\n const target = event.target as Node;\n if (\n target === event.currentTarget ||\n rowRef.current!.contains(target)\n ) {\n tree.onClick(\n event.currentTarget,\n info,\n isParent && toggleRef.current!.contains(target)\n );\n }\n }}\n >\n <div className={rowClass} ref={rowRef}>\n <span className={toggleClass} aria-hidden=\"true\" ref={toggleRef} />\n {checked !== undefined && (\n <span\n className={checkClass}\n aria-hidden=\"true\"\n onClick={event => {\n // A click on the box's label is followed by one on its\n // input, and both reach the item. The label's is cancelled,\n // so the item toggles once.\n if (!(event.target instanceof HTMLInputElement)) {\n event.preventDefault();\n }\n }}\n >\n <Checkbox\n tabIndex={-1}\n checked={checked === true}\n indeterminate={checked === 'mixed'}\n disabled={disabled}\n onChange={ignoreChange}\n />\n </span>\n )}\n {isGiven(icon) && (\n <span className={iconClass} aria-hidden=\"true\">\n {typeof icon === 'string' ? <Icon name={icon} /> : icon}\n </span>\n )}\n <span className={labelClass} id={labelId} ref={labelRef}>\n {label}\n </span>\n </div>\n {open && (hasItems || status) ? (\n <ul className={groupClass} role=\"group\">\n {items}\n {status && (\n <StatusRow\n kind={status}\n parent={value}\n level={branch.path.length + 2}\n message={loadError}\n onRetry={onRetry}\n labelRef={statusLabelRef}\n />\n )}\n </ul>\n ) : (\n items\n )}\n </li>\n );\n }\n);\n\nTreeViewItem.displayName = 'TreeView.Item';\n\n/** Props for the row at the end of a loading item's group, or a failed load's. */\ninterface StatusRowProps {\n /** `loading`, or `error` for a load that failed. */\n kind: 'loading' | 'error';\n /** The value of the item it's in. */\n parent: string;\n /** Its `aria-level`, one under the item it's in. */\n level: number;\n /** A failed load's message. */\n message: React.ReactNode;\n /** Retries a failed load. */\n onRetry?: () => void;\n /** For its label, which the item reads a failed load's message off. */\n labelRef: React.Ref<HTMLSpanElement>;\n}\n\n/**\n * The row at the end of a loading item's group, or of one whose load failed.\n * It's a `treeitem` the keys reach, the way they reach a disabled item, so a\n * screen reader finds it. It has no value and no record, so it's never\n * selected or checked, and a check never counts it. A failed load's row with\n * `onRetry` retries with Enter, Space or a click, and any other is disabled.\n * The Retry button is drawn, hidden from assistive tech and out of the tab\n * order, the way an item's box is: the row is what's pressed, and its name\n * says so. Rendered in one place, a failed load's row that starts loading\n * again is the same element, so focus stays on it.\n */\nfunction StatusRow({\n kind,\n parent,\n level,\n message,\n onRetry,\n labelRef,\n}: StatusRowProps) {\n // Only an item inside a tree renders a group.\n const tree = useContext(TreeViewContext)!;\n // Also its key in the registry and for the tab stop, where an item has its value.\n const labelId = useId();\n const retryId = useId();\n const retry = kind === 'error' ? onRetry : undefined;\n\n const itemClass = usePrefixedClassNames('tree-view-item');\n const rowClass = usePrefixedClassNames('tree-view-row', {\n 'is-disabled': !retry,\n });\n const toggleClass = usePrefixedClassNames('tree-view-toggle');\n const labelClass = usePrefixedClassNames('tree-view-label');\n const loaderClass = usePrefixedClassNames('loader');\n const retryClass = usePrefixedClassNames('button', { 'is-small': true });\n\n const { setElement } = tree;\n const setRef = useCallback(\n (node: HTMLLIElement | null) => setElement(labelId, node),\n [setElement, labelId]\n );\n const info = {\n value: labelId,\n parent,\n disabled: !retry,\n isParent: false,\n open: false,\n retry,\n };\n const position = tree.positionOf(labelId);\n\n return (\n <li\n ref={setRef}\n className={itemClass}\n role=\"treeitem\"\n aria-labelledby={retry ? `${labelId} ${retryId}` : labelId}\n aria-level={level}\n aria-posinset={position?.posinset}\n aria-setsize={position?.setsize}\n aria-disabled={!retry || undefined}\n tabIndex={tree.tabStop === labelId ? 0 : -1}\n onKeyDown={event => tree.onKeyDown(event, info)}\n onFocus={event => {\n // Focus in something the message holds isn't the row's.\n if (event.target === event.currentTarget) {\n tree.onFocus(labelId, event.currentTarget);\n }\n }}\n onBlur={event => {\n if (event.target === event.currentTarget) tree.onBlur();\n }}\n onClick={event => tree.onClick(event.currentTarget, info, false)}\n >\n <div className={rowClass}>\n <span className={toggleClass} aria-hidden=\"true\">\n {kind === 'loading' && <span className={loaderClass} />}\n </span>\n <span className={labelClass} id={labelId} ref={labelRef}>\n {kind === 'loading' ? tree.loadingLabel : message}\n </span>\n {retry && (\n <span className={retryClass} id={retryId} aria-hidden=\"true\">\n {tree.retryLabel}\n </span>\n )}\n </div>\n </li>\n );\n}\n\nexport const TreeView = withSubComponents(\n TreeViewRoot,\n { Item: TreeViewItem },\n 'TreeView'\n);\n\nexport default TreeView;\n"],"names":["_jsxs","_jsx","_Fragment"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.js","sources":["../../../src/form/Checkbox.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useCheckboxesGroup } from './FormContext';\n\n/**\n * The values the Checkbox `color` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Checkbox, checkboxColors } from '@allxsmith/bestax-bulma';\n *\n * checkboxColors.map(color => (\n * <Checkbox key={color} color={color}>\n * {color}\n * </Checkbox>\n * ));\n */\nexport const checkboxColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Checkbox `size` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['size']` is typed from it, so the two list the same values.\n * Use it to offer a size choice or to check a value that arrives at runtime:\n * the component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { checkboxSizes } from '@allxsmith/bestax-bulma';\n *\n * type CheckboxSize = (typeof checkboxSizes)[number];\n */\nexport const checkboxSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Checkbox component.\n */\nexport interface CheckboxProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the checkbox. */\n color?: (typeof checkboxColors)[number];\n /** Size of the checkbox. */\n size?: (typeof checkboxSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the checkbox is disabled. */\n disabled?: boolean;\n /**\n * Shows the mixed state, as in a \"Select all\" box when some of what it\n * covers is checked. It's a look and an announcement only: `checked` is\n * still the value, and a click still toggles `checked`. Set to `true` or\n * `false`, it's controlled: a browser clears the mixed state on a click,\n * so the component sets it again from this prop after every click and\n * every render. Unset isn't `false`. The component leaves the input's own\n * `indeterminate` property alone, so a ref can set it, and going from set\n * to unset clears it once and hands it back. It has no HTML attribute, so\n * server-rendered markup can't carry it, and a mixed box renders unmixed\n * until hydration.\n */\n indeterminate?: boolean;\n /**\n * Additional CSS classes, on the outer `<label>`. That's the element that\n * declares the `--bulma-checkbox-*` variables, so a class is how to set\n * one: `style` and the other input attributes go to the `<input>`. Name\n * `.styled-checkbox` beside your class in the selector, so it beats the\n * label's own declaration whatever order the stylesheets load in. A\n * `color` prop declares the fills again on `.styled-checkbox.is-<color>`,\n * which ties that selector, so leave `color` unset when a class sets them.\n */\n className?: string;\n /** The label/content for the checkbox. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Checkbox` component provides a Bulma-styled checkbox input.\n *\n * @function\n * @param {CheckboxProps} props - Props for the Checkbox component.\n * @returns {JSX.Element} The rendered checkbox element.\n *\n * @example\n * // Basic checkbox\n * <Checkbox>Accept terms</Checkbox>\n *\n * @example\n * // Inside a group\n * <Checkboxes name=\"tags\" defaultValue={['react']}>\n * <Checkbox value=\"react\">React</Checkbox>\n * <Checkbox value=\"vue\">Vue</Checkbox>\n * </Checkboxes>\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n indeterminate,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // The input's own ref, merged with the forwarded one. A callback ref's\n // return value is handed back, so React 19 still runs a cleanup it\n // returns, as it did when the ref went straight to the input.\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n\n // `indeterminate` is a DOM property with no attribute, so it's set on the\n // input rather than rendered. A click clears it, so this runs after every\n // render, not only when the prop changes. Unset, it's left alone, so a\n // ref that sets the property itself still works. `ownsIndeterminateRef`\n // remembers that this component set it, so a prop that goes back to unset\n // clears the dash once instead of leaving it on.\n const ownsIndeterminateRef = useRef(false);\n useClientLayoutEffect(() => {\n if (indeterminate !== undefined) {\n ownsIndeterminateRef.current = true;\n inputRef.current!.indeterminate = indeterminate;\n } else if (ownsIndeterminateRef.current) {\n ownsIndeterminateRef.current = false;\n inputRef.current!.indeterminate = false;\n }\n });\n\n // Inherit name + selection state from a surrounding <Checkboxes> group.\n // Local props always win over the group (explicit > implicit).\n const group = useCheckboxesGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Checkbox\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const groupHas = groupManaged && group!.value!.includes(String(value));\n const effectiveChecked =\n checked !== undefined ? checked : groupManaged ? groupHas : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // The click that got here cleared the mixed state. Put it back now,\n // since a click that changes no state renders nothing to do it.\n if (indeterminate !== undefined) e.target.indeterminate = indeterminate;\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — toggle this value's\n // membership in the group's array.\n if (group?.onChange && value !== undefined) {\n const valStr = String(value);\n const currentArr = group.value ?? [];\n const next = e.target.checked\n ? currentArr.includes(valStr)\n ? currentArr\n : [...currentArr, valStr]\n : currentArr.filter(v => v !== valStr);\n group.onChange(next);\n }\n },\n [onChange, group, value, indeterminate]\n );\n\n const mainClass = usePrefixedClassNames('styled-checkbox', 'checkbox', {\n [`is-${color}`]: color && checkboxColors.includes(color),\n [`is-${size}`]: size && checkboxSizes.includes(size),\n });\n const checkboxClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={checkboxClass}>\n <input\n ref={setRefs}\n type=\"checkbox\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nCheckbox.displayName = 'Checkbox';\n\nexport default Checkbox;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Checkbox.js","sources":["../../../src/form/Checkbox.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useCheckboxesGroup } from './FormContext';\n\n/**\n * The values the Checkbox `color` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Checkbox, checkboxColors } from '@allxsmith/bestax-bulma';\n *\n * checkboxColors.map(color => (\n * <Checkbox key={color} color={color}>\n * {color}\n * </Checkbox>\n * ));\n */\nexport const checkboxColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Checkbox `size` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['size']` is typed from it, so the two list the same values.\n * Use it to offer a size choice or to check a value that arrives at runtime:\n * the component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { checkboxSizes } from '@allxsmith/bestax-bulma';\n *\n * type CheckboxSize = (typeof checkboxSizes)[number];\n */\nexport const checkboxSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Checkbox component.\n *\n * @helperProps Helper props go on the outer `<label>`, with `className`. The\n * other attributes go on the `<input>`.\n */\nexport interface CheckboxProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the checkbox. */\n color?: (typeof checkboxColors)[number];\n /** Size of the checkbox. */\n size?: (typeof checkboxSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the checkbox is disabled. */\n disabled?: boolean;\n /**\n * Shows the mixed state, as in a \"Select all\" box when some of what it\n * covers is checked. It's a look and an announcement only: `checked` is\n * still the value, and a click still toggles `checked`. Set to `true` or\n * `false`, it's controlled: a browser clears the mixed state on a click,\n * so the component sets it again from this prop after every click and\n * every render. Unset isn't `false`. The component leaves the input's own\n * `indeterminate` property alone, so a ref can set it, and going from set\n * to unset clears it once and hands it back. It has no HTML attribute, so\n * server-rendered markup can't carry it, and a mixed box renders unmixed\n * until hydration.\n */\n indeterminate?: boolean;\n /**\n * Additional CSS classes, on the outer `<label>`. That's the element that\n * declares the `--bulma-checkbox-*` variables, so a class is how to set\n * one: `style` and the other input attributes go to the `<input>`. Name\n * `.styled-checkbox` beside your class in the selector, so it beats the\n * label's own declaration whatever order the stylesheets load in. A\n * `color` prop declares the fills again on `.styled-checkbox.is-<color>`,\n * which ties that selector, so leave `color` unset when a class sets them.\n */\n className?: string;\n /** The label/content for the checkbox. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Checkbox` component provides a Bulma-styled checkbox input.\n *\n * @function\n * @param {CheckboxProps} props - Props for the Checkbox component.\n * @returns {JSX.Element} The rendered checkbox element.\n *\n * @example\n * // Basic checkbox\n * <Checkbox>Accept terms</Checkbox>\n *\n * @example\n * // Inside a group\n * <Checkboxes name=\"tags\" defaultValue={['react']}>\n * <Checkbox value=\"react\">React</Checkbox>\n * <Checkbox value=\"vue\">Vue</Checkbox>\n * </Checkboxes>\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n indeterminate,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // The input's own ref, merged with the forwarded one. A callback ref's\n // return value is handed back, so React 19 still runs a cleanup it\n // returns, as it did when the ref went straight to the input.\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n\n // `indeterminate` is a DOM property with no attribute, so it's set on the\n // input rather than rendered. A click clears it, so this runs after every\n // render, not only when the prop changes. Unset, it's left alone, so a\n // ref that sets the property itself still works. `ownsIndeterminateRef`\n // remembers that this component set it, so a prop that goes back to unset\n // clears the dash once instead of leaving it on.\n const ownsIndeterminateRef = useRef(false);\n useClientLayoutEffect(() => {\n if (indeterminate !== undefined) {\n ownsIndeterminateRef.current = true;\n inputRef.current!.indeterminate = indeterminate;\n } else if (ownsIndeterminateRef.current) {\n ownsIndeterminateRef.current = false;\n inputRef.current!.indeterminate = false;\n }\n });\n\n // Inherit name + selection state from a surrounding <Checkboxes> group.\n // Local props always win over the group (explicit > implicit).\n const group = useCheckboxesGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Checkbox\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const groupHas = groupManaged && group!.value!.includes(String(value));\n const effectiveChecked =\n checked !== undefined ? checked : groupManaged ? groupHas : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // The click that got here cleared the mixed state. Put it back now,\n // since a click that changes no state renders nothing to do it.\n if (indeterminate !== undefined) e.target.indeterminate = indeterminate;\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — toggle this value's\n // membership in the group's array.\n if (group?.onChange && value !== undefined) {\n const valStr = String(value);\n const currentArr = group.value ?? [];\n const next = e.target.checked\n ? currentArr.includes(valStr)\n ? currentArr\n : [...currentArr, valStr]\n : currentArr.filter(v => v !== valStr);\n group.onChange(next);\n }\n },\n [onChange, group, value, indeterminate]\n );\n\n const mainClass = usePrefixedClassNames('styled-checkbox', 'checkbox', {\n [`is-${color}`]: color && checkboxColors.includes(color),\n [`is-${size}`]: size && checkboxSizes.includes(size),\n });\n const checkboxClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={checkboxClass}>\n <input\n ref={setRefs}\n type=\"checkbox\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nCheckbox.displayName = 'Checkbox';\n\nexport default Checkbox;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"File.js","sources":["../../../src/form/File.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useState } from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useConfig } from '../helpers/Config';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n} from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the File component.\n * Inside an outer `Field`, or a `Control` with no `Field` around it, it\n * renders no `Field` of its own. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n */\nexport interface FileProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'color' | 'type'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label. Automatically associated with the file input via `htmlFor` — uses your `id` when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping `file-label`); assistive tech reads both. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Bulma color modifier for the file input. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Size modifier for the file input. */\n size?: 'small' | 'medium' | 'large';\n /** Boxed file input. */\n isBoxed?: boolean;\n /** Whether the file input expands to full width. */\n isFullwidth?: boolean;\n /** Whether the file input expands to full width. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Position the CTA on the right (with `hasName`). */\n isRight?: boolean;\n /** Center the file input within its container. */\n isCentered?: boolean;\n /**\n * Show a file name area. Without `fileName` it shows what the user picked: the file's name, or\n * a count when `multiple` lets them pick several (see `pickedFilesLabel`). Before a pick there is\n * no name area, and the root takes Bulma's `is-empty`. A reset of the input's form clears the\n * name, but clearing the input from code fires no change event and leaves it showing, so pass\n * `fileName` to control the text then.\n */\n hasName?: boolean;\n /** Text on the file CTA button (defaults to \"Choose a file…\"). */\n buttonLabel?: React.ReactNode;\n /**\n * Left icon element. It renders inside the `<label>` that names the file input, beside\n * `buttonLabel`, so leave an `Icon` here unnamed (`<Icon name=\"upload\" />`): it is then\n * `aria-hidden`, while an `ariaLabel` would join the input's accessible name.\n */\n iconLeft?: React.ReactNode;\n /**\n * Right icon element. Sits inside the same `<label>` as `iconLeft`, so the same applies:\n * an `Icon` here with an `ariaLabel` joins the input's accessible name.\n */\n iconRight?: React.ReactNode;\n /** Additional CSS classes to apply. */\n className?: string;\n /** Additional CSS classes for the `<input>`. */\n inputClassName?: string;\n /**\n * Text for the file name area (with `hasName`), for a file chosen earlier or your own wording.\n * Setting it takes over from the picked file's name; an empty string shows no name area.\n */\n fileName?: string;\n /**\n * Builds the text `hasName` shows when several files are picked, from their count, for\n * localization. Default: `` `${count} files` ``. A single pick shows its file's name.\n */\n pickedFilesLabel?: (count: number) => string;\n}\n\n/**\n * The `File` component provides a Bulma-styled file input, supporting color, size, boxed/fullwidth/align styles, icons, \"has name\", and filename display.\n *\n * @function\n * @param {FileProps} props - Props for the File component.\n * @returns {JSX.Element} The rendered file upload field.\n * @see {@link https://bulma.io/documentation/form/file/ | Bulma File documentation}\n */\nexport const File = forwardRef<HTMLInputElement, FileProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n color,\n size,\n isBoxed,\n isFullwidth,\n isFullWidth,\n isRight,\n isCentered,\n hasName,\n buttonLabel,\n iconLeft,\n iconRight,\n className,\n inputClassName,\n fileName,\n pickedFilesLabel,\n onChange,\n ...props\n },\n ref\n ) => {\n // What the user last picked, and the form a reset of which clears it.\n const [picked, setPicked] = useState<{\n count: number;\n firstName: string;\n form: HTMLFormElement | null;\n }>();\n const pickedForm = picked?.form;\n useEffect(() => {\n if (!pickedForm) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n // The reset event fires before the form resets, and a listener after this one can still\n // cancel it, so the name is cleared a task later, and only if the reset went ahead.\n const onReset = (event: Event) => {\n timer = setTimeout(() => {\n if (!event.defaultPrevented) setPicked(undefined);\n });\n };\n pickedForm.addEventListener('reset', onReset);\n return () => {\n pickedForm.removeEventListener('reset', onReset);\n clearTimeout(timer);\n };\n }, [pickedForm]);\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const { files, form } = event.target;\n setPicked(\n files?.length\n ? { count: files.length, firstName: files[0].name, form }\n : undefined\n );\n onChange?.(event);\n };\n const pickedText =\n picked &&\n (picked.count === 1\n ? picked.firstName\n : (pickedFilesLabel?.(picked.count) ?? `${picked.count} files`));\n const shownName = fileName ?? pickedText;\n\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('File', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: ownField,\n });\n const { classPrefix } = useConfig();\n // The input takes `controlId`, so `id` stays out of the spread, where an\n // undefined `id` key would wipe the id the label points at.\n const { id: _id, ...inputProps } = props;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...inputProps,\n });\n\n // Mutually exclusive alignment\n let alignmentClass: string | undefined;\n if (isRight && isCentered) {\n // If both are set, prefer isRight and warn in dev\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isRight) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isCentered) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-centered');\n }\n\n const mainClass = usePrefixedClassNames('file', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-boxed': isBoxed,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n 'has-name': hasName,\n 'is-empty': hasName && !shownName,\n });\n const fileClass = classNames(\n mainClass,\n bulmaHelperClasses,\n alignmentClass,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n const fileElement = (\n <div className={fileClass}>\n <label className={usePrefixedClassNames('file-label')}>\n <input\n ref={ref}\n className={classNames(\n usePrefixedClassNames('file-input'),\n inputClassName\n )}\n type=\"file\"\n id={controlId}\n onChange={handleChange}\n {...rest}\n />\n <span className={usePrefixedClassNames('file-cta')}>\n {iconLeft && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconLeft}\n </span>\n )}\n <span className={usePrefixedClassNames('file-label')}>\n {buttonLabel || 'Choose a file\\u2026'}\n </span>\n {iconRight && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconRight}\n </span>\n )}\n </span>\n {hasName && shownName && (\n <span className={prefixedClassNames(classPrefix, 'file-name')}>\n {shownName}\n </span>\n )}\n </label>\n </div>\n );\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 {fileElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fileElement}\n {messageEl}\n </>\n );\n }\n);\n\nFile.displayName = 'File';\n\nexport default File;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"File.js","sources":["../../../src/form/File.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useState } from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useConfig } from '../helpers/Config';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n} from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the File component.\n * Inside an outer `Field`, or a `Control` with no `Field` around it, it\n * renders no `Field` of its own. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n *\n * @helperProps Helper props go on the `.file` wrapper `<div>`, with\n * `className`. The other attributes go on the `<input>`.\n */\nexport interface FileProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'color' | 'type'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label. Automatically associated with the file input via `htmlFor` — uses your `id` when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping `file-label`); assistive tech reads both. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Bulma color modifier for the file input. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Size modifier for the file input. */\n size?: 'small' | 'medium' | 'large';\n /** Boxed file input. */\n isBoxed?: boolean;\n /** Whether the file input expands to full width. */\n isFullwidth?: boolean;\n /** Whether the file input expands to full width. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Position the CTA on the right (with `hasName`). */\n isRight?: boolean;\n /** Center the file input within its container. */\n isCentered?: boolean;\n /**\n * Show a file name area. Without `fileName` it shows what the user picked: the file's name, or\n * a count when `multiple` lets them pick several (see `pickedFilesLabel`). Before a pick there is\n * no name area, and the root takes Bulma's `is-empty`. A reset of the input's form clears the\n * name, but clearing the input from code fires no change event and leaves it showing, so pass\n * `fileName` to control the text then.\n */\n hasName?: boolean;\n /** Text on the file CTA button (defaults to \"Choose a file…\"). */\n buttonLabel?: React.ReactNode;\n /**\n * Left icon element. It renders inside the `<label>` that names the file input, beside\n * `buttonLabel`, so leave an `Icon` here unnamed (`<Icon name=\"upload\" />`): it is then\n * `aria-hidden`, while an `ariaLabel` would join the input's accessible name.\n */\n iconLeft?: React.ReactNode;\n /**\n * Right icon element. Sits inside the same `<label>` as `iconLeft`, so the same applies:\n * an `Icon` here with an `ariaLabel` joins the input's accessible name.\n */\n iconRight?: React.ReactNode;\n /** Additional CSS classes to apply. */\n className?: string;\n /** Additional CSS classes for the `<input>`. */\n inputClassName?: string;\n /**\n * Text for the file name area (with `hasName`), for a file chosen earlier or your own wording.\n * Setting it takes over from the picked file's name; an empty string shows no name area.\n */\n fileName?: string;\n /**\n * Builds the text `hasName` shows when several files are picked, from their count, for\n * localization. Default: `` `${count} files` ``. A single pick shows its file's name.\n */\n pickedFilesLabel?: (count: number) => string;\n}\n\n/**\n * The `File` component provides a Bulma-styled file input, supporting color, size, boxed/fullwidth/align styles, icons, \"has name\", and filename display.\n *\n * @function\n * @param {FileProps} props - Props for the File component.\n * @returns {JSX.Element} The rendered file upload field.\n * @see {@link https://bulma.io/documentation/form/file/ | Bulma File documentation}\n */\nexport const File = forwardRef<HTMLInputElement, FileProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n color,\n size,\n isBoxed,\n isFullwidth,\n isFullWidth,\n isRight,\n isCentered,\n hasName,\n buttonLabel,\n iconLeft,\n iconRight,\n className,\n inputClassName,\n fileName,\n pickedFilesLabel,\n onChange,\n ...props\n },\n ref\n ) => {\n // What the user last picked, and the form a reset of which clears it.\n const [picked, setPicked] = useState<{\n count: number;\n firstName: string;\n form: HTMLFormElement | null;\n }>();\n const pickedForm = picked?.form;\n useEffect(() => {\n if (!pickedForm) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n // The reset event fires before the form resets, and a listener after this one can still\n // cancel it, so the name is cleared a task later, and only if the reset went ahead.\n const onReset = (event: Event) => {\n timer = setTimeout(() => {\n if (!event.defaultPrevented) setPicked(undefined);\n });\n };\n pickedForm.addEventListener('reset', onReset);\n return () => {\n pickedForm.removeEventListener('reset', onReset);\n clearTimeout(timer);\n };\n }, [pickedForm]);\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const { files, form } = event.target;\n setPicked(\n files?.length\n ? { count: files.length, firstName: files[0].name, form }\n : undefined\n );\n onChange?.(event);\n };\n const pickedText =\n picked &&\n (picked.count === 1\n ? picked.firstName\n : (pickedFilesLabel?.(picked.count) ?? `${picked.count} files`));\n const shownName = fileName ?? pickedText;\n\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('File', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: ownField,\n });\n const { classPrefix } = useConfig();\n // The input takes `controlId`, so `id` stays out of the spread, where an\n // undefined `id` key would wipe the id the label points at.\n const { id: _id, ...inputProps } = props;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...inputProps,\n });\n\n // Mutually exclusive alignment\n let alignmentClass: string | undefined;\n if (isRight && isCentered) {\n // If both are set, prefer isRight and warn in dev\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isRight) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isCentered) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-centered');\n }\n\n const mainClass = usePrefixedClassNames('file', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-boxed': isBoxed,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n 'has-name': hasName,\n 'is-empty': hasName && !shownName,\n });\n const fileClass = classNames(\n mainClass,\n bulmaHelperClasses,\n alignmentClass,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n const fileElement = (\n <div className={fileClass}>\n <label className={usePrefixedClassNames('file-label')}>\n <input\n ref={ref}\n className={classNames(\n usePrefixedClassNames('file-input'),\n inputClassName\n )}\n type=\"file\"\n id={controlId}\n onChange={handleChange}\n {...rest}\n />\n <span className={usePrefixedClassNames('file-cta')}>\n {iconLeft && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconLeft}\n </span>\n )}\n <span className={usePrefixedClassNames('file-label')}>\n {buttonLabel || 'Choose a file\\u2026'}\n </span>\n {iconRight && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconRight}\n </span>\n )}\n </span>\n {hasName && shownName && (\n <span className={prefixedClassNames(classPrefix, 'file-name')}>\n {shownName}\n </span>\n )}\n </label>\n </div>\n );\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 {fileElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fileElement}\n {messageEl}\n </>\n );\n }\n);\n\nFile.displayName = 'File';\n\nexport default File;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Numberinput.js","sources":["../../../src/form/Numberinput.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef } from 'react';\nimport type { JSX } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField, useInsideControl } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/** Valid sizes for the Numberinput component. */\nexport type NumberinputSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Numberinput wrapper and control buttons. */\nexport type NumberinputColor =\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'light'\n | 'dark';\n\n/** Valid colors for the Numberinput inner input element. */\nexport type NumberinputInputColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Position of the increment/decrement control buttons. */\nexport type NumberinputControlsPosition = 'left' | 'right' | 'both';\n\n/** Visual variant for the Numberinput controls. */\nexport type NumberinputVariant = 'plusminus' | 'stepper';\n\n/**\n * Props for the Numberinput component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface NumberinputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue' | 'type'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. Not rendered either by a plusminus `bare` Numberinput outside a `Field`. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Controlled value. */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: NumberinputSize;\n /** Color variant for buttons. */\n color?: NumberinputColor;\n /** Color of the input field itself. */\n inputColor?: NumberinputInputColor;\n /** Position of +/- buttons. */\n controlsPosition?: NumberinputControlsPosition;\n /** Use rounded buttons. */\n controlsRounded?: boolean;\n /** Uses compact button spacing. */\n compact?: boolean;\n /**\n * Renders the plusminus controls without a `.field` row of their own, so\n * they join the row of a `Field` with `hasAddons` or `grouped` they sit\n * in. On by default inside a `Field`, unless a `Control` is anywhere above\n * it: a `Control` stacks its children, so there the controls keep their\n * own row.\n * @defaultValue auto\n */\n bare?: boolean;\n /** Style variant for the control buttons. */\n variant?: NumberinputVariant;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input can be typed in. */\n editable?: boolean;\n /**\n * Shows a loading spinner on the input's control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * Use this rather than `isLoading` on a `Control` around the Numberinput:\n * that spinner sits at the `Control`'s right edge, on top of whichever\n * button is there, while this one stays inside the input.\n */\n isLoading?: boolean;\n /** Enables exponential step increments when holding buttons. */\n exponential?: boolean;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n}\n\nconst ArrowDropUp = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 14.5l5-5 5 5\" />\n </svg>\n);\n\nconst ArrowDropDown = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 9.5l5 5 5-5\" />\n </svg>\n);\n\n/**\n * The `Numberinput` component provides a number input with increment/decrement buttons.\n *\n * @function\n * @param {NumberinputProps} props - Props for the Numberinput component.\n * @returns {JSX.Element} The rendered numeric input element.\n *\n * @example\n * // Basic number input\n * <Numberinput defaultValue={5} min={0} max={100} />\n *\n * @example\n * // Stepper variant with color\n * <Numberinput variant=\"stepper\" color=\"primary\" step={10} />\n */\nexport const Numberinput = forwardRef<HTMLInputElement, NumberinputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue,\n min,\n max,\n step = 1,\n size,\n color,\n inputColor,\n controlsPosition = 'both',\n controlsRounded = false,\n compact = false,\n bare,\n variant = 'plusminus',\n disabled = false,\n editable = true,\n isLoading = false,\n exponential = false,\n onChange,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // Bare controls join their parent's row, which a `.control` does not lay\n // out. `useInsideControl()` is true anywhere below a `Control`, even past\n // a `Field` nested in it, so there they keep their own row as well.\n const insideControl = useInsideControl();\n const effectiveBare = bare ?? (insideField && !insideControl);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const [internalValue, setInternalValue] = useState<number | undefined>(\n defaultValue\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Layout mode\n const isStepper = variant === 'stepper';\n const isAddons = compact || isStepper;\n const effectiveControlsPosition = isStepper ? 'right' : controlsPosition;\n\n // The plusminus bare branch renders no Field and no label at all.\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: !insideField && (isStepper || !effectiveBare),\n });\n\n // Clamp value to min/max\n const clampValue = useCallback(\n (val: number): number => {\n let clamped = val;\n if (min !== undefined && clamped < min) clamped = min;\n if (max !== undefined && clamped > max) clamped = max;\n return clamped;\n },\n [min, max]\n );\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n const clampedValue = clampValue(newValue);\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, clampValue, onChange]\n );\n\n // Exponential step: step grows with value magnitude\n const getEffectiveStep = useCallback(() => {\n if (!exponential) return step;\n return step * Math.max(1, Math.floor(Math.abs(currentValue ?? 0)));\n }, [exponential, step, currentValue]);\n\n // Handle increment\n const handleIncrement = useCallback(() => {\n updateValue((currentValue ?? 0) + getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle decrement\n const handleDecrement = useCallback(() => {\n updateValue((currentValue ?? 0) - getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isNaN(newValue)) {\n updateValue(newValue);\n }\n },\n [updateValue]\n );\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleIncrement();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleDecrement();\n }\n },\n [handleIncrement, handleDecrement]\n );\n\n // Check if at limits\n const isAtMin =\n min !== undefined && currentValue !== undefined && currentValue <= min;\n const isAtMax =\n max !== undefined && currentValue !== undefined && currentValue >= max;\n\n // Generate classes\n const fieldClasses = usePrefixedClassNames('field', {\n 'is-grouped': !isAddons,\n 'has-addons': isAddons,\n });\n\n const numberinputClasses = usePrefixedClassNames('numberinput', {\n 'is-compact': isAddons,\n 'is-stepper': isStepper,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n [`controls-${effectiveControlsPosition}`]:\n effectiveControlsPosition !== 'both',\n });\n\n const controlClasses = usePrefixedClassNames('control');\n const expandedControlClasses = usePrefixedClassNames('control', {\n 'is-expanded': true,\n 'is-loading': isLoading,\n });\n\n const buttonClasses = usePrefixedClassNames('button', {\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-rounded': controlsRounded,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${size}`]: !!size,\n [`is-${inputColor}`]: !!inputColor,\n });\n\n const iconClasses = usePrefixedClassNames('icon', 'is-small');\n const stepperClasses = usePrefixedClassNames('numberinput-stepper');\n const stepperButtonClasses = usePrefixedClassNames(\n 'numberinput-stepper-button'\n );\n\n const combinedClasses = classNames(\n fieldClasses,\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // Use combined ref\n const combinedRef = (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n // Shared input element\n const inputControl = (\n <div className={expandedControlClasses}>\n <input\n ref={combinedRef}\n type=\"number\"\n className={inputClasses}\n value={currentValue ?? ''}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n readOnly={!editable}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n aria-valuenow={currentValue ?? undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n {...rest}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n </div>\n );\n\n // Stepper variant\n if (isStepper) {\n const stepperElement = (\n <div className={combinedClasses}>\n {inputControl}\n <div className={controlClasses}>\n <div className={stepperClasses}>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <ArrowDropUp />\n </button>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <ArrowDropDown />\n </button>\n </div>\n </div>\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {stepperElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {stepperElement}\n {messageEl}\n </>\n );\n }\n\n // Plusminus buttons\n const decrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">&minus;</span>\n </span>\n </button>\n );\n\n const incrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">+</span>\n </span>\n </button>\n );\n\n const decrementControl = (\n <div className={controlClasses}>{decrementButton}</div>\n );\n const incrementControl = (\n <div className={controlClasses}>{incrementButton}</div>\n );\n\n // Bare mode: no outer .field wrapper, for composing inside a parent Field\n if (effectiveBare) {\n const bareClasses = classNames(\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n if (effectiveControlsPosition === 'left') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n }\n\n if (effectiveControlsPosition === 'right') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n }\n\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n // Controls left: [−] [+] [input]\n let numberinputElement: JSX.Element;\n if (effectiveControlsPosition === 'left') {\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n } else if (effectiveControlsPosition === 'right') {\n // Controls right: [input] [−] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n } else {\n // Both sides (default): [−] [input] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {numberinputElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {numberinputElement}\n {messageEl}\n </>\n );\n }\n);\n\nNumberinput.displayName = 'Numberinput';\n\n/** @deprecated Use `Numberinput` — same component. */\nexport const NumberInput = Numberinput;\n\n/** @deprecated Use `NumberinputProps`. */\nexport type NumberInputProps = NumberinputProps;\n\nexport default Numberinput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"Numberinput.js","sources":["../../../src/form/Numberinput.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef } from 'react';\nimport type { JSX } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField, useInsideControl } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/** Valid sizes for the Numberinput component. */\nexport type NumberinputSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Numberinput wrapper and control buttons. */\nexport type NumberinputColor =\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'light'\n | 'dark';\n\n/** Valid colors for the Numberinput inner input element. */\nexport type NumberinputInputColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Position of the increment/decrement control buttons. */\nexport type NumberinputControlsPosition = 'left' | 'right' | 'both';\n\n/** Visual variant for the Numberinput controls. */\nexport type NumberinputVariant = 'plusminus' | 'stepper';\n\n/**\n * Props for the Numberinput component.\n * @helperProps Helper props go on the outer `.numberinput` `<div>`, with\n * `className`. The other attributes go on the `<input>`.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface NumberinputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue' | 'type'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. Not rendered either by a plusminus `bare` Numberinput outside a `Field`. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Controlled value. */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: NumberinputSize;\n /** Color variant for buttons. */\n color?: NumberinputColor;\n /** Color of the input field itself. */\n inputColor?: NumberinputInputColor;\n /** Position of +/- buttons. */\n controlsPosition?: NumberinputControlsPosition;\n /** Use rounded buttons. */\n controlsRounded?: boolean;\n /** Uses compact button spacing. */\n compact?: boolean;\n /**\n * Renders the plusminus controls without a `.field` row of their own, so\n * they join the row of a `Field` with `hasAddons` or `grouped` they sit\n * in. On by default inside a `Field`, unless a `Control` is anywhere above\n * it: a `Control` stacks its children, so there the controls keep their\n * own row.\n * @defaultValue auto\n */\n bare?: boolean;\n /** Style variant for the control buttons. */\n variant?: NumberinputVariant;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input can be typed in. */\n editable?: boolean;\n /**\n * Shows a loading spinner on the input's control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * Use this rather than `isLoading` on a `Control` around the Numberinput:\n * that spinner sits at the `Control`'s right edge, on top of whichever\n * button is there, while this one stays inside the input.\n */\n isLoading?: boolean;\n /** Enables exponential step increments when holding buttons. */\n exponential?: boolean;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n}\n\nconst ArrowDropUp = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 14.5l5-5 5 5\" />\n </svg>\n);\n\nconst ArrowDropDown = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 9.5l5 5 5-5\" />\n </svg>\n);\n\n/**\n * The `Numberinput` component provides a number input with increment/decrement buttons.\n *\n * @function\n * @param {NumberinputProps} props - Props for the Numberinput component.\n * @returns {JSX.Element} The rendered numeric input element.\n *\n * @example\n * // Basic number input\n * <Numberinput defaultValue={5} min={0} max={100} />\n *\n * @example\n * // Stepper variant with color\n * <Numberinput variant=\"stepper\" color=\"primary\" step={10} />\n */\nexport const Numberinput = forwardRef<HTMLInputElement, NumberinputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue,\n min,\n max,\n step = 1,\n size,\n color,\n inputColor,\n controlsPosition = 'both',\n controlsRounded = false,\n compact = false,\n bare,\n variant = 'plusminus',\n disabled = false,\n editable = true,\n isLoading = false,\n exponential = false,\n onChange,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // Bare controls join their parent's row, which a `.control` does not lay\n // out. `useInsideControl()` is true anywhere below a `Control`, even past\n // a `Field` nested in it, so there they keep their own row as well.\n const insideControl = useInsideControl();\n const effectiveBare = bare ?? (insideField && !insideControl);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const [internalValue, setInternalValue] = useState<number | undefined>(\n defaultValue\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Layout mode\n const isStepper = variant === 'stepper';\n const isAddons = compact || isStepper;\n const effectiveControlsPosition = isStepper ? 'right' : controlsPosition;\n\n // The plusminus bare branch renders no Field and no label at all.\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: !insideField && (isStepper || !effectiveBare),\n });\n\n // Clamp value to min/max\n const clampValue = useCallback(\n (val: number): number => {\n let clamped = val;\n if (min !== undefined && clamped < min) clamped = min;\n if (max !== undefined && clamped > max) clamped = max;\n return clamped;\n },\n [min, max]\n );\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n const clampedValue = clampValue(newValue);\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, clampValue, onChange]\n );\n\n // Exponential step: step grows with value magnitude\n const getEffectiveStep = useCallback(() => {\n if (!exponential) return step;\n return step * Math.max(1, Math.floor(Math.abs(currentValue ?? 0)));\n }, [exponential, step, currentValue]);\n\n // Handle increment\n const handleIncrement = useCallback(() => {\n updateValue((currentValue ?? 0) + getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle decrement\n const handleDecrement = useCallback(() => {\n updateValue((currentValue ?? 0) - getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isNaN(newValue)) {\n updateValue(newValue);\n }\n },\n [updateValue]\n );\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleIncrement();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleDecrement();\n }\n },\n [handleIncrement, handleDecrement]\n );\n\n // Check if at limits\n const isAtMin =\n min !== undefined && currentValue !== undefined && currentValue <= min;\n const isAtMax =\n max !== undefined && currentValue !== undefined && currentValue >= max;\n\n // Generate classes\n const fieldClasses = usePrefixedClassNames('field', {\n 'is-grouped': !isAddons,\n 'has-addons': isAddons,\n });\n\n const numberinputClasses = usePrefixedClassNames('numberinput', {\n 'is-compact': isAddons,\n 'is-stepper': isStepper,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n [`controls-${effectiveControlsPosition}`]:\n effectiveControlsPosition !== 'both',\n });\n\n const controlClasses = usePrefixedClassNames('control');\n const expandedControlClasses = usePrefixedClassNames('control', {\n 'is-expanded': true,\n 'is-loading': isLoading,\n });\n\n const buttonClasses = usePrefixedClassNames('button', {\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-rounded': controlsRounded,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${size}`]: !!size,\n [`is-${inputColor}`]: !!inputColor,\n });\n\n const iconClasses = usePrefixedClassNames('icon', 'is-small');\n const stepperClasses = usePrefixedClassNames('numberinput-stepper');\n const stepperButtonClasses = usePrefixedClassNames(\n 'numberinput-stepper-button'\n );\n\n const combinedClasses = classNames(\n fieldClasses,\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // Use combined ref\n const combinedRef = (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n // Shared input element\n const inputControl = (\n <div className={expandedControlClasses}>\n <input\n ref={combinedRef}\n type=\"number\"\n className={inputClasses}\n value={currentValue ?? ''}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n readOnly={!editable}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n aria-valuenow={currentValue ?? undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n {...rest}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n </div>\n );\n\n // Stepper variant\n if (isStepper) {\n const stepperElement = (\n <div className={combinedClasses}>\n {inputControl}\n <div className={controlClasses}>\n <div className={stepperClasses}>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <ArrowDropUp />\n </button>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <ArrowDropDown />\n </button>\n </div>\n </div>\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {stepperElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {stepperElement}\n {messageEl}\n </>\n );\n }\n\n // Plusminus buttons\n const decrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">&minus;</span>\n </span>\n </button>\n );\n\n const incrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">+</span>\n </span>\n </button>\n );\n\n const decrementControl = (\n <div className={controlClasses}>{decrementButton}</div>\n );\n const incrementControl = (\n <div className={controlClasses}>{incrementButton}</div>\n );\n\n // Bare mode: no outer .field wrapper, for composing inside a parent Field\n if (effectiveBare) {\n const bareClasses = classNames(\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n if (effectiveControlsPosition === 'left') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n }\n\n if (effectiveControlsPosition === 'right') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n }\n\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n // Controls left: [−] [+] [input]\n let numberinputElement: JSX.Element;\n if (effectiveControlsPosition === 'left') {\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n } else if (effectiveControlsPosition === 'right') {\n // Controls right: [input] [−] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n } else {\n // Both sides (default): [−] [input] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {numberinputElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {numberinputElement}\n {messageEl}\n </>\n );\n }\n);\n\nNumberinput.displayName = 'Numberinput';\n\n/** @deprecated Use `Numberinput` — same component. */\nexport const NumberInput = Numberinput;\n\n/** @deprecated Use `NumberinputProps`. */\nexport type NumberInputProps = NumberinputProps;\n\nexport default Numberinput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}