@codefast-ui/checkbox-group
Version:
Accessible checkbox group component built with React and Radix UI
99 lines (98 loc) • 4.16 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import { useCallback } from "react";
import { Indicator, Root, createCheckboxScope } from "@radix-ui/react-checkbox";
import { createContextScope } from "@radix-ui/react-context";
import { useDirection } from "@radix-ui/react-direction";
import { Item, Root as react_roving_focus_Root, createRovingFocusGroupScope } from "@radix-ui/react-roving-focus";
import { useControllableState } from "@radix-ui/react-use-controllable-state";
const CHECKBOX_GROUP_NAME = "CheckboxGroup";
const [createCheckboxGroupContext, createCheckboxGroupScope] = createContextScope(CHECKBOX_GROUP_NAME, [
createRovingFocusGroupScope,
createCheckboxScope
]);
const useRovingFocusGroupScope = createRovingFocusGroupScope();
const useCheckboxScope = createCheckboxScope();
const [CheckboxGroupContextProvider, useCheckboxGroupContext] = createCheckboxGroupContext(CHECKBOX_GROUP_NAME);
function CheckboxGroup({ __scopeCheckboxGroup, defaultValue, dir, disabled = false, loop = true, name, onValueChange, orientation, required = false, value: valueProperty, ...props }) {
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeCheckboxGroup);
const direction = useDirection(dir);
const [value = [], setValue] = useControllableState({
defaultProp: defaultValue,
onChange: onValueChange,
prop: valueProperty
});
const handleItemCheck = useCallback((itemValue)=>{
setValue((previousValue = [])=>[
...previousValue,
itemValue
]);
}, [
setValue
]);
const handleItemUncheck = useCallback((itemValue)=>{
setValue((previousValue = [])=>{
if (required && 1 === previousValue.length && previousValue[0] === itemValue) return previousValue;
return previousValue.filter((inputValue)=>inputValue !== itemValue);
});
}, [
setValue,
required
]);
return /*#__PURE__*/ jsx(CheckboxGroupContextProvider, {
disabled: disabled,
name: name,
required: required,
scope: __scopeCheckboxGroup,
value: value,
onItemCheck: handleItemCheck,
onItemUncheck: handleItemUncheck,
children: /*#__PURE__*/ jsx(react_roving_focus_Root, {
asChild: true,
...rovingFocusGroupScope,
dir: direction,
loop: loop,
orientation: orientation,
children: /*#__PURE__*/ jsx("div", {
"data-disabled": disabled ? "" : void 0,
dir: direction,
role: "group",
...props
})
})
});
}
const ITEM_NAME = "CheckboxGroupItem";
function CheckboxGroupItem({ __scopeCheckboxGroup, disabled, ...props }) {
const context = useCheckboxGroupContext(ITEM_NAME, __scopeCheckboxGroup);
const isDisabled = context.disabled || disabled;
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeCheckboxGroup);
const checkboxScope = useCheckboxScope(__scopeCheckboxGroup);
const checked = context.value?.includes(props.value);
return /*#__PURE__*/ jsx(Item, {
asChild: true,
...rovingFocusGroupScope,
active: checked,
focusable: !isDisabled,
children: /*#__PURE__*/ jsx(Root, {
"aria-label": props.value,
checked: checked,
disabled: isDisabled,
name: context.name,
required: context.required,
...checkboxScope,
...props,
onCheckedChange: (checkedState)=>{
if (checkedState) context.onItemCheck(props.value);
else context.onItemUncheck(props.value);
}
})
});
}
function CheckboxGroupIndicator({ __scopeCheckboxGroup, ...props }) {
const checkboxScope = useCheckboxScope(__scopeCheckboxGroup);
return /*#__PURE__*/ jsx(Indicator, {
...checkboxScope,
...props
});
}
export { CheckboxGroup, CheckboxGroupIndicator, CheckboxGroupItem, CheckboxGroupIndicator as Indicator, CheckboxGroupItem as Item, CheckboxGroup as Root, createCheckboxGroupScope };