/**
 * @file ListInput.tsx
 * @input React, StyleX, Astryx field/list/button/icon/layer/empty-state primitives, compact size context, browser scroll geometry, programmatic theme tokens, and shared Lab reorder styles
 * @output Exports ListInput and its controlled data, column, renderer, and change types
 * @position Lab experiment (RFC facebook/astryx#4531) for editing compact repeated records
 *
 * SYNC: When modified, update these files to stay in sync:
 * - /packages/lab/src/ListInput/ListInput.doc.mjs
 * - /packages/lab/src/ListInput/ListInput.test.tsx
 * - /packages/lab/src/ListInput/index.ts
 * - /apps/storybook/stories/ListInput.stories.tsx
 */
import { type Key, type ReactNode } from 'react';
import type { BaseProps } from '@astryxdesign/core';
import { type InputStatus } from '@astryxdesign/core/Field';
import type { ColumnWidth } from '@astryxdesign/core/Table';
export type ListInputChange<T> = {
    type: 'add';
    item: T;
    index: number;
} | {
    type: 'update';
    item: T;
    previousItem: T;
    index: number;
    columnKey?: string;
} | {
    type: 'remove';
    item: T;
    index: number;
} | {
    type: 'reorder';
    item: T;
    fromIndex: number;
    toIndex: number;
};
export interface ListInputValueContext<T> {
    /** Current record. */
    item: T;
    /** Current visual position. */
    index: number;
    /** Accessible cell label, including the record position. */
    label: string;
    /** True because ListInput owns the visible column label. */
    isLabelHidden: boolean;
}
export interface ListInputRenderContext<T> extends ListInputValueContext<T> {
    /** Complete validation status scoped to this field. */
    status?: InputStatus;
    /** Forward to the rendered Astryx control so status uses its native tooltip. */
    statusVariant: 'tooltip';
    /** Whether the rendered control should be disabled. */
    isDisabled: boolean;
    /** Whether an asynchronous list operation is in progress. */
    isLoading: boolean;
    /** Replace this record in the controlled list. */
    updateItem: (nextItem: T, columnKey?: string) => void;
}
export interface ListInputColumn<T> {
    /** Stable column identifier, also passed to getFieldStatus. */
    key: string;
    /** Field label shown on the first record and repeated when rows stack. */
    header: string;
    /**
     * Column sizing. Use proportional() or pixel() from @astryxdesign/core/Table
     * to tune the width ratio. Defaults to a proportional column with a 140px floor.
     */
    width?: ColumnWidth;
    /** Renders the editable control for one cell. */
    renderInput: (context: ListInputRenderContext<T>) => ReactNode;
}
export interface ListInputProps<T> extends Omit<BaseProps<HTMLDivElement>, 'onChange'> {
    /** Ref forwarded to the outer field element. */
    ref?: React.Ref<HTMLDivElement>;
    /** Visible and accessible label for the list. */
    label: string;
    /** Optional supporting text. */
    description?: string;
    /** Controlled records. */
    value: T[];
    /** Called for every record mutation with the next value and mutation detail. */
    onChange: (nextValue: T[], change: ListInputChange<T>) => void;
    /** Returns a stable key for focus preservation and reordering. */
    getItemKey: (item: T) => Key;
    /** Creates a new record when the Add action is used. */
    createItem: () => T;
    /** Column definitions and cell renderers. */
    columns: ListInputColumn<T>[];
    /** Singular name used in action labels and announcements. @default 'item' */
    itemName?: string;
    /** Validation status for the whole list. */
    status?: InputStatus;
    /** Returns a validation status displayed across one record. */
    getItemStatus?: (item: T, index: number) => InputStatus | undefined;
    /** Returns a validation status passed to one field renderer. */
    getFieldStatus?: (item: T, columnKey: string, index: number) => InputStatus | undefined;
    /** Enables handle-only pointer and keyboard reordering. @default false */
    isReorderable?: boolean;
    /** Disables fields and mutation controls. @default false */
    isDisabled?: boolean;
    /** Marks the list busy and prevents mutations. @default false */
    isLoading?: boolean;
    /** Maximum record count. Reaching it disables, but does not remove, Add. */
    maxItems?: number;
    /** Visually hides the list label while preserving its accessible name. */
    isLabelHidden?: boolean;
    /** Marks the list optional. */
    isOptional?: boolean;
    /** Marks the list required. */
    isRequired?: boolean;
}
/**
 * A compact editor for short collections of consistent, simple records.
 *
 * ListInput owns list semantics, add/remove controls, handle-only reordering,
 * live collection motion, focus restoration, announcements, and list/item/
 * field validation placement. Consumers keep ownership of the controlled data
 * and render each field with standard Astryx inputs.
 *
 * @example
 * ```
 * <ListInput
 *   label="Guests"
 *   value={guests}
 *   onChange={setGuests}
 *   getItemKey={guest => guest.id}
 *   createItem={() => ({id: crypto.randomUUID(), name: '', email: ''})}
 *   columns={columns}
 *   itemName="guest"
 *   isReorderable
 * />
 * ```
 */
export declare function ListInput<T>({ label, description, value, onChange, getItemKey, createItem, columns, itemName, status, getItemStatus, getFieldStatus, isReorderable, isDisabled, isLoading, maxItems, isLabelHidden, isOptional, isRequired, ref, ...rest }: ListInputProps<T>): ReactNode;
export declare namespace ListInput {
    var displayName: string;
}
//# sourceMappingURL=ListInput.d.ts.map