UNPKG

@yamada-ui/radio

Version:

Yamada UI radio component

817 lines (803 loc) • 25.7 kB
"use client" "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { Radio: () => Radio, RadioCard: () => RadioCard, RadioCardAddon: () => RadioCardAddon, RadioCardDescription: () => RadioCardDescription, RadioCardGroup: () => RadioCardGroup, RadioCardLabel: () => RadioCardLabel, RadioGroup: () => RadioGroup, useRadio: () => useRadio, useRadioGroup: () => useRadioGroup }); module.exports = __toCommonJS(index_exports); // src/radio.tsx var import_core = require("@yamada-ui/core"); var import_form_control2 = require("@yamada-ui/form-control"); var import_utils3 = require("@yamada-ui/utils"); var import_react2 = require("react"); // src/radio-context.ts var import_utils = require("@yamada-ui/utils"); var [RadioGroupProvider, useRadioGroupContext] = (0, import_utils.createContext)({ name: "RadioGroupContext", strict: false }); var [RadioCardGroupProvider, useRadioCardGroupContext] = (0, import_utils.createContext)({ name: "RadioCardGroupContext", strict: false }); var [RadioCardProvider, useRadioCardContext] = (0, import_utils.createContext)({ name: "RadioCardContext", errorMessage: `useRadioCardContext returned is 'undefined'. Seems you forgot to wrap the components in "<RadioCard />"` }); // src/use-radio.ts var import_form_control = require("@yamada-ui/form-control"); var import_use_focus_visible = require("@yamada-ui/use-focus-visible"); var import_utils2 = require("@yamada-ui/utils"); var import_react = require("react"); var useRadio = ({ id, ...props }) => { const uuid = (0, import_react.useId)(); id != null ? id : id = uuid; const { id: _id, name, isChecked, checked: checkedProp = isChecked, defaultIsChecked, defaultChecked = defaultIsChecked, value, onChange: onChangeProp, ...computedProps } = (0, import_form_control.useFormControlProps)({ id, ...props }); const [ { "aria-readonly": _ariaReadonly, disabled, readOnly, required, onBlur: onBlurProp, onFocus: onFocusProp, ...formControlProps }, rest ] = (0, import_utils2.splitObject)(computedProps, import_form_control.formControlProperties); const [focusVisible, setFocusVisible] = (0, import_react.useState)(false); const [focused, setFocused] = (0, import_react.useState)(false); const [hovered, setHovered] = (0, import_react.useState)(false); const [active, setActive] = (0, import_react.useState)(false); const [checked, setChecked] = (0, import_react.useState)(!!defaultChecked); const controlled = checkedProp !== void 0; const resolvedChecked = controlled ? checkedProp : checked; (0, import_react.useEffect)(() => { return (0, import_use_focus_visible.trackFocusVisible)(setFocusVisible); }, []); const onChange = (0, import_utils2.useCallbackRef)( (ev) => { if (readOnly || disabled) { ev.preventDefault(); return; } if (!controlled) setChecked(ev.target.checked); onChangeProp == null ? void 0 : onChangeProp(ev); }, [readOnly, disabled, controlled] ); const onFocus = (0, import_utils2.useCallbackRef)(onFocusProp); const onBlur = (0, import_utils2.useCallbackRef)(onBlurProp); const onKeyDown = (0, import_react.useCallback)( ({ key }) => { if (key === " ") setActive(true); }, [setActive] ); const onKeyUp = (0, import_react.useCallback)( ({ key }) => { if (key === " ") setActive(false); }, [setActive] ); const getContainerProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ ...formControlProps, ...props2, ref, "data-checked": (0, import_utils2.dataAttr)(resolvedChecked), "data-focus": (0, import_utils2.dataAttr)(focused), "data-focus-visible": (0, import_utils2.dataAttr)(focused && focusVisible) }), [resolvedChecked, formControlProps, focused, focusVisible] ); const getIconProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ ...formControlProps, ...props2, ref, "aria-hidden": true, "data-active": (0, import_utils2.dataAttr)(active), "data-checked": (0, import_utils2.dataAttr)(resolvedChecked), "data-focus": (0, import_utils2.dataAttr)(focused), "data-focus-visible": (0, import_utils2.dataAttr)(focused && focusVisible), "data-hover": (0, import_utils2.dataAttr)(hovered), onMouseDown: (0, import_utils2.handlerAll)(props2.onMouseDown, () => setActive(true)), onMouseEnter: (0, import_utils2.handlerAll)(props2.onMouseEnter, () => setHovered(true)), onMouseLeave: (0, import_utils2.handlerAll)(props2.onMouseLeave, () => setHovered(false)), onMouseUp: (0, import_utils2.handlerAll)(props2.onMouseUp, () => setActive(false)) }), [resolvedChecked, active, focused, focusVisible, hovered, formControlProps] ); const getInputProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ ...formControlProps, ...props2, id, ref, type: "radio", name, style: { border: "0px", clip: "rect(0px, 0px, 0px, 0px)", height: "1px", margin: "-1px", overflow: "hidden", padding: "0px", position: "absolute", whiteSpace: "nowrap", width: "1px" }, "aria-checked": resolvedChecked, checked: resolvedChecked, disabled, readOnly, required, value, onBlur: (0, import_utils2.handlerAll)(props2.onBlur, onBlur, () => setFocused(false)), onChange: (0, import_utils2.handlerAll)(props2.onChange, onChange), onFocus: (0, import_utils2.handlerAll)(props2.onFocus, onFocus, () => setFocused(true)), onKeyDown: (0, import_utils2.handlerAll)(props2.onKeyDown, onKeyDown), onKeyUp: (0, import_utils2.handlerAll)(props2.onKeyUp, onKeyUp) }), [ formControlProps, id, name, value, required, disabled, readOnly, resolvedChecked, onChange, onBlur, onFocus, onKeyDown, onKeyUp ] ); const getLabelProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ ...formControlProps, ...props2, ref, "data-checked": (0, import_utils2.dataAttr)(resolvedChecked), onMouseDown: (0, import_utils2.handlerAll)(props2.onMouseDown, (ev) => { ev.preventDefault(); ev.stopPropagation(); }), onTouchStart: (0, import_utils2.handlerAll)(props2.onTouchStart, (ev) => { ev.preventDefault(); ev.stopPropagation(); }) }), [resolvedChecked, formControlProps] ); return { active, checked: resolvedChecked, focused, focusVisible, hovered, /** * @deprecated Use `active` instead. */ isActive: active, /** * @deprecated Use `checked` instead. */ isChecked: resolvedChecked, /** * @deprecated Use `focused` instead. */ isFocused: focused, /** * @deprecated Use `focusVisible` instead. */ isFocusVisible: focusVisible, /** * @deprecated Use `hovered` instead. */ isHovered: hovered, props: rest, getContainerProps, getIconProps, getInputProps, getLabelProps }; }; // src/radio.tsx var import_jsx_runtime = require("react/jsx-runtime"); var Radio = (0, import_react2.forwardRef)( (props, ref) => { var _a, _b, _c, _d, _e; const group = useRadioGroupContext(); const { value: groupValue, ...groupProps } = { ...group }; const control = (0, import_form_control2.useFormControl)(props); const [styles, mergedProps] = (0, import_core.useComponentMultiStyle)("Radio", { ...groupProps, ...props }); const { className, children, disabled = (_a = groupProps.disabled) != null ? _a : control.disabled, gap = "0.5rem", invalid = (_b = groupProps.invalid) != null ? _b : control.invalid, label, readOnly = (_c = groupProps.readOnly) != null ? _c : control.readOnly, required = (_d = groupProps.required) != null ? _d : control.required, iconProps, inputProps, labelProps, ...computedProps } = (0, import_core.omitThemeProps)(mergedProps); (_e = computedProps.checked) != null ? _e : computedProps.checked = computedProps.isChecked; const checkedProp = groupValue && computedProps.value ? groupValue === computedProps.value : computedProps.checked; const onChange = groupProps.onChange && computedProps.value ? (0, import_utils3.funcAll)(groupProps.onChange, computedProps.onChange) : computedProps.onChange; const { checked, props: rest, getContainerProps, getIconProps, getInputProps, getLabelProps } = useRadio({ ...computedProps, checked: checkedProp, disabled, invalid, readOnly, required, onChange }); const tabIndex = !groupValue ? 0 : checked ? 0 : -1; return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( import_core.ui.label, { className: (0, import_utils3.cx)("ui-radio", className), ...getContainerProps(rest), __css: { alignItems: "center", cursor: "pointer", display: "inline-flex", gap, position: "relative", verticalAlign: "top", ...styles.container }, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.input, { className: "ui-radio__input", ...getInputProps( { ...inputProps, tabIndex }, ref ) } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { className: "ui-radio__icon", ...getIconProps(iconProps), __css: { display: "inline-block", position: "relative", userSelect: "none", ...styles.icon } } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.span, { className: "ui-radio__label", ...getLabelProps(labelProps), __css: { ...styles.label }, children: children != null ? children : label } ) ] } ); } ); Radio.displayName = "Radio"; Radio.__ui__ = "Radio"; // src/radio-card.tsx var import_core8 = require("@yamada-ui/core"); var import_form_control3 = require("@yamada-ui/form-control"); var import_utils7 = require("@yamada-ui/utils"); var import_react3 = require("react"); // src/radio-card-addon.tsx var import_core2 = require("@yamada-ui/core"); var import_core3 = require("@yamada-ui/core"); var import_utils4 = require("@yamada-ui/utils"); var import_jsx_runtime2 = require("react/jsx-runtime"); var RadioCardAddon = (0, import_core2.forwardRef)( ({ className, ...rest }, ref) => { const { styles } = useRadioCardContext(); const css = { ...styles.addon }; return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( import_core3.ui.div, { ref, className: (0, import_utils4.cx)("ui-radio-card__addon", className), __css: css, ...rest } ); } ); RadioCardAddon.displayName = "RadioCardAddon"; RadioCardAddon.__ui__ = "RadioCardAddon"; // src/radio-card-description.tsx var import_core4 = require("@yamada-ui/core"); var import_core5 = require("@yamada-ui/core"); var import_utils5 = require("@yamada-ui/utils"); var import_jsx_runtime3 = require("react/jsx-runtime"); var RadioCardDescription = (0, import_core4.forwardRef)(({ className, ...rest }, ref) => { const { styles } = useRadioCardContext(); const css = { ...styles.description }; return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( import_core5.ui.div, { ref, className: (0, import_utils5.cx)("ui-radio-card__description", className), __css: css, ...rest } ); }); RadioCardDescription.displayName = "RadioCardDescription"; RadioCardDescription.__ui__ = "RadioCardDescription"; // src/radio-card-label.tsx var import_core6 = require("@yamada-ui/core"); var import_core7 = require("@yamada-ui/core"); var import_utils6 = require("@yamada-ui/utils"); var import_jsx_runtime4 = require("react/jsx-runtime"); var RadioCardLabel = (0, import_core6.forwardRef)( ({ className, children, withIcon, contentProps, iconProps, ...rest }, ref) => { const { styles, withIcon: defaultWithIcon, getIconProps, iconProps: defaultIconProps } = useRadioCardContext(); withIcon != null ? withIcon : withIcon = defaultWithIcon; return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( import_core7.ui.div, { ref, className: (0, import_utils6.cx)("ui-radio-card__label", className), __css: { ...styles.label }, ...rest, children: [ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( import_core7.ui.span, { className: "ui-radio-card__label-content", __css: { ...styles.labelContent }, ...contentProps, children } ), withIcon ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( import_core7.ui.div, { className: "ui-radio-card__icon", __css: { ...styles.icon }, ...getIconProps({ ...defaultIconProps, ...iconProps }) } ) : null ] } ); } ); RadioCardLabel.displayName = "RadioCardLabel"; RadioCardLabel.__ui__ = "RadioCardLabel"; // src/radio-card.tsx var import_jsx_runtime5 = require("react/jsx-runtime"); var RadioCard = (0, import_react3.forwardRef)( (props, ref) => { var _a, _b, _c, _d, _e; const group = useRadioCardGroupContext(); const { value: groupValue, ...groupProps } = { ...group }; const control = (0, import_form_control3.useFormControl)(props); const [styles, mergedProps] = (0, import_core8.useComponentMultiStyle)("RadioCard", { ...groupProps, ...props }); const { className, addon, children, description, disabled = (_a = groupProps.disabled) != null ? _a : control.disabled, invalid = (_b = groupProps.invalid) != null ? _b : control.invalid, label, readOnly = (_c = groupProps.readOnly) != null ? _c : control.readOnly, required = (_d = groupProps.required) != null ? _d : control.required, withIcon = true, addonProps, descriptionProps, iconProps, inputProps, labelProps, ...computedProps } = (0, import_core8.omitThemeProps)(mergedProps); (_e = computedProps.checked) != null ? _e : computedProps.checked = computedProps.isChecked; const checkedProp = groupValue && computedProps.value ? groupValue === computedProps.value : computedProps.checked; const onChange = groupProps.onChange && computedProps.value ? (0, import_utils7.funcAll)(groupProps.onChange, computedProps.onChange) : computedProps.onChange; const { checked, props: rest, getContainerProps, getIconProps, getInputProps } = useRadio({ ...computedProps, checked: checkedProp, disabled, invalid, readOnly, required, onChange }); const tabIndex = !groupValue ? 0 : checked ? 0 : -1; const validChildren = (0, import_utils7.getValidChildren)(children); const customLabel = (0, import_utils7.findChild)(validChildren, RadioCardLabel); const customDescription = (0, import_utils7.findChild)(validChildren, RadioCardDescription); const customAddon = (0, import_utils7.findChild)(validChildren, RadioCardAddon); const computedChildren = !(0, import_utils7.isEmpty)(validChildren) ? (0, import_utils7.omitChildren)( validChildren, RadioCardLabel, RadioCardDescription, RadioCardAddon ) : children; return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RadioCardProvider, { value: { styles, withIcon, getIconProps, iconProps }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)( import_core8.ui.label, { className: (0, import_utils7.cx)("ui-radio-card", className), ...getContainerProps(rest), __css: { ...styles.container }, children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)( import_core8.ui.input, { className: "ui-radio-card__input", ...getInputProps( { ...inputProps, tabIndex }, ref ) } ), customLabel != null ? customLabel : label ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RadioCardLabel, { ...labelProps, children: label }) : null, customDescription != null ? customDescription : description ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RadioCardDescription, { ...descriptionProps, children: description }) : null, customAddon != null ? customAddon : addon ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RadioCardAddon, { ...addonProps, children: addon }) : null, computedChildren ] } ) }); } ); RadioCard.displayName = "RadioCard"; RadioCard.__ui__ = "RadioCard"; // src/radio-card-group.tsx var import_form_control4 = require("@yamada-ui/form-control"); var import_layouts = require("@yamada-ui/layouts"); var import_utils9 = require("@yamada-ui/utils"); var import_react5 = require("react"); // src/use-radio-group.ts var import_use_controllable_state = require("@yamada-ui/use-controllable-state"); var import_utils8 = require("@yamada-ui/utils"); var import_react4 = require("react"); var isEvent = (value) => value && (0, import_utils8.isObject)(value) && (0, import_utils8.isObject)(value.target); var useRadioGroup = ({ id, name, defaultValue, isNative, value: valueProp, onChange: onChangeProp, ...props }) => { const uuid = (0, import_react4.useId)(); id != null ? id : id = uuid; name != null ? name : name = `radio-${id}`; const containerRef = (0, import_react4.useRef)(null); const onChangeRef = (0, import_utils8.useCallbackRef)(onChangeProp); const [value, setValue] = (0, import_use_controllable_state.useControllableState)({ defaultValue, value: valueProp, onChange: onChangeRef }); const onFocus = (0, import_react4.useCallback)(() => { const container = containerRef.current; if (!container) return; let query = `input:not(:disabled):checked`; let firstInput = container.querySelector(query); if (firstInput) { firstInput.focus(); } else { query = `input:not(:disabled)`; firstInput = container.querySelector(query); firstInput == null ? void 0 : firstInput.focus(); } }, []); const onChange = (0, import_react4.useCallback)( (evOrValue) => { const nextValue = isEvent(evOrValue) ? evOrValue.target.value : evOrValue; setValue(nextValue); }, [setValue] ); const getContainerProps = (0, import_react4.useCallback)( (props2 = {}, ref = null) => ({ role: "radiogroup", ...props2, ref: (0, import_utils8.mergeRefs)(ref, containerRef) }), [] ); const getRadioProps = (0, import_react4.useCallback)( (props2 = {}, ref = null) => { const checked = props2.value === value; return { ...props2, ref, name, "aria-checked": checked, [isNative ? "checked" : "isChecked"]: ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition value != null ? checked : void 0 ), // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition ...!isNative ? { checked: value != null ? checked : void 0 } : {}, onChange }; }, [name, value, onChange, isNative] ); return { id, name, props, setValue, value, getContainerProps, getRadioProps, onChange, onFocus }; }; // src/radio-card-group.tsx var import_jsx_runtime6 = require("react/jsx-runtime"); var RadioCardGroup = (0, import_react5.forwardRef)( ({ id: idProp, className, colorScheme, size, variant, children, direction = "row", gap = "0.5rem", items = [], withIcon = true, addonProps, descriptionProps, labelProps, ...props }, ref) => { const { disabled, invalid, isDisabled: _isDisabled, isInvalid: _isInvalid, isReadOnly: _isReadOnly, isRequired: _isRequired, labelId, readOnly, required, ...computedProps } = (0, import_form_control4.useFormControl)({ id: idProp, ...props }); const { id, name, props: rest, value, getContainerProps, onChange } = useRadioGroup(computedProps); const validChildren = (0, import_utils9.getValidChildren)(children); let computedChildren = []; if (!validChildren.length && items.length) computedChildren = items.map((props2, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RadioCard, { ...props2 }, i)); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( RadioCardGroupProvider, { value: { name, colorScheme, size, variant, disabled, invalid, readOnly, required, value, withIcon, addonProps, descriptionProps, labelProps, onChange }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_layouts.Flex, { ref, className: (0, import_utils9.cx)("ui-radio-card-group", className), gap, w: "100%", ...getContainerProps({ id, "aria-labelledby": labelId, ...rest }), direction, children: children != null ? children : computedChildren } ) } ); } ); RadioCardGroup.displayName = "RadioCardGroup"; RadioCardGroup.__ui__ = "RadioCardGroup"; // src/radio-group.tsx var import_form_control5 = require("@yamada-ui/form-control"); var import_layouts2 = require("@yamada-ui/layouts"); var import_utils10 = require("@yamada-ui/utils"); var import_react6 = require("react"); var import_jsx_runtime7 = require("react/jsx-runtime"); var RadioGroup = (0, import_react6.forwardRef)( ({ id: idProp, className, colorScheme, size, variant, children, direction = "column", gap, items = [], ...props }, ref) => { const { disabled, invalid, isDisabled: _isDisabled, isInvalid: _isInvalid, isReadOnly: _isReadOnly, isRequired: _isRequired, labelId, readOnly, required, ...computedProps } = (0, import_form_control5.useFormControl)({ id: idProp, ...props }); const { id, name, props: rest, value, getContainerProps, onChange } = useRadioGroup(computedProps); const validChildren = (0, import_utils10.getValidChildren)(children); let computedChildren = []; if (!validChildren.length && items.length) computedChildren = items.map((props2, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Radio, { ...props2 }, index)); return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( RadioGroupProvider, { value: { name, colorScheme, size, variant, disabled, invalid, readOnly, required, value, onChange }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( import_layouts2.Flex, { ref, className: (0, import_utils10.cx)("ui-radio-group", className), gap: gap != null ? gap : direction === "row" ? "1rem" : void 0, ...getContainerProps({ id, "aria-labelledby": labelId, ...rest }), direction, children: children != null ? children : computedChildren } ) } ); } ); RadioGroup.displayName = "RadioGroup"; RadioGroup.__ui__ = "RadioGroup"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Radio, RadioCard, RadioCardAddon, RadioCardDescription, RadioCardGroup, RadioCardLabel, RadioGroup, useRadio, useRadioGroup }); //# sourceMappingURL=index.js.map