UNPKG

@ariakit/react-core

Version:

Ariakit React core

177 lines (174 loc) 5.24 kB
"use client"; import { useCommand } from "./2W3RN7C5.js"; import { CheckboxCheckedContext } from "./EYKMH5G5.js"; import { useCheckboxContext } from "./WWPIG7YG.js"; import { useStoreState } from "./RTNCFSKZ.js"; import { createElement, createHook, forwardRef } from "./VOQWLFSQ.js"; import { useEvent, useForceUpdate, useMergeRefs, useTagName, useWrapElement } from "./5GGHRIN3.js"; import { __objRest, __spreadProps, __spreadValues } from "./3YLGPPWQ.js"; // src/checkbox/checkbox.tsx import { disabledFromProps, removeUndefinedValues } from "@ariakit/core/utils/misc"; import { useEffect, useRef, useState } from "react"; import { jsx } from "react/jsx-runtime"; var TagName = "input"; function setMixed(element, mixed) { if (mixed) { element.indeterminate = true; } else if (element.indeterminate) { element.indeterminate = false; } } function isNativeCheckbox(tagName, type) { return tagName === "input" && (!type || type === "checkbox"); } function getPrimitiveValue(value) { if (Array.isArray(value)) { return value.toString(); } return value; } var useCheckbox = createHook( function useCheckbox2(_a) { var _b = _a, { store, name, value: valueProp, checked: checkedProp, defaultChecked } = _b, props = __objRest(_b, [ "store", "name", "value", "checked", "defaultChecked" ]); const context = useCheckboxContext(); store = store || context; const [_checked, setChecked] = useState(defaultChecked != null ? defaultChecked : false); const checked = useStoreState(store, (state) => { if (checkedProp !== void 0) return checkedProp; if ((state == null ? void 0 : state.value) === void 0) return _checked; if (valueProp != null) { if (Array.isArray(state.value)) { const primitiveValue = getPrimitiveValue(valueProp); return state.value.includes(primitiveValue); } return state.value === valueProp; } if (Array.isArray(state.value)) return false; if (typeof state.value === "boolean") return state.value; return false; }); const ref = useRef(null); const tagName = useTagName(ref, TagName); const nativeCheckbox = isNativeCheckbox(tagName, props.type); const mixed = checked ? checked === "mixed" : void 0; const isChecked = checked === "mixed" ? false : checked; const disabled = disabledFromProps(props); const [propertyUpdated, schedulePropertyUpdate] = useForceUpdate(); useEffect(() => { const element = ref.current; if (!element) return; setMixed(element, mixed); if (nativeCheckbox) return; element.checked = isChecked; if (name !== void 0) { element.name = name; } if (valueProp !== void 0) { element.value = `${valueProp}`; } }, [propertyUpdated, mixed, nativeCheckbox, isChecked, name, valueProp]); const onChangeProp = props.onChange; const onChange = useEvent((event) => { if (disabled) { event.stopPropagation(); event.preventDefault(); return; } setMixed(event.currentTarget, mixed); if (!nativeCheckbox) { event.currentTarget.checked = !event.currentTarget.checked; schedulePropertyUpdate(); } onChangeProp == null ? void 0 : onChangeProp(event); if (event.defaultPrevented) return; const elementChecked = event.currentTarget.checked; setChecked(elementChecked); store == null ? void 0 : store.setValue((prevValue) => { if (valueProp == null) return elementChecked; const primitiveValue = getPrimitiveValue(valueProp); if (!Array.isArray(prevValue)) { return prevValue === primitiveValue ? false : primitiveValue; } if (elementChecked) { if (prevValue.includes(primitiveValue)) { return prevValue; } return [...prevValue, primitiveValue]; } return prevValue.filter((v) => v !== primitiveValue); }); }); const onClickProp = props.onClick; const onClick = useEvent((event) => { onClickProp == null ? void 0 : onClickProp(event); if (event.defaultPrevented) return; if (nativeCheckbox) return; onChange(event); }); props = useWrapElement( props, (element) => /* @__PURE__ */ jsx(CheckboxCheckedContext.Provider, { value: isChecked, children: element }), [isChecked] ); props = __spreadProps(__spreadValues({ role: !nativeCheckbox ? "checkbox" : void 0, type: nativeCheckbox ? "checkbox" : void 0, "aria-checked": checked }, props), { ref: useMergeRefs(ref, props.ref), onChange, onClick }); props = useCommand(__spreadValues({ clickOnEnter: !nativeCheckbox }, props)); return removeUndefinedValues(__spreadValues({ name: nativeCheckbox ? name : void 0, value: nativeCheckbox ? valueProp : void 0, checked: isChecked }, props)); } ); var Checkbox = forwardRef(function Checkbox2(props) { const htmlProps = useCheckbox(props); return createElement(TagName, htmlProps); }); export { useCheckbox, Checkbox };