UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

244 lines (240 loc) • 8.15 kB
"use client"; const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs'); const require_context = require('../../utils/context.cjs'); const require_dom = require('../../utils/dom.cjs'); const require_ref = require('../../utils/ref.cjs'); const require_utils_index = require('../../utils/index.cjs'); const require_hooks_use_controllable_state_index = require('../../hooks/use-controllable-state/index.cjs'); const require_use_field_props = require('../field/use-field-props.cjs'); let react = require("react"); react = require_rolldown_runtime.__toESM(react); //#region src/components/rating/use-rating.tsx const getRoundedValue = (value, to) => { const rounded = Math.round(value / to) * to; const precision = `${to}`.split(".")[1]?.length || 0; return Number(rounded.toFixed(precision)); }; const [RatingContext, useRatingContext] = require_context.createContext({ name: "RatingContext" }); const useRating = (props = {}) => { const uuid = (0, react.useId)(); const { props: { id = uuid, name = uuid, count: countProp = 5, defaultValue = 0, disabled, fractions: fractionsProp = 1, highlightSelectedOnly = false, readOnly, required, value: valueProp, onChange: onChangeProp, onHover,...rest }, ariaProps, dataProps, eventProps } = require_use_field_props.useFieldProps({ ...props, notSupportReadOnly: true }); const rootRef = (0, react.useRef)(null); const [value, setValue] = require_hooks_use_controllable_state_index.useControllableState({ defaultValue, value: valueProp, onChange: onChangeProp }); const [hoveredValue, setHoveredValue] = (0, react.useState)(-1); const outsideRef = (0, react.useRef)(true); const fractions = Math.floor(fractionsProp); const count = Math.floor(countProp); const decimal = 1 / fractions; const roundedValue = (0, react.useMemo)(() => getRoundedValue(value, decimal), [decimal, value]); const interactive = !(readOnly || disabled); const displayValue = hoveredValue !== -1 ? hoveredValue : roundedValue; const getHoveredValue = (0, react.useCallback)((x) => { if (!rootRef.current) return -1; const { left, width } = rootRef.current.getBoundingClientRect(); const itemWidth = width / count; return (0, require_utils_index.utils_exports.clampNumber)(getRoundedValue((x - left) / itemWidth + decimal / 2, decimal), decimal, count); }, [count, decimal]); const onMouseEnter = (0, react.useCallback)(() => { if (interactive) outsideRef.current = false; }, [interactive]); const onMouseLeave = (0, react.useCallback)(() => { if (!interactive) return; setHoveredValue(-1); outsideRef.current = true; if (hoveredValue !== -1) onHover?.(-1); }, [ hoveredValue, onHover, interactive, setHoveredValue ]); const onMouseMove = (0, react.useCallback)((ev) => { if (disabled || readOnly) return; const roundedValue$1 = getHoveredValue(ev.clientX); setHoveredValue(roundedValue$1); if (roundedValue$1 !== hoveredValue) onHover?.(roundedValue$1); }, [ disabled, getHoveredValue, hoveredValue, readOnly, onHover ]); const onTouchStart = (0, react.useCallback)((ev) => { ev.preventDefault(); const el = ev.touches[0]; if (!el) return; setValue(getHoveredValue(el.clientX)); }, [getHoveredValue, setValue]); const onTouchEnd = (0, react.useCallback)((ev) => { ev.preventDefault(); }, []); return { id, name, count, decimal, disabled, displayValue, fractions, highlightSelectedOnly, hoveredValue, interactive, outsideRef, readOnly, required, roundedValue, setHoveredValue, setValue, value, ariaProps, dataProps, eventProps, getRootProps: (0, react.useCallback)(({ ref,...props$1 } = {}) => ({ ...dataProps, ...eventProps, ...ariaProps, id, "aria-label": `${value} Stars`, "aria-readonly": (0, require_utils_index.utils_exports.ariaAttr)(readOnly), role: "radiogroup", ...rest, ...props$1, ref: require_ref.mergeRefs(ref, rest.ref, rootRef), onMouseEnter: (0, require_utils_index.utils_exports.handlerAll)(props$1.onMouseEnter, rest.onMouseEnter, onMouseEnter), onMouseLeave: (0, require_utils_index.utils_exports.handlerAll)(props$1.onMouseLeave, rest.onMouseLeave, onMouseLeave), onMouseMove: (0, require_utils_index.utils_exports.handlerAll)(props$1.onMouseMove, rest.onMouseMove, onMouseMove), onTouchEnd: (0, require_utils_index.utils_exports.handlerAll)(props$1.onTouchEnd, rest.onTouchEnd, onTouchEnd), onTouchStart: (0, require_utils_index.utils_exports.handlerAll)(props$1.onTouchStart, rest.onTouchStart, onTouchStart) }), [ ariaProps, dataProps, eventProps, id, onMouseEnter, onMouseLeave, onMouseMove, onTouchEnd, onTouchStart, readOnly, rest, value ]) }; }; const useRatingItem = ({ groupValue, index,...rest }) => { const { id: rootId, name, decimal, disabled, displayValue, highlightSelectedOnly, interactive, outsideRef, readOnly, required, roundedValue, setHoveredValue, setValue, ariaProps, dataProps, eventProps } = useRatingContext(); const fractionValue = decimal * (groupValue === 1 ? index : index + 1); const value = (0, react.useMemo)(() => getRoundedValue(groupValue - 1 + fractionValue, decimal), [ decimal, fractionValue, groupValue ]); const active = value === displayValue; const checked = value === roundedValue; const filled = highlightSelectedOnly ? value === displayValue : value <= displayValue; const id = `${rootId}-${groupValue}-${value}`; const onBlur = (0, react.useCallback)(() => { if (outsideRef.current) setHoveredValue(-1); }, [outsideRef, setHoveredValue]); const onInputChange = (0, react.useCallback)((ev) => { if (!interactive) return; setHoveredValue(parseFloat(ev.target.value)); }, [interactive, setHoveredValue]); const onChange = (0, react.useCallback)((value$1) => { if (!interactive) return; setValue(value$1); }, [interactive, setValue]); const onMouseDown = (0, react.useCallback)(() => { onChange(value); }, [onChange, value]); const onTouchStart = (0, react.useCallback)(() => { onChange(value); }, [onChange, value]); const onKeyDown = (0, react.useCallback)((ev) => { require_dom.runKeyAction(ev, { Space: () => onChange(value) }); }, [onChange, value]); const getLabelProps = (0, react.useCallback)(({ style,...props } = {}) => ({ ...dataProps, ...ariaProps, htmlFor: id, "data-active": (0, require_utils_index.utils_exports.dataAttr)(active), "data-filled": (0, require_utils_index.utils_exports.dataAttr)(filled), ...rest, ...props, style: { ...style, zIndex: fractionValue !== 1 ? active ? 1 : -1 : void 0 }, onMouseDown: (0, require_utils_index.utils_exports.handlerAll)(props.onMouseDown, onMouseDown), onTouchStart: (0, require_utils_index.utils_exports.handlerAll)(props.onTouchStart, onTouchStart) }), [ active, ariaProps, dataProps, filled, fractionValue, id, onMouseDown, onTouchStart, rest ]); return { active, checked, filled, fractionValue, groupValue, value, getInputProps: (0, react.useCallback)((props = {}) => ({ ...dataProps, ...eventProps, ...ariaProps, id, type: "radio", name, style: require_dom.visuallyHiddenAttributes.style, "aria-label": value.toString(), "data-active": (0, require_utils_index.utils_exports.dataAttr)(active), "data-checked": (0, require_utils_index.utils_exports.dataAttr)(checked), checked, disabled, readOnly, required, value, ...props, onBlur: (0, require_utils_index.utils_exports.handlerAll)(onBlur, props.onBlur), onChange: (0, require_utils_index.utils_exports.handlerAll)(props.onChange, onInputChange), onKeyDown: (0, require_utils_index.utils_exports.handlerAll)(props.onKeyDown, onKeyDown) }), [ id, name, value, active, checked, dataProps, eventProps, ariaProps, disabled, readOnly, required, onBlur, onInputChange, onKeyDown ]), getLabelProps }; }; //#endregion exports.RatingContext = RatingContext; exports.useRating = useRating; exports.useRatingContext = useRatingContext; exports.useRatingItem = useRatingItem; //# sourceMappingURL=use-rating.cjs.map