UNPKG

@heroui/radio

Version:

Radios allow users to select a single option from a list of mutually exclusive options.

211 lines (208 loc) 6.6 kB
"use client"; import { useRadioGroupContext } from "./chunk-A5ZCUROT.mjs"; // src/use-radio.ts import { useCallback, useId } from "react"; import { useMemo, useRef } from "react"; import { useFocusRing } from "@react-aria/focus"; import { useHover } from "@react-aria/interactions"; import { radio } from "@heroui/theme"; import { useRadio as useReactAriaRadio } from "@react-aria/radio"; import { useProviderContext } from "@heroui/system"; import { __DEV__, warn, clsx, dataAttr } from "@heroui/shared-utils"; import { useDOMRef } from "@heroui/react-utils"; import { chain, mergeProps } from "@react-aria/utils"; function useRadio(props) { var _a, _b, _c, _d, _e; const globalContext = useProviderContext(); const groupContext = useRadioGroupContext(); const { as, ref, classNames, id, value, children, description, size = (_a = groupContext == null ? void 0 : groupContext.size) != null ? _a : "md", color = (_b = groupContext == null ? void 0 : groupContext.color) != null ? _b : "primary", isDisabled: isDisabledProp = (_c = groupContext == null ? void 0 : groupContext.isDisabled) != null ? _c : false, disableAnimation = (_e = (_d = groupContext == null ? void 0 : groupContext.disableAnimation) != null ? _d : globalContext == null ? void 0 : globalContext.disableAnimation) != null ? _e : false, onChange = groupContext == null ? void 0 : groupContext.onChange, autoFocus = false, className, ...otherProps } = props; if (groupContext && __DEV__) { if ("checked" in otherProps) { warn('Remove props "checked" if in the Radio.Group.', "Radio"); } if (value === void 0) { warn('Props "value" must be defined if in the Radio.Group.', "Radio"); } } const Component = as || "label"; const domRef = useDOMRef(ref); const inputRef = useRef(null); const labelId = useId(); const descriptionId = useId(); const isRequired = useMemo(() => { var _a2; return (_a2 = groupContext.isRequired) != null ? _a2 : false; }, [groupContext.isRequired]); const isInvalid = groupContext.isInvalid; const ariaRadioProps = useMemo(() => { const ariaDescribedBy = [otherProps["aria-describedby"], descriptionId].filter(Boolean).join(" ") || void 0; return { id, isRequired, isDisabled: isDisabledProp, "aria-label": otherProps["aria-label"], "aria-labelledby": otherProps["aria-labelledby"] || labelId, "aria-describedby": ariaDescribedBy }; }, [ id, isDisabledProp, isRequired, description, otherProps["aria-label"], otherProps["aria-labelledby"], otherProps["aria-describedby"], descriptionId ]); const { inputProps, isDisabled, isSelected, isPressed } = useReactAriaRadio( { value, children: typeof children === "function" ? true : children, ...ariaRadioProps }, groupContext.groupState, inputRef ); const { focusProps, isFocused, isFocusVisible } = useFocusRing({ autoFocus }); const interactionDisabled = isDisabled || inputProps.readOnly; const { hoverProps, isHovered } = useHover({ isDisabled: interactionDisabled }); const pressed = interactionDisabled ? false : isPressed; const slots = useMemo( () => radio({ color, size, isInvalid, isDisabled, disableAnimation }), [color, size, isDisabled, isInvalid, disableAnimation] ); const baseStyles = clsx(classNames == null ? void 0 : classNames.base, className); const getBaseProps = useCallback( (props2 = {}) => { return { ...props2, ref: domRef, className: slots.base({ class: baseStyles }), "data-disabled": dataAttr(isDisabled), "data-focus": dataAttr(isFocused), "data-focus-visible": dataAttr(isFocusVisible), "data-selected": dataAttr(isSelected), "data-invalid": dataAttr(isInvalid), "data-hover": dataAttr(isHovered), "data-pressed": dataAttr(pressed), "data-hover-unselected": dataAttr(isHovered && !isSelected), "data-readonly": dataAttr(inputProps.readOnly), "aria-required": dataAttr(isRequired), ...mergeProps(hoverProps, otherProps) }; }, [ slots, baseStyles, domRef, isDisabled, isFocused, isFocusVisible, isSelected, isInvalid, isHovered, pressed, inputProps.readOnly, isRequired, otherProps ] ); const getWrapperProps = useCallback( (props2 = {}) => { return { ...props2, "aria-hidden": true, className: clsx(slots.wrapper({ class: clsx(classNames == null ? void 0 : classNames.wrapper, props2.className) })) }; }, [slots, classNames == null ? void 0 : classNames.wrapper] ); const getInputProps = useCallback( (props2 = {}) => { return { ref: inputRef, ...mergeProps(props2, inputProps, focusProps), className: slots.hiddenInput({ class: classNames == null ? void 0 : classNames.hiddenInput }), onChange: chain(inputProps.onChange, onChange) }; }, [inputProps, focusProps, onChange] ); const getLabelProps = useCallback( (props2 = {}) => ({ ...props2, id: labelId, className: slots.label({ class: classNames == null ? void 0 : classNames.label }) }), [slots, classNames == null ? void 0 : classNames.label, isDisabled, isSelected, isInvalid] ); const getLabelWrapperProps = useCallback( (props2 = {}) => ({ ...props2, className: slots.labelWrapper({ class: classNames == null ? void 0 : classNames.labelWrapper }) }), [slots, classNames == null ? void 0 : classNames.labelWrapper] ); const getControlProps = useCallback( (props2 = {}) => ({ ...props2, className: slots.control({ class: classNames == null ? void 0 : classNames.control }) }), [slots, classNames == null ? void 0 : classNames.control] ); const getDescriptionProps = useCallback( (props2 = {}) => ({ ...props2, id: descriptionId, className: slots.description({ class: classNames == null ? void 0 : classNames.description }) }), [slots, classNames == null ? void 0 : classNames.description] ); return { Component, children, isSelected, isDisabled, isInvalid, isFocusVisible, description, getBaseProps, getWrapperProps, getInputProps, getLabelProps, getLabelWrapperProps, getControlProps, getDescriptionProps }; } export { useRadio };