UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

84 lines (81 loc) 2.51 kB
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'; /** * An accessible, native checkbox component */ const Checkbox = /*#__PURE__*/React.forwardRef(({ checked, className, defaultChecked, indeterminate, disabled, onChange, required, validationStatus, value, ['data-component']: dataComponent, ...rest }, ref // eslint-disable-next-line @typescript-eslint/no-explicit-any ) => { const checkboxRef = useProvidedRefOrCreate(ref); const checkboxGroupContext = useContext(CheckboxGroupContext); const handleOnChange = e => { checkboxGroupContext.onChange && checkboxGroupContext.onChange(e); onChange && onChange(e); if (indeterminate && checkboxRef.current) { checkboxRef.current.indeterminate = true; checkboxRef.current.setAttribute('aria-checked', 'mixed'); } }; 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) { 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'); } }); return ( /*#__PURE__*/ // @ts-expect-error inputProp needs a non nullable ref jsx("input", { ...inputProps, "data-component": dataComponent !== null && dataComponent !== void 0 ? dataComponent : 'Checkbox', className: clsx(className, sharedClasses.Input, classes.Checkbox) }) ); }); Checkbox.displayName = 'Checkbox'; Checkbox.__SLOT__ = Symbol('Checkbox'); export { Checkbox as default };