UNPKG

@ark-ui/vue

Version:

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

84 lines (81 loc) 2.63 kB
import { dataAttr } from '@zag-js/dom-query'; import { reactive, ref, useId, computed, toValue, onMounted, onBeforeUnmount } from 'vue'; import { useEnvironmentContext, DEFAULT_ENVIRONMENT } from '../../providers/environment/use-environment-context.js'; import { parts } from './fieldset.anatomy.js'; const useFieldset = (props) => { const env = useEnvironmentContext(DEFAULT_ENVIRONMENT); const state = reactive({ hasErrorText: false, hasHelperText: false }); const rootRef = ref(null); const uuid = useId(); const ids = computed(() => { const fieldsetProps = toValue(props); const id = fieldsetProps.id ?? uuid; return { labelId: `fieldset::${id}::label`, errorTextId: `fieldset::${id}::error-text`, helperTextId: `fieldset::${id}::helper-text` }; }); onMounted(() => { const rootNode = rootRef.value; if (!rootNode) return; const checkTextElements = () => { const { errorTextId, helperTextId } = ids.value; const docOrShadowRoot = env.value.getRootNode(); state.hasErrorText = !!docOrShadowRoot.getElementById(errorTextId); state.hasHelperText = !!docOrShadowRoot.getElementById(helperTextId); }; checkTextElements(); const win = env.value.getWindow(); const observer = new win.MutationObserver(checkTextElements); observer.observe(rootNode, { childList: true, subtree: true }); onBeforeUnmount(() => { observer.disconnect(); }); }); return computed(() => { const { disabled, invalid } = toValue(props); const { labelId, errorTextId, helperTextId } = ids.value; const labelIds = []; if (state.hasErrorText && invalid) labelIds.push(errorTextId); if (state.hasHelperText) labelIds.push(helperTextId); const getRootProps = () => ({ ...parts.root.attrs, disabled, "data-disabled": dataAttr(!!disabled), "data-invalid": dataAttr(invalid), "aria-labelledby": labelId, "aria-describedby": labelIds.join(" ") }); const getLegendProps = () => ({ id: labelId, ...parts.legend.attrs, "data-disabled": dataAttr(!!disabled), "data-invalid": dataAttr(invalid) }); const getHelperTextProps = () => ({ id: helperTextId, ...parts.helperText.attrs }); const getErrorTextProps = () => ({ id: errorTextId, ...parts.errorText.attrs, "aria-live": "polite" }); return { refs: { rootRef }, disabled, invalid, getRootProps, getLegendProps, getHelperTextProps, getErrorTextProps }; }); }; export { useFieldset };