@ark-ui/solid
Version:
A collection of unstyled, accessible UI components for Solid, utilizing state machines for seamless interaction.
289 lines (273 loc) • 9.11 kB
JSX
import {
useFieldsetContext
} from "./NHEM6XZR.jsx";
import {
parts
} from "./6P2AQNUE.jsx";
import {
composeRefs
} from "./PT2CJE3O.jsx";
import {
createSplitProps
} from "./6WEDGJKQ.jsx";
import {
ark
} from "./UFYZ7HLU.jsx";
import {
useEnvironmentContext
} from "./CGW54HAQ.jsx";
import {
createContext
} from "./UZJJWJQM.jsx";
import {
__export
} from "./7IUG3E2V.jsx";
// src/components/field/use-field-context.ts
var [FieldProvider, useFieldContext] = createContext({
hookName: "useFieldContext",
providerName: "<FieldProvider />",
strict: false
});
// src/components/field/field-context.tsx
var FieldContext = (props) => props.children(useFieldContext());
// src/components/field/field-error-text.tsx
import { mergeProps } from "@zag-js/solid";
import { Show } from "solid-js";
var FieldErrorText = (props) => {
const field = useFieldContext();
const mergedProps = mergeProps(() => field().getErrorTextProps(), props);
return <Show when={field?.().invalid}>
<ark.span {...mergedProps} />
</Show>;
};
// src/components/field/field-helper-text.tsx
import { mergeProps as mergeProps2 } from "@zag-js/solid";
var FieldHelperText = (props) => {
const field = useFieldContext();
const mergedProps = mergeProps2(() => field().getHelperTextProps(), props);
return <ark.span {...mergedProps} />;
};
// src/components/field/field-input.tsx
import { mergeProps as mergeProps3 } from "@zag-js/solid";
var FieldInput = (props) => {
const field = useFieldContext();
const mergedProps = mergeProps3(() => field?.().getInputProps(), props);
return <ark.input {...mergedProps} />;
};
// src/components/field/field-label.tsx
import { mergeProps as mergeProps4 } from "@zag-js/solid";
var FieldLabel = (props) => {
const field = useFieldContext();
const mergedProps = mergeProps4(() => field?.().getLabelProps(), props);
return <ark.label {...mergedProps} />;
};
// src/components/field/field-required-indicator.tsx
import { mergeProps as mergeProps5 } from "@zag-js/solid";
import { Show as Show2 } from "solid-js";
var FieldRequiredIndicator = (props) => {
const field = useFieldContext();
const mergedProps = mergeProps5(() => field().getRequiredIndicatorProps(), props);
return <Show2 when={field().required} fallback={props.fallback}>
<ark.span {...mergedProps}>{props.children ?? "*"}</ark.span>
</Show2>;
};
// src/components/field/field-root.tsx
import { mergeProps as mergeProps7 } from "@zag-js/solid";
// src/components/field/use-field.ts
import { ariaAttr, dataAttr } from "@zag-js/dom-query";
import { createMemo, createSignal, createUniqueId, mergeProps as mergeProps6, onCleanup, onMount } from "solid-js";
var useField = (props) => {
const fieldset = useFieldsetContext();
const env = useEnvironmentContext();
const fieldProps = mergeProps6(
{ disabled: Boolean(fieldset?.().disabled), required: false, invalid: false, readOnly: false },
props
);
const [hasErrorText, setHasErrorText] = createSignal(false);
const [hasHelperText, setHasHelperText] = createSignal(false);
const id = fieldProps.id ?? createUniqueId();
const [rootRef, setRootRef] = createSignal(void 0);
const rootId = fieldProps.ids?.control ?? `field::${id}`;
const errorTextId = fieldProps.ids?.errorText ?? `field::${id}::error-text`;
const helperTextId = fieldProps.ids?.helperText ?? `field::${id}::helper-text`;
const labelId = fieldProps.ids?.label ?? `field::${id}::label`;
onMount(() => {
const rootNode = rootRef();
if (!rootNode) return;
const checkTextElements = () => {
const docOrShadowRoot = env().getRootNode();
setHasErrorText(!!docOrShadowRoot.getElementById(errorTextId));
setHasHelperText(!!docOrShadowRoot.getElementById(helperTextId));
};
checkTextElements();
const win = env().getWindow();
const observer = new win.MutationObserver(checkTextElements);
observer.observe(rootNode, { childList: true, subtree: true });
onCleanup(() => observer.disconnect());
});
const getRootProps = () => ({
...parts.root.attrs,
id: rootId,
role: "group",
"data-disabled": dataAttr(fieldProps.disabled),
"data-invalid": dataAttr(fieldProps.invalid),
"data-readonly": dataAttr(fieldProps.readOnly)
});
const getLabelProps = () => ({
...parts.label.attrs,
id: labelId,
"data-disabled": dataAttr(fieldProps.disabled),
"data-invalid": dataAttr(fieldProps.invalid),
"data-readonly": dataAttr(fieldProps.readOnly),
"data-required": dataAttr(fieldProps.required),
htmlFor: id
});
const labelIds = createMemo(() => {
const ids = [];
if (hasErrorText() && fieldProps.invalid) ids.push(errorTextId);
if (hasHelperText()) ids.push(helperTextId);
return ids;
});
const getControlProps = () => ({
"aria-describedby": labelIds().join(" ") || void 0,
"aria-invalid": ariaAttr(fieldProps.invalid),
"data-invalid": dataAttr(fieldProps.invalid),
"data-required": dataAttr(fieldProps.required),
"data-readonly": dataAttr(fieldProps.readOnly),
id,
required: fieldProps.required,
disabled: fieldProps.disabled,
readOnly: fieldProps.readOnly || void 0
});
const getInputProps = () => ({
...getControlProps(),
...parts.input.attrs
});
const getTextareaProps = () => ({
...getControlProps(),
...parts.textarea.attrs
});
const getSelectProps = () => ({
...getControlProps(),
...parts.select.attrs
});
const getHelperTextProps = () => ({
id: helperTextId,
...parts.helperText.attrs,
"data-disabled": dataAttr(fieldProps.disabled)
});
const getErrorTextProps = () => ({
id: errorTextId,
...parts.errorText.attrs,
"aria-live": "polite"
});
const getRequiredIndicatorProps = () => ({
"aria-hidden": true,
...parts.requiredIndicator.attrs
});
return createMemo(() => ({
ariaDescribedby: labelIds().join(" "),
ids: {
control: id,
label: labelId,
errorText: errorTextId,
helperText: helperTextId
},
refs: {
rootRef: setRootRef
},
disabled: fieldProps.disabled,
invalid: fieldProps.invalid,
readOnly: fieldProps.readOnly,
required: fieldProps.required,
getLabelProps,
getRootProps,
getInputProps,
getTextareaProps,
getSelectProps,
getHelperTextProps,
getErrorTextProps,
getRequiredIndicatorProps
}));
};
// src/components/field/field-root.tsx
var FieldRoot = (props) => {
const [useFieldProps, localProps] = createSplitProps()(props, [
"id",
"ids",
"disabled",
"invalid",
"readOnly",
"required"
]);
const field = useField(useFieldProps);
const mergedProps = mergeProps7(() => field().getRootProps(), localProps);
return <FieldProvider value={field}>
<ark.div {...mergedProps} ref={composeRefs(field().refs.rootRef, props.ref)} />
</FieldProvider>;
};
// src/components/field/field-root-provider.tsx
import { mergeProps as mergeProps8 } from "@zag-js/solid";
var FieldRootProvider = (props) => {
const [{ value: field }, localProps] = createSplitProps()(props, ["value"]);
const mergedProps = mergeProps8(() => field().getRootProps(), localProps);
return <FieldProvider value={field}>
<ark.div {...mergedProps} />
</FieldProvider>;
};
// src/components/field/field-select.tsx
import { mergeProps as mergeProps9 } from "@zag-js/solid";
var FieldSelect = (props) => {
const field = useFieldContext();
const mergedProps = mergeProps9(() => field?.().getSelectProps(), props);
return <ark.select {...mergedProps} />;
};
// src/components/field/field-textarea.tsx
import { autoresizeTextarea } from "@zag-js/auto-resize";
import { mergeProps as mergeProps10 } from "@zag-js/solid";
import { onCleanup as onCleanup2, onMount as onMount2, splitProps } from "solid-js";
var FieldTextarea = (props) => {
const field = useFieldContext();
let textareaRef;
const [autoresizeProps, textareaProps] = splitProps(props, ["autoresize"]);
const mergedProps = mergeProps10(
() => field?.().getTextareaProps(),
() => ({ style: { resize: autoresizeProps.autoresize ? "none" : void 0 } }),
textareaProps
);
onMount2(() => {
if (!autoresizeProps.autoresize) return;
const cleanup = autoresizeTextarea(textareaRef);
onCleanup2(() => cleanup?.());
});
return <ark.textarea {...mergedProps} ref={composeRefs((el) => textareaRef = el, props.ref)} />;
};
// src/components/field/field.ts
var field_exports = {};
__export(field_exports, {
Context: () => FieldContext,
ErrorText: () => FieldErrorText,
HelperText: () => FieldHelperText,
Input: () => FieldInput,
Label: () => FieldLabel,
RequiredIndicator: () => FieldRequiredIndicator,
Root: () => FieldRoot,
RootProvider: () => FieldRootProvider,
Select: () => FieldSelect,
Textarea: () => FieldTextarea
});
export {
useFieldContext,
FieldContext,
FieldErrorText,
FieldHelperText,
FieldInput,
FieldLabel,
FieldRequiredIndicator,
useField,
FieldRoot,
FieldRootProvider,
FieldSelect,
FieldTextarea,
field_exports
};