@allxsmith/bestax-bulma 5.27.3 → 5.27.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/form/Field.js.map +1 -1
- package/dist/esm/form/FormContext.js +4 -2
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/Slider.js +39 -4
- package/dist/esm/form/Slider.js.map +1 -1
- package/dist/esm/form/useAutoLabelId.js +21 -9
- package/dist/esm/form/useAutoLabelId.js.map +1 -1
- package/dist/index.cjs +64 -15
- package/dist/index.cjs.map +1 -1
- package/dist/types/form/Field.d.ts +2 -2
- package/dist/types/form/FormContext.d.ts +4 -2
- package/dist/types/form/Slider.d.ts +4 -4
- package/dist/types/form/useAutoLabelId.d.ts +16 -2
- package/dist/types-cjs/form/Field.d.ts +2 -2
- package/dist/types-cjs/form/FormContext.d.ts +4 -2
- package/dist/types-cjs/form/Slider.d.ts +4 -4
- package/dist/types-cjs/form/useAutoLabelId.d.ts +16 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sources":["../../../src/form/Field.tsx"],"sourcesContent":["import React, { useId } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport {\n FieldProvider,\n FieldLabelIdProvider,\n FieldLabelElementIdProvider,\n FieldLabelForProvider,\n useFieldLabelFor,\n} from './FormContext';\nimport { Control } from './Control';\n\n/**\n * Props for the Field component.\n */\nexport interface FieldProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Renders the field as horizontal (label and control side by side). */\n horizontal?: boolean;\n /** Group controls in a row (optionally centered, right, or multiline). */\n grouped?: boolean | 'centered' | 'right' | 'multiline';\n /** Group controls as addons (optionally centered or right-aligned). */\n hasAddons?: boolean | 'centered' | 'right';\n /** Constrains the field to its content's width (used inside horizontal field bodies). */\n narrow?: boolean;\n /** Field label, rendered above the widget. Automatically names the one control the Field holds: a composed `InputBase`, `SelectBase` or `TextAreaBase`, or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id that the label's `htmlFor` points at, and a group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`) points `aria-labelledby` at the label's own id unless you gave the group an `aria-label` or `aria-labelledby`. Nothing else takes the label: `Checkbox`, `Radio` and `Switch` are named by their own children. Only the single inputs take the `htmlFor`, so with a group or any other content it matches nothing. Pass `labelProps={{ htmlFor }}` to wire your own `id`, or `labelProps={{ htmlFor: undefined }}` to opt out. Skipped for `grouped`/`hasAddons` fields (multiple controls), and a nested `Field` starts its own scope, so a horizontal Field whose body holds an inner `Field` names the control there only when you wire it. Two controls in one plain labeled Field would both adopt the id, so give each an `id` of its own. */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: 'small' | 'normal' | 'medium' | 'large';\n /** Props for the label element. An explicit `htmlFor` key — even set to `undefined` — takes over the association. An `id` here is the one a group control's `aria-labelledby` points at; otherwise the label gets a generated one while the association is on. To point a group in an inner `Field` at this label by hand, pass that `id` with `htmlFor: undefined`, or the label keeps a generated `htmlFor` that nothing takes. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Text color for the field. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldLabel component.\n */\nexport interface FieldLabelProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Size for the field label. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /** Text color for the label. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the label. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the label. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field label content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldBody component.\n */\nexport interface FieldBodyProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Text color for the field body. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field body. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field body. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field body content. */\n children?: React.ReactNode;\n}\n\n/**\n * FieldLabel component for rendering a Bulma field label.\n *\n * @function\n * @param {FieldLabelProps} props - Props for the FieldLabel component.\n * @returns {JSX.Element} The rendered field label.\n *\n * @example\n * <FieldLabel size=\"normal\">Name</FieldLabel>\n */\nexport const FieldLabel: React.FC<FieldLabelProps> = ({\n size,\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-label', {\n [`is-${size}`]: !!size,\n });\n const fieldLabelClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldLabelClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * FieldBody component for rendering Bulma field body.\n *\n * @function\n * @param {FieldBodyProps} props - Props for the FieldBody component.\n * @returns {JSX.Element} The rendered field body.\n *\n * @example\n * <FieldBody><input className=\"input\" /></FieldBody>\n */\nexport const FieldBody: React.FC<FieldBodyProps> = ({\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-body');\n const fieldBodyClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldBodyClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * The `Field` component is a Bulma-styled form field container.\n *\n * @function\n * @param {FieldProps} props - Props for the Field component.\n * @returns {JSX.Element} The rendered field container.\n * @see {@link https://bulma.io/documentation/form/general/#field | Bulma Field documentation}\n *\n * @example\n * // Labelled field — the label auto-associates with the composed base\n * <Field label=\"Email\">\n * <Control>\n * <InputBase type=\"email\" />\n * </Control>\n * </Field>\n *\n * @example\n * // Horizontal field\n * <Field horizontal label=\"Name\">\n * <Control>\n * <InputBase />\n * </Control>\n * </Field>\n */\nconst FieldComponent: React.FC<FieldProps> = ({\n horizontal,\n grouped,\n hasAddons,\n narrow,\n label,\n labelSize,\n labelProps,\n textColor,\n color: _fieldColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field', {\n 'is-horizontal': horizontal,\n 'has-addons': !!hasAddons,\n 'has-addons-centered': hasAddons === 'centered',\n 'has-addons-right': hasAddons === 'right',\n 'is-narrow': narrow,\n 'is-grouped':\n grouped === true ||\n grouped === 'centered' ||\n grouped === 'right' ||\n grouped === 'multiline',\n 'is-grouped-centered': grouped === 'centered',\n 'is-grouped-right': grouped === 'right',\n 'is-grouped-multiline': grouped === 'multiline',\n });\n const fieldClass = classNames(mainClass, bulmaHelperClasses, className);\n\n // Default labelSize to 'normal' when horizontal for proper baseline alignment\n const effectiveLabelSize = labelSize ?? (horizontal ? 'normal' : undefined);\n\n const labelClass = usePrefixedClassNames('label');\n\n // Auto-associate the label with a single composed base control (#495): the\n // label points at a generated id shared via context, which InputBase/\n // SelectBase/TextAreaBase adopt when the user supplied no id of their own.\n // Presence semantics on htmlFor — even an explicit `htmlFor: undefined`\n // means the caller owns the association. Grouped/addons fields hold several\n // controls, so no single association is generated for them.\n const generatedId = useId();\n const userWiredLabel = !!labelProps && 'htmlFor' in labelProps;\n const targetId =\n label && !userWiredLabel && !grouped && !hasAddons\n ? generatedId\n : undefined;\n // A group control (Radios, Checkboxes, Rate, DateRangeInput) cannot take\n // that `for`, so it points `aria-labelledby` at the label itself (#939).\n // The label gets an id whenever the association is on, unless the caller\n // gave it one.\n const labelId =\n labelProps?.id ?? (targetId ? `${targetId}-label` : undefined);\n // What the rendered label's `for` points at, generated or the caller's, so\n // a control can tell when a label wired by hand names it. An unlabeled\n // Field passes on its parent's.\n const inheritedLabelFor = useFieldLabelFor();\n const labelFor = label\n ? userWiredLabel\n ? labelProps.htmlFor\n : targetId\n : inheritedLabelFor;\n\n let renderedLabel = null;\n if (label) {\n if (horizontal) {\n renderedLabel = (\n <FieldLabel size={effectiveLabelSize}>\n <label\n htmlFor={targetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={labelProps?.style}\n >\n {label}\n </label>\n </FieldLabel>\n );\n } else {\n renderedLabel = (\n <label\n htmlFor={targetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={{ display: 'block', ...(labelProps?.style || {}) }}\n >\n {label}\n </label>\n );\n }\n }\n\n // If horizontal, wrap children in FieldBody (unless the user already provided\n // a FieldBody — either as the single child, or as one element among siblings\n // like <Field.Label/> + <Field.Body/>).\n let content = children;\n if (horizontal) {\n const isFieldBody = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldBody || c.type?.displayName === 'FieldBody');\n const isFieldLabel = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldLabel || c.type?.displayName === 'FieldLabel');\n const childArray = React.Children.toArray(children);\n const userProvidedStructure = childArray.some(\n c => isFieldBody(c) || isFieldLabel(c)\n );\n if (userProvidedStructure) {\n content = children;\n } else {\n content = <FieldBody>{children}</FieldBody>;\n }\n }\n\n return (\n <FieldProvider value={true}>\n <FieldLabelIdProvider value={targetId}>\n <FieldLabelElementIdProvider value={targetId ? labelId : undefined}>\n <FieldLabelForProvider value={labelFor}>\n <div className={fieldClass} {...rest}>\n {renderedLabel}\n {content}\n </div>\n </FieldLabelForProvider>\n </FieldLabelElementIdProvider>\n </FieldLabelIdProvider>\n </FieldProvider>\n );\n};\n\nFieldLabel.displayName = 'FieldLabel';\nFieldBody.displayName = 'FieldBody';\n\nexport const Field = withSubComponents(\n FieldComponent,\n {\n Label: FieldLabel,\n Body: FieldBody,\n Control,\n },\n 'Field'\n);\n\nexport default Field;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Field.js","sources":["../../../src/form/Field.tsx"],"sourcesContent":["import React, { useId } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport {\n FieldProvider,\n FieldLabelIdProvider,\n FieldLabelElementIdProvider,\n FieldLabelForProvider,\n useFieldLabelFor,\n} from './FormContext';\nimport { Control } from './Control';\n\n/**\n * Props for the Field component.\n */\nexport interface FieldProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Renders the field as horizontal (label and control side by side). */\n horizontal?: boolean;\n /** Group controls in a row (optionally centered, right, or multiline). */\n grouped?: boolean | 'centered' | 'right' | 'multiline';\n /** Group controls as addons (optionally centered or right-aligned). */\n hasAddons?: boolean | 'centered' | 'right';\n /** Constrains the field to its content's width (used inside horizontal field bodies). */\n narrow?: boolean;\n /** Field label, rendered above the widget. Automatically names the one control the Field holds: a composed `InputBase`, `SelectBase` or `TextAreaBase`, or a bestax input that renders a single input of its own (`Input`, `Select`, `TextArea`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`, `Taginput`, `File`), adopts a generated id that the label's `htmlFor` points at, and a group (`Radios`, `Checkboxes`, `Rate`, `DateRangeInput`) points `aria-labelledby` at the label's own id unless you gave the group an `aria-label` or `aria-labelledby`. A range `Slider` takes the id on its low thumb and also starts each thumb's name with the label through `aria-labelledby`, unless its `ariaLabel` names that thumb or its own `aria-label` or `aria-labelledby` takes the label's place. Nothing else takes the label: `Checkbox`, `Radio` and `Switch` are named by their own children. Only the single inputs take the `htmlFor`, so with a group or any other content it matches nothing. Pass `labelProps={{ htmlFor }}` to wire your own `id`, or `labelProps={{ htmlFor: undefined }}` to opt out. Skipped for `grouped`/`hasAddons` fields (multiple controls), and a nested `Field` starts its own scope, so a horizontal Field whose body holds an inner `Field` names the control there only when you wire it. Two controls in one plain labeled Field would both adopt the id, so give each an `id` of its own. */\n label?: React.ReactNode;\n /** Size for the label. */\n labelSize?: 'small' | 'normal' | 'medium' | 'large';\n /** Props for the label element. An explicit `htmlFor` key — even set to `undefined` — takes over the association. An `id` here is the one a group control's, or a range `Slider`'s, `aria-labelledby` points at; otherwise the label gets a generated one while the association is on. To point a group in an inner `Field` at this label by hand, pass that `id` with `htmlFor: undefined`, or the label keeps a generated `htmlFor` that nothing takes. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Text color for the field. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldLabel component.\n */\nexport interface FieldLabelProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Size for the field label. */\n size?: 'small' | 'normal' | 'medium' | 'large';\n /** Text color for the label. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the label. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the label. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field label content. */\n children?: React.ReactNode;\n}\n\n/**\n * Props for the FieldBody component.\n */\nexport interface FieldBodyProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /** Text color for the field body. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Bulma color for the field body. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Background color for the field body. */\n bgColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Additional CSS classes. */\n className?: string;\n /** Field body content. */\n children?: React.ReactNode;\n}\n\n/**\n * FieldLabel component for rendering a Bulma field label.\n *\n * @function\n * @param {FieldLabelProps} props - Props for the FieldLabel component.\n * @returns {JSX.Element} The rendered field label.\n *\n * @example\n * <FieldLabel size=\"normal\">Name</FieldLabel>\n */\nexport const FieldLabel: React.FC<FieldLabelProps> = ({\n size,\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-label', {\n [`is-${size}`]: !!size,\n });\n const fieldLabelClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldLabelClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * FieldBody component for rendering Bulma field body.\n *\n * @function\n * @param {FieldBodyProps} props - Props for the FieldBody component.\n * @returns {JSX.Element} The rendered field body.\n *\n * @example\n * <FieldBody><input className=\"input\" /></FieldBody>\n */\nexport const FieldBody: React.FC<FieldBodyProps> = ({\n textColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field-body');\n const fieldBodyClass = classNames(mainClass, bulmaHelperClasses, className);\n // Spread ...props and ...rest so custom props like data-testid are included\n return (\n <div className={fieldBodyClass} {...props} {...rest}>\n {children}\n </div>\n );\n};\n\n/**\n * The `Field` component is a Bulma-styled form field container.\n *\n * @function\n * @param {FieldProps} props - Props for the Field component.\n * @returns {JSX.Element} The rendered field container.\n * @see {@link https://bulma.io/documentation/form/general/#field | Bulma Field documentation}\n *\n * @example\n * // Labelled field — the label auto-associates with the composed base\n * <Field label=\"Email\">\n * <Control>\n * <InputBase type=\"email\" />\n * </Control>\n * </Field>\n *\n * @example\n * // Horizontal field\n * <Field horizontal label=\"Name\">\n * <Control>\n * <InputBase />\n * </Control>\n * </Field>\n */\nconst FieldComponent: React.FC<FieldProps> = ({\n horizontal,\n grouped,\n hasAddons,\n narrow,\n label,\n labelSize,\n labelProps,\n textColor,\n color: _fieldColor,\n bgColor,\n className,\n children,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n backgroundColor: bgColor,\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('field', {\n 'is-horizontal': horizontal,\n 'has-addons': !!hasAddons,\n 'has-addons-centered': hasAddons === 'centered',\n 'has-addons-right': hasAddons === 'right',\n 'is-narrow': narrow,\n 'is-grouped':\n grouped === true ||\n grouped === 'centered' ||\n grouped === 'right' ||\n grouped === 'multiline',\n 'is-grouped-centered': grouped === 'centered',\n 'is-grouped-right': grouped === 'right',\n 'is-grouped-multiline': grouped === 'multiline',\n });\n const fieldClass = classNames(mainClass, bulmaHelperClasses, className);\n\n // Default labelSize to 'normal' when horizontal for proper baseline alignment\n const effectiveLabelSize = labelSize ?? (horizontal ? 'normal' : undefined);\n\n const labelClass = usePrefixedClassNames('label');\n\n // Auto-associate the label with a single composed base control (#495): the\n // label points at a generated id shared via context, which InputBase/\n // SelectBase/TextAreaBase adopt when the user supplied no id of their own.\n // Presence semantics on htmlFor — even an explicit `htmlFor: undefined`\n // means the caller owns the association. Grouped/addons fields hold several\n // controls, so no single association is generated for them.\n const generatedId = useId();\n const userWiredLabel = !!labelProps && 'htmlFor' in labelProps;\n const targetId =\n label && !userWiredLabel && !grouped && !hasAddons\n ? generatedId\n : undefined;\n // A group control (Radios, Checkboxes, Rate, DateRangeInput) cannot take\n // that `for`, so it points `aria-labelledby` at the label itself (#939).\n // The label gets an id whenever the association is on, unless the caller\n // gave it one.\n const labelId =\n labelProps?.id ?? (targetId ? `${targetId}-label` : undefined);\n // What the rendered label's `for` points at, generated or the caller's, so\n // a control can tell when a label wired by hand names it. An unlabeled\n // Field passes on its parent's.\n const inheritedLabelFor = useFieldLabelFor();\n const labelFor = label\n ? userWiredLabel\n ? labelProps.htmlFor\n : targetId\n : inheritedLabelFor;\n\n let renderedLabel = null;\n if (label) {\n if (horizontal) {\n renderedLabel = (\n <FieldLabel size={effectiveLabelSize}>\n <label\n htmlFor={targetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={labelProps?.style}\n >\n {label}\n </label>\n </FieldLabel>\n );\n } else {\n renderedLabel = (\n <label\n htmlFor={targetId}\n {...labelProps}\n id={labelId}\n className={classNames(labelClass, labelProps?.className)}\n style={{ display: 'block', ...(labelProps?.style || {}) }}\n >\n {label}\n </label>\n );\n }\n }\n\n // If horizontal, wrap children in FieldBody (unless the user already provided\n // a FieldBody — either as the single child, or as one element among siblings\n // like <Field.Label/> + <Field.Body/>).\n let content = children;\n if (horizontal) {\n const isFieldBody = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldBody || c.type?.displayName === 'FieldBody');\n const isFieldLabel = (c: React.ReactNode): boolean =>\n React.isValidElement(c) &&\n // @ts-expect-error displayName isn't on the public type\n (c.type === FieldLabel || c.type?.displayName === 'FieldLabel');\n const childArray = React.Children.toArray(children);\n const userProvidedStructure = childArray.some(\n c => isFieldBody(c) || isFieldLabel(c)\n );\n if (userProvidedStructure) {\n content = children;\n } else {\n content = <FieldBody>{children}</FieldBody>;\n }\n }\n\n return (\n <FieldProvider value={true}>\n <FieldLabelIdProvider value={targetId}>\n <FieldLabelElementIdProvider value={targetId ? labelId : undefined}>\n <FieldLabelForProvider value={labelFor}>\n <div className={fieldClass} {...rest}>\n {renderedLabel}\n {content}\n </div>\n </FieldLabelForProvider>\n </FieldLabelElementIdProvider>\n </FieldLabelIdProvider>\n </FieldProvider>\n );\n};\n\nFieldLabel.displayName = 'FieldLabel';\nFieldBody.displayName = 'FieldBody';\n\nexport const Field = withSubComponents(\n FieldComponent,\n {\n Label: FieldLabel,\n Body: FieldBody,\n Control,\n },\n 'Field'\n);\n\nexport default Field;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -154,8 +154,10 @@ const FieldLabelElementIdContext = createContext(undefined);
|
|
|
154
154
|
/**
|
|
155
155
|
* The id of a labeled Field's own `<label>`, for a group control (Radios,
|
|
156
156
|
* Checkboxes, Rate, DateRangeInput) to point `aria-labelledby` at, since a group cannot take
|
|
157
|
-
* the label's `htmlFor` (#939)
|
|
158
|
-
*
|
|
157
|
+
* the label's `htmlFor` (#939), and for a range Slider's thumbs, which each
|
|
158
|
+
* need the label in a name of their own (#981). Set under the same conditions
|
|
159
|
+
* as {@link useFieldLabelId}. Consumed through `useAutoLabelledBy` and
|
|
160
|
+
* `useAutoLabelId`.
|
|
159
161
|
* Internal; not part of the public API.
|
|
160
162
|
*/
|
|
161
163
|
const useFieldLabelElementId = () => useContext(FieldLabelElementIdContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormContext.js","sources":["../../../src/form/FormContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from 'react';\nimport { warnOnce } from '../helpers/devWarnings';\nimport type { ControlBaseProps } from './Control';\n\nconst FieldContext = createContext(false);\nconst ControlContext = createContext(false);\n\n/**\n * Hook to detect if the component is inside a Field wrapper.\n * Form components use this to skip rendering their own Field.\n */\nexport const useInsideField = () => useContext(FieldContext);\n\n/**\n * Hook to detect if the component is inside a Control wrapper.\n * Form components use this to skip rendering their own Control.\n */\nexport const useInsideControl = () => useContext(ControlContext);\n\n/** Provider for Field context — used internally by Field component. */\nexport const FieldProvider = FieldContext.Provider;\n\n/** Provider for Control context — used internally by Control component. */\nexport const ControlProvider = ControlContext.Provider;\n\n/** The wrapper props that change what its own `Field` renders. */\ninterface FieldShapingProps {\n /** Rendered as the `Field`'s label. */\n label?: React.ReactNode;\n /** Rendered as help text after the widget. */\n message?: React.ReactNode;\n /** Lays the `Field` out horizontally. */\n horizontal?: boolean;\n /** Set on the `Field` as its class. */\n fieldClassName?: string;\n}\n\ninterface OwnFieldOptions extends FieldShapingProps {\n /** `useInsideField()` as the wrapper read it. */\n insideField: boolean;\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n}\n\n// Each Field-shaping prop, with what takes its place on a `Field` the caller\n// wraps around the `Control`. `message` needs nothing there, because the\n// wrapper still renders it inside `Field > Control`. The other Field-level\n// props (`labelSize`, `labelProps`, `messageColor`) change nothing unless a\n// `label` or `message` renders, so on their own they keep no `Field`.\n// `bare-control.test.tsx` holds this list to what each wrapper hands its\n// `Field` and to which props change its markup, so a new Field-level prop\n// fails there until it is sorted into one group or the other.\nconst FIELD_SHAPING: ReadonlyArray<\n [keyof FieldShapingProps, string | undefined]\n> = [\n ['label', 'label'],\n ['message', undefined],\n ['horizontal', 'horizontal'],\n ['fieldClassName', 'className (for fieldClassName)'],\n];\n\n/** `a`, `a and b`, `a, b and c`. */\nconst listOf = (items: string[]): string =>\n items.length > 1\n ? `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`\n : items[0];\n\n/**\n * Whether a convenience form wrapper renders a `Field` of its own (#905).\n * Never inside an outer `Field`. Inside a `Control` with no `Field` around\n * it, a `Field` of its own would put a `.field` inside the `.control`, where\n * Bulma's control styles break (its icon rules are sibling selectors on the\n * input). So it renders one there only when a prop that shapes the `Field`'s\n * markup is set (`label`, `message`, `horizontal`, `fieldClassName`), keeping\n * the markup it always had, and warns in development that the fix is a\n * `Field` around that `Control`. A prop counts when it is truthy, the same\n * test that decides whether it changes the `Field`'s output.\n * Internal; not part of the public API.\n */\nexport const rendersOwnField = (\n component: string,\n options: OwnFieldOptions\n): boolean => {\n if (options.insideField) return false;\n if (!options.insideControl) return true;\n const held = FIELD_SHAPING.filter(([prop]) => options[prop]);\n if (held.length === 0) return false;\n const names = held.map(([prop]) => prop);\n const moved = held\n .map(([, onField]) => onField)\n .filter((onField): onField is string => onField !== undefined);\n warnOnce(\n `${component}:Field-in-bare-Control:${names.join('+')}`,\n `[bestax-bulma] <${component} ${names.join(' ')}> inside a <Control> ` +\n `with no <Field> around it renders its own <Field> for ` +\n `${names.length > 1 ? 'those props' : 'that prop'}, which puts a ` +\n `.field inside the .control, a nesting Bulma's styles are not ` +\n `written for. Wrap the <Control> in a <Field> instead` +\n (moved.length > 0 ? `, and set ${listOf(moved)} on that <Field>.` : '.')\n );\n return true;\n};\n\n/** The props a convenience form wrapper hands its own `Control`. Internal. */\nexport interface ControlLevelProps {\n /** Shows the `Control`'s loading spinner. */\n isLoading?: boolean;\n /** The `Control`'s left icon. */\n iconLeft?: ControlBaseProps['iconLeft'];\n /** Shortcut for the left icon's name. */\n iconLeftName?: string;\n /** Shortcut for the left icon's size. */\n iconLeftSize?: ControlBaseProps['iconLeftSize'];\n /** The `Control`'s right icon. */\n iconRight?: ControlBaseProps['iconRight'];\n /** Shortcut for the right icon's name. */\n iconRightName?: string;\n /** Shortcut for the right icon's size. */\n iconRightSize?: ControlBaseProps['iconRightSize'];\n /** Reserves the `Control`'s left icon space. */\n hasIconsLeft?: boolean;\n /** Reserves the `Control`'s right icon space. */\n hasIconsRight?: boolean;\n /** Expands the `Control`. */\n isExpanded?: boolean;\n /** Set on the `Control` as its `size`. */\n controlSize?: ControlBaseProps['size'];\n /** Set on the `Control` as its class. */\n controlClassName?: string;\n}\n\ninterface OwnControlOptions extends ControlLevelProps {\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n /** A picker's `inline`, which renders no `Control` inside one or out. */\n inline?: boolean;\n /**\n * The left glyph the wrapper's own `Control` shows when the caller sets no\n * `iconLeftName`; read only then. `bare-control.test.tsx` reads that glyph\n * from what each wrapper hands its own `Control`, so a wrapper that gains\n * one fails there until it passes it here.\n */\n defaultIconLeftName?: string;\n}\n\n// Each Control-level prop, with what takes its place on the `Control` the\n// caller wrapped around the wrapper. `bare-control.test.tsx` holds this to\n// what each wrapper hands its own `Control`, so a new Control-level prop\n// fails there until it is added here and passed to `rendersOwnControl`.\nconst ON_CONTROL: Record<keyof ControlLevelProps, string> = {\n isLoading: 'isLoading',\n iconLeft: 'iconLeft',\n iconLeftName: 'iconLeftName',\n iconLeftSize: 'iconLeftSize',\n iconRight: 'iconRight',\n iconRightName: 'iconRightName',\n iconRightSize: 'iconRightSize',\n hasIconsLeft: 'hasIconsLeft',\n hasIconsRight: 'hasIconsRight',\n isExpanded: 'isExpanded',\n controlSize: 'size (for controlSize)',\n controlClassName: 'className (for controlClassName)',\n};\n\n/**\n * Whether a convenience form wrapper renders a `Control` of its own (#921):\n * only outside one. Inside a `Control` it renders none, so the props it\n * would have handed its own do nothing there, and it warns in development,\n * naming them and saying to set them on that `Control`. An `inline` picker\n * renders none in either place, so it drops them inside a `Control` or not,\n * and its warning says so without pointing at a `Control`. A wrapper passes\n * only the props it hands its own `Control`, as the caller gave them, so a\n * default the wrapper fills in itself never warns. A prop counts when it is\n * truthy, since a falsy one would change nothing on a `Control` either.\n * `iconLeftSize` and `hasIconsLeft` show nothing on a `Control` without a\n * glyph, so when they move and the caller chose no left icon, the advice\n * names the wrapper's default glyph too, and following it draws what the\n * wrapper's own `Control` did.\n * Internal; not part of the public API.\n */\nexport const rendersOwnControl = (\n component: string,\n options: OwnControlOptions\n): boolean => {\n if (!options.inline && !options.insideControl) return true;\n const held = (\n Object.keys(ON_CONTROL) as Array<keyof ControlLevelProps>\n ).filter(prop => options[prop]);\n if (held.length === 0) return false;\n const names = held.join(' ');\n const doNothing = held.length > 1 ? 'those props do' : 'that prop does';\n let message: string;\n if (options.inline) {\n message =\n `[bestax-bulma] <${component} inline ${names}> renders no <Control> ` +\n `in inline mode, inside a <Control> or not, so ${doNothing} ` +\n `nothing. Leave ${held.length > 1 ? 'them' : 'it'} out of an ` +\n `inline picker.`;\n } else {\n const toSet = held.map(prop => ON_CONTROL[prop]);\n const needsGlyph =\n (options.iconLeftSize || options.hasIconsLeft) &&\n !options.iconLeft &&\n options.iconLeftName === undefined &&\n options.defaultIconLeftName;\n if (needsGlyph) {\n toSet.push(\n `iconLeftName=\"${options.defaultIconLeftName}\" (its default icon)`\n );\n }\n message =\n `[bestax-bulma] <${component} ${names}> inside a <Control> renders ` +\n `no <Control> of its own, so ${doNothing} nothing there. Set ` +\n `${listOf(toSet)} on that <Control> instead.`;\n }\n // Keyed by the message itself: the props named do not settle the advice\n // (an empty `iconLeftName` and an unset one name the same props), so two\n // calls that would advise differently must not share a key.\n warnOnce(message, message);\n return false;\n};\n\nconst FieldLabelIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id a labeled Field wants its single composed control to adopt (#495).\n * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the\n * user took over the association with an explicit `labelProps.htmlFor`.\n * Consumed by the single-control bases (InputBase, SelectBase, TextAreaBase)\n * and, through `useAutoLabelId`, by the convenience inputs that render an\n * input of their own (#939). Internal; not part of the public API.\n */\nexport const useFieldLabelId = () => useContext(FieldLabelIdContext);\n\n/** Provider for the Field label-target id — used internally by Field. */\nexport const FieldLabelIdProvider = FieldLabelIdContext.Provider;\n\nconst FieldLabelElementIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id of a labeled Field's own `<label>`, for a group control (Radios,\n * Checkboxes, Rate, DateRangeInput) to point `aria-labelledby` at, since a group cannot take\n * the label's `htmlFor` (#939). Set under the same conditions as\n * {@link useFieldLabelId}. Consumed through `useAutoLabelledBy`.\n * Internal; not part of the public API.\n */\nexport const useFieldLabelElementId = () =>\n useContext(FieldLabelElementIdContext);\n\n/** Provider for the Field label's own id, used internally by Field. */\nexport const FieldLabelElementIdProvider = FieldLabelElementIdContext.Provider;\n\nconst FieldLabelForContext = createContext<string | undefined>(undefined);\n\n/**\n * What the nearest labeled Field's `<label>` points `htmlFor` at: the id it\n * generated, or the caller's own `labelProps.htmlFor`. An unlabeled Field\n * passes it through, so a control in the inner Field of a horizontal layout\n * can tell the outer label names it. Only ever compared with a control's own\n * id, never adopted, so it hands out no id. Internal; not part of the public\n * API.\n */\nexport const useFieldLabelFor = () => useContext(FieldLabelForContext);\n\n/** Provider for the Field label's `htmlFor` target, used internally by Field. */\nexport const FieldLabelForProvider = FieldLabelForContext.Provider;\n\n/**\n * Shape of the Radios group context. The group provides:\n * - `name`: shared form field name (Stage 1)\n * - `value`: currently-selected radio value (Stage 2 — group-managed selection)\n * - `onChange`: dispatched by child Radios when clicked (Stage 2)\n *\n * Group sets `value`/`onChange` only when actively managing selection\n * (i.e., the user passed `value`, `defaultValue`, or `onChange` to `<Radios>`).\n * When only `name` is provided, the group is in \"name-only\" mode and child\n * Radios manage their own checked state independently.\n */\nexport interface RadiosGroupContextValue {\n name?: string;\n value?: string;\n onChange?: (value: string) => void;\n}\n\n/**\n * Shape of the Checkboxes group context. Like Radios but with array semantics\n * for multi-select.\n */\nexport interface CheckboxesGroupContextValue {\n name?: string;\n value?: string[];\n onChange?: (values: string[]) => void;\n}\n\nconst RadiosContext = createContext<RadiosGroupContextValue | undefined>(\n undefined\n);\nconst CheckboxesContext = createContext<\n CheckboxesGroupContextValue | undefined\n>(undefined);\n\n/**\n * Hook to read the full surrounding `<Radios>` group context (name + selection).\n * Returns `undefined` when not inside a `<Radios>` group.\n */\nexport const useRadiosGroup = () => useContext(RadiosContext);\n\n/**\n * Hook to read the full surrounding `<Checkboxes>` group context.\n * Returns `undefined` when not inside a `<Checkboxes>` group.\n */\nexport const useCheckboxesGroup = () => useContext(CheckboxesContext);\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Radios>` group.\n * Child `<Radio>` components fall back to this when no local `name` prop is set.\n * Returns `undefined` outside of a `<Radios>` group.\n */\nexport const useRadiosName = () => useRadiosGroup()?.name;\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Checkboxes>` group.\n * Returns `undefined` outside of a `<Checkboxes>` group.\n */\nexport const useCheckboxesName = () => useCheckboxesGroup()?.name;\n\n/** Provider for the Radios group context — used internally by Radios. */\nexport const RadiosProvider = RadiosContext.Provider;\n\n/** Provider for the Checkboxes group context — used internally by Checkboxes. */\nexport const CheckboxesProvider = CheckboxesContext.Provider;\n\n// --- Backward-compat aliases (Stage 1 names) -----------------------------\n// Internal callers may still import these. Both still work because they refer\n// to the same providers/hooks under the new shape.\n\n/** @deprecated Use `RadiosProvider` (provides {name, value, onChange}). */\nexport const RadiosNameProvider = RadiosProvider;\n\n/** @deprecated Use `CheckboxesProvider` (provides {name, value, onChange}). */\nexport const CheckboxesNameProvider = CheckboxesProvider;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FormContext.js","sources":["../../../src/form/FormContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from 'react';\nimport { warnOnce } from '../helpers/devWarnings';\nimport type { ControlBaseProps } from './Control';\n\nconst FieldContext = createContext(false);\nconst ControlContext = createContext(false);\n\n/**\n * Hook to detect if the component is inside a Field wrapper.\n * Form components use this to skip rendering their own Field.\n */\nexport const useInsideField = () => useContext(FieldContext);\n\n/**\n * Hook to detect if the component is inside a Control wrapper.\n * Form components use this to skip rendering their own Control.\n */\nexport const useInsideControl = () => useContext(ControlContext);\n\n/** Provider for Field context — used internally by Field component. */\nexport const FieldProvider = FieldContext.Provider;\n\n/** Provider for Control context — used internally by Control component. */\nexport const ControlProvider = ControlContext.Provider;\n\n/** The wrapper props that change what its own `Field` renders. */\ninterface FieldShapingProps {\n /** Rendered as the `Field`'s label. */\n label?: React.ReactNode;\n /** Rendered as help text after the widget. */\n message?: React.ReactNode;\n /** Lays the `Field` out horizontally. */\n horizontal?: boolean;\n /** Set on the `Field` as its class. */\n fieldClassName?: string;\n}\n\ninterface OwnFieldOptions extends FieldShapingProps {\n /** `useInsideField()` as the wrapper read it. */\n insideField: boolean;\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n}\n\n// Each Field-shaping prop, with what takes its place on a `Field` the caller\n// wraps around the `Control`. `message` needs nothing there, because the\n// wrapper still renders it inside `Field > Control`. The other Field-level\n// props (`labelSize`, `labelProps`, `messageColor`) change nothing unless a\n// `label` or `message` renders, so on their own they keep no `Field`.\n// `bare-control.test.tsx` holds this list to what each wrapper hands its\n// `Field` and to which props change its markup, so a new Field-level prop\n// fails there until it is sorted into one group or the other.\nconst FIELD_SHAPING: ReadonlyArray<\n [keyof FieldShapingProps, string | undefined]\n> = [\n ['label', 'label'],\n ['message', undefined],\n ['horizontal', 'horizontal'],\n ['fieldClassName', 'className (for fieldClassName)'],\n];\n\n/** `a`, `a and b`, `a, b and c`. */\nconst listOf = (items: string[]): string =>\n items.length > 1\n ? `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`\n : items[0];\n\n/**\n * Whether a convenience form wrapper renders a `Field` of its own (#905).\n * Never inside an outer `Field`. Inside a `Control` with no `Field` around\n * it, a `Field` of its own would put a `.field` inside the `.control`, where\n * Bulma's control styles break (its icon rules are sibling selectors on the\n * input). So it renders one there only when a prop that shapes the `Field`'s\n * markup is set (`label`, `message`, `horizontal`, `fieldClassName`), keeping\n * the markup it always had, and warns in development that the fix is a\n * `Field` around that `Control`. A prop counts when it is truthy, the same\n * test that decides whether it changes the `Field`'s output.\n * Internal; not part of the public API.\n */\nexport const rendersOwnField = (\n component: string,\n options: OwnFieldOptions\n): boolean => {\n if (options.insideField) return false;\n if (!options.insideControl) return true;\n const held = FIELD_SHAPING.filter(([prop]) => options[prop]);\n if (held.length === 0) return false;\n const names = held.map(([prop]) => prop);\n const moved = held\n .map(([, onField]) => onField)\n .filter((onField): onField is string => onField !== undefined);\n warnOnce(\n `${component}:Field-in-bare-Control:${names.join('+')}`,\n `[bestax-bulma] <${component} ${names.join(' ')}> inside a <Control> ` +\n `with no <Field> around it renders its own <Field> for ` +\n `${names.length > 1 ? 'those props' : 'that prop'}, which puts a ` +\n `.field inside the .control, a nesting Bulma's styles are not ` +\n `written for. Wrap the <Control> in a <Field> instead` +\n (moved.length > 0 ? `, and set ${listOf(moved)} on that <Field>.` : '.')\n );\n return true;\n};\n\n/** The props a convenience form wrapper hands its own `Control`. Internal. */\nexport interface ControlLevelProps {\n /** Shows the `Control`'s loading spinner. */\n isLoading?: boolean;\n /** The `Control`'s left icon. */\n iconLeft?: ControlBaseProps['iconLeft'];\n /** Shortcut for the left icon's name. */\n iconLeftName?: string;\n /** Shortcut for the left icon's size. */\n iconLeftSize?: ControlBaseProps['iconLeftSize'];\n /** The `Control`'s right icon. */\n iconRight?: ControlBaseProps['iconRight'];\n /** Shortcut for the right icon's name. */\n iconRightName?: string;\n /** Shortcut for the right icon's size. */\n iconRightSize?: ControlBaseProps['iconRightSize'];\n /** Reserves the `Control`'s left icon space. */\n hasIconsLeft?: boolean;\n /** Reserves the `Control`'s right icon space. */\n hasIconsRight?: boolean;\n /** Expands the `Control`. */\n isExpanded?: boolean;\n /** Set on the `Control` as its `size`. */\n controlSize?: ControlBaseProps['size'];\n /** Set on the `Control` as its class. */\n controlClassName?: string;\n}\n\ninterface OwnControlOptions extends ControlLevelProps {\n /** `useInsideControl()` as the wrapper read it. */\n insideControl: boolean;\n /** A picker's `inline`, which renders no `Control` inside one or out. */\n inline?: boolean;\n /**\n * The left glyph the wrapper's own `Control` shows when the caller sets no\n * `iconLeftName`; read only then. `bare-control.test.tsx` reads that glyph\n * from what each wrapper hands its own `Control`, so a wrapper that gains\n * one fails there until it passes it here.\n */\n defaultIconLeftName?: string;\n}\n\n// Each Control-level prop, with what takes its place on the `Control` the\n// caller wrapped around the wrapper. `bare-control.test.tsx` holds this to\n// what each wrapper hands its own `Control`, so a new Control-level prop\n// fails there until it is added here and passed to `rendersOwnControl`.\nconst ON_CONTROL: Record<keyof ControlLevelProps, string> = {\n isLoading: 'isLoading',\n iconLeft: 'iconLeft',\n iconLeftName: 'iconLeftName',\n iconLeftSize: 'iconLeftSize',\n iconRight: 'iconRight',\n iconRightName: 'iconRightName',\n iconRightSize: 'iconRightSize',\n hasIconsLeft: 'hasIconsLeft',\n hasIconsRight: 'hasIconsRight',\n isExpanded: 'isExpanded',\n controlSize: 'size (for controlSize)',\n controlClassName: 'className (for controlClassName)',\n};\n\n/**\n * Whether a convenience form wrapper renders a `Control` of its own (#921):\n * only outside one. Inside a `Control` it renders none, so the props it\n * would have handed its own do nothing there, and it warns in development,\n * naming them and saying to set them on that `Control`. An `inline` picker\n * renders none in either place, so it drops them inside a `Control` or not,\n * and its warning says so without pointing at a `Control`. A wrapper passes\n * only the props it hands its own `Control`, as the caller gave them, so a\n * default the wrapper fills in itself never warns. A prop counts when it is\n * truthy, since a falsy one would change nothing on a `Control` either.\n * `iconLeftSize` and `hasIconsLeft` show nothing on a `Control` without a\n * glyph, so when they move and the caller chose no left icon, the advice\n * names the wrapper's default glyph too, and following it draws what the\n * wrapper's own `Control` did.\n * Internal; not part of the public API.\n */\nexport const rendersOwnControl = (\n component: string,\n options: OwnControlOptions\n): boolean => {\n if (!options.inline && !options.insideControl) return true;\n const held = (\n Object.keys(ON_CONTROL) as Array<keyof ControlLevelProps>\n ).filter(prop => options[prop]);\n if (held.length === 0) return false;\n const names = held.join(' ');\n const doNothing = held.length > 1 ? 'those props do' : 'that prop does';\n let message: string;\n if (options.inline) {\n message =\n `[bestax-bulma] <${component} inline ${names}> renders no <Control> ` +\n `in inline mode, inside a <Control> or not, so ${doNothing} ` +\n `nothing. Leave ${held.length > 1 ? 'them' : 'it'} out of an ` +\n `inline picker.`;\n } else {\n const toSet = held.map(prop => ON_CONTROL[prop]);\n const needsGlyph =\n (options.iconLeftSize || options.hasIconsLeft) &&\n !options.iconLeft &&\n options.iconLeftName === undefined &&\n options.defaultIconLeftName;\n if (needsGlyph) {\n toSet.push(\n `iconLeftName=\"${options.defaultIconLeftName}\" (its default icon)`\n );\n }\n message =\n `[bestax-bulma] <${component} ${names}> inside a <Control> renders ` +\n `no <Control> of its own, so ${doNothing} nothing there. Set ` +\n `${listOf(toSet)} on that <Control> instead.`;\n }\n // Keyed by the message itself: the props named do not settle the advice\n // (an empty `iconLeftName` and an unset one name the same props), so two\n // calls that would advise differently must not share a key.\n warnOnce(message, message);\n return false;\n};\n\nconst FieldLabelIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id a labeled Field wants its single composed control to adopt (#495).\n * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the\n * user took over the association with an explicit `labelProps.htmlFor`.\n * Consumed by the single-control bases (InputBase, SelectBase, TextAreaBase)\n * and, through `useAutoLabelId`, by the convenience inputs that render an\n * input of their own (#939). Internal; not part of the public API.\n */\nexport const useFieldLabelId = () => useContext(FieldLabelIdContext);\n\n/** Provider for the Field label-target id — used internally by Field. */\nexport const FieldLabelIdProvider = FieldLabelIdContext.Provider;\n\nconst FieldLabelElementIdContext = createContext<string | undefined>(undefined);\n\n/**\n * The id of a labeled Field's own `<label>`, for a group control (Radios,\n * Checkboxes, Rate, DateRangeInput) to point `aria-labelledby` at, since a group cannot take\n * the label's `htmlFor` (#939), and for a range Slider's thumbs, which each\n * need the label in a name of their own (#981). Set under the same conditions\n * as {@link useFieldLabelId}. Consumed through `useAutoLabelledBy` and\n * `useAutoLabelId`.\n * Internal; not part of the public API.\n */\nexport const useFieldLabelElementId = () =>\n useContext(FieldLabelElementIdContext);\n\n/** Provider for the Field label's own id, used internally by Field. */\nexport const FieldLabelElementIdProvider = FieldLabelElementIdContext.Provider;\n\nconst FieldLabelForContext = createContext<string | undefined>(undefined);\n\n/**\n * What the nearest labeled Field's `<label>` points `htmlFor` at: the id it\n * generated, or the caller's own `labelProps.htmlFor`. An unlabeled Field\n * passes it through, so a control in the inner Field of a horizontal layout\n * can tell the outer label names it. Only ever compared with a control's own\n * id, never adopted, so it hands out no id. Internal; not part of the public\n * API.\n */\nexport const useFieldLabelFor = () => useContext(FieldLabelForContext);\n\n/** Provider for the Field label's `htmlFor` target, used internally by Field. */\nexport const FieldLabelForProvider = FieldLabelForContext.Provider;\n\n/**\n * Shape of the Radios group context. The group provides:\n * - `name`: shared form field name (Stage 1)\n * - `value`: currently-selected radio value (Stage 2 — group-managed selection)\n * - `onChange`: dispatched by child Radios when clicked (Stage 2)\n *\n * Group sets `value`/`onChange` only when actively managing selection\n * (i.e., the user passed `value`, `defaultValue`, or `onChange` to `<Radios>`).\n * When only `name` is provided, the group is in \"name-only\" mode and child\n * Radios manage their own checked state independently.\n */\nexport interface RadiosGroupContextValue {\n name?: string;\n value?: string;\n onChange?: (value: string) => void;\n}\n\n/**\n * Shape of the Checkboxes group context. Like Radios but with array semantics\n * for multi-select.\n */\nexport interface CheckboxesGroupContextValue {\n name?: string;\n value?: string[];\n onChange?: (values: string[]) => void;\n}\n\nconst RadiosContext = createContext<RadiosGroupContextValue | undefined>(\n undefined\n);\nconst CheckboxesContext = createContext<\n CheckboxesGroupContextValue | undefined\n>(undefined);\n\n/**\n * Hook to read the full surrounding `<Radios>` group context (name + selection).\n * Returns `undefined` when not inside a `<Radios>` group.\n */\nexport const useRadiosGroup = () => useContext(RadiosContext);\n\n/**\n * Hook to read the full surrounding `<Checkboxes>` group context.\n * Returns `undefined` when not inside a `<Checkboxes>` group.\n */\nexport const useCheckboxesGroup = () => useContext(CheckboxesContext);\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Radios>` group.\n * Child `<Radio>` components fall back to this when no local `name` prop is set.\n * Returns `undefined` outside of a `<Radios>` group.\n */\nexport const useRadiosName = () => useRadiosGroup()?.name;\n\n/**\n * Hook to read just the shared `name` from a surrounding `<Checkboxes>` group.\n * Returns `undefined` outside of a `<Checkboxes>` group.\n */\nexport const useCheckboxesName = () => useCheckboxesGroup()?.name;\n\n/** Provider for the Radios group context — used internally by Radios. */\nexport const RadiosProvider = RadiosContext.Provider;\n\n/** Provider for the Checkboxes group context — used internally by Checkboxes. */\nexport const CheckboxesProvider = CheckboxesContext.Provider;\n\n// --- Backward-compat aliases (Stage 1 names) -----------------------------\n// Internal callers may still import these. Both still work because they refer\n// to the same providers/hooks under the new shape.\n\n/** @deprecated Use `RadiosProvider` (provides {name, value, onChange}). */\nexport const RadiosNameProvider = RadiosProvider;\n\n/** @deprecated Use `CheckboxesProvider` (provides {name, value, onChange}). */\nexport const CheckboxesNameProvider = CheckboxesProvider;\n"],"names":[],"mappings":"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"}
|
package/dist/esm/form/Slider.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
-
import { forwardRef, useState, useRef, useCallback, useMemo, useLayoutEffect } from 'react';
|
|
3
|
+
import { forwardRef, useId, useState, useRef, useCallback, useMemo, useLayoutEffect } from 'react';
|
|
4
4
|
import { usePrefixedClassNames, classNames, prefixedClassNames } from '../helpers/classNames.js';
|
|
5
5
|
import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
|
|
6
6
|
import { useClassPrefix } from '../helpers/Config.js';
|
|
@@ -104,13 +104,48 @@ const Slider = forwardRef((props, ref) => {
|
|
|
104
104
|
});
|
|
105
105
|
const { bulmaHelperClasses, rest } = useBulmaClasses(restProps);
|
|
106
106
|
// In range mode the low thumb carries `rest` (and any user id), so the
|
|
107
|
-
// label targets it
|
|
108
|
-
const { controlId, fieldLabelProps } = useAutoLabelId({
|
|
107
|
+
// label's `for` targets it.
|
|
108
|
+
const { controlId, fieldLabelProps, labelId } = useAutoLabelId({
|
|
109
109
|
label,
|
|
110
110
|
id: restProps.id,
|
|
111
111
|
labelProps,
|
|
112
112
|
rendersLabel: ownField,
|
|
113
|
+
needsLabelId: !!range,
|
|
113
114
|
});
|
|
115
|
+
// A range thumb's default name is an `aria-label`, which outranks the
|
|
116
|
+
// label's `for`, so a label naming the Slider reaches each thumb through
|
|
117
|
+
// `aria-labelledby` instead: the label, then a hidden span holding the
|
|
118
|
+
// thumb's own text, as in "Price Minimum value" (#981). An `ariaLabel`
|
|
119
|
+
// entry is that thumb's whole name and wins.
|
|
120
|
+
const thumbTextId = useId();
|
|
121
|
+
const thumbLabels = range
|
|
122
|
+
? ariaLabel
|
|
123
|
+
: undefined;
|
|
124
|
+
// A caller's `aria-label` or `aria-labelledby` names the Slider in the
|
|
125
|
+
// label's place, so both thumbs read it before their own text. They are
|
|
126
|
+
// routed here rather than spread, since the spread reaches only the low
|
|
127
|
+
// thumb and would leave the pair with two unrelated names. Presence for
|
|
128
|
+
// aria-labelledby, as on a group (#974): the caller's key takes the naming
|
|
129
|
+
// over whatever its value, so an undefined one keeps every label out and
|
|
130
|
+
// leaves both thumbs their bare text. A non-empty one wins over an
|
|
131
|
+
// aria-label, as it does in the browser's name computation.
|
|
132
|
+
const { 'aria-label': callerLabel, 'aria-labelledby': callerLabelledBy, ...thumbRest } = rest;
|
|
133
|
+
const callerNamed = !!callerLabel || 'aria-labelledby' in rest;
|
|
134
|
+
const stemRef = callerLabelledBy || (callerNamed ? undefined : labelId);
|
|
135
|
+
const stemText = stemRef ? undefined : callerLabel;
|
|
136
|
+
const nameThumb = (own, text, textId) => {
|
|
137
|
+
const wired = !!stemRef && !own;
|
|
138
|
+
return {
|
|
139
|
+
text,
|
|
140
|
+
textId,
|
|
141
|
+
wired,
|
|
142
|
+
aria: wired
|
|
143
|
+
? { 'aria-labelledby': `${stemRef} ${textId}` }
|
|
144
|
+
: { 'aria-label': own || (stemText ? `${stemText} ${text}` : text) },
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
const lowThumb = nameThumb(thumbLabels?.[0], 'Minimum value', `${thumbTextId}-min`);
|
|
148
|
+
const highThumb = nameThumb(thumbLabels?.[1], 'Maximum value', `${thumbTextId}-max`);
|
|
114
149
|
// Resolve tooltip mode: explicit tooltip prop takes precedence, else showOutput maps to 'auto'
|
|
115
150
|
const tooltipMode = tooltip ?? (showOutput ? 'auto' : 'hidden');
|
|
116
151
|
// --- Range mode state ---
|
|
@@ -405,7 +440,7 @@ const Slider = forwardRef((props, ref) => {
|
|
|
405
440
|
: {
|
|
406
441
|
'--slider-progress-low': `${progressLow}%`,
|
|
407
442
|
'--slider-progress-high': `${progressHigh}%`,
|
|
408
|
-
} }), jsx("input", { ref: combinedRef, type: "range", min: min, max: max, step: step, value: currentRange[0], disabled: disabled, onChange: handleRangeLowChange, onKeyDown: handleKeyDown, onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-low'), "aria-valuenow": currentRange[0], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined,
|
|
443
|
+
} }), jsx("input", { ref: combinedRef, type: "range", min: min, max: max, step: step, value: currentRange[0], disabled: disabled, onChange: handleRangeLowChange, onKeyDown: handleKeyDown, onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-low'), "aria-valuenow": currentRange[0], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, ...lowThumb.aria, ...getAriaProps(currentRange[0]), ...thumbRest, id: controlId, ...(nameLow !== undefined ? { name: nameLow } : {}) }), jsx("input", { ref: inputHighRef, type: "range", min: min, max: max, step: step, value: currentRange[1], disabled: disabled, onChange: handleRangeHighChange, onMouseEnter: () => setShowTooltipHigh(true), onMouseLeave: () => setShowTooltipHigh(false), onFocus: () => setShowTooltipHigh(true), onBlur: () => setShowTooltipHigh(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-high'), "aria-valuenow": currentRange[1], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, ...highThumb.aria, ...getAriaProps(currentRange[1]), name: nameHigh }), [lowThumb, highThumb].map(thumb => thumb.wired && (jsx("span", { id: thumb.textId, hidden: true, children: thumb.text }, thumb.textId))), tooltipMode !== 'hidden' && (jsx("output", { ref: outputRef, className: prefixedClassNames(classPrefix, 'slider-output', 'slider-output-low', {
|
|
409
444
|
'is-visible': showTipLow,
|
|
410
445
|
'is-flipped': flipped,
|
|
411
446
|
'is-flipped-left': isVertical && verticalFlippedLeft,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.js","sources":["../../../src/form/Slider.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useMemo,\n useLayoutEffect,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useClassPrefix } from '../helpers/Config';\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/** Valid sizes for the Slider component. */\nexport type SliderSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Slider component. */\nexport type SliderColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Tooltip display mode for the Slider component. */\nexport type SliderTooltip = 'auto' | 'always' | 'hidden';\n\n/** Orientation of the Slider component. */\nexport type SliderOrientation = 'horizontal' | 'vertical';\n\n/**\n * A tick mark displayed along the Slider track.\n */\nexport interface SliderMark {\n /** Controlled value. */\n value: number;\n /** Optional label rendered below the tick mark. */\n label?: React.ReactNode;\n}\n\n/**\n * Shared base props for single and range Slider modes.\n */\ninterface SliderBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the slider input via `htmlFor` — uses your `id` when provided, otherwise a generated one. In range mode the label targets the low (minimum) thumb. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`). */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Minimum value. */\n min?: number;\n /** Maximum value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: SliderSize;\n /** Color variant. */\n color?: SliderColor;\n /** Use rounded track ends. */\n isRounded?: boolean;\n /** Use circular thumb. */\n isCircle?: boolean;\n /** Show current value tooltip. */\n showOutput?: boolean;\n /** Controls tooltip visibility on the thumb. */\n tooltip?: SliderTooltip;\n /** Shows tick marks along the track. */\n ticks?: boolean;\n /** Custom labeled marks along the track. Each mark has `{ value: number; label?: ReactNode }`. */\n marks?: SliderMark[];\n /** Orientation of the slider. */\n orientation?: SliderOrientation;\n /** Function to scale the displayed value. */\n scale?: (value: number) => number;\n /** Function to generate the `aria-valuetext` attribute. */\n getAriaValueText?: (value: number) => string;\n /** Format function for output display. */\n formatOutput?: (value: number) => string;\n}\n\n/**\n * Props for the Slider in single-value mode.\n */\nexport interface SliderSingleProps extends SliderBaseProps {\n /**\n * Enables range mode with two thumbs.\n * @defaultValue false\n */\n range?: false;\n /** Controlled value. */\n value?: number;\n /**\n * Default value for uncontrolled usage.\n * @defaultValue 0\n */\n defaultValue?: number;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n /**\n * Minimum distance between thumbs in range mode.\n * @defaultValue 0\n */\n minDistance?: never;\n /** ARIA label(s) for the slider thumb(s). */\n ariaLabel?: string;\n}\n\n/**\n * Props for the Slider in range (dual-thumb) mode.\n */\nexport interface SliderRangeProps extends SliderBaseProps {\n /**\n * Enables range mode with two thumbs.\n * @defaultValue false\n */\n range: true;\n /** Controlled value. */\n value?: [number, number];\n /**\n * Default value for uncontrolled usage.\n * @defaultValue 0\n */\n defaultValue?: [number, number];\n /** Callback when value changes. */\n onChange?: (value: [number, number]) => void;\n /**\n * Minimum distance between thumbs in range mode.\n * @defaultValue 0\n */\n minDistance?: number;\n /** ARIA label(s) for the slider thumb(s). */\n ariaLabel?: [string, string];\n /** Form field name for the low thumb. Use this in range mode so each thumb submits with its own name. */\n nameLow?: string;\n /** Form field name for the high thumb. */\n nameHigh?: string;\n}\n\n/**\n * Props for the Slider component — a discriminated union of single and range modes.\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 * @extraProp {boolean} [disabled=false] - Whether the slider is disabled.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport type SliderProps = SliderSingleProps | SliderRangeProps;\n\n/**\n * Helper to compute tick positions.\n * If `marks` are provided, those positions are used.\n * If `ticks` is true, generates ticks at every step (capped at 100).\n */\nfunction getTickPositions(\n min: number,\n max: number,\n step: number,\n ticks?: boolean,\n marks?: SliderMark[]\n): SliderMark[] {\n if (marks && marks.length > 0) return marks;\n if (!ticks) return [];\n const positions: SliderMark[] = [];\n const count = Math.round((max - min) / step);\n if (count > 100) {\n // Cap at 100 ticks to prevent perf issues\n const tickStep = (max - min) / 100;\n // Skip first (i=0) and last (i=100) — no ticks at endpoints\n for (let i = 1; i < 100; i++) {\n positions.push({ value: min + i * tickStep });\n }\n } else {\n // Skip first (i=0) and last (i=count) — no ticks at endpoints\n for (let i = 1; i < count; i++) {\n positions.push({ value: min + i * step });\n }\n }\n return positions;\n}\n\n/**\n * The `Slider` component provides a range slider input for selecting values within a range.\n *\n * @function\n * @param {SliderProps} props - Props for the Slider component.\n * @returns {JSX.Element} The rendered slider element.\n *\n * @example\n * // Basic slider\n * <Slider defaultValue={50} />\n *\n * @example\n * // Range slider\n * <Slider range defaultValue={[20, 80]} onChange={([low, high]) => {}} />\n */\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(\n (props, ref) => {\n // Pull out fields that differ between the single and range branches\n // *first*, by narrowing on the `range` discriminator. We then destructure\n // the remaining base props from a `SliderBaseProps` view of `props`.\n //\n // Why not destructure everything via `props as SliderRangeProps & SliderSingleProps`?\n // Because intersecting the two halves of a discriminated union collapses\n // overlapping fields (e.g. `range: true & false`, `value: number & [number, number]`,\n // `onChange`, `ariaLabel`) to `never`, which breaks call sites and rest spreads.\n let range: boolean | undefined;\n let controlledValue: number | [number, number] | undefined;\n let defaultValue: number | [number, number] | undefined;\n let onChange:\n ((v: number) => void) | ((v: [number, number]) => void) | undefined;\n let ariaLabel: string | [string, string] | undefined;\n let minDistance = 0;\n let nameLow: string | undefined;\n let nameHigh: string | undefined;\n if (props.range === true) {\n range = true;\n controlledValue = props.value;\n defaultValue = props.defaultValue;\n onChange = props.onChange;\n ariaLabel = props.ariaLabel;\n minDistance = props.minDistance ?? 0;\n nameLow = props.nameLow;\n nameHigh = props.nameHigh;\n } else {\n range = props.range;\n controlledValue = props.value;\n defaultValue = props.defaultValue;\n onChange = props.onChange;\n ariaLabel = props.ariaLabel;\n }\n\n // Destructure base / shared props from a `SliderBaseProps` view. None of\n // these fields differ between the two branches, so this view is safe.\n const {\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n min = 0,\n max = 100,\n step = 1,\n size,\n color,\n isRounded = false,\n isCircle = false,\n disabled = false,\n showOutput = false,\n tooltip,\n ticks,\n marks,\n orientation = 'horizontal',\n scale,\n getAriaValueText,\n formatOutput,\n className,\n // Strip the discriminated/union fields from `restProps` so they don't\n // flow back into `useBulmaClasses` / spread onto inputs.\n range: _range,\n value: _value,\n defaultValue: _defaultValue,\n onChange: _onChange,\n ariaLabel: _ariaLabel,\n minDistance: _minDistance,\n nameLow: _nameLow,\n nameHigh: _nameHigh,\n ...restProps\n } = props as SliderBaseProps & {\n range?: boolean;\n value?: number | [number, number];\n defaultValue?: number | [number, number];\n onChange?: (v: never) => void;\n ariaLabel?: string | [string, string];\n minDistance?: number;\n nameLow?: string;\n nameHigh?: string;\n };\n void _range;\n void _value;\n void _defaultValue;\n void _onChange;\n void _ariaLabel;\n void _minDistance;\n void _nameLow;\n void _nameHigh;\n\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Slider', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(restProps);\n // In range mode the low thumb carries `rest` (and any user id), so the\n // label targets it; each thumb keeps its own aria-label for AT.\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: restProps.id,\n labelProps,\n rendersLabel: ownField,\n });\n\n // Resolve tooltip mode: explicit tooltip prop takes precedence, else showOutput maps to 'auto'\n const tooltipMode: SliderTooltip =\n tooltip ?? (showOutput ? 'auto' : 'hidden');\n\n // --- Range mode state ---\n const [internalRange, setInternalRange] = useState<[number, number]>(() =>\n range ? ((defaultValue as [number, number]) ?? [min, max]) : [min, min]\n );\n const [internalSingle, setInternalSingle] = useState<number>(() =>\n !range ? ((defaultValue as number) ?? 0) : 0\n );\n const [showTooltip, setShowTooltip] = useState(false);\n const [showTooltipHigh, setShowTooltipHigh] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const inputHighRef = useRef<HTMLInputElement>(null);\n const outputRef = useRef<HTMLOutputElement>(null);\n const outputHighRef = useRef<HTMLOutputElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [flipped, setFlipped] = useState(false);\n const [flippedHigh, setFlippedHigh] = useState(false);\n const [nudgeX, setNudgeX] = useState(0);\n const [nudgeXHigh, setNudgeXHigh] = useState(0);\n const [verticalFlippedLeft, setVerticalFlippedLeft] = useState(false);\n\n const isControlled = controlledValue !== undefined;\n\n // Current values\n const currentRange: [number, number] = range\n ? isControlled\n ? (controlledValue as [number, number])\n : internalRange\n : [0, 0];\n const currentSingle: number = !range\n ? isControlled\n ? (controlledValue as number)\n : internalSingle\n : 0;\n\n // Progress percentages\n const progressSingle = !range\n ? ((currentSingle - min) / (max - min)) * 100\n : 0;\n const progressLow = range\n ? ((currentRange[0] - min) / (max - min)) * 100\n : 0;\n const progressHigh = range\n ? ((currentRange[1] - min) / (max - min)) * 100\n : 0;\n\n // Scale helper\n const scaleValue = useCallback(\n (v: number) => (scale ? scale(v) : v),\n [scale]\n );\n\n // Format helper\n const formatValue = useCallback(\n (v: number) => {\n const scaled = scaleValue(v);\n return formatOutput ? formatOutput(scaled) : scaled.toString();\n },\n [formatOutput, scaleValue]\n );\n\n // --- Handlers ---\n const handleSingleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isControlled) setInternalSingle(newValue);\n (onChange as ((v: number) => void) | undefined)?.(newValue);\n },\n [isControlled, onChange]\n );\n\n const handleRangeLowChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = parseFloat(e.target.value);\n const clamped = Math.min(raw, currentRange[1] - minDistance);\n const newRange: [number, number] = [clamped, currentRange[1]];\n if (!isControlled) setInternalRange(newRange);\n (onChange as ((v: [number, number]) => void) | undefined)?.(newRange);\n },\n [isControlled, onChange, currentRange, minDistance]\n );\n\n const handleRangeHighChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = parseFloat(e.target.value);\n const clamped = Math.max(raw, currentRange[0] + minDistance);\n const newRange: [number, number] = [currentRange[0], clamped];\n if (!isControlled) setInternalRange(newRange);\n (onChange as ((v: [number, number]) => void) | undefined)?.(newRange);\n },\n [isControlled, onChange, currentRange, minDistance]\n );\n\n // Key handler for Home/End\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Home') {\n e.preventDefault();\n if (!range) {\n if (!isControlled) setInternalSingle(min);\n (onChange as ((v: number) => void) | undefined)?.(min);\n }\n } else if (e.key === 'End') {\n e.preventDefault();\n if (!range) {\n if (!isControlled) setInternalSingle(max);\n (onChange as ((v: number) => void) | undefined)?.(max);\n }\n }\n },\n [range, isControlled, onChange, min, max]\n );\n\n // Tick positions\n const tickPositions = useMemo(\n () => getTickPositions(min, max, step, ticks, marks),\n [min, max, step, ticks, marks]\n );\n\n const hasLabels = tickPositions.some(t => t.label !== undefined);\n const isVertical = orientation === 'vertical';\n\n // Compute corrected thumb position CSS calc expression.\n // The browser insets the range input thumb by half its size from each edge,\n // so the tooltip left must account for this to align with the thumb center.\n const thumbVarName = size\n ? `slider-thumb-size-${size}`\n : 'slider-thumb-size';\n const thumbCssVar = `var(--bulma-${thumbVarName})`;\n const effectiveThumbExpr = isCircle\n ? `(${thumbCssVar} * 1.2)`\n : thumbCssVar;\n\n const getThumbLeft = (progressPct: number) => {\n const fraction = progressPct / 100;\n return `calc(${effectiveThumbExpr} / 2 + ${fraction} * (100% - ${effectiveThumbExpr}))`;\n };\n\n // Vertical tooltip offset: position to the right or left of the thumb\n const verticalTooltipOffset = `calc(50% + ${effectiveThumbExpr} / 2 + 0.5rem)`;\n\n // Get effective thumb size in px for nudge computation\n const getThumbSizePx = (): number => {\n const el = inputRef.current;\n if (!el) return 0;\n const style = getComputedStyle(el);\n const raw = style.getPropertyValue(`--bulma-${thumbVarName}`).trim();\n const value = parseFloat(raw);\n if (isNaN(value)) return 0;\n let px: number;\n if (raw.includes('rem')) {\n const rootFs =\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n px = value * rootFs;\n } else {\n px = value;\n }\n return isCircle ? px * 1.2 : px;\n };\n\n // Generate wrapper classes\n const classPrefix = useClassPrefix();\n const sliderClasses = usePrefixedClassNames('slider', {\n [`is-${size}`]: size,\n [`is-${color}`]: color,\n 'is-rounded': isRounded,\n 'is-circle': isCircle,\n 'is-disabled': disabled,\n 'has-output': tooltipMode !== 'hidden',\n 'has-output-always': tooltipMode === 'always',\n 'is-vertical': isVertical,\n 'is-range': range,\n 'has-ticks': tickPositions.length > 0,\n 'has-tick-labels': hasLabels,\n });\n\n const combinedClasses = classNames(\n sliderClasses,\n bulmaHelperClasses,\n className\n );\n\n // Combined ref for the first (or only) input\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 // Tooltip show/hide for auto mode\n const showTipLow =\n tooltipMode === 'always' || (tooltipMode === 'auto' && showTooltip);\n const showTipHigh =\n tooltipMode === 'always' || (tooltipMode === 'auto' && showTooltipHigh);\n\n // Aria value text\n const getAriaProps = (value: number) => {\n const ariaProps: Record<string, string> = {};\n if (getAriaValueText) {\n ariaProps['aria-valuetext'] = getAriaValueText(value);\n } else if (scale) {\n ariaProps['aria-valuetext'] = scaleValue(value).toString();\n }\n return ariaProps;\n };\n\n // Detect tooltip overflow: flip vertically if clipped at top,\n // nudge horizontally if clipped at left/right edge.\n // We compute the un-nudged tooltip position from the progress %\n // and wrapper rect to avoid feedback loops.\n const computeNudge = useCallback(\n (\n el: HTMLElement,\n wrapper: HTMLElement,\n progressPct: number,\n thumbSizePx: number\n ): number => {\n const wr = wrapper.getBoundingClientRect();\n const tooltipWidth = el.offsetWidth;\n // Corrected center: accounts for thumb inset from track edges\n const fraction = progressPct / 100;\n const centerX =\n wr.left + thumbSizePx / 2 + fraction * (wr.width - thumbSizePx);\n const tooltipLeft = centerX - tooltipWidth / 2;\n const tooltipRight = centerX + tooltipWidth / 2;\n if (tooltipLeft < wr.left) {\n return wr.left - tooltipLeft; // nudge right\n }\n if (tooltipRight > wr.right) {\n return wr.right - tooltipRight; // nudge left (negative)\n }\n return 0;\n },\n []\n );\n\n useLayoutEffect(() => {\n if (isVertical) return;\n const wrapper = wrapperRef.current;\n const el = outputRef.current;\n if (wrapper && el) {\n const wrapperTop = wrapper.getBoundingClientRect().top;\n const tooltipHeight = el.offsetHeight + 10;\n setFlipped(wrapperTop < tooltipHeight);\n const pct = range ? progressLow : progressSingle;\n const thumbPx = getThumbSizePx();\n setNudgeX(computeNudge(el, wrapper, pct, thumbPx));\n }\n });\n\n useLayoutEffect(() => {\n if (isVertical || !range) return;\n const wrapper = wrapperRef.current;\n const el = outputHighRef.current;\n if (wrapper && el) {\n const wrapperTop = wrapper.getBoundingClientRect().top;\n const tooltipHeight = el.offsetHeight + 10;\n setFlippedHigh(wrapperTop < tooltipHeight);\n const thumbPx = getThumbSizePx();\n setNudgeXHigh(computeNudge(el, wrapper, progressHigh, thumbPx));\n }\n });\n\n // Detect vertical tooltip overflow: flip to left if no space on right\n useLayoutEffect(() => {\n if (!isVertical) return;\n const wrapper = wrapperRef.current;\n const el = outputRef.current;\n if (!wrapper || !el) return;\n const wrapperRect = wrapper.getBoundingClientRect();\n const tooltipWidth = el.offsetWidth;\n const thumbPx = getThumbSizePx();\n const gap = 8; // 0.5rem\n // Tooltip right edge if placed to the right of the thumb\n const tooltipRightEdge =\n wrapperRect.left +\n wrapperRect.width / 2 +\n thumbPx / 2 +\n gap +\n tooltipWidth;\n setVerticalFlippedLeft(tooltipRightEdge > window.innerWidth);\n });\n\n // Vertical wrapper style\n const wrapperStyle = isVertical\n ? ({\n height: 'var(--bulma-slider-vertical-height, 200px)',\n } as React.CSSProperties)\n : undefined;\n\n // Render ticks\n const renderTicks = () => {\n if (tickPositions.length === 0) return null;\n return (\n <div className={prefixedClassNames(classPrefix, 'slider-ticks')}>\n {tickPositions.map((tick, i) => {\n const pct = ((tick.value - min) / (max - min)) * 100;\n const posStyle = isVertical\n ? { bottom: `${pct}%` }\n : { left: `${pct}%` };\n const isEndpoint = tick.value === min || tick.value === max;\n return (\n <span\n key={i}\n className={prefixedClassNames(classPrefix, 'slider-tick', {\n 'is-endpoint': isEndpoint,\n })}\n style={posStyle}\n >\n {tick.label !== undefined && (\n <span\n className={prefixedClassNames(\n classPrefix,\n 'slider-tick-label'\n )}\n >\n {tick.label}\n </span>\n )}\n </span>\n );\n })}\n </div>\n );\n };\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // --- Single slider ---\n const sliderElement = !range ? (\n <div ref={wrapperRef} className={combinedClasses} style={wrapperStyle}>\n <input\n ref={combinedRef}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentSingle}\n disabled={disabled}\n onChange={handleSingleChange}\n onKeyDown={handleKeyDown}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n className={prefixedClassNames(classPrefix, 'slider-input')}\n style={\n {\n '--slider-progress': `${progressSingle}%`,\n } as React.CSSProperties\n }\n aria-valuenow={currentSingle}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-orientation={isVertical ? 'vertical' : undefined}\n aria-label={ariaLabel as string | undefined}\n {...getAriaProps(currentSingle)}\n {...rest}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n {tooltipMode !== 'hidden' && (\n <output\n ref={outputRef}\n className={prefixedClassNames(classPrefix, 'slider-output', {\n 'is-visible': showTipLow,\n 'is-flipped': flipped,\n 'is-flipped-left': isVertical && verticalFlippedLeft,\n })}\n style={\n isVertical\n ? ((verticalFlippedLeft\n ? {\n bottom: getThumbLeft(progressSingle),\n right: verticalTooltipOffset,\n left: 'auto',\n }\n : {\n bottom: getThumbLeft(progressSingle),\n left: verticalTooltipOffset,\n right: 'auto',\n }) as React.CSSProperties)\n : ({\n left: getThumbLeft(progressSingle),\n transform: `translateX(calc(-50% + ${nudgeX}px))`,\n '--slider-output-arrow-offset': `calc(50% - ${nudgeX}px)`,\n } as React.CSSProperties)\n }\n >\n {formatValue(currentSingle)}\n </output>\n )}\n {renderTicks()}\n </div>\n ) : (\n // --- Range slider ---\n <div ref={wrapperRef} className={combinedClasses} style={wrapperStyle}>\n {/* Visible track background */}\n <div\n className={prefixedClassNames(classPrefix, 'slider-track')}\n style={\n isVertical\n ? ({\n '--slider-progress-low': `${progressLow}%`,\n '--slider-progress-high': `${progressHigh}%`,\n } as React.CSSProperties)\n : ({\n '--slider-progress-low': `${progressLow}%`,\n '--slider-progress-high': `${progressHigh}%`,\n } as React.CSSProperties)\n }\n />\n {/* Low thumb. nameLow overrides any `name` from rest so each thumb has its own form field. */}\n <input\n ref={combinedRef}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentRange[0]}\n disabled={disabled}\n onChange={handleRangeLowChange}\n onKeyDown={handleKeyDown}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n className={prefixedClassNames(\n classPrefix,\n 'slider-input',\n 'slider-input-low'\n )}\n aria-valuenow={currentRange[0]}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-orientation={isVertical ? 'vertical' : undefined}\n aria-label={\n (ariaLabel as [string, string] | undefined)?.[0] ?? 'Minimum value'\n }\n {...getAriaProps(currentRange[0])}\n {...rest}\n id={controlId}\n {...(nameLow !== undefined ? { name: nameLow } : {})}\n />\n {/* High thumb */}\n <input\n ref={inputHighRef}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentRange[1]}\n disabled={disabled}\n onChange={handleRangeHighChange}\n onMouseEnter={() => setShowTooltipHigh(true)}\n onMouseLeave={() => setShowTooltipHigh(false)}\n onFocus={() => setShowTooltipHigh(true)}\n onBlur={() => setShowTooltipHigh(false)}\n className={prefixedClassNames(\n classPrefix,\n 'slider-input',\n 'slider-input-high'\n )}\n aria-valuenow={currentRange[1]}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-orientation={isVertical ? 'vertical' : undefined}\n aria-label={\n (ariaLabel as [string, string] | undefined)?.[1] ?? 'Maximum value'\n }\n {...getAriaProps(currentRange[1])}\n name={nameHigh}\n />\n {/* Low tooltip */}\n {tooltipMode !== 'hidden' && (\n <output\n ref={outputRef}\n className={prefixedClassNames(\n classPrefix,\n 'slider-output',\n 'slider-output-low',\n {\n 'is-visible': showTipLow,\n 'is-flipped': flipped,\n 'is-flipped-left': isVertical && verticalFlippedLeft,\n }\n )}\n style={\n isVertical\n ? ((verticalFlippedLeft\n ? {\n bottom: getThumbLeft(progressLow),\n right: verticalTooltipOffset,\n left: 'auto',\n }\n : {\n bottom: getThumbLeft(progressLow),\n left: verticalTooltipOffset,\n right: 'auto',\n }) as React.CSSProperties)\n : ({\n left: getThumbLeft(progressLow),\n transform: `translateX(calc(-50% + ${nudgeX}px))`,\n '--slider-output-arrow-offset': `calc(50% - ${nudgeX}px)`,\n } as React.CSSProperties)\n }\n >\n {formatValue(currentRange[0])}\n </output>\n )}\n {/* High tooltip */}\n {tooltipMode !== 'hidden' && (\n <output\n ref={outputHighRef}\n className={prefixedClassNames(\n classPrefix,\n 'slider-output',\n 'slider-output-high',\n {\n 'is-visible': showTipHigh,\n 'is-flipped': flippedHigh,\n 'is-flipped-left': isVertical && verticalFlippedLeft,\n }\n )}\n style={\n isVertical\n ? ((verticalFlippedLeft\n ? {\n bottom: getThumbLeft(progressHigh),\n right: verticalTooltipOffset,\n left: 'auto',\n }\n : {\n bottom: getThumbLeft(progressHigh),\n left: verticalTooltipOffset,\n right: 'auto',\n }) as React.CSSProperties)\n : ({\n left: getThumbLeft(progressHigh),\n transform: `translateX(calc(-50% + ${nudgeXHigh}px))`,\n '--slider-output-arrow-offset': `calc(50% - ${nudgeXHigh}px)`,\n } as React.CSSProperties)\n }\n >\n {formatValue(currentRange[1])}\n </output>\n )}\n {renderTicks()}\n </div>\n );\n\n let content = sliderElement;\n\n if (rendersOwnControl('Slider', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nSlider.displayName = 'Slider';\n\nexport default Slider;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Slider.js","sources":["../../../src/form/Slider.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useMemo,\n useLayoutEffect,\n useId,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useClassPrefix } from '../helpers/Config';\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/** Valid sizes for the Slider component. */\nexport type SliderSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Slider component. */\nexport type SliderColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Tooltip display mode for the Slider component. */\nexport type SliderTooltip = 'auto' | 'always' | 'hidden';\n\n/** Orientation of the Slider component. */\nexport type SliderOrientation = 'horizontal' | 'vertical';\n\n/**\n * A tick mark displayed along the Slider track.\n */\nexport interface SliderMark {\n /** Controlled value. */\n value: number;\n /** Optional label rendered below the tick mark. */\n label?: React.ReactNode;\n}\n\n/**\n * Shared base props for single and range Slider modes.\n */\ninterface SliderBaseProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the slider input via `htmlFor` — uses your `id` when provided, otherwise a generated one. In range mode the `htmlFor` targets the low (minimum) thumb, and the label also starts each thumb's name through `aria-labelledby`, as in \"Price Minimum value\" and \"Price Maximum value\", unless an `aria-label` or `aria-labelledby` on the Slider takes its place there. Dropped inside an outer `Field`, whose own label associates instead when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`), naming a range Slider's thumbs the same way. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). In range mode an `id` here is the one the thumbs' `aria-labelledby` points at, in place of a generated one. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Minimum value. */\n min?: number;\n /** Maximum value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: SliderSize;\n /** Color variant. */\n color?: SliderColor;\n /** Use rounded track ends. */\n isRounded?: boolean;\n /** Use circular thumb. */\n isCircle?: boolean;\n /** Show current value tooltip. */\n showOutput?: boolean;\n /** Controls tooltip visibility on the thumb. */\n tooltip?: SliderTooltip;\n /** Shows tick marks along the track. */\n ticks?: boolean;\n /** Custom labeled marks along the track. Each mark has `{ value: number; label?: ReactNode }`. */\n marks?: SliderMark[];\n /** Orientation of the slider. */\n orientation?: SliderOrientation;\n /** Function to scale the displayed value. */\n scale?: (value: number) => number;\n /** Function to generate the `aria-valuetext` attribute. */\n getAriaValueText?: (value: number) => string;\n /** Format function for output display. */\n formatOutput?: (value: number) => string;\n}\n\n/**\n * Props for the Slider in single-value mode.\n */\nexport interface SliderSingleProps extends SliderBaseProps {\n /**\n * Enables range mode with two thumbs.\n * @defaultValue false\n */\n range?: false;\n /** Controlled value. */\n value?: number;\n /**\n * Default value for uncontrolled usage.\n * @defaultValue 0\n */\n defaultValue?: number;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n /**\n * Minimum distance between thumbs in range mode.\n * @defaultValue 0\n */\n minDistance?: never;\n /** ARIA label(s) for the slider thumb(s), which win over a label, the Slider's own or a surrounding `Field`'s. In range mode each entry is that thumb's whole name, and a thumb without one is named \"Minimum value\" or \"Maximum value\", after whatever names the Slider: a label, or in its place an `aria-label` or `aria-labelledby` given to the Slider, as in \"Budget Minimum value\" and \"Budget Maximum value\". An `aria-labelledby` set to `undefined` keeps every label out of both names. */\n ariaLabel?: string;\n}\n\n/**\n * Props for the Slider in range (dual-thumb) mode.\n */\nexport interface SliderRangeProps extends SliderBaseProps {\n /**\n * Enables range mode with two thumbs.\n * @defaultValue false\n */\n range: true;\n /** Controlled value. */\n value?: [number, number];\n /**\n * Default value for uncontrolled usage.\n * @defaultValue 0\n */\n defaultValue?: [number, number];\n /** Callback when value changes. */\n onChange?: (value: [number, number]) => void;\n /**\n * Minimum distance between thumbs in range mode.\n * @defaultValue 0\n */\n minDistance?: number;\n /** ARIA label(s) for the slider thumb(s), which win over a label, the Slider's own or a surrounding `Field`'s. In range mode each entry is that thumb's whole name, and a thumb without one is named \"Minimum value\" or \"Maximum value\", after whatever names the Slider: a label, or in its place an `aria-label` or `aria-labelledby` given to the Slider, as in \"Budget Minimum value\" and \"Budget Maximum value\". An `aria-labelledby` set to `undefined` keeps every label out of both names. */\n ariaLabel?: [string, string];\n /** Form field name for the low thumb. Use this in range mode so each thumb submits with its own name. */\n nameLow?: string;\n /** Form field name for the high thumb. */\n nameHigh?: string;\n}\n\n/**\n * Props for the Slider component — a discriminated union of single and range modes.\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 * @extraProp {boolean} [disabled=false] - Whether the slider is disabled.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport type SliderProps = SliderSingleProps | SliderRangeProps;\n\n/**\n * Helper to compute tick positions.\n * If `marks` are provided, those positions are used.\n * If `ticks` is true, generates ticks at every step (capped at 100).\n */\nfunction getTickPositions(\n min: number,\n max: number,\n step: number,\n ticks?: boolean,\n marks?: SliderMark[]\n): SliderMark[] {\n if (marks && marks.length > 0) return marks;\n if (!ticks) return [];\n const positions: SliderMark[] = [];\n const count = Math.round((max - min) / step);\n if (count > 100) {\n // Cap at 100 ticks to prevent perf issues\n const tickStep = (max - min) / 100;\n // Skip first (i=0) and last (i=100) — no ticks at endpoints\n for (let i = 1; i < 100; i++) {\n positions.push({ value: min + i * tickStep });\n }\n } else {\n // Skip first (i=0) and last (i=count) — no ticks at endpoints\n for (let i = 1; i < count; i++) {\n positions.push({ value: min + i * step });\n }\n }\n return positions;\n}\n\n/**\n * The `Slider` component provides a range slider input for selecting values within a range.\n *\n * @function\n * @param {SliderProps} props - Props for the Slider component.\n * @returns {JSX.Element} The rendered slider element.\n *\n * @example\n * // Basic slider\n * <Slider defaultValue={50} />\n *\n * @example\n * // Range slider\n * <Slider range defaultValue={[20, 80]} onChange={([low, high]) => {}} />\n */\nexport const Slider = forwardRef<HTMLInputElement, SliderProps>(\n (props, ref) => {\n // Pull out fields that differ between the single and range branches\n // *first*, by narrowing on the `range` discriminator. We then destructure\n // the remaining base props from a `SliderBaseProps` view of `props`.\n //\n // Why not destructure everything via `props as SliderRangeProps & SliderSingleProps`?\n // Because intersecting the two halves of a discriminated union collapses\n // overlapping fields (e.g. `range: true & false`, `value: number & [number, number]`,\n // `onChange`, `ariaLabel`) to `never`, which breaks call sites and rest spreads.\n let range: boolean | undefined;\n let controlledValue: number | [number, number] | undefined;\n let defaultValue: number | [number, number] | undefined;\n let onChange:\n ((v: number) => void) | ((v: [number, number]) => void) | undefined;\n let ariaLabel: string | [string, string] | undefined;\n let minDistance = 0;\n let nameLow: string | undefined;\n let nameHigh: string | undefined;\n if (props.range === true) {\n range = true;\n controlledValue = props.value;\n defaultValue = props.defaultValue;\n onChange = props.onChange;\n ariaLabel = props.ariaLabel;\n minDistance = props.minDistance ?? 0;\n nameLow = props.nameLow;\n nameHigh = props.nameHigh;\n } else {\n range = props.range;\n controlledValue = props.value;\n defaultValue = props.defaultValue;\n onChange = props.onChange;\n ariaLabel = props.ariaLabel;\n }\n\n // Destructure base / shared props from a `SliderBaseProps` view. None of\n // these fields differ between the two branches, so this view is safe.\n const {\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n min = 0,\n max = 100,\n step = 1,\n size,\n color,\n isRounded = false,\n isCircle = false,\n disabled = false,\n showOutput = false,\n tooltip,\n ticks,\n marks,\n orientation = 'horizontal',\n scale,\n getAriaValueText,\n formatOutput,\n className,\n // Strip the discriminated/union fields from `restProps` so they don't\n // flow back into `useBulmaClasses` / spread onto inputs.\n range: _range,\n value: _value,\n defaultValue: _defaultValue,\n onChange: _onChange,\n ariaLabel: _ariaLabel,\n minDistance: _minDistance,\n nameLow: _nameLow,\n nameHigh: _nameHigh,\n ...restProps\n } = props as SliderBaseProps & {\n range?: boolean;\n value?: number | [number, number];\n defaultValue?: number | [number, number];\n onChange?: (v: never) => void;\n ariaLabel?: string | [string, string];\n minDistance?: number;\n nameLow?: string;\n nameHigh?: string;\n };\n void _range;\n void _value;\n void _defaultValue;\n void _onChange;\n void _ariaLabel;\n void _minDistance;\n void _nameLow;\n void _nameHigh;\n\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Slider', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(restProps);\n // In range mode the low thumb carries `rest` (and any user id), so the\n // label's `for` targets it.\n const { controlId, fieldLabelProps, labelId } = useAutoLabelId({\n label,\n id: restProps.id,\n labelProps,\n rendersLabel: ownField,\n needsLabelId: !!range,\n });\n\n // A range thumb's default name is an `aria-label`, which outranks the\n // label's `for`, so a label naming the Slider reaches each thumb through\n // `aria-labelledby` instead: the label, then a hidden span holding the\n // thumb's own text, as in \"Price Minimum value\" (#981). An `ariaLabel`\n // entry is that thumb's whole name and wins.\n const thumbTextId = useId();\n const thumbLabels = range\n ? (ariaLabel as [string, string] | undefined)\n : undefined;\n // A caller's `aria-label` or `aria-labelledby` names the Slider in the\n // label's place, so both thumbs read it before their own text. They are\n // routed here rather than spread, since the spread reaches only the low\n // thumb and would leave the pair with two unrelated names. Presence for\n // aria-labelledby, as on a group (#974): the caller's key takes the naming\n // over whatever its value, so an undefined one keeps every label out and\n // leaves both thumbs their bare text. A non-empty one wins over an\n // aria-label, as it does in the browser's name computation.\n const {\n 'aria-label': callerLabel,\n 'aria-labelledby': callerLabelledBy,\n ...thumbRest\n } = rest;\n const callerNamed = !!callerLabel || 'aria-labelledby' in rest;\n const stemRef = callerLabelledBy || (callerNamed ? undefined : labelId);\n const stemText = stemRef ? undefined : callerLabel;\n const nameThumb = (\n own: string | undefined,\n text: string,\n textId: string\n ) => {\n const wired = !!stemRef && !own;\n return {\n text,\n textId,\n wired,\n aria: wired\n ? { 'aria-labelledby': `${stemRef} ${textId}` }\n : { 'aria-label': own || (stemText ? `${stemText} ${text}` : text) },\n };\n };\n const lowThumb = nameThumb(\n thumbLabels?.[0],\n 'Minimum value',\n `${thumbTextId}-min`\n );\n const highThumb = nameThumb(\n thumbLabels?.[1],\n 'Maximum value',\n `${thumbTextId}-max`\n );\n\n // Resolve tooltip mode: explicit tooltip prop takes precedence, else showOutput maps to 'auto'\n const tooltipMode: SliderTooltip =\n tooltip ?? (showOutput ? 'auto' : 'hidden');\n\n // --- Range mode state ---\n const [internalRange, setInternalRange] = useState<[number, number]>(() =>\n range ? ((defaultValue as [number, number]) ?? [min, max]) : [min, min]\n );\n const [internalSingle, setInternalSingle] = useState<number>(() =>\n !range ? ((defaultValue as number) ?? 0) : 0\n );\n const [showTooltip, setShowTooltip] = useState(false);\n const [showTooltipHigh, setShowTooltipHigh] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const inputHighRef = useRef<HTMLInputElement>(null);\n const outputRef = useRef<HTMLOutputElement>(null);\n const outputHighRef = useRef<HTMLOutputElement>(null);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const [flipped, setFlipped] = useState(false);\n const [flippedHigh, setFlippedHigh] = useState(false);\n const [nudgeX, setNudgeX] = useState(0);\n const [nudgeXHigh, setNudgeXHigh] = useState(0);\n const [verticalFlippedLeft, setVerticalFlippedLeft] = useState(false);\n\n const isControlled = controlledValue !== undefined;\n\n // Current values\n const currentRange: [number, number] = range\n ? isControlled\n ? (controlledValue as [number, number])\n : internalRange\n : [0, 0];\n const currentSingle: number = !range\n ? isControlled\n ? (controlledValue as number)\n : internalSingle\n : 0;\n\n // Progress percentages\n const progressSingle = !range\n ? ((currentSingle - min) / (max - min)) * 100\n : 0;\n const progressLow = range\n ? ((currentRange[0] - min) / (max - min)) * 100\n : 0;\n const progressHigh = range\n ? ((currentRange[1] - min) / (max - min)) * 100\n : 0;\n\n // Scale helper\n const scaleValue = useCallback(\n (v: number) => (scale ? scale(v) : v),\n [scale]\n );\n\n // Format helper\n const formatValue = useCallback(\n (v: number) => {\n const scaled = scaleValue(v);\n return formatOutput ? formatOutput(scaled) : scaled.toString();\n },\n [formatOutput, scaleValue]\n );\n\n // --- Handlers ---\n const handleSingleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isControlled) setInternalSingle(newValue);\n (onChange as ((v: number) => void) | undefined)?.(newValue);\n },\n [isControlled, onChange]\n );\n\n const handleRangeLowChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = parseFloat(e.target.value);\n const clamped = Math.min(raw, currentRange[1] - minDistance);\n const newRange: [number, number] = [clamped, currentRange[1]];\n if (!isControlled) setInternalRange(newRange);\n (onChange as ((v: [number, number]) => void) | undefined)?.(newRange);\n },\n [isControlled, onChange, currentRange, minDistance]\n );\n\n const handleRangeHighChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = parseFloat(e.target.value);\n const clamped = Math.max(raw, currentRange[0] + minDistance);\n const newRange: [number, number] = [currentRange[0], clamped];\n if (!isControlled) setInternalRange(newRange);\n (onChange as ((v: [number, number]) => void) | undefined)?.(newRange);\n },\n [isControlled, onChange, currentRange, minDistance]\n );\n\n // Key handler for Home/End\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Home') {\n e.preventDefault();\n if (!range) {\n if (!isControlled) setInternalSingle(min);\n (onChange as ((v: number) => void) | undefined)?.(min);\n }\n } else if (e.key === 'End') {\n e.preventDefault();\n if (!range) {\n if (!isControlled) setInternalSingle(max);\n (onChange as ((v: number) => void) | undefined)?.(max);\n }\n }\n },\n [range, isControlled, onChange, min, max]\n );\n\n // Tick positions\n const tickPositions = useMemo(\n () => getTickPositions(min, max, step, ticks, marks),\n [min, max, step, ticks, marks]\n );\n\n const hasLabels = tickPositions.some(t => t.label !== undefined);\n const isVertical = orientation === 'vertical';\n\n // Compute corrected thumb position CSS calc expression.\n // The browser insets the range input thumb by half its size from each edge,\n // so the tooltip left must account for this to align with the thumb center.\n const thumbVarName = size\n ? `slider-thumb-size-${size}`\n : 'slider-thumb-size';\n const thumbCssVar = `var(--bulma-${thumbVarName})`;\n const effectiveThumbExpr = isCircle\n ? `(${thumbCssVar} * 1.2)`\n : thumbCssVar;\n\n const getThumbLeft = (progressPct: number) => {\n const fraction = progressPct / 100;\n return `calc(${effectiveThumbExpr} / 2 + ${fraction} * (100% - ${effectiveThumbExpr}))`;\n };\n\n // Vertical tooltip offset: position to the right or left of the thumb\n const verticalTooltipOffset = `calc(50% + ${effectiveThumbExpr} / 2 + 0.5rem)`;\n\n // Get effective thumb size in px for nudge computation\n const getThumbSizePx = (): number => {\n const el = inputRef.current;\n if (!el) return 0;\n const style = getComputedStyle(el);\n const raw = style.getPropertyValue(`--bulma-${thumbVarName}`).trim();\n const value = parseFloat(raw);\n if (isNaN(value)) return 0;\n let px: number;\n if (raw.includes('rem')) {\n const rootFs =\n parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\n px = value * rootFs;\n } else {\n px = value;\n }\n return isCircle ? px * 1.2 : px;\n };\n\n // Generate wrapper classes\n const classPrefix = useClassPrefix();\n const sliderClasses = usePrefixedClassNames('slider', {\n [`is-${size}`]: size,\n [`is-${color}`]: color,\n 'is-rounded': isRounded,\n 'is-circle': isCircle,\n 'is-disabled': disabled,\n 'has-output': tooltipMode !== 'hidden',\n 'has-output-always': tooltipMode === 'always',\n 'is-vertical': isVertical,\n 'is-range': range,\n 'has-ticks': tickPositions.length > 0,\n 'has-tick-labels': hasLabels,\n });\n\n const combinedClasses = classNames(\n sliderClasses,\n bulmaHelperClasses,\n className\n );\n\n // Combined ref for the first (or only) input\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 // Tooltip show/hide for auto mode\n const showTipLow =\n tooltipMode === 'always' || (tooltipMode === 'auto' && showTooltip);\n const showTipHigh =\n tooltipMode === 'always' || (tooltipMode === 'auto' && showTooltipHigh);\n\n // Aria value text\n const getAriaProps = (value: number) => {\n const ariaProps: Record<string, string> = {};\n if (getAriaValueText) {\n ariaProps['aria-valuetext'] = getAriaValueText(value);\n } else if (scale) {\n ariaProps['aria-valuetext'] = scaleValue(value).toString();\n }\n return ariaProps;\n };\n\n // Detect tooltip overflow: flip vertically if clipped at top,\n // nudge horizontally if clipped at left/right edge.\n // We compute the un-nudged tooltip position from the progress %\n // and wrapper rect to avoid feedback loops.\n const computeNudge = useCallback(\n (\n el: HTMLElement,\n wrapper: HTMLElement,\n progressPct: number,\n thumbSizePx: number\n ): number => {\n const wr = wrapper.getBoundingClientRect();\n const tooltipWidth = el.offsetWidth;\n // Corrected center: accounts for thumb inset from track edges\n const fraction = progressPct / 100;\n const centerX =\n wr.left + thumbSizePx / 2 + fraction * (wr.width - thumbSizePx);\n const tooltipLeft = centerX - tooltipWidth / 2;\n const tooltipRight = centerX + tooltipWidth / 2;\n if (tooltipLeft < wr.left) {\n return wr.left - tooltipLeft; // nudge right\n }\n if (tooltipRight > wr.right) {\n return wr.right - tooltipRight; // nudge left (negative)\n }\n return 0;\n },\n []\n );\n\n useLayoutEffect(() => {\n if (isVertical) return;\n const wrapper = wrapperRef.current;\n const el = outputRef.current;\n if (wrapper && el) {\n const wrapperTop = wrapper.getBoundingClientRect().top;\n const tooltipHeight = el.offsetHeight + 10;\n setFlipped(wrapperTop < tooltipHeight);\n const pct = range ? progressLow : progressSingle;\n const thumbPx = getThumbSizePx();\n setNudgeX(computeNudge(el, wrapper, pct, thumbPx));\n }\n });\n\n useLayoutEffect(() => {\n if (isVertical || !range) return;\n const wrapper = wrapperRef.current;\n const el = outputHighRef.current;\n if (wrapper && el) {\n const wrapperTop = wrapper.getBoundingClientRect().top;\n const tooltipHeight = el.offsetHeight + 10;\n setFlippedHigh(wrapperTop < tooltipHeight);\n const thumbPx = getThumbSizePx();\n setNudgeXHigh(computeNudge(el, wrapper, progressHigh, thumbPx));\n }\n });\n\n // Detect vertical tooltip overflow: flip to left if no space on right\n useLayoutEffect(() => {\n if (!isVertical) return;\n const wrapper = wrapperRef.current;\n const el = outputRef.current;\n if (!wrapper || !el) return;\n const wrapperRect = wrapper.getBoundingClientRect();\n const tooltipWidth = el.offsetWidth;\n const thumbPx = getThumbSizePx();\n const gap = 8; // 0.5rem\n // Tooltip right edge if placed to the right of the thumb\n const tooltipRightEdge =\n wrapperRect.left +\n wrapperRect.width / 2 +\n thumbPx / 2 +\n gap +\n tooltipWidth;\n setVerticalFlippedLeft(tooltipRightEdge > window.innerWidth);\n });\n\n // Vertical wrapper style\n const wrapperStyle = isVertical\n ? ({\n height: 'var(--bulma-slider-vertical-height, 200px)',\n } as React.CSSProperties)\n : undefined;\n\n // Render ticks\n const renderTicks = () => {\n if (tickPositions.length === 0) return null;\n return (\n <div className={prefixedClassNames(classPrefix, 'slider-ticks')}>\n {tickPositions.map((tick, i) => {\n const pct = ((tick.value - min) / (max - min)) * 100;\n const posStyle = isVertical\n ? { bottom: `${pct}%` }\n : { left: `${pct}%` };\n const isEndpoint = tick.value === min || tick.value === max;\n return (\n <span\n key={i}\n className={prefixedClassNames(classPrefix, 'slider-tick', {\n 'is-endpoint': isEndpoint,\n })}\n style={posStyle}\n >\n {tick.label !== undefined && (\n <span\n className={prefixedClassNames(\n classPrefix,\n 'slider-tick-label'\n )}\n >\n {tick.label}\n </span>\n )}\n </span>\n );\n })}\n </div>\n );\n };\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // --- Single slider ---\n const sliderElement = !range ? (\n <div ref={wrapperRef} className={combinedClasses} style={wrapperStyle}>\n <input\n ref={combinedRef}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentSingle}\n disabled={disabled}\n onChange={handleSingleChange}\n onKeyDown={handleKeyDown}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n className={prefixedClassNames(classPrefix, 'slider-input')}\n style={\n {\n '--slider-progress': `${progressSingle}%`,\n } as React.CSSProperties\n }\n aria-valuenow={currentSingle}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-orientation={isVertical ? 'vertical' : undefined}\n aria-label={ariaLabel as string | undefined}\n {...getAriaProps(currentSingle)}\n {...rest}\n // After the spread: an undefined `id` key in rest would wipe it.\n id={controlId}\n />\n {tooltipMode !== 'hidden' && (\n <output\n ref={outputRef}\n className={prefixedClassNames(classPrefix, 'slider-output', {\n 'is-visible': showTipLow,\n 'is-flipped': flipped,\n 'is-flipped-left': isVertical && verticalFlippedLeft,\n })}\n style={\n isVertical\n ? ((verticalFlippedLeft\n ? {\n bottom: getThumbLeft(progressSingle),\n right: verticalTooltipOffset,\n left: 'auto',\n }\n : {\n bottom: getThumbLeft(progressSingle),\n left: verticalTooltipOffset,\n right: 'auto',\n }) as React.CSSProperties)\n : ({\n left: getThumbLeft(progressSingle),\n transform: `translateX(calc(-50% + ${nudgeX}px))`,\n '--slider-output-arrow-offset': `calc(50% - ${nudgeX}px)`,\n } as React.CSSProperties)\n }\n >\n {formatValue(currentSingle)}\n </output>\n )}\n {renderTicks()}\n </div>\n ) : (\n // --- Range slider ---\n <div ref={wrapperRef} className={combinedClasses} style={wrapperStyle}>\n {/* Visible track background */}\n <div\n className={prefixedClassNames(classPrefix, 'slider-track')}\n style={\n isVertical\n ? ({\n '--slider-progress-low': `${progressLow}%`,\n '--slider-progress-high': `${progressHigh}%`,\n } as React.CSSProperties)\n : ({\n '--slider-progress-low': `${progressLow}%`,\n '--slider-progress-high': `${progressHigh}%`,\n } as React.CSSProperties)\n }\n />\n {/* Low thumb. nameLow overrides any `name` from rest so each thumb has its own form field. */}\n <input\n ref={combinedRef}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentRange[0]}\n disabled={disabled}\n onChange={handleRangeLowChange}\n onKeyDown={handleKeyDown}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n className={prefixedClassNames(\n classPrefix,\n 'slider-input',\n 'slider-input-low'\n )}\n aria-valuenow={currentRange[0]}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-orientation={isVertical ? 'vertical' : undefined}\n {...lowThumb.aria}\n {...getAriaProps(currentRange[0])}\n {...thumbRest}\n id={controlId}\n {...(nameLow !== undefined ? { name: nameLow } : {})}\n />\n {/* High thumb */}\n <input\n ref={inputHighRef}\n type=\"range\"\n min={min}\n max={max}\n step={step}\n value={currentRange[1]}\n disabled={disabled}\n onChange={handleRangeHighChange}\n onMouseEnter={() => setShowTooltipHigh(true)}\n onMouseLeave={() => setShowTooltipHigh(false)}\n onFocus={() => setShowTooltipHigh(true)}\n onBlur={() => setShowTooltipHigh(false)}\n className={prefixedClassNames(\n classPrefix,\n 'slider-input',\n 'slider-input-high'\n )}\n aria-valuenow={currentRange[1]}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-orientation={isVertical ? 'vertical' : undefined}\n {...highThumb.aria}\n {...getAriaProps(currentRange[1])}\n name={nameHigh}\n />\n {/* Each wired thumb's own text, read after the label. A hidden element\n still names whatever points aria-labelledby at it. */}\n {[lowThumb, highThumb].map(\n thumb =>\n thumb.wired && (\n <span key={thumb.textId} id={thumb.textId} hidden>\n {thumb.text}\n </span>\n )\n )}\n {/* Low tooltip */}\n {tooltipMode !== 'hidden' && (\n <output\n ref={outputRef}\n className={prefixedClassNames(\n classPrefix,\n 'slider-output',\n 'slider-output-low',\n {\n 'is-visible': showTipLow,\n 'is-flipped': flipped,\n 'is-flipped-left': isVertical && verticalFlippedLeft,\n }\n )}\n style={\n isVertical\n ? ((verticalFlippedLeft\n ? {\n bottom: getThumbLeft(progressLow),\n right: verticalTooltipOffset,\n left: 'auto',\n }\n : {\n bottom: getThumbLeft(progressLow),\n left: verticalTooltipOffset,\n right: 'auto',\n }) as React.CSSProperties)\n : ({\n left: getThumbLeft(progressLow),\n transform: `translateX(calc(-50% + ${nudgeX}px))`,\n '--slider-output-arrow-offset': `calc(50% - ${nudgeX}px)`,\n } as React.CSSProperties)\n }\n >\n {formatValue(currentRange[0])}\n </output>\n )}\n {/* High tooltip */}\n {tooltipMode !== 'hidden' && (\n <output\n ref={outputHighRef}\n className={prefixedClassNames(\n classPrefix,\n 'slider-output',\n 'slider-output-high',\n {\n 'is-visible': showTipHigh,\n 'is-flipped': flippedHigh,\n 'is-flipped-left': isVertical && verticalFlippedLeft,\n }\n )}\n style={\n isVertical\n ? ((verticalFlippedLeft\n ? {\n bottom: getThumbLeft(progressHigh),\n right: verticalTooltipOffset,\n left: 'auto',\n }\n : {\n bottom: getThumbLeft(progressHigh),\n left: verticalTooltipOffset,\n right: 'auto',\n }) as React.CSSProperties)\n : ({\n left: getThumbLeft(progressHigh),\n transform: `translateX(calc(-50% + ${nudgeXHigh}px))`,\n '--slider-output-arrow-offset': `calc(50% - ${nudgeXHigh}px)`,\n } as React.CSSProperties)\n }\n >\n {formatValue(currentRange[1])}\n </output>\n )}\n {renderTicks()}\n </div>\n );\n\n let content = sliderElement;\n\n if (rendersOwnControl('Slider', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n }\n);\n\nSlider.displayName = 'Slider';\n\nexport default Slider;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
@@ -10,10 +10,11 @@ import { useFieldLabelElementId, useFieldLabelId, useFieldLabelFor } from './For
|
|
|
10
10
|
* generation entirely: the user has taken over the association (#495 presence
|
|
11
11
|
* semantics). When the control renders no label of its own, it adopts the id
|
|
12
12
|
* a labeled Field around it offers, the way the bases do, so that Field's
|
|
13
|
-
* label names it (#939); a user `id` still wins there.
|
|
13
|
+
* label names it (#939); a user `id` still wins there. With `needsLabelId`
|
|
14
|
+
* it also returns the id of whichever label names the control (#981).
|
|
14
15
|
* Internal; not part of the public API.
|
|
15
16
|
*/
|
|
16
|
-
function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true, }) {
|
|
17
|
+
function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true, needsLabelId = false, }) {
|
|
17
18
|
// Called unconditionally per the rules of hooks; SSR-safe on React 18 and 19.
|
|
18
19
|
const generatedId = useId();
|
|
19
20
|
// Read outside the control's own Field, so it is set only when an outer
|
|
@@ -21,6 +22,8 @@ function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true,
|
|
|
21
22
|
const fieldLabelId = useFieldLabelId();
|
|
22
23
|
// What an outer Field's label points at, even when wired by hand.
|
|
23
24
|
const fieldLabelFor = useFieldLabelFor();
|
|
25
|
+
// That Field's label element, set under the same conditions.
|
|
26
|
+
const fieldLabelElementId = useFieldLabelElementId();
|
|
24
27
|
// Truthiness mirrors Field's own `if (label)` render gate.
|
|
25
28
|
const active = !!label && rendersLabel;
|
|
26
29
|
// Presence, not truthiness: `htmlFor: undefined` is an explicit opt-out and
|
|
@@ -29,21 +32,30 @@ function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true,
|
|
|
29
32
|
const adopted = !active && hasInput ? fieldLabelId : undefined;
|
|
30
33
|
const controlId = id ?? (active && !userWired ? generatedId : adopted);
|
|
31
34
|
const ownLabelProps = { htmlFor: controlId, ...labelProps };
|
|
35
|
+
const labelTarget = active ? ownLabelProps.htmlFor : fieldLabelFor;
|
|
36
|
+
const labelled = !!controlId && labelTarget === controlId;
|
|
37
|
+
// Only a label that names the control gets an id to point at, with the
|
|
38
|
+
// suffix Field gives its own, from an id that is already unique.
|
|
39
|
+
const ownLabelId = needsLabelId && active && labelled
|
|
40
|
+
? (labelProps?.id ?? `${generatedId}-label`)
|
|
41
|
+
: undefined;
|
|
32
42
|
// Inactive with a label still means an own Field may render it (pickers'
|
|
33
43
|
// inline mode, Taginput at maxTags) — the explicit `htmlFor: undefined`
|
|
34
44
|
// tells Field the association is owned here, so it must not generate one
|
|
35
45
|
// that would dangle (#495 presence semantics).
|
|
36
46
|
const fieldLabelProps = active
|
|
37
|
-
?
|
|
47
|
+
? ownLabelId
|
|
48
|
+
? { ...ownLabelProps, id: ownLabelId }
|
|
49
|
+
: ownLabelProps
|
|
38
50
|
: label
|
|
39
51
|
? { htmlFor: undefined, ...labelProps }
|
|
40
52
|
: labelProps;
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
};
|
|
53
|
+
const labelId = needsLabelId && labelled
|
|
54
|
+
? active
|
|
55
|
+
? ownLabelId
|
|
56
|
+
: fieldLabelElementId
|
|
57
|
+
: undefined;
|
|
58
|
+
return { controlId, fieldLabelProps, labelled, labelId };
|
|
47
59
|
}
|
|
48
60
|
/**
|
|
49
61
|
* Group-input counterpart of {@link useAutoLabelId} (#494): a group of
|