import { type Readable } from '@vielzeug/ripple'; export type ValidationTrigger = 'blur' | 'change' | 'input' | 'submit'; export type ControlValidationMode = ValidationTrigger | undefined; export type ErrorHelperState = { errorText: string; helperText: string; }; export type ErrorHelperOptions = { error?: Readable; helper?: Readable; }; export declare const createErrorHelperState: (options: ErrorHelperOptions) => Readable; /** Counter state for text fields with `maxLength`. */ export type CounterState = { counterAtLimit: boolean; counterNearLimit: boolean; counterText: string; }; export type CounterOptions = { maxLength?: Readable; value: Readable; }; /** * Creates a reactive counter state signal for text fields with `maxLength`. * Only call this when `maxLength` may be set — the state is genuinely opt-in. * * @example * ```ts * const counter = createCounterState({ value: tf.value, maxLength: props.maxlength }); * ``` */ export declare const createCounterState: (options: CounterOptions) => Readable; /** * The single implementation of "which modifier class does this counter state map to" — * every field with a character counter (`ore-input`, `ore-textarea`, `ore-message-composer`) * renders the identical near-limit/at-limit styling, so this is the one place that decides it. * * @example * ```ts * html`...` * ``` */ export declare const counterClassName: (counter: CounterState | undefined, base?: string) => string; /** * Tracks whether a control's value has ever been changed by user interaction. * * Backs the "two-state reset()" pattern used by `createCheckable` (`checked`/ * `indeterminate`) and `createChoiceField` (`selectedValues`): before the first * interaction, the live prop is still a reliable "current default" to resync from * (e.g. an async-loaded value arriving after mount); after it, the prop is * contaminated by interaction-driven attribute reflection, so only a snapshot taken * at creation still represents "the default" in the native sense. `reset()` callers * check `isDirty` to decide which source to revert to, then call `clear()`. */ export type DirtyTracker = { clear: () => void; readonly isDirty: boolean; markDirty: () => void; }; export declare function createDirtyTracker(): DirtyTracker; export type LabelPlacement = 'inset' | 'outside' | undefined; /** * A field's error/helper/disabled/validation-trigger state — everything an input * needs *except* a visible `