Headless TextField with Label, Input, Description, and ErrorMessage parts. Supports invalid, disabled, and required states with full ARIA wiring (aria-invalid, aria-required, aria-describedby, aria-errormessage). 7 tests passing.
33 lines
1.0 KiB
TypeScript
33 lines
1.0 KiB
TypeScript
// packages/core/src/components/text-field/text-field-context.ts
|
|
import type { Accessor } from "solid-js";
|
|
import { createContext, useContext } from "solid-js";
|
|
|
|
export interface TextFieldContextValue {
|
|
inputId: Accessor<string>;
|
|
descriptionId: Accessor<string | undefined>;
|
|
errorMessageId: Accessor<string | undefined>;
|
|
invalid: Accessor<boolean>;
|
|
disabled: Accessor<boolean>;
|
|
required: Accessor<boolean>;
|
|
setDescriptionId: (id: string | undefined) => void;
|
|
setErrorMessageId: (id: string | undefined) => void;
|
|
}
|
|
|
|
const TextFieldContext = createContext<TextFieldContextValue>();
|
|
|
|
/**
|
|
* Returns the TextField context. Throws if used outside <TextField>.
|
|
*/
|
|
export function useTextFieldContext(): TextFieldContextValue {
|
|
const ctx = useContext(TextFieldContext);
|
|
if (!ctx) {
|
|
throw new Error(
|
|
"[PettyUI] TextField parts must be used inside <TextField>.\n" +
|
|
" Fix: Wrap TextField.Label, TextField.Input, etc. inside <TextField>.",
|
|
);
|
|
}
|
|
return ctx;
|
|
}
|
|
|
|
export const TextFieldContextProvider = TextFieldContext.Provider;
|