UNPKG

@yamada-ui/checkbox

Version:

Yamada UI checkbox component

666 lines (659 loc) • 21 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/checkbox-group.tsx var checkbox_group_exports = {}; __export(checkbox_group_exports, { CheckboxGroup: () => CheckboxGroup }); module.exports = __toCommonJS(checkbox_group_exports); var import_form_control3 = require("@yamada-ui/form-control"); var import_layouts = require("@yamada-ui/layouts"); var import_utils5 = require("@yamada-ui/utils"); var import_react4 = require("react"); // src/checkbox.tsx var import_core = require("@yamada-ui/core"); var import_form_control2 = require("@yamada-ui/form-control"); var import_motion = require("@yamada-ui/motion"); var import_utils3 = require("@yamada-ui/utils"); var import_react2 = require("react"); // src/checkbox-context.tsx var import_utils = require("@yamada-ui/utils"); var [CheckboxGroupProvider, useCheckboxGroupContext] = (0, import_utils.createContext)({ name: "CheckboxGroupContext", strict: false }); var [CheckboxCardGroupProvider, useCheckboxCardGroupContext] = (0, import_utils.createContext)({ name: "CheckboxCardGroupContext", strict: false }); var [CheckboxCardProvider, useCheckboxCardContext] = (0, import_utils.createContext)({ name: "CheckboxCardContext", errorMessage: `useCheckboxCardContext returned is 'undefined'. Seems you forgot to wrap the components in "<CheckboxCard />"` }); // src/use-checkbox.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 useCheckbox = ({ id, ...props }) => { const uuid = (0, import_react.useId)(); id != null ? id : id = uuid; const { id: _id, name, isChecked, checked: checkedProp = isChecked, defaultIsChecked, defaultChecked = defaultIsChecked, isIndeterminate, indeterminate = isIndeterminate, selectOnEnter, tabIndex, 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 inputRef = (0, import_react.useRef)(null); const [label, setLabel] = (0, import_react.useState)(true); const [checked, setIsChecked] = (0, import_react.useState)(!!defaultChecked); const controlled = checkedProp !== void 0; const resolvedChecked = controlled ? checkedProp : checked; const onChange = (0, import_utils2.useCallbackRef)( (ev) => { if (readOnly || disabled) { ev.preventDefault(); return; } if (!controlled) setIsChecked( !resolvedChecked || indeterminate ? true : ev.target.checked ); onChangeProp == null ? void 0 : onChangeProp(ev); }, [readOnly, disabled, controlled, resolvedChecked, indeterminate] ); const onFocus = (0, import_utils2.useCallbackRef)(onFocusProp); const onBlur = (0, import_utils2.useCallbackRef)(onBlurProp); const onKeyDown = (0, import_react.useCallback)( ({ key }) => { var _a; if (key === " ") setActive(true); if (selectOnEnter && key === "Enter") (_a = inputRef.current) == null ? void 0 : _a.click(); }, [setActive, selectOnEnter] ); const onKeyUp = (0, import_react.useCallback)( ({ key }) => { if (key === " ") setActive(false); }, [setActive] ); (0, import_react.useEffect)(() => { return (0, import_use_focus_visible.trackFocusVisible)(setFocusVisible); }, []); (0, import_utils2.useSafeLayoutEffect)(() => { if (inputRef.current) inputRef.current.indeterminate = Boolean(isIndeterminate); }, [isIndeterminate]); (0, import_utils2.useUpdateEffect)(() => { if (disabled) setFocused(false); }, [disabled, setFocused]); (0, import_utils2.useSafeLayoutEffect)(() => { var _a; if (!((_a = inputRef.current) == null ? void 0 : _a.form)) return; inputRef.current.form.onreset = () => setIsChecked(!!defaultChecked); }, []); (0, import_utils2.useSafeLayoutEffect)(() => { if (!inputRef.current) return; if (inputRef.current.checked !== resolvedChecked) setIsChecked(inputRef.current.checked); }, [inputRef.current]); const getContainerProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ ...formControlProps, ...props2, ref: (0, import_utils2.mergeRefs)(ref, (el) => { if (el) setLabel(el.tagName === "LABEL"); }), "data-checked": (0, import_utils2.dataAttr)(resolvedChecked), "data-focus": (0, import_utils2.dataAttr)(focused), "data-focus-visible": (0, import_utils2.dataAttr)(focused && focusVisible), onClick: (0, import_utils2.handlerAll)(props2.onClick, () => { var _a; if (label) return; (_a = inputRef.current) == null ? void 0 : _a.click(); requestAnimationFrame(() => { var _a2; return (_a2 = inputRef.current) == null ? void 0 : _a2.focus(); }); }) }), [resolvedChecked, label, focused, focusVisible, formControlProps] ); 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), "data-indeterminate": (0, import_utils2.dataAttr)(indeterminate), onMouseDown: (0, import_utils2.handlerAll)(props2.onMouseDown, (ev) => { if (focused) ev.preventDefault(); 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)) }), [ active, resolvedChecked, focused, hovered, focusVisible, indeterminate, formControlProps ] ); const getInputProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => ({ ...formControlProps, ...props2, id, ref: (0, import_utils2.mergeRefs)(inputRef, ref), type: "checkbox", 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": indeterminate ? "mixed" : resolvedChecked, checked: resolvedChecked, disabled, readOnly, required, tabIndex, 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) }), [ indeterminate, formControlProps, id, name, value, tabIndex, 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, indeterminate, /** * @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, /** * @deprecated Use `indeterminate` instead. */ isIndeterminate, props: rest, getContainerProps, getIconProps, getInputProps, getLabelProps }; }; // src/checkbox.tsx var import_jsx_runtime = require("react/jsx-runtime"); var Checkbox = (0, import_react2.forwardRef)( (props, ref) => { var _a, _b, _c, _d, _e; const group = useCheckboxGroupContext(); const { value: groupValue, ...groupProps } = { ...group }; const control = (0, import_form_control2.useFormControl)(props); const [styles, mergedProps] = (0, import_core.useComponentMultiStyle)("Checkbox", { ...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.includes(computedProps.value) : computedProps.checked; const onChange = groupProps.onChange && computedProps.value ? (0, import_utils3.funcAll)(groupProps.onChange, computedProps.onChange) : computedProps.onChange; const { checked, indeterminate, props: rest, getContainerProps, getIconProps, getInputProps, getLabelProps } = useCheckbox({ ...computedProps, checked: checkedProp, disabled, invalid, readOnly, required, onChange }); const { children: customIcon, ...resolvedIconProps } = { ...iconProps }; const icon = (0, import_react2.cloneElement)(customIcon != null ? customIcon : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxIcon, {}), { checked, disabled, indeterminate, invalid, isDisabled: disabled, isIndeterminate: indeterminate, isInvalid: invalid, isReadOnly: readOnly, isRequired: required, readOnly, required, __css: { opacity: checked || indeterminate ? 1 : 0, transform: checked || indeterminate ? "scale(1)" : "scale(0.95)", transitionDuration: "normal", transitionProperty: "transform" } }); return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( import_core.ui.label, { className: (0, import_utils3.cx)("ui-checkbox", className), ...getContainerProps(), __css: { alignItems: "center", cursor: "pointer", display: "inline-flex", gap, position: "relative", verticalAlign: "top", ...styles.container }, ...rest, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.input, { className: "ui-checkbox__input", ...getInputProps(inputProps, ref) } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { className: "ui-checkbox__icon", __css: { display: "inline-block", position: "relative", userSelect: "none", ...styles.icon }, ...getIconProps(resolvedIconProps), children: icon } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.span, { className: "ui-checkbox__label", __css: { ...styles.label }, ...getLabelProps(labelProps), children: children != null ? children : label } ) ] } ); } ); Checkbox.displayName = "Checkbox"; Checkbox.__ui__ = "Checkbox"; var CheckboxIcon = ({ isChecked, checked = isChecked, disabled: _disabled, isIndeterminate, indeterminate = isIndeterminate, invalid: _invalid, isDisabled: _isDisabled, isInvalid: _isInvalid, isReadOnly: _isReadOnly, isRequired: _isRequired, readOnly: _readOnly, required: _required, ...rest }) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion.AnimatePresence, { initial: false, children: indeterminate || checked ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_core.ui.div, { __css: { left: "50%", position: "absolute", top: "50%", transform: "translate(-50%, -50%)" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_motion.motion.div, { style: { alignItems: "center", display: "flex", justifyContent: "center" }, animate: "checked", exit: "unchecked", initial: "unchecked", variants: { checked: { scale: 1 }, unchecked: { scale: 0.5 } }, children: indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxIndeterminateIcon, { ...rest }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CheckboxCheckIcon, { ...rest }) } ) } ) : null }); }; CheckboxIcon.displayName = "CheckboxIcon"; CheckboxIcon.__ui__ = "CheckboxIcon"; var CheckboxCheckIcon = (props) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_motion.motion.svg, { style: { fill: "none", stroke: "currentColor", strokeDasharray: 16, strokeWidth: 2 }, variants: { checked: { opacity: 1, strokeDashoffset: 0, transition: { duration: 0.2 } }, unchecked: { opacity: 0, strokeDashoffset: 16 } }, viewBox: "0 0 12 10", width: "1.2em", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "1.5 6 4.5 9 10.5 1" }) } ); }; CheckboxCheckIcon.displayName = "CheckboxCheckIcon"; CheckboxCheckIcon.__ui__ = "CheckboxCheckIcon"; var CheckboxIndeterminateIcon = (props) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_motion.motion.svg, { style: { stroke: "currentColor", strokeWidth: 4 }, variants: { checked: { opacity: 1, scaleX: 1, transition: { opacity: { duration: 0.02 }, scaleX: { duration: 0 } } }, unchecked: { opacity: 0, scaleX: 0.65 } }, viewBox: "0 0 24 24", width: "1.2em", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", x2: "3", y1: "12", y2: "12" }) } ); }; CheckboxIndeterminateIcon.displayName = "CheckboxIndeterminateIcon"; CheckboxIndeterminateIcon.__ui__ = "CheckboxIndeterminateIcon"; // src/use-checkbox-group.ts var import_use_controllable_state = require("@yamada-ui/use-controllable-state"); var import_utils4 = require("@yamada-ui/utils"); var import_react3 = require("react"); var isEvent = (value) => value && (0, import_utils4.isObject)(value) && (0, import_utils4.isObject)(value.target); var useCheckboxGroup = ({ defaultValue = [], isNative, value: valueProp, onChange: onChangeProp, ...props }) => { const onChangeRef = (0, import_utils4.useCallbackRef)(onChangeProp); const [value, setValue] = (0, import_use_controllable_state.useControllableState)({ defaultValue, value: valueProp, onChange: onChangeRef }); const onChange = (0, import_react3.useCallback)( (evOrValue) => { const isChecked = isEvent(evOrValue) ? evOrValue.target.checked : !value.includes(evOrValue); const selectedValue = isEvent(evOrValue) ? evOrValue.target.value : evOrValue; const nextValue = isChecked ? [...value, selectedValue] : value.filter((v) => String(v) !== String(selectedValue)); setValue(nextValue); }, [value, setValue] ); const getContainerProps = (0, import_react3.useCallback)( (props2 = {}, ref = null) => ({ role: "group", ...props2, ref }), [] ); const getCheckboxProps = (0, import_react3.useCallback)( (props2 = {}, ref = null) => ({ ...props2, ref, [isNative ? "checked" : "isChecked"]: value.some( (val) => String(props2.value) === String(val) ), ...!isNative ? { checked: value.some((val) => String(props2.value) === String(val)) } : {}, onChange }), [onChange, isNative, value] ); return { props, setValue, value, getCheckboxProps, getContainerProps, onChange }; }; // src/checkbox-group.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var CheckboxGroup = (0, import_react4.forwardRef)( ({ className, colorScheme, size, variant, children, direction = "column", gap, items = [], ...props }, ref) => { const { props: computedProps, value, getContainerProps, onChange } = useCheckboxGroup(props); const { disabled, invalid, isDisabled: _isDisabled, isInvalid: _isInvalid, isReadOnly: _isReadOnly, isRequired: _isRequired, labelId, readOnly, required, ...rest } = (0, import_form_control3.useFormControl)(computedProps); const validChildren = (0, import_utils5.getValidChildren)(children); let computedChildren = []; if (!validChildren.length && items.length) { computedChildren = items.map((props2, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Checkbox, { ...props2 }, index)); } return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( CheckboxGroupProvider, { value: { colorScheme, size, variant, disabled, invalid, readOnly, required, value, onChange }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( import_layouts.Flex, { ref, className: (0, import_utils5.cx)("ui-checkbox-group", className), direction, gap: gap != null ? gap : direction === "row" ? "1rem" : void 0, ...getContainerProps({ "aria-labelledby": labelId, ...rest }), children: children != null ? children : computedChildren } ) } ); } ); CheckboxGroup.displayName = "CheckboxGroup"; CheckboxGroup.__ui__ = "CheckboxGroup"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { CheckboxGroup }); //# sourceMappingURL=checkbox-group.js.map