UNPKG

@gluestack-ui/checkbox

Version:

A universal headless Checkbox component for React Native, Next.js & React

80 lines (79 loc) 2.79 kB
import React from 'react'; import { ariaAttr } from '@gluestack-ui/utils'; export const CheckboxContext = React.createContext({}); export function useCheckboxProvider(props) { const { id: idProp, isRequired, isInvalid, isDisabled, isReadOnly, ...htmlProps } = props; var idCounter = 0; function uniqueId(prefix = '') { var id = ++idCounter; return prefix + id; } const idTemp = uniqueId(); // Generate all the required ids const id = idProp || `field-${idTemp}`; const labelId = `${id}-label`; const feedbackId = `${id}-feedback`; const helpTextId = `${id}-helptext`; /** * Track whether the `FormErrorMessage` has been rendered. * We use this to append its id the the `aria-describedby` of the `input`. */ const [hasFeedbackText, setHasFeedbackText] = React.useState(false); /** * Track whether the `FormHelperText` has been rendered. * We use this to append its id the the `aria-describedby` of the `input`. */ const [hasHelpText, setHasHelpText] = React.useState(false); const context = { isRequired: !!isRequired, isInvalid: !!isInvalid, isReadOnly: !!isReadOnly, isDisabled: !!isDisabled, hasFeedbackText, setHasFeedbackText, hasHelpText, setHasHelpText, id, labelId, feedbackId, helpTextId, htmlProps, }; return context; } /** * React hook that provides the props that should be spread on to * input fields (`input`, `select`, `textarea`, etc.). * * It provides a convenient way to control a form fields, validation * and helper text. */ export function useCheckbox(props) { const field = useCheckboxContext(); const describedBy = []; // Error message must be described first in all scenarios. if (field?.hasFeedbackText) describedBy.push(field?.feedbackId); if (field?.hasHelpText) describedBy.push(field?.helpTextId); const ariaDescribedBy = describedBy.join(' '); const { isInvalid, isDisabled, isReadOnly, isRequired, ...cleanProps } = props; let id = props?.id; if (!id && field?.id) { id = `${field?.id}-input`; } return { ...cleanProps, 'id': id, 'disabled': isDisabled || field?.isDisabled, 'readOnly': isReadOnly || field?.isReadOnly, 'required': isRequired || field?.isRequired, 'aria-invalid': ariaAttr(isInvalid || field?.isInvalid), 'aria-required': ariaAttr(isRequired || field?.isRequired), 'aria-readonly': ariaAttr(isReadOnly || field?.isReadOnly), 'aria-describedby': ariaDescribedBy || undefined, }; } export const useCheckboxContext = () => { return React.useContext(CheckboxContext); };