import { RadiantElement } from '@ecopages/radiant'; import type { ContextProvider } from '@ecopages/radiant/context'; import { type FormContextValue } from '../form/form-context'; import { fieldContext } from './field-context'; import type { FieldRules } from '../form/types'; export type RuiFieldProps = { name: string; rules?: FieldRules; defaultValue?: unknown; defaultValueData?: string; disabled?: boolean; /** Standalone error message when not using a form provider. */ error?: string; /** Standalone invalid flag when not using a form provider. */ invalid?: boolean; }; /** * `` — connector between composed controls and an ancestor ``. * * Registers with the form via {@link formContext} actions, forwards control events, * and applies presentation (errors, ARIA) from the form-published `fields` map. * * The field owns error presentation: it finds `RuiFieldError` / `RuiFieldDescription` * in its light DOM, wires them into the control's `aria-describedby`, and drives * `aria-invalid` / `aria-required`. * * @element rui-field * * @attr {string} name - Field name; registers with the ancestor form. Default: `''`. * @attr {string} error - Standalone error message when not using a form provider. * Default: `''`. * @attr {boolean} invalid - Standalone invalid flag when not using a form provider. * Default: `false`. * @attr {boolean} disabled - Dims the field and disables nested controls. * Default: `false`. * @attr {string} data-default-value - JSON-serialized default value for SSR hydration. * Default: `undefined`. * * @remarks * The composed surface is `.rui-field` (column). Error / description presentation * lives on `RuiFieldError` / `RuiFieldDescription` helpers (`@cssclass` there). * * `rules` and `defaultValue` are object props — they only reach the element via * `prop:` bindings from the `RuiField` view, not plain attributes. * * **Why a custom element?** The field must observe an ancestor form context and * apply ARIA + error text to light-DOM nodes after mount — a JSX wrapper has no * lifecycle hook for that. * * @cssclass rui-field - Root column; wires the composed control, label, description, * and error into the form-published presentation. */ export declare class RuiField extends RadiantElement { name: string; rules?: FieldRules; defaultValue?: unknown; defaultValueData?: string; disabled: boolean; error: string; invalid: boolean; fieldProvider: ContextProvider; private formContextProvider?; private uid; /** Resolved field name from property or `name` attribute (Storybook can hydrate props after connect). */ private resolveFieldName; private unregister?; private unregisterPresentation?; private registeredWithForm; /** * @remarks Registers SSR-prep rules on `fieldProvider` so hydrated fields recover them after a * real SSR round-trip (`prop:rules` does not survive that boundary; `connectedCallback` never * runs during SSR). */ constructor(); protected onConnected(): void; disconnectedCallback(): void; private get currentFormContext(); private parseJsonAttr; /** * Prefers the live `rules` prop — it's the only channel that can carry a `validate` * function. Falls back to `fieldProvider`'s own context, which only ever holds the * JSON-safe subset (see its `serialize` option) — this is what recovers rules after a * real SSR hydrate, since `prop:rules` itself doesn't survive that boundary. */ private readFieldRules; private readDefaultValue; private isRequired; private resolveErrorMessage; private resolveInvalid; private connectToForm; onFormContextChanged(ctx: FormContextValue): void; onNameUpdated(): void; onRulesUpdated(): void; onPresentationUpdated(): void; onControlChange(): void; onControlInput(): void; onControlNativeChange(): void; onControlFocusOut(): void; private syncField; }