@allxsmith/bestax-bulma 5.45.1 → 5.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/form/Checkbox.js.map +1 -1
- package/dist/esm/form/File.js.map +1 -1
- package/dist/esm/form/Numberinput.js.map +1 -1
- package/dist/esm/form/PinInput.js.map +1 -1
- package/dist/esm/form/Radio.js.map +1 -1
- package/dist/esm/form/SelectBase.js.map +1 -1
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/Switch.js.map +1 -1
- package/dist/esm/helpers/Theme.js +191 -49
- package/dist/esm/helpers/Theme.js.map +1 -1
- package/dist/esm/helpers/useVisibilityClasses.js.map +1 -1
- package/dist/index.cjs +190 -49
- package/dist/index.cjs.map +1 -1
- package/dist/types/form/Checkbox.d.ts +3 -0
- package/dist/types/form/File.d.ts +3 -0
- package/dist/types/form/Numberinput.d.ts +2 -0
- package/dist/types/form/PinInput.d.ts +3 -0
- package/dist/types/form/Radio.d.ts +3 -0
- package/dist/types/form/SelectBase.d.ts +3 -0
- package/dist/types/form/Slider.d.ts +3 -0
- package/dist/types/form/Switch.d.ts +2 -0
- package/dist/types/helpers/Theme.d.ts +37 -10
- package/dist/types/helpers/useVisibilityClasses.d.ts +5 -1
- package/dist/types-cjs/form/Checkbox.d.ts +3 -0
- package/dist/types-cjs/form/File.d.ts +3 -0
- package/dist/types-cjs/form/Numberinput.d.ts +2 -0
- package/dist/types-cjs/form/PinInput.d.ts +3 -0
- package/dist/types-cjs/form/Radio.d.ts +3 -0
- package/dist/types-cjs/form/SelectBase.d.ts +3 -0
- package/dist/types-cjs/form/Slider.d.ts +3 -0
- package/dist/types-cjs/form/Switch.d.ts +2 -0
- package/dist/types-cjs/helpers/Theme.d.ts +37 -10
- package/dist/types-cjs/helpers/useVisibilityClasses.d.ts +5 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","sources":["../../../src/form/Checkbox.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useCheckboxesGroup } from './FormContext';\n\n/**\n * The values the Checkbox `color` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Checkbox, checkboxColors } from '@allxsmith/bestax-bulma';\n *\n * checkboxColors.map(color => (\n * <Checkbox key={color} color={color}>\n * {color}\n * </Checkbox>\n * ));\n */\nexport const checkboxColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Checkbox `size` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['size']` is typed from it, so the two list the same values.\n * Use it to offer a size choice or to check a value that arrives at runtime:\n * the component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { checkboxSizes } from '@allxsmith/bestax-bulma';\n *\n * type CheckboxSize = (typeof checkboxSizes)[number];\n */\nexport const checkboxSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Checkbox component.\n */\nexport interface CheckboxProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the checkbox. */\n color?: (typeof checkboxColors)[number];\n /** Size of the checkbox. */\n size?: (typeof checkboxSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the checkbox is disabled. */\n disabled?: boolean;\n /**\n * Shows the mixed state, as in a \"Select all\" box when some of what it\n * covers is checked. It's a look and an announcement only: `checked` is\n * still the value, and a click still toggles `checked`. Set to `true` or\n * `false`, it's controlled: a browser clears the mixed state on a click,\n * so the component sets it again from this prop after every click and\n * every render. Unset isn't `false`. The component leaves the input's own\n * `indeterminate` property alone, so a ref can set it, and going from set\n * to unset clears it once and hands it back. It has no HTML attribute, so\n * server-rendered markup can't carry it, and a mixed box renders unmixed\n * until hydration.\n */\n indeterminate?: boolean;\n /**\n * Additional CSS classes, on the outer `<label>`. That's the element that\n * declares the `--bulma-checkbox-*` variables, so a class is how to set\n * one: `style` and the other input attributes go to the `<input>`. Name\n * `.styled-checkbox` beside your class in the selector, so it beats the\n * label's own declaration whatever order the stylesheets load in. A\n * `color` prop declares the fills again on `.styled-checkbox.is-<color>`,\n * which ties that selector, so leave `color` unset when a class sets them.\n */\n className?: string;\n /** The label/content for the checkbox. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Checkbox` component provides a Bulma-styled checkbox input.\n *\n * @function\n * @param {CheckboxProps} props - Props for the Checkbox component.\n * @returns {JSX.Element} The rendered checkbox element.\n *\n * @example\n * // Basic checkbox\n * <Checkbox>Accept terms</Checkbox>\n *\n * @example\n * // Inside a group\n * <Checkboxes name=\"tags\" defaultValue={['react']}>\n * <Checkbox value=\"react\">React</Checkbox>\n * <Checkbox value=\"vue\">Vue</Checkbox>\n * </Checkboxes>\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n indeterminate,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // The input's own ref, merged with the forwarded one. A callback ref's\n // return value is handed back, so React 19 still runs a cleanup it\n // returns, as it did when the ref went straight to the input.\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n\n // `indeterminate` is a DOM property with no attribute, so it's set on the\n // input rather than rendered. A click clears it, so this runs after every\n // render, not only when the prop changes. Unset, it's left alone, so a\n // ref that sets the property itself still works. `ownsIndeterminateRef`\n // remembers that this component set it, so a prop that goes back to unset\n // clears the dash once instead of leaving it on.\n const ownsIndeterminateRef = useRef(false);\n useClientLayoutEffect(() => {\n if (indeterminate !== undefined) {\n ownsIndeterminateRef.current = true;\n inputRef.current!.indeterminate = indeterminate;\n } else if (ownsIndeterminateRef.current) {\n ownsIndeterminateRef.current = false;\n inputRef.current!.indeterminate = false;\n }\n });\n\n // Inherit name + selection state from a surrounding <Checkboxes> group.\n // Local props always win over the group (explicit > implicit).\n const group = useCheckboxesGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Checkbox\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const groupHas = groupManaged && group!.value!.includes(String(value));\n const effectiveChecked =\n checked !== undefined ? checked : groupManaged ? groupHas : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // The click that got here cleared the mixed state. Put it back now,\n // since a click that changes no state renders nothing to do it.\n if (indeterminate !== undefined) e.target.indeterminate = indeterminate;\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — toggle this value's\n // membership in the group's array.\n if (group?.onChange && value !== undefined) {\n const valStr = String(value);\n const currentArr = group.value ?? [];\n const next = e.target.checked\n ? currentArr.includes(valStr)\n ? currentArr\n : [...currentArr, valStr]\n : currentArr.filter(v => v !== valStr);\n group.onChange(next);\n }\n },\n [onChange, group, value, indeterminate]\n );\n\n const mainClass = usePrefixedClassNames('styled-checkbox', 'checkbox', {\n [`is-${color}`]: color && checkboxColors.includes(color),\n [`is-${size}`]: size && checkboxSizes.includes(size),\n });\n const checkboxClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={checkboxClass}>\n <input\n ref={setRefs}\n type=\"checkbox\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nCheckbox.displayName = 'Checkbox';\n\nexport default Checkbox;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sources":["../../../src/form/Checkbox.tsx"],"sourcesContent":["import React, { forwardRef, useCallback, useRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { useCheckboxesGroup } from './FormContext';\n\n/**\n * The values the Checkbox `color` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Checkbox, checkboxColors } from '@allxsmith/bestax-bulma';\n *\n * checkboxColors.map(color => (\n * <Checkbox key={color} color={color}>\n * {color}\n * </Checkbox>\n * ));\n */\nexport const checkboxColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Checkbox `size` prop accepts, as a readonly tuple.\n *\n * `CheckboxProps['size']` is typed from it, so the two list the same values.\n * Use it to offer a size choice or to check a value that arrives at runtime:\n * the component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { checkboxSizes } from '@allxsmith/bestax-bulma';\n *\n * type CheckboxSize = (typeof checkboxSizes)[number];\n */\nexport const checkboxSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Checkbox component.\n *\n * @helperProps Helper props go on the outer `<label>`, with `className`. The\n * other attributes go on the `<input>`.\n */\nexport interface CheckboxProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the checkbox. */\n color?: (typeof checkboxColors)[number];\n /** Size of the checkbox. */\n size?: (typeof checkboxSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the checkbox is disabled. */\n disabled?: boolean;\n /**\n * Shows the mixed state, as in a \"Select all\" box when some of what it\n * covers is checked. It's a look and an announcement only: `checked` is\n * still the value, and a click still toggles `checked`. Set to `true` or\n * `false`, it's controlled: a browser clears the mixed state on a click,\n * so the component sets it again from this prop after every click and\n * every render. Unset isn't `false`. The component leaves the input's own\n * `indeterminate` property alone, so a ref can set it, and going from set\n * to unset clears it once and hands it back. It has no HTML attribute, so\n * server-rendered markup can't carry it, and a mixed box renders unmixed\n * until hydration.\n */\n indeterminate?: boolean;\n /**\n * Additional CSS classes, on the outer `<label>`. That's the element that\n * declares the `--bulma-checkbox-*` variables, so a class is how to set\n * one: `style` and the other input attributes go to the `<input>`. Name\n * `.styled-checkbox` beside your class in the selector, so it beats the\n * label's own declaration whatever order the stylesheets load in. A\n * `color` prop declares the fills again on `.styled-checkbox.is-<color>`,\n * which ties that selector, so leave `color` unset when a class sets them.\n */\n className?: string;\n /** The label/content for the checkbox. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Checkbox` component provides a Bulma-styled checkbox input.\n *\n * @function\n * @param {CheckboxProps} props - Props for the Checkbox component.\n * @returns {JSX.Element} The rendered checkbox element.\n *\n * @example\n * // Basic checkbox\n * <Checkbox>Accept terms</Checkbox>\n *\n * @example\n * // Inside a group\n * <Checkboxes name=\"tags\" defaultValue={['react']}>\n * <Checkbox value=\"react\">React</Checkbox>\n * <Checkbox value=\"vue\">Vue</Checkbox>\n * </Checkboxes>\n */\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n indeterminate,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // The input's own ref, merged with the forwarded one. A callback ref's\n // return value is handed back, so React 19 still runs a cleanup it\n // returns, as it did when the ref went straight to the input.\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n\n // `indeterminate` is a DOM property with no attribute, so it's set on the\n // input rather than rendered. A click clears it, so this runs after every\n // render, not only when the prop changes. Unset, it's left alone, so a\n // ref that sets the property itself still works. `ownsIndeterminateRef`\n // remembers that this component set it, so a prop that goes back to unset\n // clears the dash once instead of leaving it on.\n const ownsIndeterminateRef = useRef(false);\n useClientLayoutEffect(() => {\n if (indeterminate !== undefined) {\n ownsIndeterminateRef.current = true;\n inputRef.current!.indeterminate = indeterminate;\n } else if (ownsIndeterminateRef.current) {\n ownsIndeterminateRef.current = false;\n inputRef.current!.indeterminate = false;\n }\n });\n\n // Inherit name + selection state from a surrounding <Checkboxes> group.\n // Local props always win over the group (explicit > implicit).\n const group = useCheckboxesGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Checkbox\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const groupHas = groupManaged && group!.value!.includes(String(value));\n const effectiveChecked =\n checked !== undefined ? checked : groupManaged ? groupHas : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // The click that got here cleared the mixed state. Put it back now,\n // since a click that changes no state renders nothing to do it.\n if (indeterminate !== undefined) e.target.indeterminate = indeterminate;\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — toggle this value's\n // membership in the group's array.\n if (group?.onChange && value !== undefined) {\n const valStr = String(value);\n const currentArr = group.value ?? [];\n const next = e.target.checked\n ? currentArr.includes(valStr)\n ? currentArr\n : [...currentArr, valStr]\n : currentArr.filter(v => v !== valStr);\n group.onChange(next);\n }\n },\n [onChange, group, value, indeterminate]\n );\n\n const mainClass = usePrefixedClassNames('styled-checkbox', 'checkbox', {\n [`is-${color}`]: color && checkboxColors.includes(color),\n [`is-${size}`]: size && checkboxSizes.includes(size),\n });\n const checkboxClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={checkboxClass}>\n <input\n ref={setRefs}\n type=\"checkbox\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nCheckbox.displayName = 'Checkbox';\n\nexport default Checkbox;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"File.js","sources":["../../../src/form/File.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useState } from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useConfig } from '../helpers/Config';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n} from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the File component.\n * Inside an outer `Field`, or a `Control` with no `Field` around it, it\n * renders no `Field` of its own. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n */\nexport interface FileProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'color' | 'type'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label. Automatically associated with the file input via `htmlFor` — uses your `id` when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping `file-label`); assistive tech reads both. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Bulma color modifier for the file input. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Size modifier for the file input. */\n size?: 'small' | 'medium' | 'large';\n /** Boxed file input. */\n isBoxed?: boolean;\n /** Whether the file input expands to full width. */\n isFullwidth?: boolean;\n /** Whether the file input expands to full width. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Position the CTA on the right (with `hasName`). */\n isRight?: boolean;\n /** Center the file input within its container. */\n isCentered?: boolean;\n /**\n * Show a file name area. Without `fileName` it shows what the user picked: the file's name, or\n * a count when `multiple` lets them pick several (see `pickedFilesLabel`). Before a pick there is\n * no name area, and the root takes Bulma's `is-empty`. A reset of the input's form clears the\n * name, but clearing the input from code fires no change event and leaves it showing, so pass\n * `fileName` to control the text then.\n */\n hasName?: boolean;\n /** Text on the file CTA button (defaults to \"Choose a file…\"). */\n buttonLabel?: React.ReactNode;\n /**\n * Left icon element. It renders inside the `<label>` that names the file input, beside\n * `buttonLabel`, so leave an `Icon` here unnamed (`<Icon name=\"upload\" />`): it is then\n * `aria-hidden`, while an `ariaLabel` would join the input's accessible name.\n */\n iconLeft?: React.ReactNode;\n /**\n * Right icon element. Sits inside the same `<label>` as `iconLeft`, so the same applies:\n * an `Icon` here with an `ariaLabel` joins the input's accessible name.\n */\n iconRight?: React.ReactNode;\n /** Additional CSS classes to apply. */\n className?: string;\n /** Additional CSS classes for the `<input>`. */\n inputClassName?: string;\n /**\n * Text for the file name area (with `hasName`), for a file chosen earlier or your own wording.\n * Setting it takes over from the picked file's name; an empty string shows no name area.\n */\n fileName?: string;\n /**\n * Builds the text `hasName` shows when several files are picked, from their count, for\n * localization. Default: `` `${count} files` ``. A single pick shows its file's name.\n */\n pickedFilesLabel?: (count: number) => string;\n}\n\n/**\n * The `File` component provides a Bulma-styled file input, supporting color, size, boxed/fullwidth/align styles, icons, \"has name\", and filename display.\n *\n * @function\n * @param {FileProps} props - Props for the File component.\n * @returns {JSX.Element} The rendered file upload field.\n * @see {@link https://bulma.io/documentation/form/file/ | Bulma File documentation}\n */\nexport const File = forwardRef<HTMLInputElement, FileProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n color,\n size,\n isBoxed,\n isFullwidth,\n isFullWidth,\n isRight,\n isCentered,\n hasName,\n buttonLabel,\n iconLeft,\n iconRight,\n className,\n inputClassName,\n fileName,\n pickedFilesLabel,\n onChange,\n ...props\n },\n ref\n ) => {\n // What the user last picked, and the form a reset of which clears it.\n const [picked, setPicked] = useState<{\n count: number;\n firstName: string;\n form: HTMLFormElement | null;\n }>();\n const pickedForm = picked?.form;\n useEffect(() => {\n if (!pickedForm) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n // The reset event fires before the form resets, and a listener after this one can still\n // cancel it, so the name is cleared a task later, and only if the reset went ahead.\n const onReset = (event: Event) => {\n timer = setTimeout(() => {\n if (!event.defaultPrevented) setPicked(undefined);\n });\n };\n pickedForm.addEventListener('reset', onReset);\n return () => {\n pickedForm.removeEventListener('reset', onReset);\n clearTimeout(timer);\n };\n }, [pickedForm]);\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const { files, form } = event.target;\n setPicked(\n files?.length\n ? { count: files.length, firstName: files[0].name, form }\n : undefined\n );\n onChange?.(event);\n };\n const pickedText =\n picked &&\n (picked.count === 1\n ? picked.firstName\n : (pickedFilesLabel?.(picked.count) ?? `${picked.count} files`));\n const shownName = fileName ?? pickedText;\n\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('File', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: ownField,\n });\n const { classPrefix } = useConfig();\n // The input takes `controlId`, so `id` stays out of the spread, where an\n // undefined `id` key would wipe the id the label points at.\n const { id: _id, ...inputProps } = props;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...inputProps,\n });\n\n // Mutually exclusive alignment\n let alignmentClass: string | undefined;\n if (isRight && isCentered) {\n // If both are set, prefer isRight and warn in dev\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isRight) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isCentered) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-centered');\n }\n\n const mainClass = usePrefixedClassNames('file', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-boxed': isBoxed,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n 'has-name': hasName,\n 'is-empty': hasName && !shownName,\n });\n const fileClass = classNames(\n mainClass,\n bulmaHelperClasses,\n alignmentClass,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n const fileElement = (\n <div className={fileClass}>\n <label className={usePrefixedClassNames('file-label')}>\n <input\n ref={ref}\n className={classNames(\n usePrefixedClassNames('file-input'),\n inputClassName\n )}\n type=\"file\"\n id={controlId}\n onChange={handleChange}\n {...rest}\n />\n <span className={usePrefixedClassNames('file-cta')}>\n {iconLeft && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconLeft}\n </span>\n )}\n <span className={usePrefixedClassNames('file-label')}>\n {buttonLabel || 'Choose a file\\u2026'}\n </span>\n {iconRight && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconRight}\n </span>\n )}\n </span>\n {hasName && shownName && (\n <span className={prefixedClassNames(classPrefix, 'file-name')}>\n {shownName}\n </span>\n )}\n </label>\n </div>\n );\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {fileElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fileElement}\n {messageEl}\n </>\n );\n }\n);\n\nFile.displayName = 'File';\n\nexport default File;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"File.js","sources":["../../../src/form/File.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useState } from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useConfig } from '../helpers/Config';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n} from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * Props for the File component.\n * Inside an outer `Field`, or a `Control` with no `Field` around it, it\n * renders no `Field` of its own. The exception is `label`, `message`,\n * `horizontal` or `fieldClassName` in that bare `Control`: it keeps a `Field`\n * for them, nested in the `.control`, and warns in development. Wrap the\n * `Control` in a `Field` instead, and set the `label`, `horizontal` and class\n * name on that `Field`.\n *\n * @helperProps Helper props go on the `.file` wrapper `<div>`, with\n * `className`. The other attributes go on the `<input>`.\n */\nexport interface FileProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'color' | 'type'\n >,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label. Automatically associated with the file input via `htmlFor` — uses your `id` when provided, otherwise a generated one. The input then has two labels (this one plus the wrapping `file-label`); assistive tech reads both. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Bulma color modifier for the file input. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Size modifier for the file input. */\n size?: 'small' | 'medium' | 'large';\n /** Boxed file input. */\n isBoxed?: boolean;\n /** Whether the file input expands to full width. */\n isFullwidth?: boolean;\n /** Whether the file input expands to full width. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Position the CTA on the right (with `hasName`). */\n isRight?: boolean;\n /** Center the file input within its container. */\n isCentered?: boolean;\n /**\n * Show a file name area. Without `fileName` it shows what the user picked: the file's name, or\n * a count when `multiple` lets them pick several (see `pickedFilesLabel`). Before a pick there is\n * no name area, and the root takes Bulma's `is-empty`. A reset of the input's form clears the\n * name, but clearing the input from code fires no change event and leaves it showing, so pass\n * `fileName` to control the text then.\n */\n hasName?: boolean;\n /** Text on the file CTA button (defaults to \"Choose a file…\"). */\n buttonLabel?: React.ReactNode;\n /**\n * Left icon element. It renders inside the `<label>` that names the file input, beside\n * `buttonLabel`, so leave an `Icon` here unnamed (`<Icon name=\"upload\" />`): it is then\n * `aria-hidden`, while an `ariaLabel` would join the input's accessible name.\n */\n iconLeft?: React.ReactNode;\n /**\n * Right icon element. Sits inside the same `<label>` as `iconLeft`, so the same applies:\n * an `Icon` here with an `ariaLabel` joins the input's accessible name.\n */\n iconRight?: React.ReactNode;\n /** Additional CSS classes to apply. */\n className?: string;\n /** Additional CSS classes for the `<input>`. */\n inputClassName?: string;\n /**\n * Text for the file name area (with `hasName`), for a file chosen earlier or your own wording.\n * Setting it takes over from the picked file's name; an empty string shows no name area.\n */\n fileName?: string;\n /**\n * Builds the text `hasName` shows when several files are picked, from their count, for\n * localization. Default: `` `${count} files` ``. A single pick shows its file's name.\n */\n pickedFilesLabel?: (count: number) => string;\n}\n\n/**\n * The `File` component provides a Bulma-styled file input, supporting color, size, boxed/fullwidth/align styles, icons, \"has name\", and filename display.\n *\n * @function\n * @param {FileProps} props - Props for the File component.\n * @returns {JSX.Element} The rendered file upload field.\n * @see {@link https://bulma.io/documentation/form/file/ | Bulma File documentation}\n */\nexport const File = forwardRef<HTMLInputElement, FileProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n color,\n size,\n isBoxed,\n isFullwidth,\n isFullWidth,\n isRight,\n isCentered,\n hasName,\n buttonLabel,\n iconLeft,\n iconRight,\n className,\n inputClassName,\n fileName,\n pickedFilesLabel,\n onChange,\n ...props\n },\n ref\n ) => {\n // What the user last picked, and the form a reset of which clears it.\n const [picked, setPicked] = useState<{\n count: number;\n firstName: string;\n form: HTMLFormElement | null;\n }>();\n const pickedForm = picked?.form;\n useEffect(() => {\n if (!pickedForm) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n // The reset event fires before the form resets, and a listener after this one can still\n // cancel it, so the name is cleared a task later, and only if the reset went ahead.\n const onReset = (event: Event) => {\n timer = setTimeout(() => {\n if (!event.defaultPrevented) setPicked(undefined);\n });\n };\n pickedForm.addEventListener('reset', onReset);\n return () => {\n pickedForm.removeEventListener('reset', onReset);\n clearTimeout(timer);\n };\n }, [pickedForm]);\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const { files, form } = event.target;\n setPicked(\n files?.length\n ? { count: files.length, firstName: files[0].name, form }\n : undefined\n );\n onChange?.(event);\n };\n const pickedText =\n picked &&\n (picked.count === 1\n ? picked.firstName\n : (pickedFilesLabel?.(picked.count) ?? `${picked.count} files`));\n const shownName = fileName ?? pickedText;\n\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('File', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: ownField,\n });\n const { classPrefix } = useConfig();\n // The input takes `controlId`, so `id` stays out of the spread, where an\n // undefined `id` key would wipe the id the label points at.\n const { id: _id, ...inputProps } = props;\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...inputProps,\n });\n\n // Mutually exclusive alignment\n let alignmentClass: string | undefined;\n if (isRight && isCentered) {\n // If both are set, prefer isRight and warn in dev\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isRight) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-right');\n } else if (isCentered) {\n alignmentClass = prefixedClassNames(classPrefix, 'is-centered');\n }\n\n const mainClass = usePrefixedClassNames('file', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-boxed': isBoxed,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n 'has-name': hasName,\n 'is-empty': hasName && !shownName,\n });\n const fileClass = classNames(\n mainClass,\n bulmaHelperClasses,\n alignmentClass,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n const fileElement = (\n <div className={fileClass}>\n <label className={usePrefixedClassNames('file-label')}>\n <input\n ref={ref}\n className={classNames(\n usePrefixedClassNames('file-input'),\n inputClassName\n )}\n type=\"file\"\n id={controlId}\n onChange={handleChange}\n {...rest}\n />\n <span className={usePrefixedClassNames('file-cta')}>\n {iconLeft && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconLeft}\n </span>\n )}\n <span className={usePrefixedClassNames('file-label')}>\n {buttonLabel || 'Choose a file\\u2026'}\n </span>\n {iconRight && (\n <span className={prefixedClassNames(classPrefix, 'file-icon')}>\n {iconRight}\n </span>\n )}\n </span>\n {hasName && shownName && (\n <span className={prefixedClassNames(classPrefix, 'file-name')}>\n {shownName}\n </span>\n )}\n </label>\n </div>\n );\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {fileElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {fileElement}\n {messageEl}\n </>\n );\n }\n);\n\nFile.displayName = 'File';\n\nexport default File;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;AAwGA;;;;;;;AAOG;AACI,MAAM,IAAI,GAAG,UAAU,CAC5B,CACE;AACE;AACA,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,KAAK,EACL,IAAI,EACJ,OAAO,EACP,WAAW,EACX,WAAW,EACX,OAAO,EACP,UAAU,EACV,OAAO,EACP,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,GAAG,KAAK,EACT,EACD,GAAG,KACD;;IAEF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,EAIhC;AACJ,IAAA,MAAM,UAAU,GAAG,MAAM,EAAE,IAAI;IAC/B,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,UAAU;YAAE;AACjB,QAAA,IAAI,KAAgD;;;AAGpD,QAAA,MAAM,OAAO,GAAG,CAAC,KAAY,KAAI;AAC/B,YAAA,KAAK,GAAG,UAAU,CAAC,MAAK;gBACtB,IAAI,CAAC,KAAK,CAAC,gBAAgB;oBAAE,SAAS,CAAC,SAAS,CAAC;AACnD,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;AACD,QAAA,UAAU,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC;AAC7C,QAAA,OAAO,MAAK;AACV,YAAA,UAAU,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;YAChD,YAAY,CAAC,KAAK,CAAC;AACrB,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;AAChB,IAAA,MAAM,YAAY,GAAG,CAAC,KAA0C,KAAI;QAClE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM;QACpC,SAAS,CACP,KAAK,EAAE;AACL,cAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI;cACrD,SAAS,CACd;AACD,QAAA,QAAQ,GAAG,KAAK,CAAC;AACnB,IAAA,CAAC;IACD,MAAM,UAAU,GACd,MAAM;AACN,SAAC,MAAM,CAAC,KAAK,KAAK;cACd,MAAM,CAAC;AACT,eAAG,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAA,MAAA,CAAQ,CAAC,CAAC;AACpE,IAAA,MAAM,SAAS,GAAG,QAAQ,IAAI,UAAU;AAExC,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;AACpC,IAAA,MAAM,aAAa,GAAG,gBAAgB,EAAE;AACxC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE;QACvC,WAAW;QACX,aAAa;QACb,KAAK;QACL,OAAO;QACP,UAAU;QACV,cAAc;AACf,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,cAAc,CAAC;QACpD,KAAK;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,UAAU;AACV,QAAA,YAAY,EAAE,QAAQ;AACvB,KAAA,CAAC;AACF,IAAA,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE;;;IAGnC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK;AACxC,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;QACnD,KAAK;AACL,QAAA,GAAG,UAAU;AACd,KAAA,CAAC;;AAGF,IAAA,IAAI,cAAkC;AACtC,IAAA,IAAI,OAAO,IAAI,UAAU,EAAE;;AAEzB,QAAA,cAAc,GAAG,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC;IAC9D;SAAO,IAAI,OAAO,EAAE;AAClB,QAAA,cAAc,GAAG,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC;IAC9D;SAAO,IAAI,UAAU,EAAE;AACrB,QAAA,cAAc,GAAG,kBAAkB,CAAC,WAAW,EAAE,aAAa,CAAC;IACjE;AAEA,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,KAAK,CAAA,CAAE,GAAG,CAAC,CAAC,KAAK;AACxB,QAAA,CAAC,MAAM,IAAI,CAAA,CAAE,GAAG,CAAC,CAAC,IAAI;AACtB,QAAA,UAAU,EAAE,OAAO;QACnB,cAAc,EAAE,WAAW,IAAI,WAAW;AAC1C,QAAA,UAAU,EAAE,OAAO;AACnB,QAAA,UAAU,EAAE,OAAO,IAAI,CAAC,SAAS;AAClC,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,UAAU,CAC1B,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,SAAS,CACV;AAED,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;AAEzE,IAAA,MAAM,WAAW,IACfA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,SAAS,EAAA,QAAA,EACvBC,IAAA,CAAA,OAAA,EAAA,EAAO,SAAS,EAAE,qBAAqB,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,CACnDD,GAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CACnB,qBAAqB,CAAC,YAAY,CAAC,EACnC,cAAc,CACf,EACD,IAAI,EAAC,MAAM,EACX,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,YAAY,EAAA,GAClB,IAAI,EAAA,CACR,EACFC,IAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,qBAAqB,CAAC,UAAU,CAAC,EAAA,QAAA,EAAA,CAC/C,QAAQ,KACPD,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAA,QAAA,EAC1D,QAAQ,EAAA,CACJ,CACR,EACDA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,qBAAqB,CAAC,YAAY,CAAC,EAAA,QAAA,EACjD,WAAW,IAAI,qBAAqB,EAAA,CAChC,EACN,SAAS,KACRA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAA,QAAA,EAC1D,SAAS,EAAA,CACL,CACR,CAAA,EAAA,CACI,EACN,OAAO,IAAI,SAAS,KACnBA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE,WAAW,CAAC,EAAA,QAAA,EAC1D,SAAS,EAAA,CACL,CACR,CAAA,EAAA,CACK,EAAA,CACJ,CACP;IAED,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,WAAW,EACX,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,WAAW,EACX,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAGH,IAAI,CAAC,WAAW,GAAG,MAAM;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Numberinput.js","sources":["../../../src/form/Numberinput.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef } from 'react';\nimport type { JSX } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField, useInsideControl } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/** Valid sizes for the Numberinput component. */\nexport type NumberinputSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Numberinput wrapper and control buttons. */\nexport type NumberinputColor =\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'light'\n | 'dark';\n\n/** Valid colors for the Numberinput inner input element. */\nexport type NumberinputInputColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Position of the increment/decrement control buttons. */\nexport type NumberinputControlsPosition = 'left' | 'right' | 'both';\n\n/** Visual variant for the Numberinput controls. */\nexport type NumberinputVariant = 'plusminus' | 'stepper';\n\n/**\n * Props for the Numberinput component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface NumberinputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue' | 'type'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. Not rendered either by a plusminus `bare` Numberinput outside a `Field`. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Controlled value. */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: NumberinputSize;\n /** Color variant for buttons. */\n color?: NumberinputColor;\n /** Color of the input field itself. */\n inputColor?: NumberinputInputColor;\n /** Position of +/- buttons. */\n controlsPosition?: NumberinputControlsPosition;\n /** Use rounded buttons. */\n controlsRounded?: boolean;\n /** Uses compact button spacing. */\n compact?: boolean;\n /**\n * Renders the plusminus controls without a `.field` row of their own, so\n * they join the row of a `Field` with `hasAddons` or `grouped` they sit\n * in. On by default inside a `Field`, unless a `Control` is anywhere above\n * it: a `Control` stacks its children, so there the controls keep their\n * own row.\n * @defaultValue auto\n */\n bare?: boolean;\n /** Style variant for the control buttons. */\n variant?: NumberinputVariant;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input can be typed in. */\n editable?: boolean;\n /**\n * Shows a loading spinner on the input's control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * Use this rather than `isLoading` on a `Control` around the Numberinput:\n * that spinner sits at the `Control`'s right edge, on top of whichever\n * button is there, while this one stays inside the input.\n */\n isLoading?: boolean;\n /** Enables exponential step increments when holding buttons. */\n exponential?: boolean;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n}\n\nconst ArrowDropUp = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 14.5l5-5 5 5\" />\n </svg>\n);\n\nconst ArrowDropDown = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 9.5l5 5 5-5\" />\n </svg>\n);\n\n/**\n * The `Numberinput` component provides a number input with increment/decrement buttons.\n *\n * @function\n * @param {NumberinputProps} props - Props for the Numberinput component.\n * @returns {JSX.Element} The rendered numeric input element.\n *\n * @example\n * // Basic number input\n * <Numberinput defaultValue={5} min={0} max={100} />\n *\n * @example\n * // Stepper variant with color\n * <Numberinput variant=\"stepper\" color=\"primary\" step={10} />\n */\nexport const Numberinput = forwardRef<HTMLInputElement, NumberinputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue,\n min,\n max,\n step = 1,\n size,\n color,\n inputColor,\n controlsPosition = 'both',\n controlsRounded = false,\n compact = false,\n bare,\n variant = 'plusminus',\n disabled = false,\n editable = true,\n isLoading = false,\n exponential = false,\n onChange,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // Bare controls join their parent's row, which a `.control` does not lay\n // out. `useInsideControl()` is true anywhere below a `Control`, even past\n // a `Field` nested in it, so there they keep their own row as well.\n const insideControl = useInsideControl();\n const effectiveBare = bare ?? (insideField && !insideControl);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const [internalValue, setInternalValue] = useState<number | undefined>(\n defaultValue\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Layout mode\n const isStepper = variant === 'stepper';\n const isAddons = compact || isStepper;\n const effectiveControlsPosition = isStepper ? 'right' : controlsPosition;\n\n // The plusminus bare branch renders no Field and no label at all.\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: !insideField && (isStepper || !effectiveBare),\n });\n\n // Clamp value to min/max\n const clampValue = useCallback(\n (val: number): number => {\n let clamped = val;\n if (min !== undefined && clamped < min) clamped = min;\n if (max !== undefined && clamped > max) clamped = max;\n return clamped;\n },\n [min, max]\n );\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n const clampedValue = clampValue(newValue);\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, clampValue, onChange]\n );\n\n // Exponential step: step grows with value magnitude\n const getEffectiveStep = useCallback(() => {\n if (!exponential) return step;\n return step * Math.max(1, Math.floor(Math.abs(currentValue ?? 0)));\n }, [exponential, step, currentValue]);\n\n // Handle increment\n const handleIncrement = useCallback(() => {\n updateValue((currentValue ?? 0) + getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle decrement\n const handleDecrement = useCallback(() => {\n updateValue((currentValue ?? 0) - getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isNaN(newValue)) {\n updateValue(newValue);\n }\n },\n [updateValue]\n );\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleIncrement();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleDecrement();\n }\n },\n [handleIncrement, handleDecrement]\n );\n\n // Check if at limits\n const isAtMin =\n min !== undefined && currentValue !== undefined && currentValue <= min;\n const isAtMax =\n max !== undefined && currentValue !== undefined && currentValue >= max;\n\n // Generate classes\n const fieldClasses = usePrefixedClassNames('field', {\n 'is-grouped': !isAddons,\n 'has-addons': isAddons,\n });\n\n const numberinputClasses = usePrefixedClassNames('numberinput', {\n 'is-compact': isAddons,\n 'is-stepper': isStepper,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n [`controls-${effectiveControlsPosition}`]:\n effectiveControlsPosition !== 'both',\n });\n\n const controlClasses = usePrefixedClassNames('control');\n const expandedControlClasses = usePrefixedClassNames('control', {\n 'is-expanded': true,\n 'is-loading': isLoading,\n });\n\n const buttonClasses = usePrefixedClassNames('button', {\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-rounded': controlsRounded,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${size}`]: !!size,\n [`is-${inputColor}`]: !!inputColor,\n });\n\n const iconClasses = usePrefixedClassNames('icon', 'is-small');\n const stepperClasses = usePrefixedClassNames('numberinput-stepper');\n const stepperButtonClasses = usePrefixedClassNames(\n 'numberinput-stepper-button'\n );\n\n const combinedClasses = classNames(\n fieldClasses,\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // Use combined ref\n const combinedRef = (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n // Shared input element\n const inputControl = (\n <div className={expandedControlClasses}>\n <input\n ref={combinedRef}\n type=\"number\"\n className={inputClasses}\n value={currentValue ?? ''}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n readOnly={!editable}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n aria-valuenow={currentValue ?? undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n {...rest}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n </div>\n );\n\n // Stepper variant\n if (isStepper) {\n const stepperElement = (\n <div className={combinedClasses}>\n {inputControl}\n <div className={controlClasses}>\n <div className={stepperClasses}>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <ArrowDropUp />\n </button>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <ArrowDropDown />\n </button>\n </div>\n </div>\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {stepperElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {stepperElement}\n {messageEl}\n </>\n );\n }\n\n // Plusminus buttons\n const decrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">−</span>\n </span>\n </button>\n );\n\n const incrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">+</span>\n </span>\n </button>\n );\n\n const decrementControl = (\n <div className={controlClasses}>{decrementButton}</div>\n );\n const incrementControl = (\n <div className={controlClasses}>{incrementButton}</div>\n );\n\n // Bare mode: no outer .field wrapper, for composing inside a parent Field\n if (effectiveBare) {\n const bareClasses = classNames(\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n if (effectiveControlsPosition === 'left') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n }\n\n if (effectiveControlsPosition === 'right') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n }\n\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n // Controls left: [−] [+] [input]\n let numberinputElement: JSX.Element;\n if (effectiveControlsPosition === 'left') {\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n } else if (effectiveControlsPosition === 'right') {\n // Controls right: [input] [−] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n } else {\n // Both sides (default): [−] [input] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {numberinputElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {numberinputElement}\n {messageEl}\n </>\n );\n }\n);\n\nNumberinput.displayName = 'Numberinput';\n\n/** @deprecated Use `Numberinput` — same component. */\nexport const NumberInput = Numberinput;\n\n/** @deprecated Use `NumberinputProps`. */\nexport type NumberInputProps = NumberinputProps;\n\nexport default Numberinput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Numberinput.js","sources":["../../../src/form/Numberinput.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef } from 'react';\nimport type { JSX } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField, useInsideControl } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/** Valid sizes for the Numberinput component. */\nexport type NumberinputSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Numberinput wrapper and control buttons. */\nexport type NumberinputColor =\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'light'\n | 'dark';\n\n/** Valid colors for the Numberinput inner input element. */\nexport type NumberinputInputColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Position of the increment/decrement control buttons. */\nexport type NumberinputControlsPosition = 'left' | 'right' | 'both';\n\n/** Visual variant for the Numberinput controls. */\nexport type NumberinputVariant = 'plusminus' | 'stepper';\n\n/**\n * Props for the Numberinput component.\n * @helperProps Helper props go on the outer `.numberinput` `<div>`, with\n * `className`. The other attributes go on the `<input>`.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface NumberinputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue' | 'type'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. Not rendered either by a plusminus `bare` Numberinput outside a `Field`. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Controlled value. */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: NumberinputSize;\n /** Color variant for buttons. */\n color?: NumberinputColor;\n /** Color of the input field itself. */\n inputColor?: NumberinputInputColor;\n /** Position of +/- buttons. */\n controlsPosition?: NumberinputControlsPosition;\n /** Use rounded buttons. */\n controlsRounded?: boolean;\n /** Uses compact button spacing. */\n compact?: boolean;\n /**\n * Renders the plusminus controls without a `.field` row of their own, so\n * they join the row of a `Field` with `hasAddons` or `grouped` they sit\n * in. On by default inside a `Field`, unless a `Control` is anywhere above\n * it: a `Control` stacks its children, so there the controls keep their\n * own row.\n * @defaultValue auto\n */\n bare?: boolean;\n /** Style variant for the control buttons. */\n variant?: NumberinputVariant;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input can be typed in. */\n editable?: boolean;\n /**\n * Shows a loading spinner on the input's control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * Use this rather than `isLoading` on a `Control` around the Numberinput:\n * that spinner sits at the `Control`'s right edge, on top of whichever\n * button is there, while this one stays inside the input.\n */\n isLoading?: boolean;\n /** Enables exponential step increments when holding buttons. */\n exponential?: boolean;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n}\n\nconst ArrowDropUp = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 14.5l5-5 5 5\" />\n </svg>\n);\n\nconst ArrowDropDown = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 9.5l5 5 5-5\" />\n </svg>\n);\n\n/**\n * The `Numberinput` component provides a number input with increment/decrement buttons.\n *\n * @function\n * @param {NumberinputProps} props - Props for the Numberinput component.\n * @returns {JSX.Element} The rendered numeric input element.\n *\n * @example\n * // Basic number input\n * <Numberinput defaultValue={5} min={0} max={100} />\n *\n * @example\n * // Stepper variant with color\n * <Numberinput variant=\"stepper\" color=\"primary\" step={10} />\n */\nexport const Numberinput = forwardRef<HTMLInputElement, NumberinputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue,\n min,\n max,\n step = 1,\n size,\n color,\n inputColor,\n controlsPosition = 'both',\n controlsRounded = false,\n compact = false,\n bare,\n variant = 'plusminus',\n disabled = false,\n editable = true,\n isLoading = false,\n exponential = false,\n onChange,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // Bare controls join their parent's row, which a `.control` does not lay\n // out. `useInsideControl()` is true anywhere below a `Control`, even past\n // a `Field` nested in it, so there they keep their own row as well.\n const insideControl = useInsideControl();\n const effectiveBare = bare ?? (insideField && !insideControl);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const [internalValue, setInternalValue] = useState<number | undefined>(\n defaultValue\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Layout mode\n const isStepper = variant === 'stepper';\n const isAddons = compact || isStepper;\n const effectiveControlsPosition = isStepper ? 'right' : controlsPosition;\n\n // The plusminus bare branch renders no Field and no label at all.\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: !insideField && (isStepper || !effectiveBare),\n });\n\n // Clamp value to min/max\n const clampValue = useCallback(\n (val: number): number => {\n let clamped = val;\n if (min !== undefined && clamped < min) clamped = min;\n if (max !== undefined && clamped > max) clamped = max;\n return clamped;\n },\n [min, max]\n );\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n const clampedValue = clampValue(newValue);\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, clampValue, onChange]\n );\n\n // Exponential step: step grows with value magnitude\n const getEffectiveStep = useCallback(() => {\n if (!exponential) return step;\n return step * Math.max(1, Math.floor(Math.abs(currentValue ?? 0)));\n }, [exponential, step, currentValue]);\n\n // Handle increment\n const handleIncrement = useCallback(() => {\n updateValue((currentValue ?? 0) + getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle decrement\n const handleDecrement = useCallback(() => {\n updateValue((currentValue ?? 0) - getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isNaN(newValue)) {\n updateValue(newValue);\n }\n },\n [updateValue]\n );\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleIncrement();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleDecrement();\n }\n },\n [handleIncrement, handleDecrement]\n );\n\n // Check if at limits\n const isAtMin =\n min !== undefined && currentValue !== undefined && currentValue <= min;\n const isAtMax =\n max !== undefined && currentValue !== undefined && currentValue >= max;\n\n // Generate classes\n const fieldClasses = usePrefixedClassNames('field', {\n 'is-grouped': !isAddons,\n 'has-addons': isAddons,\n });\n\n const numberinputClasses = usePrefixedClassNames('numberinput', {\n 'is-compact': isAddons,\n 'is-stepper': isStepper,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n [`controls-${effectiveControlsPosition}`]:\n effectiveControlsPosition !== 'both',\n });\n\n const controlClasses = usePrefixedClassNames('control');\n const expandedControlClasses = usePrefixedClassNames('control', {\n 'is-expanded': true,\n 'is-loading': isLoading,\n });\n\n const buttonClasses = usePrefixedClassNames('button', {\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-rounded': controlsRounded,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${size}`]: !!size,\n [`is-${inputColor}`]: !!inputColor,\n });\n\n const iconClasses = usePrefixedClassNames('icon', 'is-small');\n const stepperClasses = usePrefixedClassNames('numberinput-stepper');\n const stepperButtonClasses = usePrefixedClassNames(\n 'numberinput-stepper-button'\n );\n\n const combinedClasses = classNames(\n fieldClasses,\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // Use combined ref\n const combinedRef = (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n // Shared input element\n const inputControl = (\n <div className={expandedControlClasses}>\n <input\n ref={combinedRef}\n type=\"number\"\n className={inputClasses}\n value={currentValue ?? ''}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n readOnly={!editable}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n aria-valuenow={currentValue ?? undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n {...rest}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n </div>\n );\n\n // Stepper variant\n if (isStepper) {\n const stepperElement = (\n <div className={combinedClasses}>\n {inputControl}\n <div className={controlClasses}>\n <div className={stepperClasses}>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <ArrowDropUp />\n </button>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <ArrowDropDown />\n </button>\n </div>\n </div>\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {stepperElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {stepperElement}\n {messageEl}\n </>\n );\n }\n\n // Plusminus buttons\n const decrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">−</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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinInput.js","sources":["../../../src/form/PinInput.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { getActiveElementInTree } from '../helpers/shadowDom';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * What a PinInput takes: `'number'` keeps digits only, and `'alphanumeric'`\n * keeps the letters A to Z, in either case, and digits. A digit from any\n * script, such as an Arabic-Indic `٣` or a Persian `۳`, is kept as its ASCII\n * digit, `3`.\n */\nexport type PinInputType = 'number' | 'alphanumeric';\n\n/**\n * Props for the PinInput 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 * Every other prop goes to the `<input>` that holds the code, except\n * `className` and the helper props, which go to the row of boxes.\n * @extraProp {string} [name] - Form field name, on the input, so a form submits the code under it.\n * @extraProp {string} [autoComplete=\"one-time-code\"] - Lets the browser offer a code it received by text message, and tells a password manager this is a one-time code.\n * @extraProp {string} [inputMode] - The keyboard a phone shows: `\"numeric\"` with `type=\"number\"`, `\"text\"` with `type=\"alphanumeric\"`.\n * @extraProp {string} [pattern] - Exactly `length` of what `type` takes, `[0-9]{6}` by default, so a form with `required` won't submit a partial code. Any non-empty partial code fails it, `required` or not.\n * @extraProp {string} [className] - Additional CSS classes for the row of boxes.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the input that holds the code.\n */\nexport interface PinInputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'color'\n | 'size'\n | 'type'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'maxLength'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the input that holds the code via `htmlFor`, so a screen reader announces one field under this name. Uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\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 /** Applied to the input that holds the code (the labellable control), not the row of boxes. */\n id?: string;\n /** How many characters the code has. Each gets a box, and it is the input's `maxLength`. */\n length?: number;\n /** The code (controlled). Only its first `length` characters are shown and submitted. */\n value?: string;\n /** The code to start with (uncontrolled). Only its first `length` characters are kept. */\n defaultValue?: string;\n /**\n * What the code takes. A digit from any script, such as an Arabic-Indic or\n * a Persian one, goes in as its ASCII digit, so the code reaches\n * `onChange`, `onComplete` and the form as `0` to `9`. Anything else typed\n * or pasted is dropped, and the caret stays where it was. The input stays a\n * text field either way, so a code keeps its leading zeros.\n */\n type?: PinInputType;\n /**\n * Shows a dot in each filled box in place of its character, and makes the\n * input a password field, so a screen reader doesn't read the code out\n * either.\n */\n isMasked?: boolean;\n /** Bulma color for the boxes, the colors an `Input` takes. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Size of the boxes. */\n size?: 'small' | 'medium' | 'large';\n /** Round boxes. */\n isRounded?: boolean;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /**\n * Called with the code each time it changes. A paste replaces the whole\n * code with what was pasted, kept to what `type` takes and cut to `length`,\n * and a paste with nothing the code takes changes nothing.\n */\n onChange?: (value: string) => void;\n /**\n * Called with the code when a change makes it `length` characters long,\n * such as typing the last character, a paste or autofill. It fires once for\n * each change that fills the last box with a new code, and never on a\n * render. A `value` you set yourself doesn't call it.\n */\n onComplete?: (value: string) => void;\n}\n\ntype Selection = readonly [start: number, end: number];\n\n/** What a masked box shows for its character, a filled circle. */\nconst MASK = '\\u25CF';\n\n/**\n * `text` with each decimal digit, in any script, turned into its ASCII digit:\n * `١٢٣` and `۱۲۳` become `123`. Unicode assigns decimal digits in runs of ten,\n * from 0 to 9, so a digit's value is how far it is from the start of its run,\n * modulo ten for runs that sit next to each other.\n */\nconst toAsciiDigits = (text: string) =>\n text.replace(/\\p{Nd}/gu, digit => {\n const point = digit.codePointAt(0)!;\n let start = point;\n while (/\\p{Nd}/u.test(String.fromCodePoint(start - 1))) start--;\n return String((point - start) % 10);\n });\n\n/**\n * The `PinInput` component is a field for a short code, such as a one-time\n * code or a PIN, drawn as a row of boxes with one character in each.\n *\n * The code lives in one real `<input>` that lies over the boxes, so it is\n * one field to a screen reader, and paste, autofill from a text message and\n * password managers work on it as they do on any input. The boxes draw what\n * it holds, and the box at the caret, or every box in a selection, shows\n * Bulma's focus look.\n *\n * @function\n * @param {PinInputProps} props - Props for the PinInput component.\n * @returns {JSX.Element} The rendered code field.\n *\n * @example\n * <PinInput\n * label=\"Verification code\"\n * value={code}\n * onChange={setCode}\n * onComplete={verify}\n * />\n */\nexport const PinInput = forwardRef<HTMLInputElement, PinInputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n length = 6,\n value: controlledValue,\n defaultValue = '',\n type = 'number',\n isMasked = false,\n color,\n size,\n isRounded = false,\n disabled = false,\n onChange,\n onComplete,\n onPaste,\n onFocus,\n onBlur,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('PinInput', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const ownControl = rendersOwnControl('PinInput', { insideControl });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: ownField,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n\n const [internalValue, setInternalValue] = useState(defaultValue);\n // Cut to `length`, so the boxes, the input and the form all hold the same\n // code.\n const code = (\n controlledValue !== undefined ? controlledValue : internalValue\n ).slice(0, length);\n\n const allowed = type === 'alphanumeric' ? '[0-9A-Za-z]' : '[0-9]';\n /** The characters of `text` the code takes, digits in ASCII, cut to `length`. */\n const keep = (text: string) =>\n (toAsciiDigits(text).match(new RegExp(allowed, 'g')) ?? [])\n .join('')\n .slice(0, length);\n\n const commit = (next: string) => {\n if (next === code) return;\n if (controlledValue === undefined) setInternalValue(next);\n onChange?.(next);\n if (next.length === length) onComplete?.(next);\n };\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n\n // The input's selection while it has focus, which the boxes draw.\n const [selection, setSelection] = useState<Selection | null>(null);\n const follow = useCallback(() => {\n const input = inputRef.current!;\n const next: Selection | null =\n getActiveElementInTree(input) === input\n ? [input.selectionStart!, input.selectionEnd!]\n : null;\n setSelection(prev =>\n prev?.[0] === next?.[0] && prev?.[1] === next?.[1] ? prev : next\n );\n }, []);\n // A new code moves the caret, and so can a value set from outside.\n useClientLayoutEffect(follow, [code, follow]);\n // React's `onSelect` never fires inside a shadow root, so the boxes\n // follow the browser's own `selectionchange`. A caret that moves fires it\n // at the input, and it bubbles to the document, but in a shadow root some\n // browsers fire it at the document alone and others at the input alone,\n // so both are followed.\n useEffect(() => {\n const input = inputRef.current!;\n const doc = input.ownerDocument;\n input.addEventListener('selectionchange', follow);\n doc.addEventListener('selectionchange', follow);\n return () => {\n input.removeEventListener('selectionchange', follow);\n doc.removeEventListener('selectionchange', follow);\n };\n }, [follow]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const input = e.target;\n const typed = input.value;\n const next = keep(typed);\n if (next !== typed) {\n // Drop what the code doesn't take before React sees the value, so\n // the caret stays where it was rather than jumping to the end.\n const caret = keep(typed.slice(0, input.selectionStart!)).length;\n input.value = next;\n input.setSelectionRange(caret, caret);\n }\n commit(next);\n };\n\n // The browser cuts a paste to `maxLength` before anything else sees it,\n // so a code pasted as \"123 456\" would lose its last digit. What the code\n // takes is kept first, and it replaces the whole code, since what you\n // paste into a code field is the code.\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n onPaste?.(e);\n if (e.defaultPrevented) return;\n e.preventDefault();\n const pasted = keep(e.clipboardData.getData('text'));\n if (pasted && !e.currentTarget.readOnly) commit(pasted);\n };\n\n const rootClass = classNames(\n usePrefixedClassNames('pin-input'),\n bulmaHelperClasses,\n className\n );\n const fieldClass = usePrefixedClassNames('pin-input-field');\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // The boxes the selection covers: the one at a caret, or every selected\n // one. A caret after the last character marks the last box.\n const [start, end] = selection ?? [-1, -1];\n const first = Math.min(start, length - 1);\n const last = Math.max(first + 1, Math.min(end, length));\n const boxes = Array.from({ length }, (_, i) => {\n const char = code[i];\n const active = i >= first && i < last;\n return (\n <div\n key={i}\n aria-hidden=\"true\"\n className={prefixedClassNames(classPrefix, 'input', 'pin-input-box', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': isRounded,\n 'is-focused': active,\n 'has-caret': active && start === end && !char,\n 'is-disabled': disabled,\n })}\n >\n {char && (isMasked ? MASK : char)}\n </div>\n );\n });\n\n // Left to right on a right-to-left page too: a code is written that way,\n // so its first character stays in the first box on the left, and the\n // arrow keys move the caret the way the boxes run.\n let content = (\n <div className={rootClass} dir=\"ltr\">\n <input\n ref={setRefs}\n className={fieldClass}\n type={isMasked ? 'password' : 'text'}\n inputMode={type === 'alphanumeric' ? 'text' : 'numeric'}\n autoComplete=\"one-time-code\"\n autoCorrect=\"off\"\n spellCheck={false}\n // A partial code fails constraint validation. `minLength` would\n // say so only after a keystroke, never after a paste or a filtered\n // character, which set the value from script.\n pattern={`${allowed}{${length}}`}\n {...rest}\n value={code}\n maxLength={length}\n disabled={disabled}\n onChange={handleChange}\n onPaste={handlePaste}\n onFocus={e => {\n follow();\n onFocus?.(e);\n }}\n onBlur={e => {\n setSelection(null);\n onBlur?.(e);\n }}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n {boxes}\n </div>\n );\n\n if (ownControl) {\n content = <Control>{content}</Control>;\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\nPinInput.displayName = 'PinInput';\n\nexport default PinInput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PinInput.js","sources":["../../../src/form/PinInput.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { getActiveElementInTree } from '../helpers/shadowDom';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/**\n * What a PinInput takes: `'number'` keeps digits only, and `'alphanumeric'`\n * keeps the letters A to Z, in either case, and digits. A digit from any\n * script, such as an Arabic-Indic `٣` or a Persian `۳`, is kept as its ASCII\n * digit, `3`.\n */\nexport type PinInputType = 'number' | 'alphanumeric';\n\n/**\n * Props for the PinInput 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 * Every other prop goes to the `<input>` that holds the code, except\n * `className` and the helper props, which go to the row of boxes.\n * @helperProps Helper props go on the `.pin-input` `<div>`, the row of boxes,\n * with `className`. The other attributes go on the `<input>` that holds the\n * code.\n * @extraProp {string} [name] - Form field name, on the input, so a form submits the code under it.\n * @extraProp {string} [autoComplete=\"one-time-code\"] - Lets the browser offer a code it received by text message, and tells a password manager this is a one-time code.\n * @extraProp {string} [inputMode] - The keyboard a phone shows: `\"numeric\"` with `type=\"number\"`, `\"text\"` with `type=\"alphanumeric\"`.\n * @extraProp {string} [pattern] - Exactly `length` of what `type` takes, `[0-9]{6}` by default, so a form with `required` won't submit a partial code. Any non-empty partial code fails it, `required` or not.\n * @extraProp {string} [className] - Additional CSS classes for the row of boxes.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the input that holds the code.\n */\nexport interface PinInputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'color'\n | 'size'\n | 'type'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'maxLength'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the input that holds the code via `htmlFor`, so a screen reader announces one field under this name. Uses your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`) and you set no `id` here. */\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 /** Applied to the input that holds the code (the labellable control), not the row of boxes. */\n id?: string;\n /** How many characters the code has. Each gets a box, and it is the input's `maxLength`. */\n length?: number;\n /** The code (controlled). Only its first `length` characters are shown and submitted. */\n value?: string;\n /** The code to start with (uncontrolled). Only its first `length` characters are kept. */\n defaultValue?: string;\n /**\n * What the code takes. A digit from any script, such as an Arabic-Indic or\n * a Persian one, goes in as its ASCII digit, so the code reaches\n * `onChange`, `onComplete` and the form as `0` to `9`. Anything else typed\n * or pasted is dropped, and the caret stays where it was. The input stays a\n * text field either way, so a code keeps its leading zeros.\n */\n type?: PinInputType;\n /**\n * Shows a dot in each filled box in place of its character, and makes the\n * input a password field, so a screen reader doesn't read the code out\n * either.\n */\n isMasked?: boolean;\n /** Bulma color for the boxes, the colors an `Input` takes. */\n color?:\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'black'\n | 'dark'\n | 'light'\n | 'white';\n /** Size of the boxes. */\n size?: 'small' | 'medium' | 'large';\n /** Round boxes. */\n isRounded?: boolean;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /**\n * Called with the code each time it changes. A paste replaces the whole\n * code with what was pasted, kept to what `type` takes and cut to `length`,\n * and a paste with nothing the code takes changes nothing.\n */\n onChange?: (value: string) => void;\n /**\n * Called with the code when a change makes it `length` characters long,\n * such as typing the last character, a paste or autofill. It fires once for\n * each change that fills the last box with a new code, and never on a\n * render. A `value` you set yourself doesn't call it.\n */\n onComplete?: (value: string) => void;\n}\n\ntype Selection = readonly [start: number, end: number];\n\n/** What a masked box shows for its character, a filled circle. */\nconst MASK = '\\u25CF';\n\n/**\n * `text` with each decimal digit, in any script, turned into its ASCII digit:\n * `١٢٣` and `۱۲۳` become `123`. Unicode assigns decimal digits in runs of ten,\n * from 0 to 9, so a digit's value is how far it is from the start of its run,\n * modulo ten for runs that sit next to each other.\n */\nconst toAsciiDigits = (text: string) =>\n text.replace(/\\p{Nd}/gu, digit => {\n const point = digit.codePointAt(0)!;\n let start = point;\n while (/\\p{Nd}/u.test(String.fromCodePoint(start - 1))) start--;\n return String((point - start) % 10);\n });\n\n/**\n * The `PinInput` component is a field for a short code, such as a one-time\n * code or a PIN, drawn as a row of boxes with one character in each.\n *\n * The code lives in one real `<input>` that lies over the boxes, so it is\n * one field to a screen reader, and paste, autofill from a text message and\n * password managers work on it as they do on any input. The boxes draw what\n * it holds, and the box at the caret, or every box in a selection, shows\n * Bulma's focus look.\n *\n * @function\n * @param {PinInputProps} props - Props for the PinInput component.\n * @returns {JSX.Element} The rendered code field.\n *\n * @example\n * <PinInput\n * label=\"Verification code\"\n * value={code}\n * onChange={setCode}\n * onComplete={verify}\n * />\n */\nexport const PinInput = forwardRef<HTMLInputElement, PinInputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n length = 6,\n value: controlledValue,\n defaultValue = '',\n type = 'number',\n isMasked = false,\n color,\n size,\n isRounded = false,\n disabled = false,\n onChange,\n onComplete,\n onPaste,\n onFocus,\n onBlur,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('PinInput', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const ownControl = rendersOwnControl('PinInput', { insideControl });\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: ownField,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n\n const [internalValue, setInternalValue] = useState(defaultValue);\n // Cut to `length`, so the boxes, the input and the form all hold the same\n // code.\n const code = (\n controlledValue !== undefined ? controlledValue : internalValue\n ).slice(0, length);\n\n const allowed = type === 'alphanumeric' ? '[0-9A-Za-z]' : '[0-9]';\n /** The characters of `text` the code takes, digits in ASCII, cut to `length`. */\n const keep = (text: string) =>\n (toAsciiDigits(text).match(new RegExp(allowed, 'g')) ?? [])\n .join('')\n .slice(0, length);\n\n const commit = (next: string) => {\n if (next === code) return;\n if (controlledValue === undefined) setInternalValue(next);\n onChange?.(next);\n if (next.length === length) onComplete?.(next);\n };\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const setRefs = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === 'function') return ref(node);\n if (ref) ref.current = node;\n },\n [ref]\n );\n\n // The input's selection while it has focus, which the boxes draw.\n const [selection, setSelection] = useState<Selection | null>(null);\n const follow = useCallback(() => {\n const input = inputRef.current!;\n const next: Selection | null =\n getActiveElementInTree(input) === input\n ? [input.selectionStart!, input.selectionEnd!]\n : null;\n setSelection(prev =>\n prev?.[0] === next?.[0] && prev?.[1] === next?.[1] ? prev : next\n );\n }, []);\n // A new code moves the caret, and so can a value set from outside.\n useClientLayoutEffect(follow, [code, follow]);\n // React's `onSelect` never fires inside a shadow root, so the boxes\n // follow the browser's own `selectionchange`. A caret that moves fires it\n // at the input, and it bubbles to the document, but in a shadow root some\n // browsers fire it at the document alone and others at the input alone,\n // so both are followed.\n useEffect(() => {\n const input = inputRef.current!;\n const doc = input.ownerDocument;\n input.addEventListener('selectionchange', follow);\n doc.addEventListener('selectionchange', follow);\n return () => {\n input.removeEventListener('selectionchange', follow);\n doc.removeEventListener('selectionchange', follow);\n };\n }, [follow]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const input = e.target;\n const typed = input.value;\n const next = keep(typed);\n if (next !== typed) {\n // Drop what the code doesn't take before React sees the value, so\n // the caret stays where it was rather than jumping to the end.\n const caret = keep(typed.slice(0, input.selectionStart!)).length;\n input.value = next;\n input.setSelectionRange(caret, caret);\n }\n commit(next);\n };\n\n // The browser cuts a paste to `maxLength` before anything else sees it,\n // so a code pasted as \"123 456\" would lose its last digit. What the code\n // takes is kept first, and it replaces the whole code, since what you\n // paste into a code field is the code.\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n onPaste?.(e);\n if (e.defaultPrevented) return;\n e.preventDefault();\n const pasted = keep(e.clipboardData.getData('text'));\n if (pasted && !e.currentTarget.readOnly) commit(pasted);\n };\n\n const rootClass = classNames(\n usePrefixedClassNames('pin-input'),\n bulmaHelperClasses,\n className\n );\n const fieldClass = usePrefixedClassNames('pin-input-field');\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n\n // The boxes the selection covers: the one at a caret, or every selected\n // one. A caret after the last character marks the last box.\n const [start, end] = selection ?? [-1, -1];\n const first = Math.min(start, length - 1);\n const last = Math.max(first + 1, Math.min(end, length));\n const boxes = Array.from({ length }, (_, i) => {\n const char = code[i];\n const active = i >= first && i < last;\n return (\n <div\n key={i}\n aria-hidden=\"true\"\n className={prefixedClassNames(classPrefix, 'input', 'pin-input-box', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': isRounded,\n 'is-focused': active,\n 'has-caret': active && start === end && !char,\n 'is-disabled': disabled,\n })}\n >\n {char && (isMasked ? MASK : char)}\n </div>\n );\n });\n\n // Left to right on a right-to-left page too: a code is written that way,\n // so its first character stays in the first box on the left, and the\n // arrow keys move the caret the way the boxes run.\n let content = (\n <div className={rootClass} dir=\"ltr\">\n <input\n ref={setRefs}\n className={fieldClass}\n type={isMasked ? 'password' : 'text'}\n inputMode={type === 'alphanumeric' ? 'text' : 'numeric'}\n autoComplete=\"one-time-code\"\n autoCorrect=\"off\"\n spellCheck={false}\n // A partial code fails constraint validation. `minLength` would\n // say so only after a keystroke, never after a paste or a filtered\n // character, which set the value from script.\n pattern={`${allowed}{${length}}`}\n {...rest}\n value={code}\n maxLength={length}\n disabled={disabled}\n onChange={handleChange}\n onPaste={handlePaste}\n onFocus={e => {\n follow();\n onFocus?.(e);\n }}\n onBlur={e => {\n setSelection(null);\n onBlur?.(e);\n }}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n {boxes}\n </div>\n );\n\n if (ownControl) {\n content = <Control>{content}</Control>;\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\nPinInput.displayName = 'PinInput';\n\nexport default PinInput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Radio.js","sources":["../../../src/form/Radio.tsx"],"sourcesContent":["import React, { forwardRef, useCallback } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useRadiosGroup } from './FormContext';\n\n/**\n * The values the Radio `color` prop accepts, as a readonly tuple.\n *\n * `RadioProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Radio, Radios, radioColors } from '@allxsmith/bestax-bulma';\n *\n * <Radios name=\"accent\" defaultValue=\"primary\">\n * {radioColors.map(color => (\n * <Radio key={color} value={color} color={color}>\n * {color}\n * </Radio>\n * ))}\n * </Radios>;\n */\nexport const radioColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Radio `size` prop accepts, as a readonly tuple.\n *\n * `RadioProps['size']` is typed from it, so the two list the same values. Use\n * it to offer a size choice or to check a value that arrives at runtime: the\n * component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { radioSizes } from '@allxsmith/bestax-bulma';\n *\n * type RadioSize = (typeof radioSizes)[number];\n */\nexport const radioSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Radio component.\n */\nexport interface RadioProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the radio button. */\n color?: (typeof radioColors)[number];\n /** Size of the radio button. */\n size?: (typeof radioSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the radio is disabled. */\n disabled?: boolean;\n /**\n * Additional CSS classes, on the outer `<label>`. That's the element that\n * declares the `--bulma-radio-*` variables, so a class is how to set one:\n * `style` and the other input attributes go to the `<input>`. Name\n * `.styled-radio` beside your class in the selector, so it beats the\n * label's own declaration whatever order the stylesheets load in. A\n * `color` prop declares the active color again on\n * `.styled-radio.is-<color>`, which ties that selector, so leave `color`\n * unset when a class sets it.\n */\n className?: string;\n /** The label/content for the radio. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Radio` component provides a Bulma-styled radio button input with flexible labels and helper classes.\n *\n * @function\n * @param {RadioProps} props - Props for the Radio component.\n * @returns {JSX.Element} The rendered radio element.\n *\n * @example\n * // Basic radio\n * <Radio name=\"option\">Option A</Radio>\n *\n * @example\n * // Inside a group\n * <Radios name=\"color\" defaultValue=\"red\">\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n */\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // Inherit name + selection state from a surrounding <Radios> group.\n // Local props always win over the group (explicit > implicit).\n const group = useRadiosGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Radio\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const effectiveChecked =\n checked !== undefined\n ? checked\n : groupManaged\n ? group!.value === value\n : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — keeps group state in sync.\n if (group?.onChange && value !== undefined) {\n group.onChange(String(value));\n }\n },\n [onChange, group, value]\n );\n\n const mainClass = usePrefixedClassNames('styled-radio', 'radio', {\n [`is-${color}`]: color && radioColors.includes(color),\n [`is-${size}`]: size && radioSizes.includes(size),\n });\n const radioClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={radioClass}>\n <input\n ref={ref}\n type=\"radio\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nRadio.displayName = 'Radio';\n\nexport default Radio;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;AASA;;;;;;;;;;;;;;;;;;AAkBG;AACI,MAAM,WAAW,GAAG;IACzB,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;;AAGV;;;;;;;;;;;;AAYG;AACI,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"Radio.js","sources":["../../../src/form/Radio.tsx"],"sourcesContent":["import React, { forwardRef, useCallback } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useRadiosGroup } from './FormContext';\n\n/**\n * The values the Radio `color` prop accepts, as a readonly tuple.\n *\n * `RadioProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Radio, Radios, radioColors } from '@allxsmith/bestax-bulma';\n *\n * <Radios name=\"accent\" defaultValue=\"primary\">\n * {radioColors.map(color => (\n * <Radio key={color} value={color} color={color}>\n * {color}\n * </Radio>\n * ))}\n * </Radios>;\n */\nexport const radioColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Radio `size` prop accepts, as a readonly tuple.\n *\n * `RadioProps['size']` is typed from it, so the two list the same values. Use\n * it to offer a size choice or to check a value that arrives at runtime: the\n * component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { radioSizes } from '@allxsmith/bestax-bulma';\n *\n * type RadioSize = (typeof radioSizes)[number];\n */\nexport const radioSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Radio component.\n *\n * @helperProps Helper props go on the outer `<label>`, with `className`. The\n * other attributes go on the `<input>`.\n */\nexport interface RadioProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the radio button. */\n color?: (typeof radioColors)[number];\n /** Size of the radio button. */\n size?: (typeof radioSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the radio is disabled. */\n disabled?: boolean;\n /**\n * Additional CSS classes, on the outer `<label>`. That's the element that\n * declares the `--bulma-radio-*` variables, so a class is how to set one:\n * `style` and the other input attributes go to the `<input>`. Name\n * `.styled-radio` beside your class in the selector, so it beats the\n * label's own declaration whatever order the stylesheets load in. A\n * `color` prop declares the active color again on\n * `.styled-radio.is-<color>`, which ties that selector, so leave `color`\n * unset when a class sets it.\n */\n className?: string;\n /** The label/content for the radio. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Radio` component provides a Bulma-styled radio button input with flexible labels and helper classes.\n *\n * @function\n * @param {RadioProps} props - Props for the Radio component.\n * @returns {JSX.Element} The rendered radio element.\n *\n * @example\n * // Basic radio\n * <Radio name=\"option\">Option A</Radio>\n *\n * @example\n * // Inside a group\n * <Radios name=\"color\" defaultValue=\"red\">\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n */\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // Inherit name + selection state from a surrounding <Radios> group.\n // Local props always win over the group (explicit > implicit).\n const group = useRadiosGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Radio\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const effectiveChecked =\n checked !== undefined\n ? checked\n : groupManaged\n ? group!.value === value\n : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — keeps group state in sync.\n if (group?.onChange && value !== undefined) {\n group.onChange(String(value));\n }\n },\n [onChange, group, value]\n );\n\n const mainClass = usePrefixedClassNames('styled-radio', 'radio', {\n [`is-${color}`]: color && radioColors.includes(color),\n [`is-${size}`]: size && radioSizes.includes(size),\n });\n const radioClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={radioClass}>\n <input\n ref={ref}\n type=\"radio\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nRadio.displayName = 'Radio';\n\nexport default Radio;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;AASA;;;;;;;;;;;;;;;;;;AAkBG;AACI,MAAM,WAAW,GAAG;IACzB,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;;AAGV;;;;;;;;;;;;AAYG;AACI,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO;AAsC/D;;;;;;;;;;;;;;;;;AAiBG;AACI,MAAM,KAAK,GAAG,UAAU,CAC7B,CACE,EACE,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,OAAO,EACP,cAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EACD,GAAG,KACD;AACF,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;;;AAIF,IAAA,MAAM,KAAK,GAAG,cAAc,EAAE;AAC9B,IAAA,MAAM,aAAa,GAAG,IAAI,IAAI,KAAK,EAAE,IAAI;;;;IAKzC,MAAM,YAAY,GAAG,KAAK,EAAE,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;AACtE,IAAA,MAAM,gBAAgB,GACpB,OAAO,KAAK;AACV,UAAE;AACF,UAAE;AACA,cAAE,KAAM,CAAC,KAAK,KAAK;cACjB,SAAS;;;IAGjB,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc;AAEzE,IAAA,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,CAAsC,KAAI;;AAEzC,QAAA,QAAQ,GAAG,CAAC,CAAC;;QAEb,IAAI,KAAK,EAAE,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE;YAC1C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B;IACF,CAAC,EACD,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CACzB;AAED,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,cAAc,EAAE,OAAO,EAAE;AAC/D,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;AACrD,QAAA,CAAC,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,GAAG,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;AAClD,KAAA,CAAC;IACF,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,EAAE,kBAAkB,EAAE,SAAS,CAAC;AACvE,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC;AACjD,IAAA,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,eAAe,CAAC;IAEhE,QACEA,IAAA,CAAA,OAAA,EAAA,EAAO,SAAS,EAAE,UAAU,EAAA,QAAA,EAAA,CAC1BC,GAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,OAAO,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,gBAAgB,EACzB,cAAc,EAAE,uBAAuB,EACvC,QAAQ,EAAE,YAAY,EAAA,GAClB,IAAI,EAAA,CACR,EACFA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,UAAU,EAAA,CAAI,EAC9B,QAAQ,IAAIA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,iBAAiB,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAQ,CAAA,EAAA,CAC5D;AAEZ,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectBase.js","sources":["../../../src/form/SelectBase.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useFieldLabelTarget } from './FormContext';\n\n/**\n * Props for the Select component.\n */\nexport interface SelectBaseProps\n extends\n Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'>,\n Omit<BulmaClassesProps, 'color'> {\n /** Bulma color modifier for the select. */\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 select. */\n size?: 'small' | 'medium' | 'large';\n /** Rounded select corners. */\n isRounded?: boolean;\n /**\n * Replaces the chevron with a loading spinner.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n */\n isLoading?: boolean;\n /** Applies Bulma's is-active modifier. */\n isActive?: boolean;\n /** Forces hovered state on the inner select. */\n isHovered?: boolean;\n /** Forces focused state on the inner select. */\n isFocused?: boolean;\n /** Makes the select span the full width of parent. */\n isFullwidth?: boolean;\n /** Makes the select span the full width of parent. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Additional CSS classes to apply. */\n className?: string;\n /** Disables the select. */\n disabled?: boolean;\n /** Allows multiple selections. */\n multiple?: boolean;\n /** Number of visible options in multiselect. */\n multipleSize?: number;\n /** `<option>` elements. */\n children?: React.ReactNode;\n}\n\n/**\n * Bulma Select component with full Bulma helper class support.\n *\n * @function\n * @param {SelectBaseProps} props - Props for the SelectBase component.\n * @returns {JSX.Element} The rendered select element.\n * @see {@link https://bulma.io/documentation/form/select/ | Bulma Select documentation}\n */\nexport const SelectBase = forwardRef<HTMLSelectElement, SelectBaseProps>(\n (\n {\n color,\n size,\n isRounded,\n isLoading,\n isActive,\n isHovered,\n isFocused,\n isFullwidth,\n isFullWidth,\n className,\n disabled,\n children,\n multiple,\n multipleSize,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...props,\n });\n // A labeled Field's generated id when no user id arrived (rest.id may be\n // an undefined own key), reported to that Field (#1004).\n const id = useFieldLabelTarget(rest.id);\n\n const mainClass = usePrefixedClassNames('select', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': isRounded,\n 'is-loading': isLoading,\n 'is-active': isActive,\n 'is-multiple': !!multiple,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n });\n const selectClass = classNames(mainClass, bulmaHelperClasses, className);\n\n // is-hovered / is-focused belong on the inner <select> element, not the wrapper.\n const innerSelectClass = usePrefixedClassNames('', {\n 'is-hovered': isHovered,\n 'is-focused': isFocused,\n });\n\n // Only set size attribute when multiple is true and multipleSize is specified\n const selectProps: React.SelectHTMLAttributes<HTMLSelectElement> = {\n disabled,\n multiple,\n ...rest,\n };\n\n if (multiple && typeof multipleSize === 'number') {\n selectProps.size = multipleSize;\n }\n\n return (\n <div className={selectClass}>\n <select\n ref={ref}\n className={innerSelectClass || undefined}\n {...selectProps}\n // After the spread, which may carry an undefined id key; the id\n // belongs on the inner <select>.\n id={id}\n >\n {children}\n </select>\n </div>\n );\n }\n);\n\nSelectBase.displayName = 'SelectBase';\n\nexport default SelectBase;\n"],"names":["_jsx"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"SelectBase.js","sources":["../../../src/form/SelectBase.tsx"],"sourcesContent":["import React, { forwardRef } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useFieldLabelTarget } from './FormContext';\n\n/**\n * Props for the Select component.\n *\n * @helperProps Helper props go on the `.select` wrapper `<div>`, with\n * `className`. The other attributes go on the `<select>`.\n */\nexport interface SelectBaseProps\n extends\n Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'>,\n Omit<BulmaClassesProps, 'color'> {\n /** Bulma color modifier for the select. */\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 select. */\n size?: 'small' | 'medium' | 'large';\n /** Rounded select corners. */\n isRounded?: boolean;\n /**\n * Replaces the chevron with a loading spinner.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n */\n isLoading?: boolean;\n /** Applies Bulma's is-active modifier. */\n isActive?: boolean;\n /** Forces hovered state on the inner select. */\n isHovered?: boolean;\n /** Forces focused state on the inner select. */\n isFocused?: boolean;\n /** Makes the select span the full width of parent. */\n isFullwidth?: boolean;\n /** Makes the select span the full width of parent. @deprecated Use `isFullwidth` instead — `isFullwidth` wins if both are set. */\n isFullWidth?: boolean;\n /** Additional CSS classes to apply. */\n className?: string;\n /** Disables the select. */\n disabled?: boolean;\n /** Allows multiple selections. */\n multiple?: boolean;\n /** Number of visible options in multiselect. */\n multipleSize?: number;\n /** `<option>` elements. */\n children?: React.ReactNode;\n}\n\n/**\n * Bulma Select component with full Bulma helper class support.\n *\n * @function\n * @param {SelectBaseProps} props - Props for the SelectBase component.\n * @returns {JSX.Element} The rendered select element.\n * @see {@link https://bulma.io/documentation/form/select/ | Bulma Select documentation}\n */\nexport const SelectBase = forwardRef<HTMLSelectElement, SelectBaseProps>(\n (\n {\n color,\n size,\n isRounded,\n isLoading,\n isActive,\n isHovered,\n isFocused,\n isFullwidth,\n isFullWidth,\n className,\n disabled,\n children,\n multiple,\n multipleSize,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color,\n ...props,\n });\n // A labeled Field's generated id when no user id arrived (rest.id may be\n // an undefined own key), reported to that Field (#1004).\n const id = useFieldLabelTarget(rest.id);\n\n const mainClass = usePrefixedClassNames('select', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-rounded': isRounded,\n 'is-loading': isLoading,\n 'is-active': isActive,\n 'is-multiple': !!multiple,\n 'is-fullwidth': isFullwidth ?? isFullWidth,\n });\n const selectClass = classNames(mainClass, bulmaHelperClasses, className);\n\n // is-hovered / is-focused belong on the inner <select> element, not the wrapper.\n const innerSelectClass = usePrefixedClassNames('', {\n 'is-hovered': isHovered,\n 'is-focused': isFocused,\n });\n\n // Only set size attribute when multiple is true and multipleSize is specified\n const selectProps: React.SelectHTMLAttributes<HTMLSelectElement> = {\n disabled,\n multiple,\n ...rest,\n };\n\n if (multiple && typeof multipleSize === 'number') {\n selectProps.size = multipleSize;\n }\n\n return (\n <div className={selectClass}>\n <select\n ref={ref}\n className={innerSelectClass || undefined}\n {...selectProps}\n // After the spread, which may carry an undefined id key; the id\n // belongs on the inner <select>.\n id={id}\n >\n {children}\n </select>\n </div>\n );\n }\n);\n\nSelectBase.displayName = 'SelectBase';\n\nexport default SelectBase;\n"],"names":["_jsx"],"mappings":";;;;;;;AA2DA;;;;;;;AAOG;AACI,MAAM,UAAU,GAAG,UAAU,CAClC,CACE,EACE,KAAK,EACL,IAAI,EACJ,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,GAAG,KAAK,EACT,EACD,GAAG,KACD;AACF,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;QACnD,KAAK;AACL,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;;;IAGF,MAAM,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEvC,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,QAAQ,EAAE;AAChD,QAAA,CAAC,MAAM,KAAK,CAAA,CAAE,GAAG,CAAC,CAAC,KAAK;AACxB,QAAA,CAAC,MAAM,IAAI,CAAA,CAAE,GAAG,CAAC,CAAC,IAAI;AACtB,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,WAAW,EAAE,QAAQ;QACrB,aAAa,EAAE,CAAC,CAAC,QAAQ;QACzB,cAAc,EAAE,WAAW,IAAI,WAAW;AAC3C,KAAA,CAAC;IACF,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,EAAE,kBAAkB,EAAE,SAAS,CAAC;;AAGxE,IAAA,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,EAAE,EAAE;AACjD,QAAA,YAAY,EAAE,SAAS;AACvB,QAAA,YAAY,EAAE,SAAS;AACxB,KAAA,CAAC;;AAGF,IAAA,MAAM,WAAW,GAAkD;QACjE,QAAQ;QACR,QAAQ;AACR,QAAA,GAAG,IAAI;KACR;AAED,IAAA,IAAI,QAAQ,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE;AAChD,QAAA,WAAW,CAAC,IAAI,GAAG,YAAY;IACjC;AAEA,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,WAAW,YACzBA,GAAA,CAAA,QAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,gBAAgB,IAAI,SAAS,KACpC,WAAW;;;AAGf,YAAA,EAAE,EAAE,EAAE,EAAA,QAAA,EAEL,QAAQ,EAAA,CACF,EAAA,CACL;AAEV,CAAC;AAGH,UAAU,CAAC,WAAW,GAAG,YAAY;;"}
|