UNPKG

@ark-ui/react

Version:

A collection of unstyled, accessible UI components for React, utilizing state machines for seamless interaction.

152 lines (147 loc) 4.63 kB
'use client'; 'use strict'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const domQuery = require('@zag-js/dom-query'); const react = require('react'); const useSafeLayoutEffect = require('../../utils/use-safe-layout-effect.cjs'); const useFieldsetContext = require('../fieldset/use-fieldset-context.cjs'); const field_anatomy = require('./field.anatomy.cjs'); const useField = (props = {}) => { const fieldset = useFieldsetContext.useFieldsetContext(); const { ids, disabled = Boolean(fieldset?.disabled), invalid = false, readOnly = false, required = false } = props; const [hasErrorText, setHasErrorText] = react.useState(false); const [hasHelperText, setHasHelperText] = react.useState(false); const id = props.id ?? react.useId(); const rootRef = react.useRef(null); const rootId = ids?.control ?? `field::${id}`; const errorTextId = ids?.errorText ?? `field::${id}::error-text`; const helperTextId = ids?.helperText ?? `field::${id}::helper-text`; const labelId = ids?.label ?? `field::${id}::label`; useSafeLayoutEffect.useSafeLayoutEffect(() => { const rootNode = rootRef.current; if (!rootNode) return; const win = domQuery.getWindow(rootNode); const doc = win.document; const checkTextElements = () => { setHasErrorText(!!doc.getElementById(errorTextId)); setHasHelperText(!!doc.getElementById(helperTextId)); }; checkTextElements(); const observer = new win.MutationObserver(checkTextElements); observer.observe(rootNode, { childList: true, subtree: true }); return () => observer.disconnect(); }, [errorTextId, helperTextId]); const labelIds = react.useMemo(() => { const ids2 = []; if (hasErrorText && invalid) ids2.push(errorTextId); if (hasHelperText) ids2.push(helperTextId); return ids2.join(" ") || void 0; }, [invalid, errorTextId, helperTextId, hasErrorText, hasHelperText]); const getRootProps = react.useMemo( () => () => ({ ...field_anatomy.parts.root.attrs, id: rootId, ref: rootRef, role: "group", "data-disabled": domQuery.dataAttr(disabled), "data-invalid": domQuery.dataAttr(invalid), "data-readonly": domQuery.dataAttr(readOnly) }), [disabled, invalid, readOnly, rootId] ); const getLabelProps = react.useMemo( () => () => ({ ...field_anatomy.parts.label.attrs, id: labelId, "data-disabled": domQuery.dataAttr(disabled), "data-invalid": domQuery.dataAttr(invalid), "data-readonly": domQuery.dataAttr(readOnly), htmlFor: id }), [disabled, invalid, readOnly, id, labelId] ); const getControlProps = react.useMemo( () => () => ({ "aria-describedby": labelIds, "aria-invalid": domQuery.ariaAttr(invalid), "data-invalid": domQuery.dataAttr(invalid), "data-required": domQuery.dataAttr(required), "data-readonly": domQuery.dataAttr(readOnly), id, required, disabled, readOnly }), [labelIds, invalid, required, readOnly, id, disabled] ); const getInputProps = react.useMemo( () => () => ({ ...getControlProps(), ...field_anatomy.parts.input.attrs }), [getControlProps] ); const getTextareaProps = react.useMemo( () => () => ({ ...getControlProps(), ...field_anatomy.parts.textarea.attrs }), [getControlProps] ); const getSelectProps = react.useMemo( () => () => ({ ...getControlProps(), ...field_anatomy.parts.select.attrs }), [getControlProps] ); const getHelperTextProps = react.useMemo( () => () => ({ id: helperTextId, ...field_anatomy.parts.helperText.attrs, "data-disabled": domQuery.dataAttr(disabled) }), [disabled, helperTextId] ); const getErrorTextProps = react.useMemo( () => () => ({ id: errorTextId, ...field_anatomy.parts.errorText.attrs, "aria-live": "polite" }), [errorTextId] ); const getRequiredIndicatorProps = react.useMemo( () => () => ({ "aria-hidden": true, ...field_anatomy.parts.requiredIndicator.attrs }), [] ); return { ariaDescribedby: labelIds, ids: { root: rootId, control: id, label: labelId, errorText: errorTextId, helperText: helperTextId }, refs: { rootRef }, disabled, invalid, readOnly, required, getLabelProps, getRootProps, getInputProps, getTextareaProps, getSelectProps, getHelperTextProps, getErrorTextProps, getRequiredIndicatorProps }; }; exports.useField = useField;