/**
 * @typedef {Object} FormStateMember - The form state member.
 * @property {string | number | boolean | string[] | Record<string, number> | null} value - The value of the form element. Mirrors the child component's own `.value`, so the shape varies by element type (e.g. an array for `auro-checkbox-group`, an object keyed by counter name for `auro-counter-group`). A `range` `auro-datepicker` is the one form-specific case: its `.values` array is stored rather than its single `.value` string.
 * @property {ValidityState} validity - The validity state of the form element, stored when fired from the form element.
 * @property {boolean} required - Whether the form element is required or not.
 * @property {boolean} disabled - Whether the form element is currently disabled. Cached from the live attribute via the MutationObserver in `connectedCallback` and refreshed from `_handleAttributeMutations`.
 */
/**
 * @typedef {Object.<string, FormStateMember>} FormState - The form state.
 */
/**
 * The `auro-form` element provides users a way to create and manage forms in a consistent manner.
 * @customElement auro-form
 *
 * @slot default - The default slot for form elements.
 *
 * @event input - Fires when a child form element receives user input.
 * @event change - Fires when a child form element's value changes or the form is initialized.
 * @event reset - Fires when the form is reset. The event detail contains the previous value of the form before reset.
 * @event submit - Fires when the form is submitted. The event detail contains the current value of the form.
 */
export class AuroForm extends LitElement {
    static get properties(): {
        /** @private */
        formState: {
            type: ObjectConstructor;
            attribute: boolean;
        };
        /** @private */
        _validity: {
            type: ObjectConstructor;
            attribute: boolean;
        };
        /** @private */
        _isInitialState: {
            type: BooleanConstructor;
            attribute: boolean;
        };
        /** @private */
        _elements: {
            type: ArrayConstructor;
            attribute: boolean;
        };
        /** @private */
        _submitElements: {
            type: ArrayConstructor;
            attribute: boolean;
        };
        /** @private */
        _resetElements: {
            type: ArrayConstructor;
            attribute: boolean;
        };
    };
    static get formElementTags(): string[];
    static get buttonElementTags(): string[];
    static get styles(): import("lit").CSSResult[];
    /**
     * Registers the `auro-form` custom element with the browser under a given tag name.
     * @param {string} [name="auro-form"] - The custom element tag name to register.
     *
     * @example
     * AuroForm.register("custom-form") // registers as <custom-form>
     */
    static register(name?: string): void;
    /**
     * @type {FormState}
     * @private
     */
    private formState;
    /**
     * @type {"valid" | "invalid" | null}
     * @private
     */
    private _validity;
    /** @private */
    private _isInitialState;
    /**
     * @type {(HTMLElement & {reset: () => void})[]}
     * @private
     */
    private _elements;
    /**
     * @type {HTMLButtonElement[]}
     * @private
     */
    private _submitElements;
    /**
     * @type {HTMLButtonElement[]}
     * @private
     */
    private _resetElements;
    /**
     * @private
     * @type {MutationObserver[]}
     */
    private mutationObservers;
    /**
     * Captured initial (default) value per field `name`. Populated on first
     * sight of each name in `_addElementToState` and preserved across
     * subsequent `initializeState` cycles (slot change, rename, reset) so
     * `_setInitialState` can detect user edits as `current !== initial`,
     * matching HTML's `dirtyValueFlag` semantics.
     * @private
     * @type {Record<string, string | number | boolean | string[] | Record<string, number> | null | undefined>}
     */
    private _initialValues;
    /**
     * @private
     * @type {MutationObserver | null}
     */
    private _attributeObserver;
    /**
     * Handle batched MutationObserver records for `disabled` and `name`
     * attribute changes on tracked form elements. A `name` change invalidates
     * the formState keying — we resolve it by re-initializing state. A `disabled`
     * change simply needs a re-render (so `value` / `validity` getters re-evaluate)
     * and a refresh of the submit/reset button enablement.
     * @param {MutationRecord[]} mutations - The batched mutation records.
     * @returns {void}
     * @private
     */
    private _handleAttributeMutations;
    /**
     * Resets all form elements to their initial state and fires a `reset` event. The event's `detail.previousValue` contains the form values captured immediately before the reset.
     * @returns {void}
     */
    reset(): void;
    /**
     * Validates all form elements. If all are valid, fires a `submit` event with `detail.value` containing the current form values. If any element is invalid, its error state is surfaced and the `submit` event is not fired.
     * @returns {Promise<void>}
     */
    submit(): Promise<void>;
    /**
     * Shared input listener for all form elements.
     * @param {Event} event - The event that is fired from the form element.
     * @private
     */
    private sharedInputListener;
    /**
     * Shared validation listener for all form elements.
     * @param {Event} event - The event that is fired from the form element.
     * @private
     */
    private sharedValidationListener;
    /**
     * Mutation observer for form elements. Slot change does not trigger unless
     * root-level elements are added/removed. This is a workaround to ensure
     * nested form elements are also observed.
     *
     * @returns {void}
     * @private
     */
    private mutationEventListener;
    /**
     * Handle Enter key press on form elements.
     * @param {KeyboardEvent} event - The keyboard event.
     * @private
     */
    private handleKeyDown;
    /**
     * Compare tag name with element to identify it (for API purposes).
     * @param {string} elementTag - The HTML tag name like `auro-datepicker`.
     * @param {HTMLElement} element - The actual HTML element to compare.
     * @returns {boolean}
     * @private
     */
    private _isElementTag;
    /**
     * Shared code for determining if an element is something we care about (submit, form element, etc.).
     * @param {string[]} collection - The array to use for tag name search.
     * @param {HTMLElement} element - The element to compare against the master list.
     * @returns {boolean}
     * @private
     */
    private _isInElementCollection;
    /**
     * Check if the tag name is a form element.
     * @param {HTMLElement} element - The element to check (attr or tag name).
     * @returns {boolean}
     * @private
     */
    private isFormElement;
    /**
     * Whether a given element is currently disabled. Disabled controls are excluded
     * from submission, validity, and initial-state checks per the HTML spec
     * (section 4.10.19.2 "Enabling and disabling form controls":
     * https://www.w3.org/TR/2011/WD-html5-20110113/association-of-controls-and-forms.html).
     *
     * Implementation note: we deliberately read only the attribute. Every Auro
     * form element in `formElementTags` declares `disabled` with `reflect: true`,
     * so the attribute and property stay in sync. Reading the attribute also
     * lets the MutationObserver in `connectedCallback` (which is filtered to
     * `['disabled', 'name']`) be the single source of truth for re-renders.
     * If a future form-element type ships without attribute reflection, expand
     * this helper to also read `element.disabled`.
     * @param {HTMLElement | undefined | null} element - The element to check.
     * @returns {boolean}
     * @private
     */
    private _isDisabled;
    /**
     * Whether the tracked form element registered under `name` is currently disabled.
     * See `_isDisabled` for the HTML-spec rationale behind excluding disabled
     * controls from form state.
     *
     * Reads a cached flag on `formState[name]` populated by `_addElementToState`
     * at registration and refreshed by `_handleAttributeMutations` whenever the
     * element's `disabled` attribute toggles. The cache is fed by the same
     * `hasAttribute('disabled')` read as `_isDisabled`, so the "future form-element
     * type without attribute reflection" caveat documented there applies here too.
     * @param {string} name - The `name` attribute used to register the element.
     * @returns {boolean}
     * @private
     */
    private _isNameDisabled;
    /**
     * Validates if an event is from a valid form element with a name.
     * @param {Event} event - The event to validate.
     * @returns {boolean} - True if event is valid for processing.
     * @private
     */
    private _eventIsValidFormEvent;
    /**
     * Check if the tag name is a button element.
     * @param {HTMLElement} element - The element to check.
     * @returns {boolean}
     * @private
     */
    private isButtonElement;
    /**
     * Returns the current values of all named, enabled form elements as a key-value object, keyed by each element's `name` attribute. Each value is the child component's own `.value`, so the shape depends on the element type — see that component's documentation for its exact shape (for example, `auro-checkbox-group` yields an array, `auro-counter-group` yields an object keyed by counter name, and `auro-select` with `multiSelect` yields a JSON-encoded string). The one form-specific exception is a `range` `auro-datepicker`, whose `.values` array (`[start, end]`) is stored instead of its single `.value` string.
     * @returns {Record<string, string | number | boolean | string[] | Record<string, number> | null>} The current form values.
     */
    get value(): Record<string, string | number | boolean | string[] | Record<string, number> | null>;
    /**
     * Getter for internal _submitElements.
     * @returns {HTMLButtonElement[]}
     * @private
     */
    private get submitElements();
    /**
     * Returns a collection of elements that will reset the form.
     * @returns {HTMLButtonElement[]}
     * @private
     */
    private get resetElements();
    /**
     * Raw constraint-validation check. Returns `true` when no enabled field
     * has a validity error. Unlike the public `validity` getter, this does
     * NOT gate on `isInitialState` — callers that need to make a decision
     * based on the actual constraint state (submit-button enablement, the
     * internal `submit()` gate) read this so a pre-filled valid form is
     * correctly recognized as submittable at first render.
     * @returns {boolean}
     * @private
     */
    private _isFormValid;
    /**
     * Whether the reset button should be enabled. True when the form has
     * diverged from its initial state (so the user can always return to
     * defaults — even if the dirty value lives behind a now-disabled field),
     * OR when any non-disabled field has a current value or captured initial
     * value (covers pre-filled forms and user-cleared-back-to-empty cases).
     * @returns {boolean}
     * @private
     */
    private _hasResetableState;
    /**
     * Collapse empty representations to a single canonical `null`.
     *
     * `_addElementToState` captures `null` for a field that mounts without a
     * `value` attribute (`element.value || element.getAttribute('value')` is
     * falsy → resolves to `null`), but `sharedInputListener` later stores the
     * raw `event.target.value` — which is `''` for a user-cleared text input.
     * Without this normalization, backspacing back to empty would taint the
     * form forever (`'' !== null`) and Reset would stay enabled with nothing
     * to actually reset.
     *
     * `''`, `undefined`, and `[]` all collapse to `null`. The empty-array case
     * covers checkbox-group, radio-group, and multiselect, where `[]` means
     * "no selection" — semantically the same as `null`/`''`. Genuine values
     * — including `0`, `false`, non-empty strings, and non-empty arrays —
     * pass through unchanged so number, boolean, and populated multi-value
     * fields still compare correctly.
     * @param {*} value - Value to normalize.
     * @returns {*}
     * @private
     */
    private _normalizeEmpty;
    /**
     * Infer validity status based on current formState.
     *
     * Validity stays `null` while the form is in its initial state — this is
     * the "stay quiet until the user interacts" UX contract that consumers
     * depend on to delay error indicators. Code that needs the raw
     * constraint-validation result regardless of interaction (e.g.,
     * submit-button enablement) should call `_isFormValid()` directly.
     * @private
     */
    private _calculateValidity;
    /**
     * Returns `'valid'` if all required and interacted-with form elements are valid, `'invalid'` if any are not, or `null` if the form has not been interacted with yet.
     * @returns {"valid" | "invalid" | null}
     */
    get validity(): "valid" | "invalid" | null;
    /**
     * Determines whether the form is in its initial (untouched) state.
     *
     * A field is tainted if either:
     *   - its value differs from the value captured on first render, OR
     *   - its validity is failing (anything other than `null` or `'valid'`).
     *
     * Validity acts as a backup signal: it catches users who interact with a
     * field without changing its value (e.g., focusing and blurring a required
     * field). We skip `null` (not yet validated) and `'valid'` (the default
     * after Auro's auto-validation on mount) because neither proves the user
     * touched anything.
     * @returns {void}
     * @private
     */
    private _setInitialState;
    /**
     * Returns `true` if no form element has been interacted with or had its value changed since the form was initialized or last reset.
     * @returns {boolean}
     */
    get isInitialState(): boolean;
    /**
     * Enables or disables submit and reset buttons based on the current form state and validity.
     * @returns {void}
     * @private
     */
    private setDisabledStateOnButtons;
    /**
     * Construct the query strings from elements, append them together, execute, and return the NodeList.
     * @returns {NodeList}
     * @private
     */
    private queryAuroElements;
    /**
     * Store an element in state and on the _elements array.
     * @param {HTMLElement} element - The element to add to our state.
     * @private
     */
    private _addElementToState;
    /**
     * Initialize (or reinitialize) the form state.
     * @returns {void}
     * @private
     */
    private initializeState;
    /**
     * Attaches input, validation, and keydown listeners to all tracked form and button elements.
     * Removes existing listeners first to avoid duplicates on re-initialization.
     * @returns {void}
     * @private
     */
    private _attachEventListeners;
    /**
     * Slot change event listener. This is the main entry point for the form element.
     * @param {Event} event - The slot change event.
     * @returns {void}
     * @private
     */
    private onSlotChange;
    /**
     * @returns {import('lit').TemplateResult}
     */
    render(): import("lit").TemplateResult;
}
/**
 * - The form state member.
 */
export type FormStateMember = {
    /**
     * - The value of the form element. Mirrors the child component's own `.value`, so the shape varies by element type (e.g. an array for `auro-checkbox-group`, an object keyed by counter name for `auro-counter-group`). A `range` `auro-datepicker` is the one form-specific case: its `.values` array is stored rather than its single `.value` string.
     */
    value: string | number | boolean | string[] | Record<string, number> | null;
    /**
     * - The validity state of the form element, stored when fired from the form element.
     */
    validity: ValidityState;
    /**
     * - Whether the form element is required or not.
     */
    required: boolean;
    /**
     * - Whether the form element is currently disabled. Cached from the live attribute via the MutationObserver in `connectedCallback` and refreshed from `_handleAttributeMutations`.
     */
    disabled: boolean;
};
/**
 * - The form state.
 */
export type FormState = {
    [x: string]: FormStateMember;
};
import { LitElement } from "lit";
