@allxsmith/bestax-bulma 5.57.0 → 5.57.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/bestax.css +1 -1
- package/dist/bestax.css.map +1 -1
- package/dist/esm/components/Dropdown.js +4 -1
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/Toast.js +21 -7
- package/dist/esm/components/Toast.js.map +1 -1
- package/dist/esm/elements/Tr.js.map +1 -1
- package/dist/esm/form/Checkbox.js +21 -14
- package/dist/esm/form/Checkbox.js.map +1 -1
- package/dist/esm/form/CheckboxCard.js +17 -11
- package/dist/esm/form/CheckboxCard.js.map +1 -1
- package/dist/esm/form/Checkboxes.js +30 -3
- package/dist/esm/form/Checkboxes.js.map +1 -1
- package/dist/esm/form/FormContext.js +31 -1
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/Radio.js +13 -10
- package/dist/esm/form/Radio.js.map +1 -1
- package/dist/esm/form/RadioCard.js +10 -8
- package/dist/esm/form/RadioCard.js.map +1 -1
- package/dist/esm/form/Radios.js +15 -3
- package/dist/esm/form/Radios.js.map +1 -1
- package/dist/esm/form/Rate.js +2 -2
- package/dist/esm/form/Rate.js.map +1 -1
- package/dist/extras.css +1 -1
- package/dist/extras.css.map +1 -1
- package/dist/index.cjs +156 -53
- package/dist/index.cjs.map +1 -1
- package/dist/types/components/Toast.d.ts +14 -3
- package/dist/types/elements/Tr.d.ts +3 -3
- package/dist/types/form/CheckboxCard.d.ts +1 -1
- package/dist/types/form/Checkboxes.d.ts +7 -1
- package/dist/types/form/FormContext.d.ts +34 -1
- package/dist/types/form/RadioCard.d.ts +1 -1
- package/dist/types/form/Radios.d.ts +5 -1
- package/dist/types/form/Rate.d.ts +5 -1
- package/dist/types-cjs/components/Toast.d.ts +14 -3
- package/dist/types-cjs/elements/Tr.d.ts +3 -3
- package/dist/types-cjs/form/CheckboxCard.d.ts +1 -1
- package/dist/types-cjs/form/Checkboxes.d.ts +7 -1
- package/dist/types-cjs/form/FormContext.d.ts +34 -1
- package/dist/types-cjs/form/RadioCard.d.ts +1 -1
- package/dist/types-cjs/form/Radios.d.ts +5 -1
- package/dist/types-cjs/form/Rate.d.ts +5 -1
- package/dist/versions/bestax-no-dark-mode.css +1 -1
- package/dist/versions/bestax-no-dark-mode.css.map +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
- package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
- package/dist/versions/bestax-no-helpers.css +1 -1
- package/dist/versions/bestax-no-helpers.css.map +1 -1
- package/dist/versions/bestax-prefixed.css +1 -1
- package/dist/versions/bestax-prefixed.css.map +1 -1
- package/package.json +28 -28
- package/src/scss/CLAUDE.md +4 -1
- package/src/scss/_selected-row.scss +43 -0
- package/src/scss/components/_index.scss +1 -0
- package/src/scss/components/_pagination.scss +25 -0
- package/src/scss/components/_toast.scss +2 -1
- package/src/scss/form/_checkbox.scss +18 -42
- package/src/scss/form/_combobox.scss +11 -0
- package/src/scss/form/_radio.scss +28 -2
- package/src/scss/form/_switch.scss +9 -5
- package/src/scss/form/_taginput.scss +6 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Radios.js","sources":["../../../src/form/Radios.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n RadiosProvider,\n RadiosGroupContextValue,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\nimport { Radio } from './Radio';\nimport { GroupFieldset } from './groupFieldset';\n\n/**\n * Props for the Radios component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n */\nexport interface RadiosProps\n extends Omit<BulmaClassesProps, 'color'>, FormFieldProps {\n /** Field label naming the whole group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` wrapper — uses your `labelProps.id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label names the group instead through `aria-labelledby` when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`). An `aria-label` or `aria-labelledby` you set on the group wins over either label, which still renders but no longer names it. An `aria-labelledby` key counts even when undefined, since it is spread over the group's own. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Additional CSS classes to apply. */\n className?: string;\n /** Form field name shared by every Radio in the group (via context). */\n name?: string;\n /** Currently-selected value (controlled mode). */\n value?: string;\n /** Initial selected value (uncontrolled mode). */\n defaultValue?: string;\n /** Fires when the selection changes. */\n onChange?: (value: string) => void;\n /** Radio elements to render in the group. */\n children: React.ReactNode;\n /**\n * The element the group renders as. With `fieldset` it's a native\n * `<fieldset>` that keeps `role=\"radiogroup\"`. Where the group renders a\n * `Field` of its own, that `Field` is the `<fieldset>` and the `label` is\n * its `<legend>`, in the label column when `horizontal`, so the legend names\n * the group with no ids to wire. Your other attributes then go on the\n * `<fieldset>`, while `className` and the helper props stay on the box that\n * lays out the radios. Inside an outer `Field` there's no legend: the group\n * element itself is the `<fieldset>`, named by that `Field`'s label as\n * before. `div`, the default, renders the group as it always has.\n * @defaultValue 'div'\n */\n as?: 'div' | 'fieldset';\n}\n\n/**\n * The `Radios` component wraps multiple `Radio` components in a Bulma-styled group.\n *\n * @function\n * @param {RadiosProps} props - Props for the Radios component.\n * @returns {JSX.Element} The rendered radios group.\n * @see {@link https://bulma.io/documentation/form/radio/#grouped-radios | Bulma Radios documentation}\n *\n * @example\n * // Controlled\n * const [color, setColor] = useState('red');\n * <Radios name=\"color\" value={color} onChange={setColor}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n *\n * @example\n * // Uncontrolled\n * <Radios name=\"color\" defaultValue=\"red\" onChange={v => console.log(v)}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * </Radios>\n */\nconst RadiosComponent: React.FC<RadiosProps> = ({\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n name,\n value,\n defaultValue,\n onChange,\n children,\n className,\n as,\n ...props\n}) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Radios', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n // As a fieldset with a Field of its own, the group's label is its legend,\n // which names it with no id, so nothing points `aria-labelledby` at it.\n const asFieldset = as === 'fieldset';\n const fieldsetField = asFieldset && ownField;\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField && !fieldsetField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('radios');\n const wrapperClass = classNames(mainClass, bulmaHelperClasses, className);\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The group is \"active\" (manages child selection) when the user opted in by\n // passing value, defaultValue, or onChange. Otherwise it's name-only and\n // children manage their own checked state (Stage 1 behavior).\n const groupActive =\n value !== undefined || defaultValue !== undefined || onChange !== undefined;\n\n const [internalValue, setInternalValue] = useState<string | undefined>(\n defaultValue\n );\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n const ctx = useMemo<RadiosGroupContextValue>(\n () => ({\n name,\n ...(groupActive ? { value: currentValue, onChange: handleChange } : {}),\n }),\n [name, groupActive, currentValue, handleChange]\n );\n\n const choices = <RadiosProvider value={ctx}>{children}</RadiosProvider>;\n // ARIA in HTML allows `radiogroup` on a fieldset, so it keeps the role.\n const Group = asFieldset ? 'fieldset' : 'div';\n const radiosElement = fieldsetField ? (\n <div className={wrapperClass}>{choices}</div>\n ) : (\n <Group\n className={wrapperClass}\n role=\"radiogroup\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n {choices}\n </Group>\n );\n\n let content = radiosElement;\n\n if (rendersOwnControl('Radios', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n\n if (fieldsetField) {\n return (\n <GroupFieldset\n label={label}\n labelSize={labelSize}\n labelProps={labelProps}\n horizontal={horizontal}\n fieldClassName={fieldClassName}\n role=\"radiogroup\"\n attributes={rest}\n message={messageEl}\n >\n {content}\n </GroupFieldset>\n );\n }\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n};\n\nexport const Radios = withSubComponents(RadiosComponent, { Radio }, 'Radios');\n\nexport default Radios;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Radios.js","sources":["../../../src/form/Radios.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n RadiosProvider,\n RadiosGroupContextValue,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\nimport { Radio } from './Radio';\nimport { GroupFieldset } from './groupFieldset';\n\n/**\n * Props for the Radios component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n */\nexport interface RadiosProps\n extends Omit<BulmaClassesProps, 'color'>, FormFieldProps {\n /** Field label naming the whole group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` wrapper — uses your `labelProps.id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose own label names the group instead through `aria-labelledby` when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`). An `aria-label` or `aria-labelledby` you set on the group wins over either label, which still renders but no longer names it. An `aria-labelledby` key counts even when undefined, since it is spread over the group's own. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Additional CSS classes to apply. */\n className?: string;\n /** Form field name shared by every Radio in the group (via context). */\n name?: string;\n /** Currently-selected value (controlled mode). */\n value?: string;\n /** Initial selected value (uncontrolled mode). */\n defaultValue?: string;\n /**\n * Fires when the selection changes; receives the value picked. Passed\n * without `value` or `defaultValue`, it still has the group manage the\n * selection, starting from the radio with `defaultChecked`.\n */\n onChange?: (value: string) => void;\n /** Radio elements to render in the group. */\n children: React.ReactNode;\n /**\n * The element the group renders as. With `fieldset` it's a native\n * `<fieldset>` that keeps `role=\"radiogroup\"`. Where the group renders a\n * `Field` of its own, that `Field` is the `<fieldset>` and the `label` is\n * its `<legend>`, in the label column when `horizontal`, so the legend names\n * the group with no ids to wire. Your other attributes then go on the\n * `<fieldset>`, while `className` and the helper props stay on the box that\n * lays out the radios. Inside an outer `Field` there's no legend: the group\n * element itself is the `<fieldset>`, named by that `Field`'s label as\n * before. `div`, the default, renders the group as it always has.\n * @defaultValue 'div'\n */\n as?: 'div' | 'fieldset';\n}\n\n/**\n * The `Radios` component wraps multiple `Radio` components in a Bulma-styled group.\n *\n * @function\n * @param {RadiosProps} props - Props for the Radios component.\n * @returns {JSX.Element} The rendered radios group.\n * @see {@link https://bulma.io/documentation/form/radio/#grouped-radios | Bulma Radios documentation}\n *\n * @example\n * // Controlled\n * const [color, setColor] = useState('red');\n * <Radios name=\"color\" value={color} onChange={setColor}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n *\n * @example\n * // Uncontrolled\n * <Radios name=\"color\" defaultValue=\"red\" onChange={v => console.log(v)}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * </Radios>\n */\nconst RadiosComponent: React.FC<RadiosProps> = ({\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n name,\n value,\n defaultValue,\n onChange,\n children,\n className,\n as,\n ...props\n}) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Radios', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n // As a fieldset with a Field of its own, the group's label is its legend,\n // which names it with no id, so nothing points `aria-labelledby` at it.\n const asFieldset = as === 'fieldset';\n const fieldsetField = asFieldset && ownField;\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField && !fieldsetField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('radios');\n const wrapperClass = classNames(mainClass, bulmaHelperClasses, className);\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The group is \"active\" (manages child selection) when the user opted in by\n // passing value, defaultValue, or onChange. Otherwise it's name-only and\n // children manage their own checked state (Stage 1 behavior). With only\n // onChange it holds no value until the first change, and the radios show\n // their own defaultChecked until then.\n const groupActive =\n value !== undefined || defaultValue !== undefined || onChange !== undefined;\n\n const [internalValue, setInternalValue] = useState<string | null | undefined>(\n defaultValue\n );\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n // A radio without a value, sharing the group's name, was picked, and the\n // browser unchecked the radio showing checked. A group with no value yet\n // holds `null`, which no radio's value matches, so React leaves that radio\n // unchecked instead of undoing the pick. A group that holds a value keeps\n // it, as it always has.\n const pickWithoutValue = useCallback(() => {\n setInternalValue(current => (current === undefined ? null : current));\n }, []);\n\n const ctx = useMemo<RadiosGroupContextValue>(\n () => ({\n name,\n ...(groupActive\n ? { value: currentValue, onChange: handleChange, pickWithoutValue }\n : {}),\n }),\n [name, groupActive, currentValue, handleChange, pickWithoutValue]\n );\n\n const choices = <RadiosProvider value={ctx}>{children}</RadiosProvider>;\n // ARIA in HTML allows `radiogroup` on a fieldset, so it keeps the role.\n const Group = asFieldset ? 'fieldset' : 'div';\n const radiosElement = fieldsetField ? (\n <div className={wrapperClass}>{choices}</div>\n ) : (\n <Group\n className={wrapperClass}\n role=\"radiogroup\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n {choices}\n </Group>\n );\n\n let content = radiosElement;\n\n if (rendersOwnControl('Radios', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n\n if (fieldsetField) {\n return (\n <GroupFieldset\n label={label}\n labelSize={labelSize}\n labelProps={labelProps}\n horizontal={horizontal}\n fieldClassName={fieldClassName}\n role=\"radiogroup\"\n attributes={rest}\n message={messageEl}\n >\n {content}\n </GroupFieldset>\n );\n }\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n};\n\nexport const Radios = withSubComponents(RadiosComponent, { Radio }, 'Radios');\n\nexport default Radios;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
package/dist/esm/form/Rate.js
CHANGED
|
@@ -261,7 +261,7 @@ const Rate = forwardRef(({ label, labelSize, labelProps, horizontal, message, me
|
|
|
261
261
|
'is-hovered': isHovered,
|
|
262
262
|
}), onClick: e => handleClick(iconIndex, e), onMouseEnter: () => handleMouseEnter(iconIndex), onMouseMove: e => handleMouseMove(iconIndex, e), onMouseLeave: handleMouseLeave, id: `${starBaseId}-${iconIndex}`, role: "radio", "aria-checked": iconIndex === checkedIndex, "aria-label": iconIndex === checkedIndex && shownValue % 1 !== 0
|
|
263
263
|
? `${shownValue} stars`
|
|
264
|
-
: `${iconIndex + 1} star${iconIndex === 0 ? '' : 's'}`, tabIndex: -1, children: icon }, iconIndex));
|
|
264
|
+
: `${iconIndex + 1} star${iconIndex === 0 ? '' : 's'}`, "aria-disabled": disabled || undefined, tabIndex: -1, children: icon }, iconIndex));
|
|
265
265
|
}
|
|
266
266
|
return icons;
|
|
267
267
|
};
|
|
@@ -274,7 +274,7 @@ const Rate = forwardRef(({ label, labelSize, labelProps, horizontal, message, me
|
|
|
274
274
|
const rateScoreClass = usePrefixedClassNames('rate-score');
|
|
275
275
|
const rateTextClass = usePrefixedClassNames('rate-text');
|
|
276
276
|
const rateCustomTextClass = usePrefixedClassNames('rate-custom-text');
|
|
277
|
-
const rateElement = (jsxs("div", { ref: ref, className: combinedClasses, role: "radiogroup", "aria-label": ariaLabelledBy ? undefined : 'Rating', "aria-labelledby": ariaLabelledBy, "aria-activedescendant": checkedIndex >= 0 ? `${starBaseId}-${checkedIndex}` : undefined, tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, ...rest, children: [jsx("div", { className: rateItemsClass, children: renderIcons() }), showScore && (jsx("span", { className: rateScoreClass, children: getScoreDisplay() })), text && jsx("span", { className: rateTextClass, children: text }), customText && (jsx("span", { className: rateCustomTextClass, children: customText })), name && (jsx("input", { type: "hidden", name: name, value: currentValue, form: form }))] }));
|
|
277
|
+
const rateElement = (jsxs("div", { ref: ref, className: combinedClasses, role: "radiogroup", "aria-label": ariaLabelledBy ? undefined : 'Rating', "aria-labelledby": ariaLabelledBy, "aria-activedescendant": checkedIndex >= 0 ? `${starBaseId}-${checkedIndex}` : undefined, "aria-disabled": disabled || undefined, tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, ...rest, children: [jsx("div", { className: rateItemsClass, children: renderIcons() }), showScore && (jsx("span", { className: rateScoreClass, children: getScoreDisplay() })), text && jsx("span", { className: rateTextClass, children: text }), customText && (jsx("span", { className: rateCustomTextClass, children: customText })), name && (jsx("input", { type: "hidden", name: name, value: currentValue, form: form }))] }));
|
|
278
278
|
let content = rateElement;
|
|
279
279
|
if (rendersOwnControl('Rate', { insideControl })) {
|
|
280
280
|
content = jsx(Control, { children: content });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rate.js","sources":["../../../src/form/Rate.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useId } from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { Icon } from '../elements/Icon';\nimport { useClassPrefix, useIconLibrary } from '../helpers/Config';\nimport { useNumberFormat } from '../helpers/localeFormat';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n useFieldsetDisabled,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\n\n/** Available size modifiers for the Rate component. */\nexport type RateSize = 'small' | 'medium' | 'large';\ntype IconLibrary = 'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols';\ntype BulmaColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * Props for individual rate icons.\n */\nexport interface RateIconProps {\n /** The index of this icon (0-based) */\n index: number;\n /** Whether this icon is currently active (filled) */\n isActive: boolean;\n /** Whether this icon is currently hovered */\n isHovered: boolean;\n /** The current value */\n value: number;\n /** Fill percentage for partial icons (0-100). Used with precision < 1. */\n fillPercent: number;\n}\n\n/**\n * Props for the Rate component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the container element.\n */\nexport interface RateProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'>,\n Omit<BulmaClassesProps, 'size'>,\n FormFieldProps {\n /** Field label naming the rating group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` container — uses your `labelProps.id` when provided, otherwise a generated one; it also replaces the default `aria-label=\"Rating\"`. Dropped inside an outer `Field`, whose own label names the group instead through `aria-labelledby` when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`), and replaces the `aria-label=\"Rating\"` fallback too. An `aria-label` or `aria-labelledby` you set on the group wins over either label, which still renders but no longer names it. An `aria-labelledby` key counts even when undefined, since it is spread over the group's own, and leaves the `\"Rating\"` fallback. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Form field name. When set, a hidden input is rendered. */\n name?: string;\n /** Optional id of the form this hidden input belongs to (use when the input lives outside the form element). */\n form?: string;\n /** Controlled value (0 to max). */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Maximum rating value. */\n max?: number;\n /** Size variant. */\n size?: RateSize;\n /** Whether the rating is disabled. */\n disabled?: boolean;\n /**\n * Show the numeric score next to stars, written the way the `locale` of a\n * `LocaleProvider` around it writes numbers.\n */\n showScore?: boolean;\n /** Show custom text based on value. */\n showText?: boolean;\n /** Array of text labels for each rating value. */\n texts?: string[];\n /** Callback when rating changes. */\n onChange?: (value: number) => void;\n /** Custom icon renderer. */\n customIcon?: (props: RateIconProps) => React.ReactNode;\n /** Add spacing between icons. */\n spaced?: boolean;\n /** Right-to-left direction. */\n rtl?: boolean;\n /** Custom icon name for the rating stars. */\n iconName?: string;\n /** Icon library to use (defaults to ConfigProvider value or 'fa'). */\n iconLibrary?: IconLibrary;\n /** Icon style variant (e.g., 'solid', 'outlined'). */\n iconVariant?: string;\n /** Additional icon modifiers. */\n iconFeatures?: string | string[];\n /** Color of the active rating icons. */\n color?: BulmaColor;\n /** Rating precision (e.g., `0.5` for half stars). */\n precision?: number;\n /** Custom text displayed next to the rating. */\n customText?: string;\n}\n\n/**\n * Default star icon component.\n */\nconst StarIcon: React.FC<{ filled: boolean }> = ({ filled }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill={filled ? 'currentColor' : 'none'}\n stroke=\"currentColor\"\n strokeWidth={filled ? 0 : 2}\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\"\n />\n </svg>\n);\n\n/** Snap a value to the nearest precision step. */\nfunction snapToPrecision(val: number, precision: number): number {\n return Math.round(val / precision) * precision;\n}\n\n/** Get fill percentage for a given icon index based on current value. */\nfunction getFillPercent(iconIndex: number, value: number): number {\n if (value >= iconIndex + 1) return 100;\n if (value <= iconIndex) return 0;\n return Math.round((value - iconIndex) * 100);\n}\n\n/**\n * The `Rate` component provides a star/icon-based rating system.\n *\n * @function\n * @param {RateProps} props - Props for the Rate component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the container element.\n * @returns {JSX.Element} The rendered rating component.\n *\n * @example\n * // Basic 5-star rating\n * <Rate defaultValue={3} />\n *\n * @example\n * // With color and precision\n * <Rate defaultValue={3.5} color=\"warning\" precision={0.5} showScore />\n *\n * @example\n * // With Font Awesome icons\n * <Rate iconName=\"star\" iconLibrary=\"fa\" iconVariant=\"solid\" />\n */\nexport const Rate = forwardRef<HTMLDivElement, RateProps>(\n (\n {\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue = 0,\n max = 5,\n size,\n disabled: disabledProp,\n showScore = false,\n showText = false,\n texts,\n onChange,\n customIcon,\n spaced = false,\n rtl = false,\n iconName,\n iconLibrary: iconLibraryProp,\n iconVariant,\n iconFeatures,\n color,\n precision = 1,\n customText,\n name,\n form,\n className,\n ...props\n },\n ref\n ) => {\n const disabled = useFieldsetDisabled(disabledProp);\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Rate', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const formatNumber = useNumberFormat();\n const starBaseId = useId();\n const [internalValue, setInternalValue] = useState(defaultValue);\n const [hoverValue, setHoverValue] = useState<number | null>(null);\n\n const defaultIconLibrary = useIconLibrary();\n const resolvedLibrary = iconLibraryProp || defaultIconLibrary || 'fa';\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n const displayValue = hoverValue !== null ? hoverValue : currentValue;\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n if (disabled) return;\n\n // Allow clicking same value to deselect (set to 0)\n const finalValue = newValue === currentValue ? 0 : newValue;\n\n if (!isControlled) {\n setInternalValue(finalValue);\n }\n onChange?.(finalValue);\n },\n [isControlled, currentValue, disabled, onChange]\n );\n\n // Handle click with precision support\n const handleClick = useCallback(\n (iconIndex: number, e: React.MouseEvent<HTMLSpanElement>) => {\n if (disabled) return;\n\n if (precision < 1) {\n const rect = e.currentTarget.getBoundingClientRect();\n let relativeX = (e.clientX - rect.left) / rect.width;\n if (rtl) relativeX = 1 - relativeX;\n const rawValue = iconIndex + relativeX;\n const snapped = snapToPrecision(rawValue, precision);\n const clamped = Math.max(precision, Math.min(snapped, max));\n updateValue(clamped);\n } else {\n updateValue(iconIndex + 1);\n }\n },\n [disabled, precision, rtl, max, updateValue]\n );\n\n // Handle mouse enter on icon\n const handleMouseEnter = useCallback(\n (iconIndex: number) => {\n if (disabled) return;\n setHoverValue(iconIndex + 1);\n },\n [disabled]\n );\n\n // Handle mouse move with precision support\n const handleMouseMove = useCallback(\n (iconIndex: number, e: React.MouseEvent<HTMLSpanElement>) => {\n if (disabled || precision >= 1) return;\n const rect = e.currentTarget.getBoundingClientRect();\n let relativeX = (e.clientX - rect.left) / rect.width;\n if (rtl) relativeX = 1 - relativeX;\n const rawValue = iconIndex + relativeX;\n const snapped = snapToPrecision(rawValue, precision);\n const clamped = Math.max(precision, Math.min(snapped, max));\n setHoverValue(clamped);\n },\n [disabled, precision, rtl, max]\n );\n\n // Handle mouse leave\n const handleMouseLeave = useCallback(() => {\n setHoverValue(null);\n }, []);\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled) return;\n\n let newValue = currentValue;\n const step = precision < 1 ? precision : 1;\n\n if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {\n e.preventDefault();\n newValue = Math.min(currentValue + step, max);\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {\n e.preventDefault();\n newValue = Math.max(currentValue - step, 0);\n } else if (e.key === 'Home') {\n e.preventDefault();\n newValue = 0;\n } else if (e.key === 'End') {\n e.preventDefault();\n newValue = max;\n }\n\n // Round to avoid floating point issues\n newValue = Math.round(newValue * 1000) / 1000;\n\n if (newValue !== currentValue) {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n }\n },\n [currentValue, max, precision, disabled, isControlled, onChange]\n );\n\n // Get text for current value\n const getText = () => {\n if (!showText || !texts) return null;\n const wholeIndex = Math.ceil(displayValue) - 1;\n const baseText = texts[wholeIndex] || null;\n if (!baseText) return null;\n // For fractional hover values with precision < 1, append \"+\"\n if (precision < 1 && hoverValue !== null && hoverValue % 1 !== 0) {\n return `${baseText}+`;\n }\n return baseText;\n };\n\n // Format score display\n const getScoreDisplay = () => {\n const fractional = precision < 1 && currentValue % 1 !== 0;\n if (formatNumber) {\n return formatNumber(\n currentValue,\n fractional\n ? { minimumFractionDigits: 1, maximumFractionDigits: 1 }\n : undefined\n );\n }\n if (fractional) {\n return currentValue.toFixed(1);\n }\n return currentValue;\n };\n\n // Generate classes\n const classPrefix = useClassPrefix();\n const rateClasses = usePrefixedClassNames('rate', {\n [`is-${size}`]: size,\n 'is-disabled': disabled,\n 'is-spaced': spaced,\n 'is-rtl': rtl,\n [`is-${color}`]: color,\n });\n\n const combinedClasses = classNames(\n rateClasses,\n bulmaHelperClasses,\n className\n );\n\n // Render a single icon based on priority: customIcon > iconName > default SVG\n const renderIcon = (\n iconIndex: number,\n isActive: boolean,\n fillPercent: number\n ) => {\n const iconProps: RateIconProps = {\n index: iconIndex,\n isActive,\n isHovered: hoverValue !== null && iconIndex < hoverValue,\n value: displayValue,\n fillPercent,\n };\n\n if (customIcon) {\n return customIcon(iconProps);\n }\n\n if (iconName) {\n return (\n <Icon\n name={iconName}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n />\n );\n }\n\n return <StarIcon filled={isActive} />;\n };\n\n // Render partial icon with layered approach\n const renderPartialIcon = (iconIndex: number, fillPercent: number) => {\n if (customIcon) {\n // For custom icons, pass fillPercent and let consumer handle it\n const iconProps: RateIconProps = {\n index: iconIndex,\n isActive: fillPercent > 0,\n isHovered: hoverValue !== null && iconIndex < (hoverValue ?? 0),\n value: displayValue,\n fillPercent,\n };\n return customIcon(iconProps);\n }\n\n if (iconName) {\n return (\n <span\n className={prefixedClassNames(classPrefix, 'rate-icon-partial')}\n style={\n {\n '--rate-fill-percent': `${fillPercent}%`,\n } as React.CSSProperties\n }\n >\n <span className={prefixedClassNames(classPrefix, 'rate-icon-bg')}>\n <Icon\n name={iconName}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n />\n </span>\n <span className={prefixedClassNames(classPrefix, 'rate-icon-fg')}>\n <Icon\n name={iconName}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n />\n </span>\n </span>\n );\n }\n\n // Default SVG with clipPath for partial fill\n const clipId = `rate-clip-${iconIndex}`;\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <defs>\n <clipPath id={clipId}>\n <rect\n x=\"0\"\n y=\"0\"\n width={`${(fillPercent / 100) * 24}`}\n height=\"24\"\n />\n </clipPath>\n </defs>\n {/* Background: empty star */}\n <path\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\"\n />\n {/* Foreground: filled portion */}\n <path\n clipPath={`url(#${clipId})`}\n fill=\"currentColor\"\n d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\"\n />\n </svg>\n );\n };\n\n // The star the value falls in is the checked radio, and it carries the\n // value: a radiogroup takes no aria-value* of its own. A fractional value\n // names that star by the value itself (\"3.5 stars\"). Both go by the value\n // as that name writes it, to hundredths, so a value a hair over a whole\n // number checks that number's star under its own name, and no two stars\n // share a name.\n const shownValue = Number(currentValue.toFixed(2));\n const checkedIndex =\n shownValue > 0 ? Math.min(Math.ceil(shownValue), max) - 1 : -1;\n\n // Render icons\n const renderIcons = () => {\n const icons = [];\n\n for (let i = 0; i < max; i++) {\n const iconIndex = rtl ? max - 1 - i : i;\n const fillPercent = getFillPercent(iconIndex, displayValue);\n const isActive = fillPercent === 100;\n const isHovered = hoverValue !== null && iconIndex < hoverValue;\n const isPartial = fillPercent > 0 && fillPercent < 100;\n\n const icon = isPartial\n ? renderPartialIcon(iconIndex, fillPercent)\n : renderIcon(iconIndex, isActive, fillPercent);\n\n icons.push(\n <span\n key={iconIndex}\n className={prefixedClassNames(classPrefix, 'rate-item', {\n 'is-active': isActive,\n 'is-hovered': isHovered,\n })}\n onClick={e => handleClick(iconIndex, e)}\n onMouseEnter={() => handleMouseEnter(iconIndex)}\n onMouseMove={e => handleMouseMove(iconIndex, e)}\n onMouseLeave={handleMouseLeave}\n id={`${starBaseId}-${iconIndex}`}\n role=\"radio\"\n aria-checked={iconIndex === checkedIndex}\n aria-label={\n iconIndex === checkedIndex && shownValue % 1 !== 0\n ? `${shownValue} stars`\n : `${iconIndex + 1} star${iconIndex === 0 ? '' : 's'}`\n }\n tabIndex={-1}\n >\n {icon}\n </span>\n );\n }\n\n return icons;\n };\n\n const text = getText();\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n const rateItemsClass = usePrefixedClassNames('rate-items');\n const rateScoreClass = usePrefixedClassNames('rate-score');\n const rateTextClass = usePrefixedClassNames('rate-text');\n const rateCustomTextClass = usePrefixedClassNames('rate-custom-text');\n\n const rateElement = (\n <div\n ref={ref}\n className={combinedClasses}\n role=\"radiogroup\"\n // Fallback name only: a wired label names the group via labelledby.\n aria-label={ariaLabelledBy ? undefined : 'Rating'}\n aria-labelledby={ariaLabelledBy}\n // Focus stays on the group, so point it at the checked star for\n // assistive technology to announce as the value changes.\n aria-activedescendant={\n checkedIndex >= 0 ? `${starBaseId}-${checkedIndex}` : undefined\n }\n tabIndex={disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n <div className={rateItemsClass}>{renderIcons()}</div>\n {showScore && (\n <span className={rateScoreClass}>{getScoreDisplay()}</span>\n )}\n {text && <span className={rateTextClass}>{text}</span>}\n {customText && (\n <span className={rateCustomTextClass}>{customText}</span>\n )}\n {name && (\n <input type=\"hidden\" name={name} value={currentValue} form={form} />\n )}\n </div>\n );\n\n let content = rateElement;\n\n if (rendersOwnControl('Rate', { 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\nRate.displayName = 'Rate';\n\nexport default Rate;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Rate.js","sources":["../../../src/form/Rate.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useId } from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { Icon } from '../elements/Icon';\nimport { useClassPrefix, useIconLibrary } from '../helpers/Config';\nimport { useNumberFormat } from '../helpers/localeFormat';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n useFieldsetDisabled,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\n\n/** Available size modifiers for the Rate component. */\nexport type RateSize = 'small' | 'medium' | 'large';\ntype IconLibrary = 'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols';\ntype BulmaColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/**\n * Props for individual rate icons.\n */\nexport interface RateIconProps {\n /** The index of this icon (0-based) */\n index: number;\n /** Whether this icon is currently active (filled) */\n isActive: boolean;\n /** Whether this icon is currently hovered */\n isHovered: boolean;\n /** The current value */\n value: number;\n /** Fill percentage for partial icons (0-100). Used with precision < 1. */\n fillPercent: number;\n}\n\n/**\n * Props for the Rate component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the container element.\n */\nexport interface RateProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'color'>,\n Omit<BulmaClassesProps, 'size'>,\n FormFieldProps {\n /** Field label naming the rating group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` container — uses your `labelProps.id` when provided, otherwise a generated one; it also replaces the default `aria-label=\"Rating\"`. Dropped inside an outer `Field`, whose own label names the group instead through `aria-labelledby` when that `Field` generates a target id (not `grouped`/`hasAddons`, no explicit `labelProps.htmlFor`), and replaces the `aria-label=\"Rating\"` fallback too. An `aria-label` or `aria-labelledby` you set on the group wins over either label, which still renders but no longer names it. An `aria-labelledby` key counts even when undefined, since it is spread over the group's own, and leaves the `\"Rating\"` fallback. */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Form field name. When set, a hidden input is rendered. */\n name?: string;\n /** Optional id of the form this hidden input belongs to (use when the input lives outside the form element). */\n form?: string;\n /** Controlled value (0 to max). */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Maximum rating value. */\n max?: number;\n /** Size variant. */\n size?: RateSize;\n /**\n * Whether the rating is disabled. A disabled Rate ignores clicks and keys,\n * leaves the tab order, and sets `aria-disabled` on the group and on every\n * star, so a screen reader announces them as unavailable.\n */\n disabled?: boolean;\n /**\n * Show the numeric score next to stars, written the way the `locale` of a\n * `LocaleProvider` around it writes numbers.\n */\n showScore?: boolean;\n /** Show custom text based on value. */\n showText?: boolean;\n /** Array of text labels for each rating value. */\n texts?: string[];\n /** Callback when rating changes. */\n onChange?: (value: number) => void;\n /** Custom icon renderer. */\n customIcon?: (props: RateIconProps) => React.ReactNode;\n /** Add spacing between icons. */\n spaced?: boolean;\n /** Right-to-left direction. */\n rtl?: boolean;\n /** Custom icon name for the rating stars. */\n iconName?: string;\n /** Icon library to use (defaults to ConfigProvider value or 'fa'). */\n iconLibrary?: IconLibrary;\n /** Icon style variant (e.g., 'solid', 'outlined'). */\n iconVariant?: string;\n /** Additional icon modifiers. */\n iconFeatures?: string | string[];\n /** Color of the active rating icons. */\n color?: BulmaColor;\n /** Rating precision (e.g., `0.5` for half stars). */\n precision?: number;\n /** Custom text displayed next to the rating. */\n customText?: string;\n}\n\n/**\n * Default star icon component.\n */\nconst StarIcon: React.FC<{ filled: boolean }> = ({ filled }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill={filled ? 'currentColor' : 'none'}\n stroke=\"currentColor\"\n strokeWidth={filled ? 0 : 2}\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\"\n />\n </svg>\n);\n\n/** Snap a value to the nearest precision step. */\nfunction snapToPrecision(val: number, precision: number): number {\n return Math.round(val / precision) * precision;\n}\n\n/** Get fill percentage for a given icon index based on current value. */\nfunction getFillPercent(iconIndex: number, value: number): number {\n if (value >= iconIndex + 1) return 100;\n if (value <= iconIndex) return 0;\n return Math.round((value - iconIndex) * 100);\n}\n\n/**\n * The `Rate` component provides a star/icon-based rating system.\n *\n * @function\n * @param {RateProps} props - Props for the Rate component.\n * @param {React.Ref<HTMLDivElement>} ref - Forwarded ref to the container element.\n * @returns {JSX.Element} The rendered rating component.\n *\n * @example\n * // Basic 5-star rating\n * <Rate defaultValue={3} />\n *\n * @example\n * // With color and precision\n * <Rate defaultValue={3.5} color=\"warning\" precision={0.5} showScore />\n *\n * @example\n * // With Font Awesome icons\n * <Rate iconName=\"star\" iconLibrary=\"fa\" iconVariant=\"solid\" />\n */\nexport const Rate = forwardRef<HTMLDivElement, RateProps>(\n (\n {\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue = 0,\n max = 5,\n size,\n disabled: disabledProp,\n showScore = false,\n showText = false,\n texts,\n onChange,\n customIcon,\n spaced = false,\n rtl = false,\n iconName,\n iconLibrary: iconLibraryProp,\n iconVariant,\n iconFeatures,\n color,\n precision = 1,\n customText,\n name,\n form,\n className,\n ...props\n },\n ref\n ) => {\n const disabled = useFieldsetDisabled(disabledProp);\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Rate', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n callerProps: props,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const formatNumber = useNumberFormat();\n const starBaseId = useId();\n const [internalValue, setInternalValue] = useState(defaultValue);\n const [hoverValue, setHoverValue] = useState<number | null>(null);\n\n const defaultIconLibrary = useIconLibrary();\n const resolvedLibrary = iconLibraryProp || defaultIconLibrary || 'fa';\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n const displayValue = hoverValue !== null ? hoverValue : currentValue;\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n if (disabled) return;\n\n // Allow clicking same value to deselect (set to 0)\n const finalValue = newValue === currentValue ? 0 : newValue;\n\n if (!isControlled) {\n setInternalValue(finalValue);\n }\n onChange?.(finalValue);\n },\n [isControlled, currentValue, disabled, onChange]\n );\n\n // Handle click with precision support\n const handleClick = useCallback(\n (iconIndex: number, e: React.MouseEvent<HTMLSpanElement>) => {\n if (disabled) return;\n\n if (precision < 1) {\n const rect = e.currentTarget.getBoundingClientRect();\n let relativeX = (e.clientX - rect.left) / rect.width;\n if (rtl) relativeX = 1 - relativeX;\n const rawValue = iconIndex + relativeX;\n const snapped = snapToPrecision(rawValue, precision);\n const clamped = Math.max(precision, Math.min(snapped, max));\n updateValue(clamped);\n } else {\n updateValue(iconIndex + 1);\n }\n },\n [disabled, precision, rtl, max, updateValue]\n );\n\n // Handle mouse enter on icon\n const handleMouseEnter = useCallback(\n (iconIndex: number) => {\n if (disabled) return;\n setHoverValue(iconIndex + 1);\n },\n [disabled]\n );\n\n // Handle mouse move with precision support\n const handleMouseMove = useCallback(\n (iconIndex: number, e: React.MouseEvent<HTMLSpanElement>) => {\n if (disabled || precision >= 1) return;\n const rect = e.currentTarget.getBoundingClientRect();\n let relativeX = (e.clientX - rect.left) / rect.width;\n if (rtl) relativeX = 1 - relativeX;\n const rawValue = iconIndex + relativeX;\n const snapped = snapToPrecision(rawValue, precision);\n const clamped = Math.max(precision, Math.min(snapped, max));\n setHoverValue(clamped);\n },\n [disabled, precision, rtl, max]\n );\n\n // Handle mouse leave\n const handleMouseLeave = useCallback(() => {\n setHoverValue(null);\n }, []);\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled) return;\n\n let newValue = currentValue;\n const step = precision < 1 ? precision : 1;\n\n if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {\n e.preventDefault();\n newValue = Math.min(currentValue + step, max);\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {\n e.preventDefault();\n newValue = Math.max(currentValue - step, 0);\n } else if (e.key === 'Home') {\n e.preventDefault();\n newValue = 0;\n } else if (e.key === 'End') {\n e.preventDefault();\n newValue = max;\n }\n\n // Round to avoid floating point issues\n newValue = Math.round(newValue * 1000) / 1000;\n\n if (newValue !== currentValue) {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n }\n },\n [currentValue, max, precision, disabled, isControlled, onChange]\n );\n\n // Get text for current value\n const getText = () => {\n if (!showText || !texts) return null;\n const wholeIndex = Math.ceil(displayValue) - 1;\n const baseText = texts[wholeIndex] || null;\n if (!baseText) return null;\n // For fractional hover values with precision < 1, append \"+\"\n if (precision < 1 && hoverValue !== null && hoverValue % 1 !== 0) {\n return `${baseText}+`;\n }\n return baseText;\n };\n\n // Format score display\n const getScoreDisplay = () => {\n const fractional = precision < 1 && currentValue % 1 !== 0;\n if (formatNumber) {\n return formatNumber(\n currentValue,\n fractional\n ? { minimumFractionDigits: 1, maximumFractionDigits: 1 }\n : undefined\n );\n }\n if (fractional) {\n return currentValue.toFixed(1);\n }\n return currentValue;\n };\n\n // Generate classes\n const classPrefix = useClassPrefix();\n const rateClasses = usePrefixedClassNames('rate', {\n [`is-${size}`]: size,\n 'is-disabled': disabled,\n 'is-spaced': spaced,\n 'is-rtl': rtl,\n [`is-${color}`]: color,\n });\n\n const combinedClasses = classNames(\n rateClasses,\n bulmaHelperClasses,\n className\n );\n\n // Render a single icon based on priority: customIcon > iconName > default SVG\n const renderIcon = (\n iconIndex: number,\n isActive: boolean,\n fillPercent: number\n ) => {\n const iconProps: RateIconProps = {\n index: iconIndex,\n isActive,\n isHovered: hoverValue !== null && iconIndex < hoverValue,\n value: displayValue,\n fillPercent,\n };\n\n if (customIcon) {\n return customIcon(iconProps);\n }\n\n if (iconName) {\n return (\n <Icon\n name={iconName}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n />\n );\n }\n\n return <StarIcon filled={isActive} />;\n };\n\n // Render partial icon with layered approach\n const renderPartialIcon = (iconIndex: number, fillPercent: number) => {\n if (customIcon) {\n // For custom icons, pass fillPercent and let consumer handle it\n const iconProps: RateIconProps = {\n index: iconIndex,\n isActive: fillPercent > 0,\n isHovered: hoverValue !== null && iconIndex < (hoverValue ?? 0),\n value: displayValue,\n fillPercent,\n };\n return customIcon(iconProps);\n }\n\n if (iconName) {\n return (\n <span\n className={prefixedClassNames(classPrefix, 'rate-icon-partial')}\n style={\n {\n '--rate-fill-percent': `${fillPercent}%`,\n } as React.CSSProperties\n }\n >\n <span className={prefixedClassNames(classPrefix, 'rate-icon-bg')}>\n <Icon\n name={iconName}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n />\n </span>\n <span className={prefixedClassNames(classPrefix, 'rate-icon-fg')}>\n <Icon\n name={iconName}\n library={resolvedLibrary}\n variant={iconVariant}\n features={iconFeatures}\n />\n </span>\n </span>\n );\n }\n\n // Default SVG with clipPath for partial fill\n const clipId = `rate-clip-${iconIndex}`;\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <defs>\n <clipPath id={clipId}>\n <rect\n x=\"0\"\n y=\"0\"\n width={`${(fillPercent / 100) * 24}`}\n height=\"24\"\n />\n </clipPath>\n </defs>\n {/* Background: empty star */}\n <path\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\"\n />\n {/* Foreground: filled portion */}\n <path\n clipPath={`url(#${clipId})`}\n fill=\"currentColor\"\n d=\"M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z\"\n />\n </svg>\n );\n };\n\n // The star the value falls in is the checked radio, and it carries the\n // value: a radiogroup takes no aria-value* of its own. A fractional value\n // names that star by the value itself (\"3.5 stars\"). Both go by the value\n // as that name writes it, to hundredths, so a value a hair over a whole\n // number checks that number's star under its own name, and no two stars\n // share a name.\n const shownValue = Number(currentValue.toFixed(2));\n const checkedIndex =\n shownValue > 0 ? Math.min(Math.ceil(shownValue), max) - 1 : -1;\n\n // Render icons\n const renderIcons = () => {\n const icons = [];\n\n for (let i = 0; i < max; i++) {\n const iconIndex = rtl ? max - 1 - i : i;\n const fillPercent = getFillPercent(iconIndex, displayValue);\n const isActive = fillPercent === 100;\n const isHovered = hoverValue !== null && iconIndex < hoverValue;\n const isPartial = fillPercent > 0 && fillPercent < 100;\n\n const icon = isPartial\n ? renderPartialIcon(iconIndex, fillPercent)\n : renderIcon(iconIndex, isActive, fillPercent);\n\n icons.push(\n <span\n key={iconIndex}\n className={prefixedClassNames(classPrefix, 'rate-item', {\n 'is-active': isActive,\n 'is-hovered': isHovered,\n })}\n onClick={e => handleClick(iconIndex, e)}\n onMouseEnter={() => handleMouseEnter(iconIndex)}\n onMouseMove={e => handleMouseMove(iconIndex, e)}\n onMouseLeave={handleMouseLeave}\n id={`${starBaseId}-${iconIndex}`}\n role=\"radio\"\n aria-checked={iconIndex === checkedIndex}\n aria-label={\n iconIndex === checkedIndex && shownValue % 1 !== 0\n ? `${shownValue} stars`\n : `${iconIndex + 1} star${iconIndex === 0 ? '' : 's'}`\n }\n // The group's aria-disabled covers its stars too, but a screen\n // reader that doesn't carry it down still hears it here.\n aria-disabled={disabled || undefined}\n tabIndex={-1}\n >\n {icon}\n </span>\n );\n }\n\n return icons;\n };\n\n const text = getText();\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n const rateItemsClass = usePrefixedClassNames('rate-items');\n const rateScoreClass = usePrefixedClassNames('rate-score');\n const rateTextClass = usePrefixedClassNames('rate-text');\n const rateCustomTextClass = usePrefixedClassNames('rate-custom-text');\n\n const rateElement = (\n <div\n ref={ref}\n className={combinedClasses}\n role=\"radiogroup\"\n // Fallback name only: a wired label names the group via labelledby.\n aria-label={ariaLabelledBy ? undefined : 'Rating'}\n aria-labelledby={ariaLabelledBy}\n // Focus stays on the group, so point it at the checked star for\n // assistive technology to announce as the value changes.\n aria-activedescendant={\n checkedIndex >= 0 ? `${starBaseId}-${checkedIndex}` : undefined\n }\n // Dimmed and out of the tab order isn't enough: a screen reader\n // reaching the stars by its own navigation needs to hear it too.\n aria-disabled={disabled || undefined}\n tabIndex={disabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n <div className={rateItemsClass}>{renderIcons()}</div>\n {showScore && (\n <span className={rateScoreClass}>{getScoreDisplay()}</span>\n )}\n {text && <span className={rateTextClass}>{text}</span>}\n {customText && (\n <span className={rateCustomTextClass}>{customText}</span>\n )}\n {name && (\n <input type=\"hidden\" name={name} value={currentValue} form={form} />\n )}\n </div>\n );\n\n let content = rateElement;\n\n if (rendersOwnControl('Rate', { 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\nRate.displayName = 'Rate';\n\nexport default Rate;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|