/**
 * @file TextArea.tsx
 * @input Uses React, useId, ChangeEvent, ClipboardEvent, FocusEvent, Field, Icon, Spinner
 * @output Exports TextArea component, TextAreaProps, TextAreaStatus, TextAreaStatusType
 * @position Core implementation; consumed by index.ts, tested by TextArea.test.tsx
 *
 * SYNC: When modified, update these files to stay in sync:
 * - /packages/core/src/TextArea/TextArea.doc.mjs (props table, features, implementation notes)
 * - /packages/core/src/TextArea/TextArea.test.tsx (tests for new/changed behavior)
 * - /packages/core/src/TextArea/index.ts (exports if types change)
 * - /apps/storybook/stories/TextArea.stories.tsx (storybook stories)
 * - /packages/cli/assets/templates/blocks/components/TextArea/ (showcase blocks)
 */
import { type ChangeEvent, type ClipboardEvent, type FocusEvent, type ReactNode } from 'react';
import { type FieldStatusVariant } from '../Field';
import { type IconType } from '../Icon';
import type { BaseProps } from '../BaseProps';
import type { SizeValue } from '../utils/types';
export type TextAreaStatusType = 'warning' | 'error' | 'success';
export type TextAreaSize = 'sm' | 'md' | 'lg';
export interface TextAreaStatus {
    /**
     * The type of status to display.
     */
    type: TextAreaStatusType;
    /**
     * Optional message to display below the textarea.
     */
    message?: string;
}
export interface TextAreaProps extends Omit<BaseProps, 'onChange' | 'defaultValue'> {
    /** Ref forwarded to the root element */
    ref?: React.Ref<HTMLTextAreaElement>;
    /**
     * Label text for the textarea (always rendered for accessibility).
     */
    label: string;
    /**
     * Whether to visually hide the label (still accessible to screen readers).
     * @default false
     */
    isLabelHidden?: boolean;
    /**
     * Description text displayed between the label and textarea.
     */
    description?: string;
    /**
     * Whether the field is optional. Mutually exclusive with isRequired.
     * @default false
     */
    isOptional?: boolean;
    /**
     * Whether the field is required. Mutually exclusive with isOptional.
     * @default false
     */
    isRequired?: boolean;
    /**
     * Callback fired when the textarea value changes.
     */
    onChange?: (value: string, e: ChangeEvent<HTMLTextAreaElement>) => void;
    /** Async action on change. Fires after onChange if not prevented. */
    changeAction?: (value: string, e: ChangeEvent<HTMLTextAreaElement>) => void | Promise<void>;
    /** Whether the input is in a loading state. @default false */
    isLoading?: boolean;
    /**
     * The current value of the textarea.
     */
    value: string;
    /**
     * Placeholder text shown when the textarea is empty.
     */
    placeholder?: string;
    /**
     * The number of visible text rows.
     * @default 3
     */
    rows?: number;
    /**
     * Whether the textarea is disabled.
     * @default false
     */
    isDisabled?: boolean;
    /**
     * Whether the textarea is read-only.
     * The value is shown at full opacity and still submits with the form, but
     * cannot be edited. Unlike `isDisabled`, a read-only textarea is not dimmed
     * and stays in the tab order — use it for a value the user should see and
     * send but not change. `isDisabled` takes precedence when both are set.
     * @default false
     */
    isReadOnly?: boolean;
    /**
     * Explains why the textarea is disabled. When set together with
     * `isDisabled`, the textarea shows a tooltip with this text on hover and
     * keyboard focus, and stays focusable (via `aria-disabled`) so the reason is
     * discoverable by keyboard and assistive technology. The field cannot be
     * edited (it becomes read-only) while disabled.
     *
     * Use this instead of wrapping a disabled textarea in `Tooltip` — disabled
     * controls don't emit the pointer events an external tooltip needs.
     *
     * @example
     * ```
     * <TextArea
     *   label="Notes"
     *   value={notes}
     *   isDisabled
     *   disabledMessage="Notes are locked after submission"
     * />
     * ```
     */
    disabledMessage?: string;
    /**
     * Status indicator for the textarea.
     * When set, displays a colored border and status icon.
     * If message is provided, displays a floating message box below the textarea.
     */
    status?: TextAreaStatus;
    /**
     * How the status message is placed relative to the input.
     * - 'attached': message overlaps directly below the input (bordered treatment)
     * - 'detached': message floats below as a separate element with spacing
     * - 'tooltip': no message box; the status icon becomes a focusable info-tip button that reveals the message on hover, keyboard focus, or tap
     * @default 'attached'
     */
    statusVariant?: FieldStatusVariant;
    /**
     * Width of the field. Numbers are treated as pixels, strings are used as-is
     * (e.g. `'100%'`). Sizes the whole field (label, control, and status) so they
     * stay aligned, unlike setting width via `xstyle`/`className`/`style`.
     */
    width?: SizeValue;
    /**
     * Tooltip text to display in an info icon at the end of the label.
     */
    labelTooltip?: string;
    /**
     * Icon to display at the start of the textarea.
     * Accepts a ReactNode (e.g. `<Icon icon={SearchIcon} />`) or an SVG icon component directly.
     */
    startIcon?: ReactNode | IconType;
    /**
     * Whether to enable browser spell checking.
     * @default true
     */
    hasSpellCheck?: boolean;
    /**
     * Callback fired when content is pasted into the textarea.
     */
    onPaste?: (e: ClipboardEvent<HTMLTextAreaElement>) => void;
    /**
     * Maximum number of characters allowed, counted as user-perceived
     * characters — an emoji or flag sequence counts as one. When set,
     * displays a character counter below the textarea.
     * Does not enforce the limit natively — the counter shows error styling
     * when exceeded, and the consumer can validate via onChange. Validate with
     * `characterCount` (exported from this package) rather than `value.length`
     * so enforcement matches the displayed count.
     */
    maxLength?: number;
    /**
     * Whether to automatically focus the textarea on mount.
     * @default false
     */
    hasAutoFocus?: boolean;
    /**
     * The size of the textarea, affecting internal padding.
     * Height is controlled by `rows`, not size.
     * @default 'md'
     */
    size?: TextAreaSize;
    /**
     * The HTML name attribute for the textarea.
     * Useful for form submissions.
     */
    htmlName?: string;
    /**
     * Callback fired when the textarea receives focus.
     */
    onFocus?: (e: FocusEvent<HTMLTextAreaElement>) => void;
    /**
     * Callback fired when the textarea loses focus.
     */
    onBlur?: (e: FocusEvent<HTMLTextAreaElement>) => void;
}
/**
 * A multi-line text input component for collecting longer user input.
 *
 * @example
 * ```
 * <TextArea label="Description" value={description} onChange={setDescription} />
 * <TextArea label="Notes" rows={5} value={notes} onChange={setNotes} />
 * ```
 */
export declare function TextArea({ label, isLabelHidden, description, isOptional, isRequired, onChange, changeAction, isLoading, value, placeholder, rows, isDisabled, isReadOnly, disabledMessage, status, statusVariant, labelTooltip, startIcon, hasSpellCheck, onPaste, maxLength, hasAutoFocus, size: sizeProp, htmlName, onFocus, onBlur, width, xstyle, className, style, ref, ...rest }: TextAreaProps): import("react").JSX.Element;
export declare namespace TextArea {
    var displayName: string;
}
//# sourceMappingURL=TextArea.d.ts.map