@primer/react
Version:
An implementation of GitHub's Primer Design System using React
82 lines (79 loc) • 2.32 kB
JavaScript
import { clsx } from 'clsx';
import React, { useContext, useEffect } from 'react';
import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect.js';
import { CheckboxGroupContext } from '../CheckboxGroup/CheckboxGroupContext.js';
import classes from './Checkbox.module.css.js';
import sharedClasses from './shared.module.css.js';
import { jsx } from 'react/jsx-runtime';
import { useProvidedRefOrCreate } from '../hooks/useProvidedRefOrCreate.js';
import Box from '../Box/Box.js';
/**
* An accessible, native checkbox component
*/
const Checkbox = /*#__PURE__*/React.forwardRef(({
checked,
className,
defaultChecked,
indeterminate,
disabled,
onChange,
sx: sxProp,
required,
validationStatus,
value,
...rest
}, ref) => {
const checkboxRef = useProvidedRefOrCreate(ref);
const checkboxGroupContext = useContext(CheckboxGroupContext);
const handleOnChange = e => {
checkboxGroupContext.onChange && checkboxGroupContext.onChange(e);
onChange && onChange(e);
};
const inputProps = {
type: 'checkbox',
disabled,
ref: checkboxRef,
checked: indeterminate ? false : checked,
defaultChecked,
required,
['aria-required']: required ? 'true' : 'false',
['aria-invalid']: validationStatus === 'error' ? 'true' : 'false',
onChange: handleOnChange,
value,
name: value,
...rest
};
useIsomorphicLayoutEffect(() => {
if (checkboxRef.current) {
// eslint-disable-next-line react-compiler/react-compiler
checkboxRef.current.indeterminate = indeterminate || false;
}
}, [indeterminate, checked, checkboxRef]);
useEffect(() => {
const {
current: checkbox
} = checkboxRef;
if (!checkbox) {
return;
}
if (indeterminate) {
checkbox.setAttribute('aria-checked', 'mixed');
} else {
checkbox.setAttribute('aria-checked', checkbox.checked ? 'true' : 'false');
}
});
if (sxProp) {
return /*#__PURE__*/jsx(Box, {
as: "input",
...inputProps,
className: clsx(className, sharedClasses.Input, classes.Checkbox),
sx: sxProp
});
}
return /*#__PURE__*/jsx("input", {
...inputProps,
className: clsx(className, sharedClasses.Input, classes.Checkbox)
});
});
Checkbox.displayName = 'Checkbox';
export { Checkbox as default };