@nex-ui/react
Version:
🎉 A beautiful, modern, and reliable React component library.
196 lines (192 loc) • 6.81 kB
JavaScript
"use client";
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var react = require('react');
var utils = require('@nex-ui/utils');
var hooks = require('@nex-ui/hooks');
var CheckboxGroupContext = require('./CheckboxGroupContext.cjs');
var CheckedIcon = require('./CheckedIcon.cjs');
var IndeterminateIcon = require('./IndeterminateIcon.cjs');
var Context = require('../provider/Context.cjs');
var useDefaultProps = require('../utils/useDefaultProps.cjs');
var useSlotClasses = require('../utils/useSlotClasses.cjs');
var useStyles = require('../utils/useStyles.cjs');
var useSlot = require('../utils/useSlot.cjs');
var InputBase = require('../inputBase/InputBase.cjs');
var checkbox = require('../../theme/recipes/checkbox.cjs');
const slots = [
'root',
'input',
'label',
'icon'
];
const useSlotAriaProps = (ownerState)=>{
const { children, slotProps, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy } = ownerState;
const id = react.useId();
return react.useMemo(()=>{
const labelProps = slotProps?.label;
const stringChildren = utils.isString(children);
const hasLabel = !!children;
const labelId = labelProps?.id ?? (hasLabel ? id : undefined);
return {
input: {
'aria-labelledby': ariaLabelledBy ?? labelId,
'aria-label': ariaLabel ?? (stringChildren ? children : undefined)
},
label: {
id: labelId
}
};
}, [
ariaLabel,
ariaLabelledBy,
children,
id,
slotProps?.label
]);
};
const Checkbox = (inProps)=>{
const { primaryThemeColor, css } = Context.useNexUI();
const props = useDefaultProps.useDefaultProps({
name: 'Checkbox',
props: inProps
});
const groupCtx = CheckboxGroupContext.useCheckboxGroup();
const inGroup = !!groupCtx;
if (utils.__DEV__ && inGroup) {
if ('checked' in props) {
console.warn('[Nex UI] Checkbox: The CheckboxGroup is being used, `checked` will be ignored. Use the `value` of the CheckboxGroup instead.');
}
if ('defaultChecked' in props) {
console.warn('[Nex UI] Checkbox: The CheckboxGroup is being used, `defaultChecked` will be ignored. Use the `defaultValue` of the CheckboxGroup instead.');
}
if (!('value' in props)) {
console.error('[Nex UI] Checkbox: The `value` prop is required when using Checkbox inside a CheckboxGroup.');
}
}
const { sx, icon, value, className, classNames, children, slotProps, onCheckedChange, indeterminate = false, as = 'input', checked: checkedProp, type = 'checkbox', defaultChecked = false, name = groupCtx?.name, color = groupCtx?.color ?? primaryThemeColor, disabled = groupCtx?.disabled ?? false, size = groupCtx?.size ?? 'md', radius = groupCtx?.radius ?? groupCtx?.size ?? size, ...remainingProps } = props;
const [rawChecked, setRawChecked] = hooks.useControlledState(checkedProp, defaultChecked, onCheckedChange);
const checked = inGroup ? groupCtx.isChecked(value) : rawChecked;
const ownerState = {
...props,
as,
defaultChecked,
type,
name,
disabled,
color,
checked,
size,
radius,
inGroup,
indeterminate
};
const handleChange = hooks.useEvent((newChecked)=>{
if (inGroup && value !== undefined) {
groupCtx.toggleValue(value);
}
if (!inGroup) {
setRawChecked(newChecked);
}
});
const slotClasses = useSlotClasses.useSlotClasses({
name: 'Checkbox',
slots,
classNames
});
const styles = useStyles.useStyles({
ownerState,
name: 'Checkbox',
recipe: checkbox.checkboxRecipe
});
const slotAriaProps = useSlotAriaProps(ownerState);
const [CheckboxRoot, getCheckboxRootProps] = useSlot.useSlot({
elementType: 'label',
externalSlotProps: slotProps?.root,
style: styles.root,
classNames: slotClasses.root,
additionalProps: {
sx,
className
},
dataAttrs: {
radius,
size,
color,
disabled,
checked,
indeterminate,
inGroup
}
});
const [CheckboxInput, getCheckboxInputProps] = useSlot.useSlot({
elementType: InputBase.InputBase,
externalForwardedProps: remainingProps,
classNames: slotClasses.input,
style: styles.input,
a11y: slotAriaProps.input,
shouldForwardComponent: false,
additionalProps: {
as,
type,
name,
disabled,
checked,
value,
onCheckedChange: handleChange
}
});
const [CheckboxIcon, getCheckboxIconProps] = useSlot.useSlot({
elementType: 'span',
externalSlotProps: slotProps?.icon,
style: styles.icon,
classNames: slotClasses.icon
});
const [CheckboxLabel, getCheckboxLabelProps] = useSlot.useSlot({
elementType: 'span',
externalSlotProps: slotProps?.label,
style: styles.label,
classNames: slotClasses.label,
a11y: slotAriaProps.label
});
const renderCheckedIcon = ()=>{
if (indeterminate) {
return /*#__PURE__*/ jsxRuntime.jsx(IndeterminateIcon.IndeterminateIcon, {});
}
const customIcon = icon ? utils.isFunction(icon) ? icon(ownerState) : icon : null;
if (!customIcon) {
return /*#__PURE__*/ jsxRuntime.jsx(CheckedIcon.CheckedIcon, {
checked: checked
});
}
if (/*#__PURE__*/ react.isValidElement(customIcon)) {
const element = customIcon;
return /*#__PURE__*/ react.cloneElement(element, {
...element.props,
style: {
...element.props.style,
...css(styles.checkedIcon)
}
});
}
return customIcon;
};
return /*#__PURE__*/ jsxRuntime.jsxs(CheckboxRoot, {
...getCheckboxRootProps(),
children: [
/*#__PURE__*/ jsxRuntime.jsx(CheckboxInput, {
...getCheckboxInputProps()
}),
/*#__PURE__*/ jsxRuntime.jsx(CheckboxIcon, {
...getCheckboxIconProps(),
children: renderCheckedIcon()
}),
children && /*#__PURE__*/ jsxRuntime.jsx(CheckboxLabel, {
...getCheckboxLabelProps(),
children: children
})
]
});
};
Checkbox.displayName = 'Checkbox';
exports.Checkbox = Checkbox;