@allxsmith/bestax-bulma 5.27.1 → 5.27.2

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 (74) hide show
  1. package/dist/esm/form/Autocomplete.js.map +1 -1
  2. package/dist/esm/form/Checkboxes.js +1 -0
  3. package/dist/esm/form/Checkboxes.js.map +1 -1
  4. package/dist/esm/form/DateInput.js +2 -1
  5. package/dist/esm/form/DateInput.js.map +1 -1
  6. package/dist/esm/form/DateRangeInput.js +1 -0
  7. package/dist/esm/form/DateRangeInput.js.map +1 -1
  8. package/dist/esm/form/DateTimeInput.js +2 -1
  9. package/dist/esm/form/DateTimeInput.js.map +1 -1
  10. package/dist/esm/form/Field.js +18 -4
  11. package/dist/esm/form/Field.js.map +1 -1
  12. package/dist/esm/form/File.js +4 -1
  13. package/dist/esm/form/File.js.map +1 -1
  14. package/dist/esm/form/FormContext.js +27 -3
  15. package/dist/esm/form/FormContext.js.map +1 -1
  16. package/dist/esm/form/Input.js +1 -1
  17. package/dist/esm/form/Input.js.map +1 -1
  18. package/dist/esm/form/Numberinput.js +3 -1
  19. package/dist/esm/form/Numberinput.js.map +1 -1
  20. package/dist/esm/form/Radios.js +1 -0
  21. package/dist/esm/form/Radios.js.map +1 -1
  22. package/dist/esm/form/Rate.js +1 -0
  23. package/dist/esm/form/Rate.js.map +1 -1
  24. package/dist/esm/form/Select.js +1 -1
  25. package/dist/esm/form/Select.js.map +1 -1
  26. package/dist/esm/form/Slider.js +4 -2
  27. package/dist/esm/form/Slider.js.map +1 -1
  28. package/dist/esm/form/Taginput.js +4 -5
  29. package/dist/esm/form/Taginput.js.map +1 -1
  30. package/dist/esm/form/TextArea.js +1 -1
  31. package/dist/esm/form/TextArea.js.map +1 -1
  32. package/dist/esm/form/TimeInput.js +2 -1
  33. package/dist/esm/form/TimeInput.js.map +1 -1
  34. package/dist/esm/form/useAutoLabelId.js +42 -8
  35. package/dist/esm/form/useAutoLabelId.js.map +1 -1
  36. package/dist/esm/helpers/Config.js.map +1 -1
  37. package/dist/esm/helpers/Theme.js.map +1 -1
  38. package/dist/index.cjs +112 -28
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/types/form/Autocomplete.d.ts +1 -1
  41. package/dist/types/form/Checkboxes.d.ts +1 -1
  42. package/dist/types/form/DateInput.d.ts +1 -1
  43. package/dist/types/form/DateRangeInput.d.ts +1 -1
  44. package/dist/types/form/DateTimeInput.d.ts +1 -1
  45. package/dist/types/form/Field.d.ts +2 -2
  46. package/dist/types/form/File.d.ts +1 -1
  47. package/dist/types/form/FormContext.d.ts +24 -2
  48. package/dist/types/form/Numberinput.d.ts +1 -1
  49. package/dist/types/form/Radios.d.ts +1 -1
  50. package/dist/types/form/Rate.d.ts +1 -1
  51. package/dist/types/form/Slider.d.ts +1 -1
  52. package/dist/types/form/Taginput.d.ts +1 -1
  53. package/dist/types/form/TimeInput.d.ts +1 -1
  54. package/dist/types/form/useAutoLabelId.d.ts +25 -4
  55. package/dist/types/helpers/Config.d.ts +3 -4
  56. package/dist/types/helpers/Theme.d.ts +44 -40
  57. package/dist/types-cjs/form/Autocomplete.d.ts +1 -1
  58. package/dist/types-cjs/form/Checkboxes.d.ts +1 -1
  59. package/dist/types-cjs/form/DateInput.d.ts +1 -1
  60. package/dist/types-cjs/form/DateRangeInput.d.ts +1 -1
  61. package/dist/types-cjs/form/DateTimeInput.d.ts +1 -1
  62. package/dist/types-cjs/form/Field.d.ts +2 -2
  63. package/dist/types-cjs/form/File.d.ts +1 -1
  64. package/dist/types-cjs/form/FormContext.d.ts +24 -2
  65. package/dist/types-cjs/form/Numberinput.d.ts +1 -1
  66. package/dist/types-cjs/form/Radios.d.ts +1 -1
  67. package/dist/types-cjs/form/Rate.d.ts +1 -1
  68. package/dist/types-cjs/form/Slider.d.ts +1 -1
  69. package/dist/types-cjs/form/Taginput.d.ts +1 -1
  70. package/dist/types-cjs/form/TimeInput.d.ts +1 -1
  71. package/dist/types-cjs/form/useAutoLabelId.d.ts +25 -4
  72. package/dist/types-cjs/helpers/Config.d.ts +3 -4
  73. package/dist/types-cjs/helpers/Theme.d.ts +44 -40
  74. package/package.json +1 -1
@@ -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` (label that `Field` yourself). */\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. A reset of the input's form clears the name, but clearing the input from code\n * fires no change event and leaves it showing, so pass `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 const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...props,\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 });\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 */\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`). */\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. A reset of the input's form clears the name, but clearing the input from code\n * fires no change event and leaves it showing, so pass `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 });\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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"}
@@ -143,12 +143,36 @@ const FieldLabelIdContext = createContext(undefined);
143
143
  * The id a labeled Field wants its single composed control to adopt (#495).
144
144
  * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
145
145
  * user took over the association with an explicit `labelProps.htmlFor`.
146
- * Consumed only by the single-control bases (InputBase, SelectBase,
147
- * TextAreaBase). Internal; not part of the public API.
146
+ * Consumed by the single-control bases (InputBase, SelectBase, TextAreaBase)
147
+ * and, through `useAutoLabelId`, by the convenience inputs that render an
148
+ * input of their own (#939). Internal; not part of the public API.
148
149
  */
149
150
  const useFieldLabelId = () => useContext(FieldLabelIdContext);
150
151
  /** Provider for the Field label-target id — used internally by Field. */
151
152
  const FieldLabelIdProvider = FieldLabelIdContext.Provider;
153
+ const FieldLabelElementIdContext = createContext(undefined);
154
+ /**
155
+ * The id of a labeled Field's own `<label>`, for a group control (Radios,
156
+ * Checkboxes, Rate, DateRangeInput) to point `aria-labelledby` at, since a group cannot take
157
+ * the label's `htmlFor` (#939). Set under the same conditions as
158
+ * {@link useFieldLabelId}. Consumed through `useAutoLabelledBy`.
159
+ * Internal; not part of the public API.
160
+ */
161
+ const useFieldLabelElementId = () => useContext(FieldLabelElementIdContext);
162
+ /** Provider for the Field label's own id, used internally by Field. */
163
+ const FieldLabelElementIdProvider = FieldLabelElementIdContext.Provider;
164
+ const FieldLabelForContext = createContext(undefined);
165
+ /**
166
+ * What the nearest labeled Field's `<label>` points `htmlFor` at: the id it
167
+ * generated, or the caller's own `labelProps.htmlFor`. An unlabeled Field
168
+ * passes it through, so a control in the inner Field of a horizontal layout
169
+ * can tell the outer label names it. Only ever compared with a control's own
170
+ * id, never adopted, so it hands out no id. Internal; not part of the public
171
+ * API.
172
+ */
173
+ const useFieldLabelFor = () => useContext(FieldLabelForContext);
174
+ /** Provider for the Field label's `htmlFor` target, used internally by Field. */
175
+ const FieldLabelForProvider = FieldLabelForContext.Provider;
152
176
  const RadiosContext = createContext(undefined);
153
177
  const CheckboxesContext = createContext(undefined);
154
178
  /**
@@ -166,5 +190,5 @@ const RadiosProvider = RadiosContext.Provider;
166
190
  /** Provider for the Checkboxes group context — used internally by Checkboxes. */
167
191
  const CheckboxesProvider = CheckboxesContext.Provider;
168
192
 
169
- export { CheckboxesProvider, ControlProvider, FieldLabelIdProvider, FieldProvider, RadiosProvider, rendersOwnControl, rendersOwnField, useCheckboxesGroup, useFieldLabelId, useInsideControl, useInsideField, useRadiosGroup };
193
+ export { CheckboxesProvider, ControlProvider, FieldLabelElementIdProvider, FieldLabelForProvider, FieldLabelIdProvider, FieldProvider, RadiosProvider, rendersOwnControl, rendersOwnField, useCheckboxesGroup, useFieldLabelElementId, useFieldLabelFor, useFieldLabelId, useInsideControl, useInsideField, useRadiosGroup };
170
194
  //# sourceMappingURL=FormContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FormContext.js","sources":["../../../src/form/FormContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from 'react';\nimport { warnOnce } from '../helpers/devWarnings';\nimport type { ControlBaseProps } from './Control';\n\nconst FieldContext = createContext(false);\nconst ControlContext = createContext(false);\n\n/**\n * Hook to detect if the component is inside a Field wrapper.\n * Form components use this to skip rendering their own Field.\n */\nexport const useInsideField = () => useContext(FieldContext);\n\n/**\n * Hook to detect if the component is inside a Control wrapper.\n * Form components use this to skip rendering their own Control.\n */\nexport const useInsideControl = () => useContext(ControlContext);\n\n/** Provider for Field context — used internally by Field component. */\nexport const FieldProvider = FieldContext.Provider;\n\n/** Provider for Control context — used internally by Control component. */\nexport const ControlProvider = ControlContext.Provider;\n\n/** The wrapper props that change what its own `Field` renders. */\ninterface FieldShapingProps {\n /** Rendered as the `Field`'s label. */\n label?: React.ReactNode;\n /** Rendered as help text after the widget. */\n message?: React.ReactNode;\n /** Lays the `Field` out horizontally. */\n horizontal?: boolean;\n /** Set on the `Field` as its class. */\n fieldClassName?: string;\n}\n\ninterface OwnFieldOptions extends FieldShapingProps {\n /** `useInsideField()` as the wrapper read it. */\n insideField: boolean;\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n}\n\n// Each Field-shaping prop, with what takes its place on a `Field` the caller\n// wraps around the `Control`. `message` needs nothing there, because the\n// wrapper still renders it inside `Field > Control`. The other Field-level\n// props (`labelSize`, `labelProps`, `messageColor`) change nothing unless a\n// `label` or `message` renders, so on their own they keep no `Field`.\n// `bare-control.test.tsx` holds this list to what each wrapper hands its\n// `Field` and to which props change its markup, so a new Field-level prop\n// fails there until it is sorted into one group or the other.\nconst FIELD_SHAPING: ReadonlyArray<\n [keyof FieldShapingProps, string | undefined]\n> = [\n ['label', 'label'],\n ['message', undefined],\n ['horizontal', 'horizontal'],\n ['fieldClassName', 'className (for fieldClassName)'],\n];\n\n/** `a`, `a and b`, `a, b and c`. */\nconst listOf = (items: string[]): string =>\n items.length > 1\n ? `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`\n : items[0];\n\n/**\n * Whether a convenience form wrapper renders a `Field` of its own (#905).\n * Never inside an outer `Field`. Inside a `Control` with no `Field` around\n * it, a `Field` of its own would put a `.field` inside the `.control`, where\n * Bulma's control styles break (its icon rules are sibling selectors on the\n * input). So it renders one there only when a prop that shapes the `Field`'s\n * markup is set (`label`, `message`, `horizontal`, `fieldClassName`), keeping\n * the markup it always had, and warns in development that the fix is a\n * `Field` around that `Control`. A prop counts when it is truthy, the same\n * test that decides whether it changes the `Field`'s output.\n * Internal; not part of the public API.\n */\nexport const rendersOwnField = (\n component: string,\n options: OwnFieldOptions\n): boolean => {\n if (options.insideField) return false;\n if (!options.insideControl) return true;\n const held = FIELD_SHAPING.filter(([prop]) => options[prop]);\n if (held.length === 0) return false;\n const names = held.map(([prop]) => prop);\n const moved = held\n .map(([, onField]) => onField)\n .filter((onField): onField is string => onField !== undefined);\n warnOnce(\n `${component}:Field-in-bare-Control:${names.join('+')}`,\n `[bestax-bulma] <${component} ${names.join(' ')}> inside a <Control> ` +\n `with no <Field> around it renders its own <Field> for ` +\n `${names.length > 1 ? 'those props' : 'that prop'}, which puts a ` +\n `.field inside the .control, a nesting Bulma's styles are not ` +\n `written for. Wrap the <Control> in a <Field> instead` +\n (moved.length > 0 ? `, and set ${listOf(moved)} on that <Field>.` : '.')\n );\n return true;\n};\n\n/** The props a convenience form wrapper hands its own `Control`. Internal. */\nexport interface ControlLevelProps {\n /** Shows the `Control`'s loading spinner. */\n isLoading?: boolean;\n /** The `Control`'s left icon. */\n iconLeft?: ControlBaseProps['iconLeft'];\n /** Shortcut for the left icon's name. */\n iconLeftName?: string;\n /** Shortcut for the left icon's size. */\n iconLeftSize?: ControlBaseProps['iconLeftSize'];\n /** The `Control`'s right icon. */\n iconRight?: ControlBaseProps['iconRight'];\n /** Shortcut for the right icon's name. */\n iconRightName?: string;\n /** Shortcut for the right icon's size. */\n iconRightSize?: ControlBaseProps['iconRightSize'];\n /** Reserves the `Control`'s left icon space. */\n hasIconsLeft?: boolean;\n /** Reserves the `Control`'s right icon space. */\n hasIconsRight?: boolean;\n /** Expands the `Control`. */\n isExpanded?: boolean;\n /** Set on the `Control` as its `size`. */\n controlSize?: ControlBaseProps['size'];\n /** Set on the `Control` as its class. */\n controlClassName?: string;\n}\n\ninterface OwnControlOptions extends ControlLevelProps {\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n /** A picker's `inline`, which renders no `Control` inside one or out. */\n inline?: boolean;\n /**\n * The left glyph the wrapper's own `Control` shows when the caller sets no\n * `iconLeftName`; read only then. `bare-control.test.tsx` reads that glyph\n * from what each wrapper hands its own `Control`, so a wrapper that gains\n * one fails there until it passes it here.\n */\n defaultIconLeftName?: string;\n}\n\n// Each Control-level prop, with what takes its place on the `Control` the\n// caller wrapped around the wrapper. `bare-control.test.tsx` holds this to\n// what each wrapper hands its own `Control`, so a new Control-level prop\n// fails there until it is added here and passed to `rendersOwnControl`.\nconst ON_CONTROL: Record<keyof ControlLevelProps, string> = {\n isLoading: 'isLoading',\n iconLeft: 'iconLeft',\n iconLeftName: 'iconLeftName',\n iconLeftSize: 'iconLeftSize',\n iconRight: 'iconRight',\n iconRightName: 'iconRightName',\n iconRightSize: 'iconRightSize',\n hasIconsLeft: 'hasIconsLeft',\n hasIconsRight: 'hasIconsRight',\n isExpanded: 'isExpanded',\n controlSize: 'size (for controlSize)',\n controlClassName: 'className (for controlClassName)',\n};\n\n/**\n * Whether a convenience form wrapper renders a `Control` of its own (#921):\n * only outside one. Inside a `Control` it renders none, so the props it\n * would have handed its own do nothing there, and it warns in development,\n * naming them and saying to set them on that `Control`. An `inline` picker\n * renders none in either place, so it drops them inside a `Control` or not,\n * and its warning says so without pointing at a `Control`. A wrapper passes\n * only the props it hands its own `Control`, as the caller gave them, so a\n * default the wrapper fills in itself never warns. A prop counts when it is\n * truthy, since a falsy one would change nothing on a `Control` either.\n * `iconLeftSize` and `hasIconsLeft` show nothing on a `Control` without a\n * glyph, so when they move and the caller chose no left icon, the advice\n * names the wrapper's default glyph too, and following it draws what the\n * wrapper's own `Control` did.\n * Internal; not part of the public API.\n */\nexport const rendersOwnControl = (\n component: string,\n options: OwnControlOptions\n): boolean => {\n if (!options.inline && !options.insideControl) return true;\n const held = (\n Object.keys(ON_CONTROL) as Array<keyof ControlLevelProps>\n ).filter(prop => options[prop]);\n if (held.length === 0) return false;\n const names = held.join(' ');\n const doNothing = held.length > 1 ? 'those props do' : 'that prop does';\n let message: string;\n if (options.inline) {\n message =\n `[bestax-bulma] <${component} inline ${names}> renders no <Control> ` +\n `in inline mode, inside a <Control> or not, so ${doNothing} ` +\n `nothing. Leave ${held.length > 1 ? 'them' : 'it'} out of an ` +\n `inline picker.`;\n } else {\n const toSet = held.map(prop => ON_CONTROL[prop]);\n const needsGlyph =\n (options.iconLeftSize || options.hasIconsLeft) &&\n !options.iconLeft &&\n options.iconLeftName === undefined &&\n options.defaultIconLeftName;\n if (needsGlyph) {\n toSet.push(\n `iconLeftName=\"${options.defaultIconLeftName}\" (its default icon)`\n );\n }\n message =\n `[bestax-bulma] <${component} ${names}> inside a <Control> renders ` +\n `no <Control> of its own, so ${doNothing} nothing there. Set ` +\n `${listOf(toSet)} on that <Control> instead.`;\n }\n // Keyed by the message itself: the props named do not settle the advice\n // (an empty `iconLeftName` and an unset one name the same props), so two\n // calls that would advise differently must not share a key.\n warnOnce(message, message);\n return false;\n};\n\nconst FieldLabelIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id a labeled Field wants its single composed control to adopt (#495).\n * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the\n * user took over the association with an explicit `labelProps.htmlFor`.\n * Consumed only by the single-control bases (InputBase, SelectBase,\n * TextAreaBase). Internal; not part of the public API.\n */\nexport const useFieldLabelId = () => useContext(FieldLabelIdContext);\n\n/** Provider for the Field label-target id — used internally by Field. */\nexport const FieldLabelIdProvider = FieldLabelIdContext.Provider;\n\n/**\n * Shape of the Radios group context. The group provides:\n * - `name`: shared form field name (Stage 1)\n * - `value`: currently-selected radio value (Stage 2 — group-managed selection)\n * - `onChange`: dispatched by child Radios when clicked (Stage 2)\n *\n * Group sets `value`/`onChange` only when actively managing selection\n * (i.e., the user passed `value`, `defaultValue`, or `onChange` to `<Radios>`).\n * When only `name` is provided, the group is in \"name-only\" mode and child\n * Radios manage their own checked state independently.\n */\nexport interface RadiosGroupContextValue {\n name?: string;\n value?: string;\n onChange?: (value: string) => void;\n}\n\n/**\n * Shape of the Checkboxes group context. Like Radios but with array semantics\n * for multi-select.\n */\nexport interface CheckboxesGroupContextValue {\n name?: string;\n value?: string[];\n onChange?: (values: string[]) => void;\n}\n\nconst RadiosContext = createContext<RadiosGroupContextValue | undefined>(\n undefined\n);\nconst CheckboxesContext = createContext<\n CheckboxesGroupContextValue | undefined\n>(undefined);\n\n/**\n * Hook to read the full surrounding `<Radios>` group context (name + selection).\n * Returns `undefined` when not inside a `<Radios>` group.\n */\nexport const useRadiosGroup = () => useContext(RadiosContext);\n\n/**\n * Hook to read the full surrounding `<Checkboxes>` group context.\n * Returns `undefined` when not inside a `<Checkboxes>` group.\n */\nexport const useCheckboxesGroup = () => useContext(CheckboxesContext);\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Radios>` group.\n * Child `<Radio>` components fall back to this when no local `name` prop is set.\n * Returns `undefined` outside of a `<Radios>` group.\n */\nexport const useRadiosName = () => useRadiosGroup()?.name;\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Checkboxes>` group.\n * Returns `undefined` outside of a `<Checkboxes>` group.\n */\nexport const useCheckboxesName = () => useCheckboxesGroup()?.name;\n\n/** Provider for the Radios group context — used internally by Radios. */\nexport const RadiosProvider = RadiosContext.Provider;\n\n/** Provider for the Checkboxes group context — used internally by Checkboxes. */\nexport const CheckboxesProvider = CheckboxesContext.Provider;\n\n// --- Backward-compat aliases (Stage 1 names) -----------------------------\n// Internal callers may still import these. Both still work because they refer\n// to the same providers/hooks under the new shape.\n\n/** @deprecated Use `RadiosProvider` (provides {name, value, onChange}). */\nexport const RadiosNameProvider = RadiosProvider;\n\n/** @deprecated Use `CheckboxesProvider` (provides {name, value, onChange}). */\nexport const CheckboxesNameProvider = CheckboxesProvider;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FormContext.js","sources":["../../../src/form/FormContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from 'react';\nimport { warnOnce } from '../helpers/devWarnings';\nimport type { ControlBaseProps } from './Control';\n\nconst FieldContext = createContext(false);\nconst ControlContext = createContext(false);\n\n/**\n * Hook to detect if the component is inside a Field wrapper.\n * Form components use this to skip rendering their own Field.\n */\nexport const useInsideField = () => useContext(FieldContext);\n\n/**\n * Hook to detect if the component is inside a Control wrapper.\n * Form components use this to skip rendering their own Control.\n */\nexport const useInsideControl = () => useContext(ControlContext);\n\n/** Provider for Field context — used internally by Field component. */\nexport const FieldProvider = FieldContext.Provider;\n\n/** Provider for Control context — used internally by Control component. */\nexport const ControlProvider = ControlContext.Provider;\n\n/** The wrapper props that change what its own `Field` renders. */\ninterface FieldShapingProps {\n /** Rendered as the `Field`'s label. */\n label?: React.ReactNode;\n /** Rendered as help text after the widget. */\n message?: React.ReactNode;\n /** Lays the `Field` out horizontally. */\n horizontal?: boolean;\n /** Set on the `Field` as its class. */\n fieldClassName?: string;\n}\n\ninterface OwnFieldOptions extends FieldShapingProps {\n /** `useInsideField()` as the wrapper read it. */\n insideField: boolean;\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n}\n\n// Each Field-shaping prop, with what takes its place on a `Field` the caller\n// wraps around the `Control`. `message` needs nothing there, because the\n// wrapper still renders it inside `Field > Control`. The other Field-level\n// props (`labelSize`, `labelProps`, `messageColor`) change nothing unless a\n// `label` or `message` renders, so on their own they keep no `Field`.\n// `bare-control.test.tsx` holds this list to what each wrapper hands its\n// `Field` and to which props change its markup, so a new Field-level prop\n// fails there until it is sorted into one group or the other.\nconst FIELD_SHAPING: ReadonlyArray<\n [keyof FieldShapingProps, string | undefined]\n> = [\n ['label', 'label'],\n ['message', undefined],\n ['horizontal', 'horizontal'],\n ['fieldClassName', 'className (for fieldClassName)'],\n];\n\n/** `a`, `a and b`, `a, b and c`. */\nconst listOf = (items: string[]): string =>\n items.length > 1\n ? `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`\n : items[0];\n\n/**\n * Whether a convenience form wrapper renders a `Field` of its own (#905).\n * Never inside an outer `Field`. Inside a `Control` with no `Field` around\n * it, a `Field` of its own would put a `.field` inside the `.control`, where\n * Bulma's control styles break (its icon rules are sibling selectors on the\n * input). So it renders one there only when a prop that shapes the `Field`'s\n * markup is set (`label`, `message`, `horizontal`, `fieldClassName`), keeping\n * the markup it always had, and warns in development that the fix is a\n * `Field` around that `Control`. A prop counts when it is truthy, the same\n * test that decides whether it changes the `Field`'s output.\n * Internal; not part of the public API.\n */\nexport const rendersOwnField = (\n component: string,\n options: OwnFieldOptions\n): boolean => {\n if (options.insideField) return false;\n if (!options.insideControl) return true;\n const held = FIELD_SHAPING.filter(([prop]) => options[prop]);\n if (held.length === 0) return false;\n const names = held.map(([prop]) => prop);\n const moved = held\n .map(([, onField]) => onField)\n .filter((onField): onField is string => onField !== undefined);\n warnOnce(\n `${component}:Field-in-bare-Control:${names.join('+')}`,\n `[bestax-bulma] <${component} ${names.join(' ')}> inside a <Control> ` +\n `with no <Field> around it renders its own <Field> for ` +\n `${names.length > 1 ? 'those props' : 'that prop'}, which puts a ` +\n `.field inside the .control, a nesting Bulma's styles are not ` +\n `written for. Wrap the <Control> in a <Field> instead` +\n (moved.length > 0 ? `, and set ${listOf(moved)} on that <Field>.` : '.')\n );\n return true;\n};\n\n/** The props a convenience form wrapper hands its own `Control`. Internal. */\nexport interface ControlLevelProps {\n /** Shows the `Control`'s loading spinner. */\n isLoading?: boolean;\n /** The `Control`'s left icon. */\n iconLeft?: ControlBaseProps['iconLeft'];\n /** Shortcut for the left icon's name. */\n iconLeftName?: string;\n /** Shortcut for the left icon's size. */\n iconLeftSize?: ControlBaseProps['iconLeftSize'];\n /** The `Control`'s right icon. */\n iconRight?: ControlBaseProps['iconRight'];\n /** Shortcut for the right icon's name. */\n iconRightName?: string;\n /** Shortcut for the right icon's size. */\n iconRightSize?: ControlBaseProps['iconRightSize'];\n /** Reserves the `Control`'s left icon space. */\n hasIconsLeft?: boolean;\n /** Reserves the `Control`'s right icon space. */\n hasIconsRight?: boolean;\n /** Expands the `Control`. */\n isExpanded?: boolean;\n /** Set on the `Control` as its `size`. */\n controlSize?: ControlBaseProps['size'];\n /** Set on the `Control` as its class. */\n controlClassName?: string;\n}\n\ninterface OwnControlOptions extends ControlLevelProps {\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n /** A picker's `inline`, which renders no `Control` inside one or out. */\n inline?: boolean;\n /**\n * The left glyph the wrapper's own `Control` shows when the caller sets no\n * `iconLeftName`; read only then. `bare-control.test.tsx` reads that glyph\n * from what each wrapper hands its own `Control`, so a wrapper that gains\n * one fails there until it passes it here.\n */\n defaultIconLeftName?: string;\n}\n\n// Each Control-level prop, with what takes its place on the `Control` the\n// caller wrapped around the wrapper. `bare-control.test.tsx` holds this to\n// what each wrapper hands its own `Control`, so a new Control-level prop\n// fails there until it is added here and passed to `rendersOwnControl`.\nconst ON_CONTROL: Record<keyof ControlLevelProps, string> = {\n isLoading: 'isLoading',\n iconLeft: 'iconLeft',\n iconLeftName: 'iconLeftName',\n iconLeftSize: 'iconLeftSize',\n iconRight: 'iconRight',\n iconRightName: 'iconRightName',\n iconRightSize: 'iconRightSize',\n hasIconsLeft: 'hasIconsLeft',\n hasIconsRight: 'hasIconsRight',\n isExpanded: 'isExpanded',\n controlSize: 'size (for controlSize)',\n controlClassName: 'className (for controlClassName)',\n};\n\n/**\n * Whether a convenience form wrapper renders a `Control` of its own (#921):\n * only outside one. Inside a `Control` it renders none, so the props it\n * would have handed its own do nothing there, and it warns in development,\n * naming them and saying to set them on that `Control`. An `inline` picker\n * renders none in either place, so it drops them inside a `Control` or not,\n * and its warning says so without pointing at a `Control`. A wrapper passes\n * only the props it hands its own `Control`, as the caller gave them, so a\n * default the wrapper fills in itself never warns. A prop counts when it is\n * truthy, since a falsy one would change nothing on a `Control` either.\n * `iconLeftSize` and `hasIconsLeft` show nothing on a `Control` without a\n * glyph, so when they move and the caller chose no left icon, the advice\n * names the wrapper's default glyph too, and following it draws what the\n * wrapper's own `Control` did.\n * Internal; not part of the public API.\n */\nexport const rendersOwnControl = (\n component: string,\n options: OwnControlOptions\n): boolean => {\n if (!options.inline && !options.insideControl) return true;\n const held = (\n Object.keys(ON_CONTROL) as Array<keyof ControlLevelProps>\n ).filter(prop => options[prop]);\n if (held.length === 0) return false;\n const names = held.join(' ');\n const doNothing = held.length > 1 ? 'those props do' : 'that prop does';\n let message: string;\n if (options.inline) {\n message =\n `[bestax-bulma] <${component} inline ${names}> renders no <Control> ` +\n `in inline mode, inside a <Control> or not, so ${doNothing} ` +\n `nothing. Leave ${held.length > 1 ? 'them' : 'it'} out of an ` +\n `inline picker.`;\n } else {\n const toSet = held.map(prop => ON_CONTROL[prop]);\n const needsGlyph =\n (options.iconLeftSize || options.hasIconsLeft) &&\n !options.iconLeft &&\n options.iconLeftName === undefined &&\n options.defaultIconLeftName;\n if (needsGlyph) {\n toSet.push(\n `iconLeftName=\"${options.defaultIconLeftName}\" (its default icon)`\n );\n }\n message =\n `[bestax-bulma] <${component} ${names}> inside a <Control> renders ` +\n `no <Control> of its own, so ${doNothing} nothing there. Set ` +\n `${listOf(toSet)} on that <Control> instead.`;\n }\n // Keyed by the message itself: the props named do not settle the advice\n // (an empty `iconLeftName` and an unset one name the same props), so two\n // calls that would advise differently must not share a key.\n warnOnce(message, message);\n return false;\n};\n\nconst FieldLabelIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id a labeled Field wants its single composed control to adopt (#495).\n * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the\n * user took over the association with an explicit `labelProps.htmlFor`.\n * Consumed by the single-control bases (InputBase, SelectBase, TextAreaBase)\n * and, through `useAutoLabelId`, by the convenience inputs that render an\n * input of their own (#939). Internal; not part of the public API.\n */\nexport const useFieldLabelId = () => useContext(FieldLabelIdContext);\n\n/** Provider for the Field label-target id — used internally by Field. */\nexport const FieldLabelIdProvider = FieldLabelIdContext.Provider;\n\nconst FieldLabelElementIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id of a labeled Field's own `<label>`, for a group control (Radios,\n * Checkboxes, Rate, DateRangeInput) to point `aria-labelledby` at, since a group cannot take\n * the label's `htmlFor` (#939). Set under the same conditions as\n * {@link useFieldLabelId}. Consumed through `useAutoLabelledBy`.\n * Internal; not part of the public API.\n */\nexport const useFieldLabelElementId = () =>\n useContext(FieldLabelElementIdContext);\n\n/** Provider for the Field label's own id, used internally by Field. */\nexport const FieldLabelElementIdProvider = FieldLabelElementIdContext.Provider;\n\nconst FieldLabelForContext = createContext<string | undefined>(undefined);\n\n/**\n * What the nearest labeled Field's `<label>` points `htmlFor` at: the id it\n * generated, or the caller's own `labelProps.htmlFor`. An unlabeled Field\n * passes it through, so a control in the inner Field of a horizontal layout\n * can tell the outer label names it. Only ever compared with a control's own\n * id, never adopted, so it hands out no id. Internal; not part of the public\n * API.\n */\nexport const useFieldLabelFor = () => useContext(FieldLabelForContext);\n\n/** Provider for the Field label's `htmlFor` target, used internally by Field. */\nexport const FieldLabelForProvider = FieldLabelForContext.Provider;\n\n/**\n * Shape of the Radios group context. The group provides:\n * - `name`: shared form field name (Stage 1)\n * - `value`: currently-selected radio value (Stage 2 — group-managed selection)\n * - `onChange`: dispatched by child Radios when clicked (Stage 2)\n *\n * Group sets `value`/`onChange` only when actively managing selection\n * (i.e., the user passed `value`, `defaultValue`, or `onChange` to `<Radios>`).\n * When only `name` is provided, the group is in \"name-only\" mode and child\n * Radios manage their own checked state independently.\n */\nexport interface RadiosGroupContextValue {\n name?: string;\n value?: string;\n onChange?: (value: string) => void;\n}\n\n/**\n * Shape of the Checkboxes group context. Like Radios but with array semantics\n * for multi-select.\n */\nexport interface CheckboxesGroupContextValue {\n name?: string;\n value?: string[];\n onChange?: (values: string[]) => void;\n}\n\nconst RadiosContext = createContext<RadiosGroupContextValue | undefined>(\n undefined\n);\nconst CheckboxesContext = createContext<\n CheckboxesGroupContextValue | undefined\n>(undefined);\n\n/**\n * Hook to read the full surrounding `<Radios>` group context (name + selection).\n * Returns `undefined` when not inside a `<Radios>` group.\n */\nexport const useRadiosGroup = () => useContext(RadiosContext);\n\n/**\n * Hook to read the full surrounding `<Checkboxes>` group context.\n * Returns `undefined` when not inside a `<Checkboxes>` group.\n */\nexport const useCheckboxesGroup = () => useContext(CheckboxesContext);\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Radios>` group.\n * Child `<Radio>` components fall back to this when no local `name` prop is set.\n * Returns `undefined` outside of a `<Radios>` group.\n */\nexport const useRadiosName = () => useRadiosGroup()?.name;\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Checkboxes>` group.\n * Returns `undefined` outside of a `<Checkboxes>` group.\n */\nexport const useCheckboxesName = () => useCheckboxesGroup()?.name;\n\n/** Provider for the Radios group context — used internally by Radios. */\nexport const RadiosProvider = RadiosContext.Provider;\n\n/** Provider for the Checkboxes group context — used internally by Checkboxes. */\nexport const CheckboxesProvider = CheckboxesContext.Provider;\n\n// --- Backward-compat aliases (Stage 1 names) -----------------------------\n// Internal callers may still import these. Both still work because they refer\n// to the same providers/hooks under the new shape.\n\n/** @deprecated Use `RadiosProvider` (provides {name, value, onChange}). */\nexport const RadiosNameProvider = RadiosProvider;\n\n/** @deprecated Use `CheckboxesProvider` (provides {name, value, onChange}). */\nexport const CheckboxesNameProvider = CheckboxesProvider;\n"],"names":[],"mappings":"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"}
@@ -72,7 +72,7 @@ fieldClassName, controlClassName,
72
72
  const helpClass = usePrefixedClassNames('help', {
73
73
  [`is-${messageColor}`]: !!messageColor,
74
74
  });
75
- let content = jsx(InputBase, { ref: ref, id: controlId, ...inputProps });
75
+ let content = jsx(InputBase, { ref: ref, ...inputProps, id: controlId });
76
76
  if (ownControl) {
77
77
  content = (jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
78
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../src/form/Input.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { usePrefixedClassNames } from '../helpers/classNames';\nimport { Field, FieldProps } from './Field';\nimport { Control, ControlBaseProps } from './Control';\nimport { InputBase, InputBaseProps } from './InputBase';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the Input component.\n *\n * Composes Field, Control, and Input into a single convenience component.\n * Supports all Input props, plus Field-level (label, horizontal) and\n * Control-level (icons, loading) props.\n * Inside an existing `Control` it renders no `Control` of its own, so its\n * Control-level props do nothing there and warn in development; set them on\n * that `Control` instead. Inside an outer `Field`, or a `Control` with no\n * `Field` around it, it renders no `Field` of its own either.\n * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that\n * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and\n * warns in development. Wrap the `Control` in a `Field` instead, and set the\n * `label`, `horizontal` and class name on that `Field`.\n */\nexport interface InputProps extends InputBaseProps {\n /** Field label. Automatically associated with the 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`). */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: FieldProps['labelSize'];\n /** Props for the label element when the component renders its own `Field`; dropped inside an outer `Field` (use that `Field`'s `labelProps` instead). An explicit `htmlFor` key — even `undefined` — overrides the automatic association and no id is generated. */\n labelProps?: FieldProps['labelProps'];\n /** Horizontal field layout. */\n horizontal?: boolean;\n /**\n * Icon props for left icon.\n * Bulma gives control icons `pointer-events: none`, so a clickable node here\n * never receives a click. Put a button beside the input in its own addon `Control` instead.\n */\n iconLeft?: ControlBaseProps['iconLeft'];\n /**\n * Icon props for right icon.\n * Bulma gives control icons `pointer-events: none`, so a clickable node here\n * never receives a click. Put a button beside the input in its own addon `Control` instead.\n */\n iconRight?: ControlBaseProps['iconRight'];\n /** Shortcut for left icon name. */\n iconLeftName?: string;\n /** Shortcut for right icon name. */\n iconRightName?: string;\n /** Shortcut for left icon size. */\n iconLeftSize?: ControlBaseProps['iconLeftSize'];\n /** Shortcut for right icon size. */\n iconRightSize?: ControlBaseProps['iconRightSize'];\n /** Force left icon container. */\n hasIconsLeft?: boolean;\n /** Force right icon container. */\n hasIconsRight?: boolean;\n /**\n * Shows a loading spinner on the `Control` it renders.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * The spinner sits at the right edge, where `iconRight` also sits, and the\n * two overlap; leave the right icon out while loading.\n */\n isLoading?: boolean;\n /** Expand the control. */\n isExpanded?: boolean;\n /** Control size. */\n controlSize?: ControlBaseProps['size'];\n /** Help/validation message below the input. */\n message?: React.ReactNode;\n /** Bulma color for the message. */\n messageColor?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Additional CSS classes for the Field. */\n fieldClassName?: string;\n /** Additional CSS classes for the Control. */\n controlClassName?: string;\n}\n\n/**\n * The `Input` component provides a Bulma-styled text input, supporting colors, sizes, rounded corners, static state, hover/focus/loading states, and all Bulma helper props.\n *\n * @function\n * @param {InputProps} props - Props for Input.\n * @returns {JSX.Element} The composed field element.\n *\n * @example\n * <Input label=\"Username\" placeholder=\"Enter username\" iconLeftName=\"user\" />\n *\n * @example\n * <Input\n * label=\"Email\"\n * type=\"email\"\n * message=\"Please enter a valid email\"\n * messageColor=\"danger\"\n * color=\"danger\"\n * />\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n // Control props\n iconLeft,\n iconRight,\n iconLeftName,\n iconRightName,\n iconLeftSize,\n iconRightSize,\n hasIconsLeft,\n hasIconsRight,\n isLoading,\n isExpanded,\n controlSize,\n // Message props\n message,\n messageColor,\n // Container class overrides\n fieldClassName,\n controlClassName,\n // Everything else goes to Input\n ...inputProps\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Input', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const ownControl = rendersOwnControl('Input', {\n insideControl,\n isLoading,\n iconLeft,\n iconLeftName,\n iconLeftSize,\n iconRight,\n iconRightName,\n iconRightSize,\n hasIconsLeft,\n hasIconsRight,\n isExpanded,\n controlSize,\n controlClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: inputProps.id,\n labelProps,\n rendersLabel: ownField,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n let content = <InputBase ref={ref} id={controlId} {...inputProps} />;\n\n if (ownControl) {\n content = (\n <Control\n iconLeft={iconLeft}\n iconRight={iconRight}\n iconLeftName={iconLeftName}\n iconRightName={iconRightName}\n iconLeftSize={iconLeftSize}\n iconRightSize={iconRightSize}\n hasIconsLeft={hasIconsLeft}\n hasIconsRight={hasIconsRight}\n isLoading={isLoading}\n isExpanded={isExpanded}\n size={controlSize}\n className={controlClassName}\n >\n {content}\n </Control>\n );\n }\n\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nInput.displayName = 'Input';\n\nexport default Input;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;AAmFA;;;;;;;;;;;;;;;;;;AAkBG;AACI,MAAM,KAAK,GAAG,UAAU,CAC7B,CACE;AACE;AACA,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU;AACV;AACA,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,SAAS,EACT,UAAU,EACV,WAAW;AACX;AACA,OAAO,EACP,YAAY;AACZ;AACA,cAAc,EACd,gBAAgB;AAChB;AACA,GAAG,UAAU,EACd,EACD,GAAG,KACD;AACF,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;AACpC,IAAA,MAAM,aAAa,GAAG,gBAAgB,EAAE;AACxC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE;QACxC,WAAW;QACX,aAAa;QACb,KAAK;QACL,OAAO;QACP,UAAU;QACV,cAAc;AACf,KAAA,CAAC;AACF,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,EAAE;QAC5C,aAAa;QACb,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,YAAY;QACZ,SAAS;QACT,aAAa;QACb,aAAa;QACb,YAAY;QACZ,aAAa;QACb,UAAU;QACV,WAAW;QACX,gBAAgB;AACjB,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,cAAc,CAAC;QACpD,KAAK;QACL,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,UAAU;AACV,QAAA,YAAY,EAAE,QAAQ;AACvB,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,YAAY,CAAA,CAAE,GAAG,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC;AAEF,IAAA,IAAI,OAAO,GAAGA,GAAA,CAAC,SAAS,IAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAA,GAAM,UAAU,GAAI;IAEpE,IAAI,UAAU,EAAE;QACd,OAAO,IACLA,GAAA,CAAC,OAAO,EAAA,EACN,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAE1B,OAAO,EAAA,CACA,CACX;IACH;AAEA,IAAA,MAAM,SAAS,GAAG,OAAO,GAAGA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,SAAS,YAAG,OAAO,EAAA,CAAK,GAAG,IAAI;IAEzE,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEC,IAAA,CAAC,KAAK,EAAA,EACJ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAExB,OAAO,EACP,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,OAAO,EACP,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;"}
1
+ {"version":3,"file":"Input.js","sources":["../../../src/form/Input.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { usePrefixedClassNames } from '../helpers/classNames';\nimport { Field, FieldProps } from './Field';\nimport { Control, ControlBaseProps } from './Control';\nimport { InputBase, InputBaseProps } from './InputBase';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n} from './FormContext';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the Input component.\n *\n * Composes Field, Control, and Input into a single convenience component.\n * Supports all Input props, plus Field-level (label, horizontal) and\n * Control-level (icons, loading) props.\n * Inside an existing `Control` it renders no `Control` of its own, so its\n * Control-level props do nothing there and warn in development; set them on\n * that `Control` instead. Inside an outer `Field`, or a `Control` with no\n * `Field` around it, it renders no `Field` of its own either.\n * The exception is `label`, `message`, `horizontal` or `fieldClassName` in that\n * bare `Control`: it keeps a `Field` for them, nested in the `.control`, and\n * warns in development. Wrap the `Control` in a `Field` instead, and set the\n * `label`, `horizontal` and class name on that `Field`.\n */\nexport interface InputProps extends InputBaseProps {\n /** Field label. Automatically associated with the 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`). */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: FieldProps['labelSize'];\n /** Props for the label element when the component renders its own `Field`; dropped inside an outer `Field` (use that `Field`'s `labelProps` instead). An explicit `htmlFor` key — even `undefined` — overrides the automatic association and no id is generated. */\n labelProps?: FieldProps['labelProps'];\n /** Horizontal field layout. */\n horizontal?: boolean;\n /**\n * Icon props for left icon.\n * Bulma gives control icons `pointer-events: none`, so a clickable node here\n * never receives a click. Put a button beside the input in its own addon `Control` instead.\n */\n iconLeft?: ControlBaseProps['iconLeft'];\n /**\n * Icon props for right icon.\n * Bulma gives control icons `pointer-events: none`, so a clickable node here\n * never receives a click. Put a button beside the input in its own addon `Control` instead.\n */\n iconRight?: ControlBaseProps['iconRight'];\n /** Shortcut for left icon name. */\n iconLeftName?: string;\n /** Shortcut for right icon name. */\n iconRightName?: string;\n /** Shortcut for left icon size. */\n iconLeftSize?: ControlBaseProps['iconLeftSize'];\n /** Shortcut for right icon size. */\n iconRightSize?: ControlBaseProps['iconRightSize'];\n /** Force left icon container. */\n hasIconsLeft?: boolean;\n /** Force right icon container. */\n hasIconsRight?: boolean;\n /**\n * Shows a loading spinner on the `Control` it renders.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * The spinner sits at the right edge, where `iconRight` also sits, and the\n * two overlap; leave the right icon out while loading.\n */\n isLoading?: boolean;\n /** Expand the control. */\n isExpanded?: boolean;\n /** Control size. */\n controlSize?: ControlBaseProps['size'];\n /** Help/validation message below the input. */\n message?: React.ReactNode;\n /** Bulma color for the message. */\n messageColor?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Additional CSS classes for the Field. */\n fieldClassName?: string;\n /** Additional CSS classes for the Control. */\n controlClassName?: string;\n}\n\n/**\n * The `Input` component provides a Bulma-styled text input, supporting colors, sizes, rounded corners, static state, hover/focus/loading states, and all Bulma helper props.\n *\n * @function\n * @param {InputProps} props - Props for Input.\n * @returns {JSX.Element} The composed field element.\n *\n * @example\n * <Input label=\"Username\" placeholder=\"Enter username\" iconLeftName=\"user\" />\n *\n * @example\n * <Input\n * label=\"Email\"\n * type=\"email\"\n * message=\"Please enter a valid email\"\n * messageColor=\"danger\"\n * color=\"danger\"\n * />\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n // Control props\n iconLeft,\n iconRight,\n iconLeftName,\n iconRightName,\n iconLeftSize,\n iconRightSize,\n hasIconsLeft,\n hasIconsRight,\n isLoading,\n isExpanded,\n controlSize,\n // Message props\n message,\n messageColor,\n // Container class overrides\n fieldClassName,\n controlClassName,\n // Everything else goes to Input\n ...inputProps\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Input', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const ownControl = rendersOwnControl('Input', {\n insideControl,\n isLoading,\n iconLeft,\n iconLeftName,\n iconLeftSize,\n iconRight,\n iconRightName,\n iconRightSize,\n hasIconsLeft,\n hasIconsRight,\n isExpanded,\n controlSize,\n controlClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: inputProps.id,\n labelProps,\n rendersLabel: ownField,\n });\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n let content = <InputBase ref={ref} {...inputProps} id={controlId} />;\n\n if (ownControl) {\n content = (\n <Control\n iconLeft={iconLeft}\n iconRight={iconRight}\n iconLeftName={iconLeftName}\n iconRightName={iconRightName}\n iconLeftSize={iconLeftSize}\n iconRightSize={iconRightSize}\n hasIconsLeft={hasIconsLeft}\n hasIconsRight={hasIconsRight}\n isLoading={isLoading}\n isExpanded={isExpanded}\n size={controlSize}\n className={controlClassName}\n >\n {content}\n </Control>\n );\n }\n\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nInput.displayName = 'Input';\n\nexport default Input;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;AAmFA;;;;;;;;;;;;;;;;;;AAkBG;AACI,MAAM,KAAK,GAAG,UAAU,CAC7B,CACE;AACE;AACA,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU;AACV;AACA,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,SAAS,EACT,UAAU,EACV,WAAW;AACX;AACA,OAAO,EACP,YAAY;AACZ;AACA,cAAc,EACd,gBAAgB;AAChB;AACA,GAAG,UAAU,EACd,EACD,GAAG,KACD;AACF,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;AACpC,IAAA,MAAM,aAAa,GAAG,gBAAgB,EAAE;AACxC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE;QACxC,WAAW;QACX,aAAa;QACb,KAAK;QACL,OAAO;QACP,UAAU;QACV,cAAc;AACf,KAAA,CAAC;AACF,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,EAAE;QAC5C,aAAa;QACb,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,YAAY;QACZ,SAAS;QACT,aAAa;QACb,aAAa;QACb,YAAY;QACZ,aAAa;QACb,UAAU;QACV,WAAW;QACX,gBAAgB;AACjB,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,cAAc,CAAC;QACpD,KAAK;QACL,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,UAAU;AACV,QAAA,YAAY,EAAE,QAAQ;AACvB,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,YAAY,CAAA,CAAE,GAAG,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC;AAEF,IAAA,IAAI,OAAO,GAAGA,GAAA,CAAC,SAAS,IAAC,GAAG,EAAE,GAAG,EAAA,GAAM,UAAU,EAAE,EAAE,EAAE,SAAS,GAAI;IAEpE,IAAI,UAAU,EAAE;QACd,OAAO,IACLA,GAAA,CAAC,OAAO,EAAA,EACN,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAE1B,OAAO,EAAA,CACA,CACX;IACH;AAEA,IAAA,MAAM,SAAS,GAAG,OAAO,GAAGA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,SAAS,YAAG,OAAO,EAAA,CAAK,GAAG,IAAI;IAEzE,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEC,IAAA,CAAC,KAAK,EAAA,EACJ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAExB,OAAO,EACP,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,OAAO,EACP,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;"}
@@ -148,7 +148,9 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
148
148
  }
149
149
  };
150
150
  // Shared input element
151
- const inputControl = (jsx("div", { className: expandedControlClasses, children: jsx("input", { ref: combinedRef, type: "number", className: inputClasses, value: currentValue ?? '', min: min, max: max, step: step, disabled: disabled, readOnly: !editable, onChange: handleInputChange, onKeyDown: handleKeyDown, "aria-valuenow": currentValue ?? undefined, "aria-valuemin": min, "aria-valuemax": max, id: controlId, ...rest }) }));
151
+ const inputControl = (jsx("div", { className: expandedControlClasses, children: jsx("input", { ref: combinedRef, type: "number", className: inputClasses, value: currentValue ?? '', min: min, max: max, step: step, disabled: disabled, readOnly: !editable, onChange: handleInputChange, onKeyDown: handleKeyDown, "aria-valuenow": currentValue ?? undefined, "aria-valuemin": min, "aria-valuemax": max, ...rest,
152
+ // After the spread: an undefined `id` key in rest would wipe it.
153
+ id: controlId }) }));
152
154
  // Stepper variant
153
155
  if (isStepper) {
154
156
  const stepperElement = (jsxs("div", { className: combinedClasses, children: [inputControl, jsx("div", { className: controlClasses, children: jsxs("div", { className: stepperClasses, children: [jsx("button", { type: "button", className: stepperButtonClasses, onClick: handleIncrement, disabled: disabled || isAtMax, tabIndex: -1, "aria-label": "Increase value", children: jsx(ArrowDropUp, {}) }), jsx("button", { type: "button", className: stepperButtonClasses, onClick: handleDecrement, disabled: disabled || isAtMin, tabIndex: -1, "aria-label": "Decrease value", children: jsx(ArrowDropDown, {}) })] }) })] }));
@@ -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. Not wired when no Field wrapper is rendered (inside a `Field`, or plusminus `bare`). */\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 id={controlId}\n {...rest}\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 * @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`). 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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"}
@@ -49,6 +49,7 @@ const RadiosComponent = ({ label, labelSize, labelProps, horizontal, message, me
49
49
  label,
50
50
  labelProps,
51
51
  rendersLabel: ownField,
52
+ callerProps: props,
52
53
  });
53
54
  const { bulmaHelperClasses, rest } = useBulmaClasses({
54
55
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"Radios.js","sources":["../../../src/form/Radios.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n RadiosProvider,\n RadiosGroupContextValue,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\nimport { Radio } from './Radio';\n\n/**\n * Props for the Radios component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n */\nexport interface RadiosProps\n extends Omit<BulmaClassesProps, 'color'>, FormFieldProps {\n /** Field label naming the whole group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` wrapper — uses your `labelProps.id` when provided, otherwise a generated one. Dropped inside an outer `Field` (label that `Field` yourself). */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Additional CSS classes to apply. */\n className?: string;\n /** Form field name shared by every Radio in the group (via context). */\n name?: string;\n /** Currently-selected value (controlled mode). */\n value?: string;\n /** Initial selected value (uncontrolled mode). */\n defaultValue?: string;\n /** Fires when the selection changes. */\n onChange?: (value: string) => void;\n /** Radio elements to render in the group. */\n children: React.ReactNode;\n}\n\n/**\n * The `Radios` component wraps multiple `Radio` components in a Bulma-styled group.\n *\n * @function\n * @param {RadiosProps} props - Props for the Radios component.\n * @returns {JSX.Element} The rendered radios group.\n * @see {@link https://bulma.io/documentation/form/radio/#grouped-radios | Bulma Radios documentation}\n *\n * @example\n * // Controlled\n * const [color, setColor] = useState('red');\n * <Radios name=\"color\" value={color} onChange={setColor}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n *\n * @example\n * // Uncontrolled\n * <Radios name=\"color\" defaultValue=\"red\" onChange={v => console.log(v)}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * </Radios>\n */\nconst RadiosComponent: React.FC<RadiosProps> = ({\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n name,\n value,\n defaultValue,\n onChange,\n children,\n className,\n ...props\n}) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Radios', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('radios');\n const wrapperClass = classNames(mainClass, bulmaHelperClasses, className);\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The group is \"active\" (manages child selection) when the user opted in by\n // passing value, defaultValue, or onChange. Otherwise it's name-only and\n // children manage their own checked state (Stage 1 behavior).\n const groupActive =\n value !== undefined || defaultValue !== undefined || onChange !== undefined;\n\n const [internalValue, setInternalValue] = useState<string | undefined>(\n defaultValue\n );\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n const ctx = useMemo<RadiosGroupContextValue>(\n () => ({\n name,\n ...(groupActive ? { value: currentValue, onChange: handleChange } : {}),\n }),\n [name, groupActive, currentValue, handleChange]\n );\n\n const radiosElement = (\n <div\n className={wrapperClass}\n role=\"radiogroup\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n <RadiosProvider value={ctx}>{children}</RadiosProvider>\n </div>\n );\n\n let content = radiosElement;\n\n if (rendersOwnControl('Radios', { insideControl })) {\n content = <Control>{content}</Control>;\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 {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n};\n\nexport const Radios = withSubComponents(RadiosComponent, { Radio }, 'Radios');\n\nexport default Radios;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;;;AAkDA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACH,MAAM,eAAe,GAA0B,CAAC,EAC9C,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,KAAI;AACH,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;AACpC,IAAA,MAAM,aAAa,GAAG,gBAAgB,EAAE;AACxC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE;QACzC,WAAW;QACX,aAAa;QACb,KAAK;QACL,OAAO;QACP,UAAU;QACV,cAAc;AACf,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,iBAAiB,CAAC;QAC5D,KAAK;QACL,UAAU;AACV,QAAA,YAAY,EAAE,QAAQ;AACvB,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;AAEF,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,QAAQ,CAAC;IACjD,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,EAAE,kBAAkB,EAAE,SAAS,CAAC;AAEzE,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,YAAY,CAAA,CAAE,GAAG,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,OAAO,GAAGA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,SAAS,YAAG,OAAO,EAAA,CAAK,GAAG,IAAI;;;;AAKzE,IAAA,MAAM,WAAW,GACf,KAAK,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;IAE7E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAChD,YAAY,CACb;AACD,IAAA,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;IACxC,MAAM,YAAY,GAAG,YAAY,GAAG,KAAK,GAAG,aAAa;AAEzD,IAAA,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,QAAgB,KAAI;AACnB,QAAA,IAAI,CAAC,YAAY;YAAE,gBAAgB,CAAC,QAAQ,CAAC;AAC7C,QAAA,QAAQ,GAAG,QAAQ,CAAC;AACtB,IAAA,CAAC,EACD,CAAC,YAAY,EAAE,QAAQ,CAAC,CACzB;AAED,IAAA,MAAM,GAAG,GAAG,OAAO,CACjB,OAAO;QACL,IAAI;AACJ,QAAA,IAAI,WAAW,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;KACxE,CAAC,EACF,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,CAAC,CAChD;IAED,MAAM,aAAa,IACjBA,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAE,YAAY,EACvB,IAAI,EAAC,YAAY,EAAA,iBAAA,EACA,cAAc,EAAA,GAC3B,IAAI,EAAA,QAAA,EAERA,GAAA,CAAC,cAAc,EAAA,EAAC,KAAK,EAAE,GAAG,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAkB,EAAA,CACnD,CACP;IAED,IAAI,OAAO,GAAG,aAAa;IAE3B,IAAI,iBAAiB,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE;AAClD,QAAA,OAAO,GAAGA,GAAA,CAAC,OAAO,EAAA,EAAA,QAAA,EAAE,OAAO,GAAW;IACxC;IAEA,IAAI,QAAQ,EAAE;AACZ,QAAA,QACEC,IAAA,CAAC,KAAK,EAAA,EACJ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAExB,OAAO,EACP,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,OAAO,EACP,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAEM,MAAM,MAAM,GAAG,iBAAiB,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ;;"}
1
+ {"version":3,"file":"Radios.js","sources":["../../../src/form/Radios.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n RadiosProvider,\n RadiosGroupContextValue,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\nimport { Radio } from './Radio';\n\n/**\n * Props for the Radios component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n */\nexport interface RadiosProps\n extends Omit<BulmaClassesProps, 'color'>, FormFieldProps {\n /** Field label naming the whole group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` wrapper — uses your `labelProps.id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label names the group instead through `aria-labelledby` when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`). An `aria-label` or `aria-labelledby` you set on the group wins over either label, which still renders but no longer names it. An `aria-labelledby` key counts even when undefined, since it is spread over the group's own. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Additional CSS classes to apply. */\n className?: string;\n /** Form field name shared by every Radio in the group (via context). */\n name?: string;\n /** Currently-selected value (controlled mode). */\n value?: string;\n /** Initial selected value (uncontrolled mode). */\n defaultValue?: string;\n /** Fires when the selection changes. */\n onChange?: (value: string) => void;\n /** Radio elements to render in the group. */\n children: React.ReactNode;\n}\n\n/**\n * The `Radios` component wraps multiple `Radio` components in a Bulma-styled group.\n *\n * @function\n * @param {RadiosProps} props - Props for the Radios component.\n * @returns {JSX.Element} The rendered radios group.\n * @see {@link https://bulma.io/documentation/form/radio/#grouped-radios | Bulma Radios documentation}\n *\n * @example\n * // Controlled\n * const [color, setColor] = useState('red');\n * <Radios name=\"color\" value={color} onChange={setColor}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n *\n * @example\n * // Uncontrolled\n * <Radios name=\"color\" defaultValue=\"red\" onChange={v => console.log(v)}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * </Radios>\n */\nconst RadiosComponent: React.FC<RadiosProps> = ({\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n name,\n value,\n defaultValue,\n onChange,\n children,\n className,\n ...props\n}) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Radios', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('radios');\n const wrapperClass = classNames(mainClass, bulmaHelperClasses, className);\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The group is \"active\" (manages child selection) when the user opted in by\n // passing value, defaultValue, or onChange. Otherwise it's name-only and\n // children manage their own checked state (Stage 1 behavior).\n const groupActive =\n value !== undefined || defaultValue !== undefined || onChange !== undefined;\n\n const [internalValue, setInternalValue] = useState<string | undefined>(\n defaultValue\n );\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n const ctx = useMemo<RadiosGroupContextValue>(\n () => ({\n name,\n ...(groupActive ? { value: currentValue, onChange: handleChange } : {}),\n }),\n [name, groupActive, currentValue, handleChange]\n );\n\n const radiosElement = (\n <div\n className={wrapperClass}\n role=\"radiogroup\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n <RadiosProvider value={ctx}>{children}</RadiosProvider>\n </div>\n );\n\n let content = radiosElement;\n\n if (rendersOwnControl('Radios', { insideControl })) {\n content = <Control>{content}</Control>;\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 {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n};\n\nexport const Radios = withSubComponents(RadiosComponent, { Radio }, 'Radios');\n\nexport default Radios;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -61,6 +61,7 @@ const Rate = forwardRef(({ label, labelSize, labelProps, horizontal, message, me
61
61
  label,
62
62
  labelProps,
63
63
  rendersLabel: ownField,
64
+ callerProps: props,
64
65
  });
65
66
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
66
67
  const starBaseId = useId();