import * as mn_angular_lib_forms from 'mn-angular-lib/forms'; import * as i0 from '@angular/core'; import { InjectionToken, OnInit, OnChanges, EventEmitter, ElementRef, TemplateRef } from '@angular/core'; import * as tailwind_variants from 'tailwind-variants'; import { VariantProps } from 'tailwind-variants'; import { MnErrorMessageFn } from 'mn-angular-lib/core'; import * as _angular_forms from '@angular/forms'; import { NgControl, AbstractControl, ValidationErrors } from '@angular/forms'; import * as _lucide_angular from '@lucide/angular'; import { LucideIconData } from '@lucide/angular'; import { MnButtonTypes } from 'mn-angular-lib/button'; declare const mnInputFieldVariants: tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; disabled: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 placeholder-base-content/50 text-base-content text-sm outline-none focus:ring-1 focus:ring-primary", { shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; disabled: { true: string; }; }, undefined, tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; disabled: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 placeholder-base-content/50 text-base-content text-sm outline-none focus:ring-1 focus:ring-primary", unknown, unknown, undefined>>; type MnInputVariants = VariantProps; /** * Supported input types for the MnInputField component. * Includes standard text inputs, specialized inputs (email, tel, url), * and date/time inputs. */ type MnInputType = 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number' | 'date' | 'time' | 'datetime-local'; type MnErrorMessageData = string | MnErrorMessageFn; /** * Map of error keys to error message definitions. * Keys correspond to Angular validator error keys (e.g., 'required', 'email', 'minlength') * or custom validator keys. */ type MnErrorMessagesData = Partial>; /** * Base properties for all MnInputField variants. * Contains common UI, styling, and error handling configuration. */ type MnInputBaseProps = { /** Unique identifier for the input element (required for accessibility) */ id: string; /** Name attribute for the input element (used in form submission) */ name?: string; /** Type of input field (text, email, date, etc.) */ type: MnInputType; /** Label text (overrides uiConfig.label when provided) */ label?: string; /** Placeholder text (overrides uiConfig.placeholder when provided) */ placeholder?: string; /** * ARIA label for screen readers (overrides uiConfig.ariaLabel when provided). * Use it to give an accessible name to an input rendered without a visible label. */ ariaLabel?: string; /** * Id of the option a surrounding listbox has highlighted, set as `aria-activedescendant`. Used by * the select's search box, which keeps focus while the arrow keys move through the options. */ ariaActiveDescendant?: string | null; /** Input mask (e.g., '(000) 000-0000') */ mask?: string; /** Autocomplete attribute */ autocomplete?: string; /** Whether to focus this field when the component initializes */ autoFocus?: boolean; /** Size variant of the input field (default: 'md') */ size?: MnInputVariants['size']; /** Border radius variant (default: 'md') */ borderRadius?: MnInputVariants['borderRadius']; /** Shadow variant for the input field */ shadow?: MnInputVariants['shadow']; /** Whether the input should take full width of its container */ fullWidth?: MnInputVariants['fullWidth']; /** Whether to apply hover effect (cursor pointer and background change) */ hover?: MnInputVariants['hover']; /** * Custom error messages mapped by validator error key. * Example: { required: 'This field is mandatory', email: 'Invalid email format' } */ errorMessages?: MnErrorMessagesData; /** * Fallback error message when no specific message is found for an error. * Default: 'Invalid input' */ defaultErrorMessage?: string; /** * Priority order for displaying errors when multiple validation errors exist. * Only used when showAllErrors is false. * Example: ['required', 'email', 'minlength'] * If not provided, the first error key will be displayed. */ errorPriority?: string[]; /** * Whether to use built-in default error messages. * Set to false to only use custom errorMessages and defaultErrorMessage. * Default: true (backwards compatible) */ useBuiltInErrorMessages?: boolean; /** * Whether to display all validation errors or just the first/priority error. * - true: Display all error messages present on the control * - false: Display only one error based on errorPriority or first error * Default: false (backwards compatible - show single error) */ showAllErrors?: boolean; }; /** * Configuration for MnInputField resolved from MnConfigService. * Contains UI properties that can ONLY be set via configuration. */ type MnInputFieldUIConfig = { /** Label text displayed above the input field */ label?: string; /** Placeholder text shown inside the input when empty */ placeholder?: string; /** ARIA label for screen readers (falls back to label if not provided) */ ariaLabel?: string; /** * Error messages resolved from config (supports $translate markers). * These override built-in error messages but are overridden by props.errorMessages. */ errorMessages?: Record; }; /** * Properties for standard input fields (text, email, password, tel, url, number, search). * Excludes date/time input types which have additional properties. */ type MnInputFieldProps = { type: Exclude; } & MnInputBaseProps; /** * Properties for date/time input fields. * Includes additional date range validation properties. */ type MnInputDateTimeProps = { type: Extract; /** Minimum allowed date/time value (ISO 8601 format) */ startDate?: string; /** Maximum allowed date/time value (ISO 8601 format) */ endDate?: string; } & MnInputBaseProps; /** * Union type of all possible input field property configurations. * Use this type when accepting props in components or functions. */ type MnInputProps = MnInputFieldProps | MnInputDateTimeProps; declare const MN_INPUT_FIELD_CONFIG: InjectionToken; /** * MnInputField Component * * A flexible, accessible input field component that implements Angular's ControlValueAccessor * and Validator interfaces. Supports multiple input types, custom validation messages, * and configurable error display (single or multiple errors). * * Features: * - Works with Angular Reactive Forms (FormControl, FormGroup) * - Supports standard and date/time input types * - Built-in error messages with internationalization support * - Custom error messages per field * - Priority-based error display or show all errors * - Full accessibility (ARIA attributes) * - Type-safe adapter pattern for different input types * * @example * ```typescript * * ``` */ declare class MnInputField implements OnInit { ngControl: NgControl | null; /** Resolved UI configuration for the input field */ protected uiConfig: MnInputFieldUIConfig; private readonly el; /** Configuration properties for the input field */ props: MnInputProps; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; /** Marks the view when a locale change re-resolves the config (OnPush). */ private readonly cdr; private readonly lang; private readonly destroyRef; /** Current raw string value of the input element */ value: string | null; /** Whether the input is disabled */ isDisabled: boolean; /** Callback function to notify Angular forms of value changes */ private onChange; /** Callback function to notify Angular forms when input is touched/blurred */ private onTouched; /** * Built-in default error messages in English. * These are used when useBuiltInErrorMessages is true (default). * Can be overridden per-field using props.errorMessages. */ private readonly builtInErrorMessages; /** * Constructor - Registers this component as the ControlValueAccessor * for the injected NgControl (FormControl). * */ constructor(); ngOnInit(): void; /** * Focuses the input element. */ focus(): void; private resolveConfig; /** * Gets the appropriate adapter based on the input type. * Adapters handle type-specific formatting, parsing, and validation. */ private get adapter(); /** * Writes a new value to the input element (called by Angular Forms). * Formats the value using the type-specific adapter. * * @param val - The value to write (type depends on input type) */ writeValue(val: unknown): void; /** * Registers a callback function to be called when the input value changes. * * @param fn - Callback function to notify Angular Forms of changes */ registerOnChange(fn: (val: unknown) => void): void; /** * Registers a callback function to be called when the input is touched/blurred. * * @param fn - Callback function to notify Angular Forms of touch events */ registerOnTouched(fn: () => void): void; /** * Sets the disabled state of the input element. * * @param isDisabled - Whether the input should be disabled */ setDisabledState(isDisabled: boolean): void; /** * Handles input events from the input element. * Parses the raw string value and notifies Angular Forms. * * @param raw - Raw string value from the input element */ handleInput(raw: string): void; /** * Handles blur events from the input element. * Notifies Angular Forms that the input has been touched. */ handleBlur(): void; /** * Validates the control using the type-specific adapter. * Called by Angular Forms during validation. * * @param control - The AbstractControl to validate * @returns ValidationErrors if invalid, null if valid */ validate(control: AbstractControl): ValidationErrors | null; /** * Gets all DOM attributes from the adapter. * These are input-type-specific attributes (min, max, step, inputmode). */ get domAttrs(): mn_angular_lib_forms.MnDomAttrs; /** Min attribute for date/time/number inputs */ get minAttr(): string | null; /** Max attribute for date/time/number inputs */ get maxAttr(): string | null; /** Step attribute for number/date/time inputs */ get stepAttr(): string | null; /** Inputmode attribute for mobile keyboard optimization */ get inputmodeAttr(): string | null; /** * Gets the FormControl instance from Angular Forms. * Returns null if no control is attached. */ get control(): AbstractControl | null; /** * Determines whether to show error messages. * Errors are shown when the control is invalid and has been touched or modified. */ /** * Ids of the rendered error messages, space-separated, for `aria-describedby`. Mirrors the * `{id}-error` / `{id}-{index}-error` ids `mn-error-message` renders in single and show-all mode. */ get errorDescribedBy(): string; get showError(): boolean; /** * Picks the error key to display based on errorPriority. * Used when showAllErrors is false (default). * * @param errors - ValidationErrors object from the control * @returns The error key to display */ private pickErrorKey; protected isRequired(): boolean; /** * Resolves a single error message for a specific error key. * Checks custom messages, built-in messages, and fallback in order. * * @param errorKey - The error key (e.g., 'required', 'email') * @param errors - All validation errors on the control * @returns The resolved error message string */ private resolveErrorMessageForKey; /** * Gets all error messages for the current control state. * Returns an array of error messages (used when showAllErrors is true). * * @returns Array of error message strings */ get errorMessages(): string[]; /** * Gets a single error message for the current control state. * Uses errorPriority to determine which error to show (when showAllErrors is false). * * @returns Single error message string, or null if no errors */ get errorMessage(): string | null; /** Resolved ID for the input element */ get resolvedId(): string; /** Resolved name attribute for the input element */ get resolvedName(): string | null; /** * Computes the CSS classes from tailwind-variants based on the props. * Returns the variant classes for styling the input element. */ get inputClasses(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * MnInputField Adapters * * This module implements the Adapter Pattern to handle type-specific behavior * for different HTML input types in the MnInputField component. * * The adapter pattern allows the component to support multiple input types * (text, number, date, time, etc.) without coupling the component logic to * type-specific implementations. Each adapter handles: * - Parsing: converting raw string input to the appropriate data type * - Formatting: converting typed values back to string for display * - Attributes: providing type-specific DOM attributes (min, max, step, inputmode) * - Validation: implementing type-specific validation rules * * This approach keeps the component code clean and makes it easy to add * support for new input types by creating new adapters. */ /** * DOM attributes that can be dynamically set on input elements. * These attributes are type-specific and provided by adapters. */ type MnDomAttrs = { /** Minimum value for date/time/number inputs */ min?: string | null; /** Maximum value for date/time/number inputs */ max?: string | null; /** Step increment for number/date/time inputs */ step?: string | null; /** Mobile keyboard hint (e.g., 'decimal' for number inputs) */ inputmode?: string | null; }; /** * Adapter interface for handling input type-specific behavior. * * Each adapter implementation defines how to handle a specific input type * (or group of related types) throughout the component lifecycle. * * @template TOut - The output type after parsing (e.g., string | null, number | null) */ type MnInputAdapter = { /** * Parses the raw string value from the input element into the typed value * that will be sent to the FormControl. * * @param raw - Raw string value from the input element * @returns Typed value to store in the FormControl * * @example * // Text adapter * parse('hello') // => 'hello' * parse('') // => null * * // Number adapter * parse('42') // => 42 * parse('') // => null * parse('abc') // => null */ parse(raw: string): TOut; /** * Formats the typed value from the FormControl into a string * that will be displayed in the input element. * * @param val - Typed value from the FormControl * @returns String representation for the input element's value attribute * * @example * // Text adapter * format('hello') // => 'hello' * format(null) // => '' * * // Number adapter * format(42) // => '42' * format(null) // => '' */ format(val: unknown): string; /** * Returns type-specific DOM attributes for the input element. * These attributes are applied dynamically based on the input type and props. * * @param props - Input field properties * @returns Object containing DOM attributes (min, max, step, inputmode) * * @example * // Date adapter with date range * attrs({ startDate: '2024-01-01', endDate: '2024-12-31' }) * // => { min: '2024-01-01', max: '2024-12-31' } * * // Number adapter * attrs({}) // => { inputmode: 'decimal' } */ attrs(props: MnInputProps): MnDomAttrs; /** * Performs type-specific validation on the current input value. * This validation runs in addition to Angular's built-in validators. * * @param props - Input field properties (may contain validation constraints) * @param control - The AbstractControl being validated * @param currentRaw - Current raw string value from the input element * @returns ValidationErrors object if invalid, null if valid * * @example * // Date adapter validation * validate(props, control, '2024-06-15') * // Returns { mnMin: { min: '2024-07-01', actual: '2024-06-15' } } * // if startDate is '2024-07-01' */ validate(props: MnInputProps, control: AbstractControl, currentRaw: string | null): ValidationErrors | null; /** * Applies a mask to the raw input value. */ applyMask?(value: string, mask: string): string; }; /** * Default adapter for text-based input types. * Used for: text, email, password, search, tel, url * * Behavior: * - Empty strings are converted to null * - Values are stored as strings in the FormControl * - No special DOM attributes * - No additional validation (relies on Angular's built-in validators) * - Supports simple masking (0 for digit, A for alpha, * for any) */ declare const defaultTextAdapter: MnInputAdapter; /** * Adapter for date and time input types. * Used for: date, time, datetime-local * * Behavior: * - Empty strings are converted to null * - Values are stored as ISO 8601 strings in the FormControl * - Provides min/max attributes from startDate/endDate props * - Validates date/time ranges using string comparison * * Note: String comparison works for ISO 8601 dates/times because they are * lexicographically ordered (e.g., '2024-01-15' < '2024-12-31'). */ declare const dateTimeAdapter: MnInputAdapter; /** * Adapter for number input type. * * Behavior: * - Empty strings are converted to null * - Valid numbers are parsed to number type * - Invalid numbers (NaN, Infinity) are converted to null * - Values are stored as numbers (or null) in the FormControl * - Sets inputmode='decimal' for optimized mobile keyboards * - No additional validation (relies on Angular's built-in validators) * * Note: The browser's native number input validation handles * basic number format validation automatically. */ declare const numberAdapter: MnInputAdapter; /** * Selects the appropriate adapter based on the input type. * This is the main factory function used by the MnInputField component * to determine which adapter to use for a given input type. * * @param type - The input type (e.g., 'text', 'email', 'date', 'number') * @returns The appropriate adapter instance * * @example * pickAdapter('text') // => defaultTextAdapter * pickAdapter('email') // => defaultTextAdapter * pickAdapter('date') // => dateTimeAdapter * pickAdapter('number') // => numberAdapter */ declare function pickAdapter(type: MnInputType): MnInputAdapter; declare const mnCheckboxVariants: tailwind_variants.TVReturnType<{ size: { xs: string; sm: string; md: string; lg: string; xl: string; }; color: { primary: string; secondary: string; accent: string; neutral: string; info: string; success: string; warning: string; error: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; }; }, undefined, "mn-checkbox", { size: { xs: string; sm: string; md: string; lg: string; xl: string; }; color: { primary: string; secondary: string; accent: string; neutral: string; info: string; success: string; warning: string; error: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; }; }, undefined, tailwind_variants.TVReturnType<{ size: { xs: string; sm: string; md: string; lg: string; xl: string; }; color: { primary: string; secondary: string; accent: string; neutral: string; info: string; success: string; warning: string; error: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; }; }, undefined, "mn-checkbox", unknown, unknown, undefined>>; declare const mnCheckboxWrapperVariants: tailwind_variants.TVReturnType<{ size: { xs: string; sm: string; md: string; lg: string; xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; }, undefined, "text-base-content", { size: { xs: string; sm: string; md: string; lg: string; xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; }, undefined, tailwind_variants.TVReturnType<{ size: { xs: string; sm: string; md: string; lg: string; xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; }, undefined, "text-base-content", unknown, unknown, undefined>>; type MnCheckboxVariants = VariantProps; type MnCheckboxWrapperVariants = VariantProps; type MnCheckboxErrorMessageData = string | MnErrorMessageFn; type MnCheckboxErrorMessagesData = Partial>; type MnCheckboxProps = { /** Unique identifier for the checkbox element (required for accessibility) */ id: string; /** Name attribute for the checkbox element (used in form submission) */ name?: string; /** Label text displayed next to the checkbox */ label?: string; /** Size variant of the checkbox (default: 'md') */ size?: MnCheckboxVariants['size']; /** Color variant of the checkbox (default: 'primary') */ color?: MnCheckboxVariants['color']; /** Border radius variant (default: 'sm') */ borderRadius?: MnCheckboxVariants['borderRadius']; /** Whether the checkbox wrapper should take full width */ fullWidth?: MnCheckboxWrapperVariants['fullWidth']; /** Whether to show hover effect on the label row (default: true) */ hover?: MnCheckboxWrapperVariants['hover']; /** Custom error messages mapped by validator error key */ errorMessages?: MnCheckboxErrorMessagesData; /** Fallback error message when no specific message is found for an error */ defaultErrorMessage?: string; /** Priority order for displaying errors when multiple validation errors exist */ errorPriority?: string[]; /** Whether to use built-in default error messages (default: true) */ useBuiltInErrorMessages?: boolean; /** Whether to display all validation errors or just the first/priority error (default: false) */ showAllErrors?: boolean; }; type MnCheckboxUIConfig = { /** Label text displayed next to the checkbox */ label?: string; /** ARIA label for screen readers (falls back to label if not provided) */ ariaLabel?: string; /** * Error messages resolved from config (supports $translate markers). * These override built-in error messages but are overridden by props.errorMessages. */ errorMessages?: Record; }; declare const MN_CHECKBOX_CONFIG: InjectionToken; declare class MnCheckbox implements OnInit, OnChanges { ngControl: NgControl | null; protected uiConfig: MnCheckboxUIConfig; props: MnCheckboxProps; /** Direct checked binding for non-form usage */ checked?: boolean; /** Emits when checked state changes (for non-form usage) */ checkedChange: EventEmitter; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; /** Marks the view when a locale change re-resolves the config (OnPush). */ private readonly cdr; private readonly lang; private readonly destroyRef; value: boolean; isDisabled: boolean; private onChange; private onTouched; private readonly builtInErrorMessages; constructor(); ngOnInit(): void; private resolveConfig; writeValue(val: unknown): void; /** Sync value from checked input when not using forms */ ngOnChanges(): void; registerOnChange(fn: (val: unknown) => void): void; registerOnTouched(fn: () => void): void; setDisabledState(isDisabled: boolean): void; handleChange(checked: boolean): void; handleBlur(): void; get control(): _angular_forms.AbstractControl | null; get showError(): boolean; private pickErrorKey; protected isRequired(): boolean; private resolveErrorMessageForKey; get errorMessages(): string[]; get errorMessage(): string | null; get resolvedId(): string; get resolvedName(): string | null; get checkboxClasses(): string; get wrapperClasses(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare const mnTextareaVariants: tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; resize: { none: string; vertical: string; horizontal: string; both: string; }; }, undefined, "bg-base-100 border-1 border-base-300 placeholder-base-content/50 text-base-content text-sm outline-none focus:ring-1 focus:ring-primary", { shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; resize: { none: string; vertical: string; horizontal: string; both: string; }; }, undefined, tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; resize: { none: string; vertical: string; horizontal: string; both: string; }; }, undefined, "bg-base-100 border-1 border-base-300 placeholder-base-content/50 text-base-content text-sm outline-none focus:ring-1 focus:ring-primary", unknown, unknown, undefined>>; type MnTextareaVariants = VariantProps; type MnTextareaErrorMessageData = string | MnErrorMessageFn; /** * Map of error keys to error message definitions. * Keys correspond to Angular validator error keys (e.g., 'required', 'minlength') * or custom validator keys. */ type MnTextareaErrorMessagesData = Partial>; /** * Properties for the MnTextarea component. * Contains UI, styling, and error handling configuration. */ type MnTextareaProps = { /** Unique identifier for the textarea element (required for accessibility) */ id: string; /** Name attribute for the textarea element (used in form submission) */ name?: string; /** Label text displayed above the textarea */ label?: string; /** Placeholder text shown inside the textarea when empty */ placeholder?: string; /** Number of visible text rows */ rows?: number; /** Number of visible text columns */ cols?: number; /** Size variant of the textarea (default: 'md') */ size?: MnTextareaVariants['size']; /** Border radius variant (default: 'md') */ borderRadius?: MnTextareaVariants['borderRadius']; /** Shadow variant for the textarea */ shadow?: MnTextareaVariants['shadow']; /** Whether the textarea should take full width of its container */ fullWidth?: MnTextareaVariants['fullWidth']; /** resize behavior of the textarea (default: 'vertical') */ resize?: MnTextareaVariants['resize']; /** Whether to focus this field when the component initializes */ autoFocus?: boolean; /** Autocomplete attribute */ autocomplete?: string; /** * Custom error messages mapped by validator error key. * Example: { required: 'This field is mandatory' } */ errorMessages?: MnTextareaErrorMessagesData; /** * Fallback error message when no specific message is found for an error. * Default: 'Invalid input' */ defaultErrorMessage?: string; /** * Priority order for displaying errors when multiple validation errors exist. * Only used when showAllErrors is false. * Example: ['required', 'minlength'] */ errorPriority?: string[]; /** * Whether to use built-in default error messages. * Set to false to only use custom errorMessages and defaultErrorMessage. * Default: true */ useBuiltInErrorMessages?: boolean; /** * Whether to display all validation errors or just the first/priority error. * - true: Display all error messages present on the control * - false: Display only one error based on errorPriority or first error * Default: false */ showAllErrors?: boolean; }; /** * Configuration for MnTextarea resolved from MnConfigService. * Contains UI properties that can ONLY be set via configuration. */ type MnTextareaUIConfig = { /** Label text displayed above the textarea */ label?: string; /** Placeholder text shown inside the textarea when empty */ placeholder?: string; /** ARIA label for screen readers (falls back to label if not provided) */ ariaLabel?: string; /** * Error messages resolved from config (supports $translate markers). * These override built-in error messages but are overridden by props.errorMessages. */ errorMessages?: Record; }; declare const MN_TEXTAREA_CONFIG: InjectionToken; /** * MnTextarea Component * * A flexible, accessible textarea component that implements Angular's ControlValueAccessor * and Validator interfaces. Works similarly to MnInputField but uses a textarea element, * allowing users to set the height (rows), width (cols), and resize behavior. * * Features: * - Works with Angular Reactive Forms (FormControl, FormGroup) * - Configurable rows, cols, and resize behavior * - Built-in error messages with internationalization support * - Custom error messages per field * - Priority-based error display or show all errors * - Full accessibility (ARIA attributes) * * @example * ```typescript * * ``` */ declare class MnTextarea implements OnInit { ngControl: NgControl | null; /** Resolved UI configuration for the textarea */ protected uiConfig: MnTextareaUIConfig; private readonly el; /** Configuration properties for the textarea */ props: MnTextareaProps; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; /** Marks the view when a locale change re-resolves the config (OnPush). */ private readonly cdr; private readonly lang; private readonly destroyRef; /** Current raw string value of the textarea element */ value: string | null; /** Whether the textarea is disabled */ isDisabled: boolean; /** Callback function to notify Angular forms of value changes */ private onChange; /** Callback function to notify Angular forms when textarea is touched/blurred */ private onTouched; /** * Built-in default error messages in English. * These are used when useBuiltInErrorMessages is true (default). * Can be overridden per-field using props.errorMessages. */ private readonly builtInErrorMessages; /** * Constructor - Registers this component as the ControlValueAccessor * for the injected NgControl (FormControl). * */ constructor(); ngOnInit(): void; /** * Focuses the textarea element. */ focus(): void; private resolveConfig; /** * Writes a new value to the textarea element (called by Angular Forms). * * @param val - The value to write */ writeValue(val: unknown): void; /** * Registers a callback function to be called when the textarea value changes. * * @param fn - Callback function to notify Angular Forms of changes */ registerOnChange(fn: (val: unknown) => void): void; /** * Registers a callback function to be called when the textarea is touched/blurred. * * @param fn - Callback function to notify Angular Forms of touch events */ registerOnTouched(fn: () => void): void; /** * Sets the disabled state of the textarea element. * * @param isDisabled - Whether the textarea should be disabled */ setDisabledState(isDisabled: boolean): void; /** * Handles input events from the textarea element. * Notifies Angular Forms of the new value. * * @param raw - Raw string value from the textarea element */ handleInput(raw: string): void; /** * Handles blur events from the textarea element. * Notifies Angular Forms that the textarea has been touched. */ handleBlur(): void; /** * Gets the FormControl instance from Angular Forms. * Returns null if no control is attached. */ get control(): _angular_forms.AbstractControl | null; /** * Determines whether to show error messages. * Errors are shown when the control is invalid and has been touched or modified. */ /** * Ids of the rendered error messages, space-separated, for `aria-describedby`. Mirrors the * `{id}-error` / `{id}-{index}-error` ids `mn-error-message` renders in single and show-all mode. */ get errorDescribedBy(): string; get showError(): boolean; /** * Picks the error key to display based on errorPriority. * Used when showAllErrors is false (default). * * @param errors - ValidationErrors object from the control * @returns The error key to display */ private pickErrorKey; protected isRequired(): boolean; /** * Resolves a single error message for a specific error key. * * @param errorKey - The error key (e.g., 'required', 'minlength') * @param errors - All validation errors on the control * @returns The resolved error message string */ private resolveErrorMessageForKey; /** * Gets all error messages for the current control state. * * @returns Array of error message strings */ get errorMessages(): string[]; /** * Gets a single error message for the current control state. * * @returns Single error message string, or null if no errors */ get errorMessage(): string | null; /** Resolved ID for the textarea element */ get resolvedId(): string; /** Resolved name attribute for the textarea element */ get resolvedName(): string | null; /** * Computes the CSS classes from tailwind-variants based on the props. * Returns the variant classes for styling the textarea element. */ get textareaClasses(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare const mnDatetimeVariants: tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 placeholder-base-content/50 cursor-pointer text-base-content text-sm", { shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; }, undefined, tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; hover: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 placeholder-base-content/50 cursor-pointer text-base-content text-sm", unknown, unknown, undefined>>; type MnDatetimeVariants = VariantProps; type MnDatetimeErrorMessageData = string | MnErrorMessageFn; type MnDatetimeErrorMessagesData = Partial>; /** * Supported datetime input modes. * - 'date': Date only (YYYY-MM-DD) * - 'time': Time only (HH:mm) * - 'datetime-local': Date and time combined (YYYY-MM-DDTHH:mm) */ type MnDatetimeMode = 'date' | 'time' | 'datetime-local'; type MnDatetimeProps = { /** Unique identifier for the datetime element (required for accessibility) */ id: string; /** Name attribute for the datetime element (used in form submission) */ name?: string; /** Label text displayed above the datetime field */ label?: string; /** Placeholder text (overrides uiConfig.placeholder when provided) */ placeholder?: string; /** Datetime input mode (default: 'datetime-local') */ mode?: MnDatetimeMode; /** Minimum allowed date/time value (ISO 8601 format) */ min?: string; /** Maximum allowed date/time value (ISO 8601 format) */ max?: string; /** Step interval in seconds (e.g., 60 for minute precision, 1 for second precision) */ step?: number; /** Size variant of the datetime field (default: 'md') */ size?: MnDatetimeVariants['size']; /** Border radius variant (default: 'md') */ borderRadius?: MnDatetimeVariants['borderRadius']; /** Shadow variant for the datetime field */ shadow?: MnDatetimeVariants['shadow']; /** Whether the datetime field should take full width of its container */ fullWidth?: MnDatetimeVariants['fullWidth']; /** Whether to apply hover effect (cursor pointer and background change) */ hover?: MnDatetimeVariants['hover']; /** * Render the control as an icon-only button — a calendar icon in a bordered box * — instead of the full input that shows the value. The native picker still * opens on click and the field stays a working form control; only the display * collapses to the icon. Off by default. * * There is no visible text to name the control, so supply a `label`, * `ariaLabel`, or `placeholder` for its accessible name. */ iconOnly?: boolean; /** Custom error messages mapped by validator error key */ errorMessages?: MnDatetimeErrorMessagesData; /** Fallback error message when no specific message is found for an error */ defaultErrorMessage?: string; /** Priority order for displaying errors when multiple validation errors exist */ errorPriority?: string[]; /** Whether to use built-in default error messages (default: true) */ useBuiltInErrorMessages?: boolean; /** Whether to display all validation errors or just the first/priority error (default: false) */ showAllErrors?: boolean; }; type MnDatetimeUIConfig = { /** Label text displayed above the datetime field */ label?: string; /** Placeholder text shown inside the datetime field when empty */ placeholder?: string; /** ARIA label for screen readers (falls back to label if not provided) */ ariaLabel?: string; /** * Error messages resolved from config (supports $translate markers). * These override built-in error messages but are overridden by props.errorMessages. */ errorMessages?: Record; }; declare const MN_DATETIME_CONFIG: InjectionToken; declare class MnDatetime implements OnInit { /** Lucide icons the template renders. */ protected readonly icons: Record<"CalendarDays", _lucide_angular.LucideIconData>; ngControl: NgControl | null; protected uiConfig: MnDatetimeUIConfig; props: MnDatetimeProps; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; /** Marks the view when a locale change re-resolves the config (OnPush). */ private readonly cdr; private readonly lang; private readonly destroyRef; value: string | null; isDisabled: boolean; private onChange; private onTouched; private readonly builtInErrorMessages; constructor(); ngOnInit(): void; private resolveConfig; writeValue(val: unknown): void; registerOnChange(fn: (val: unknown) => void): void; registerOnTouched(fn: () => void): void; setDisabledState(isDisabled: boolean): void; handleInput(raw: string): void; handleBlur(): void; handleClick(input: HTMLInputElement): void; get control(): _angular_forms.AbstractControl | null; get showError(): boolean; private pickErrorKey; protected isRequired(): boolean; private resolveErrorMessageForKey; get errorMessages(): string[]; get errorMessage(): string | null; get resolvedId(): string; get resolvedName(): string | null; get resolvedMode(): MnDatetimeMode; /** Whether the control renders as an icon-only button rather than a full input. */ get iconOnly(): boolean; /** * Accessible name for the input. Prefers an explicit ariaLabel/label; for the * icon-only variant — which has no visible text — it falls back to the * placeholder so the button is never left unnamed. */ get resolvedAriaLabel(): string | null; /** Lucide icon size (px) tracking the field size, used only in the icon-only variant. */ get iconSize(): number; get inputClasses(): string; /** * Classes for the icon-only box: the same border/background/radius/hover the full * input would wear (reused from the variant), made a positioning context for the * overlaid input, with a `focus-within` ring standing in for the transparent * input's own focus outline. */ get iconBoxClasses(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Tailwind-variants definition for the MnFileInput component. * * Mirrors the styling vocabulary of {@link mnInputFieldVariants} (size, * borderRadius, shadow, fullWidth, disabled) so a file input visually matches the * rest of the input family, and adds a `dropzone` toggle for the large dashed * drop area used by the default display mode plus a `dragging` toggle for the * "release to drop" state while files hover over that dropzone. */ declare const mnFileInputVariants: tailwind_variants.TVReturnType<{ /** Inner padding scale of the clickable control. */ size: { sm: string; md: string; lg: string; }; /** Corner rounding of the control. */ borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; /** Drop shadow toggle. */ shadow: { true: string; }; /** Stretch the control to the full width of its container. */ fullWidth: { true: string; }; /** Renders the control as a large dashed dropzone with a hover accent. */ dropzone: { true: string; }; /** Highlighted "release to drop" appearance while files hover the dropzone. */ dragging: { true: string; }; /** Dimmed, non-interactive appearance. */ disabled: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 text-base-content text-sm outline-none transition-all duration-300 ease-in-out", { /** Inner padding scale of the clickable control. */ size: { sm: string; md: string; lg: string; }; /** Corner rounding of the control. */ borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; /** Drop shadow toggle. */ shadow: { true: string; }; /** Stretch the control to the full width of its container. */ fullWidth: { true: string; }; /** Renders the control as a large dashed dropzone with a hover accent. */ dropzone: { true: string; }; /** Highlighted "release to drop" appearance while files hover the dropzone. */ dragging: { true: string; }; /** Dimmed, non-interactive appearance. */ disabled: { true: string; }; }, undefined, tailwind_variants.TVReturnType<{ /** Inner padding scale of the clickable control. */ size: { sm: string; md: string; lg: string; }; /** Corner rounding of the control. */ borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; /** Drop shadow toggle. */ shadow: { true: string; }; /** Stretch the control to the full width of its container. */ fullWidth: { true: string; }; /** Renders the control as a large dashed dropzone with a hover accent. */ dropzone: { true: string; }; /** Highlighted "release to drop" appearance while files hover the dropzone. */ dragging: { true: string; }; /** Dimmed, non-interactive appearance. */ disabled: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 text-base-content text-sm outline-none transition-all duration-300 ease-in-out", unknown, unknown, undefined>>; /** Variant prop types derived from {@link mnFileInputVariants}. */ type MnFileInputVariants = VariantProps; /** A single error message definition: a static string or a function of the error args. */ type MnFileInputErrorMessageData = string | MnErrorMessageFn; /** * Map of error keys to error message definitions. * Keys correspond to the component's selection errors (`accept`, `maxSize`, * `maxFiles`) or the attached control's validator keys (e.g. `required`). */ type MnFileInputErrorMessagesData = Partial>; /** * Controls how the selected file(s) are presented. Every mode but `compact` * doubles as a drop target and shows a "release to drop" state while files are * dragged over it. * - `dropzone` — large dashed drop area with icon + hint, previews/rows below (default). * - `thumbnail` — grid of image tiles (file icon for non-images), with an add tile. * - `list` — compact rows of file icon + name + size + remove. * - `compact` — inline styled button + current filename + remove. */ type MnFileInputDisplayMode = 'dropzone' | 'thumbnail' | 'list' | 'compact'; /** * Configuration properties for the {@link MnFileInput} component. * Passed as a single required `props` object, mirroring the other input components. */ type MnFileInputProps = { /** Unique identifier for the input element (required for accessibility). */ id: string; /** Name attribute for the underlying file input. */ name?: string; /** Label text shown above the control (overrides config when provided). */ label?: string; /** Hint shown inside the empty dropzone (overrides config when provided). */ dropzoneHint?: string; /** * Hint that replaces {@link dropzoneHint} while files are dragged over the * dropzone (overrides config when provided). */ dropActiveHint?: string; /** Label for the "choose/replace file" affordance (overrides config when provided). */ replaceLabel?: string; /** Accessible label for the per-file remove button (overrides config when provided). */ removeLabel?: string; /** * Accepted file types, forwarded to the native `accept` attribute and * re-validated on selection (e.g. `image/*`, `.pdf,.docx`). When unset, all * file types are allowed. */ accept?: string; /** Allow selecting more than one file. Changes the value shape to `File[]`. */ multiple?: boolean; /** Maximum number of files retained (only meaningful when `multiple` is true). */ maxFiles?: number; /** Maximum size per file in bytes; larger files are rejected. */ maxSize?: number; /** How the selection is rendered. Defaults to `dropzone`. */ displayMode?: MnFileInputDisplayMode; /** * URL of an already-saved image to preview when no new file is selected * (single mode). Cleared when the user removes it; surfaced via `cleared`. */ currentUrl?: string | null; /** URLs of already-saved images to preview when nothing is selected (multiple mode). */ currentUrls?: string[] | null; /** Disables the control. */ disabled?: boolean; /** Size variant of the control (default: `md`). */ size?: MnFileInputVariants['size']; /** Border radius variant (default: `lg`). */ borderRadius?: MnFileInputVariants['borderRadius']; /** Shadow variant for the control. */ shadow?: MnFileInputVariants['shadow']; /** Whether the control should take the full width of its container. */ fullWidth?: MnFileInputVariants['fullWidth']; /** Custom error messages mapped by error key (overrides config and built-ins). */ errorMessages?: MnFileInputErrorMessagesData; /** Fallback message when no specific message is found for an error. */ defaultErrorMessage?: string; /** Priority order for displaying control errors when several exist. */ errorPriority?: string[]; /** Whether to use the built-in default error messages (default: true). */ useBuiltInErrorMessages?: boolean; /** Display every control error instead of just the first/priority one (default: false). */ showAllErrors?: boolean; }; /** * UI strings resolved from {@link MnConfigService} for the file input. * These can only be set via configuration (or the matching `props` overrides). */ type MnFileInputUIConfig = { /** Label text displayed above the control. */ label?: string; /** ARIA label for screen readers (falls back to label). */ ariaLabel?: string; /** Hint shown inside the empty dropzone. */ dropzoneHint?: string; /** Hint shown inside the dropzone while files are dragged over it. */ dropActiveHint?: string; /** Label for the "choose/replace file" affordance. */ replaceLabel?: string; /** Accessible label for the per-file remove button. */ removeLabel?: string; /** Error messages resolved from config (override built-ins, overridden by props). */ errorMessages?: Record; }; /** A single renderable entry in the file input (a newly-selected file or an existing image). */ type MnFileDisplayItem = { /** File name (new files) or a derived name (existing images). */ name: string; /** Whether the entry should render as an image preview. */ isImage: boolean; /** Object-URL (new image files) or saved URL (existing images), else null. */ previewUrl: string | null; /** Human-readable size for new files, else null. */ sizeLabel: string | null; /** Index used by the remove action. */ index: number; /** True for an already-saved image passed via `currentUrl(s)`. */ existing: boolean; }; /** * MnFileInput Component * * A generic, accessible file input that implements Angular's ControlValueAccessor. * It styles selection to match the rest of the input family, shows image previews * (and a file icon + name for non-images), supports single or multiple selection, * several display layouts, and client-side `accept` / `maxSize` / `maxFiles` limits. * * Every display mode but `compact` is also a real drop target: dragging files * over it switches the area to a highlighted "release to drop" state, and * dropping runs the files through the same validation as the file picker. * * The form control value is the plain selection: `File | null` (single) or * `File[]` (multiple). An optional `currentUrl`/`currentUrls` renders an * already-saved image; removing it leaves the value untouched and emits `cleared`. * * @example * ```html * * * ``` */ declare class MnFileInput implements OnInit { /** Lucide icons the template renders. */ protected readonly icons: Record<"File" | "ImagePlus" | "Trash2" | "Upload" | "X", _lucide_angular.LucideIconData>; ngControl: NgControl | null; /** Configuration properties for the file input. */ props: MnFileInputProps; /** Emits whenever the selected file(s) change (in addition to the form control). */ filesChange: EventEmitter; /** Emits when the user removes an already-saved image (`currentUrl(s)`). */ cleared: EventEmitter; /** Resolved UI configuration for the file input. */ protected uiConfig: MnFileInputUIConfig; /** Currently selected files (always an array internally). */ protected readonly files: i0.WritableSignal; /** True while files are dragged over the dropzone ("release to drop" state). */ protected readonly isDragging: i0.WritableSignal; /** Transient message for a rejected selection (accept/maxSize/maxFiles). */ protected readonly internalError: i0.WritableSignal; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; /** Marks the view when a locale change re-resolves the config (OnPush). */ private readonly cdr; private readonly lang; private readonly destroyRef; /** Object-URL previews aligned to {@link files}; null for non-image entries. */ private readonly previewUrls; /** True once the user removed the single existing image. */ private readonly currentCleared; /** Indices of removed existing images (multiple mode). */ private readonly removedExisting; /** Renderable entries: existing images (when nothing newer hides them) then new files. */ readonly displayItems: i0.Signal; /** Disabled state pushed by the forms API. */ private formDisabled; /** * Nesting depth of the current drag, so that moving across child elements of * the dropzone does not flicker {@link isDragging} off and on again. */ private dragDepth; /** * Built-in default error messages in English. * Used when `useBuiltInErrorMessages` is true (default); overridable per-field. */ private readonly builtInErrorMessages; /** Registers this component as the ControlValueAccessor for the injected control. */ constructor(); /** The effective display mode. */ get displayMode(): MnFileInputDisplayMode; /** * Whether the current display mode acts as a drop target. `compact` is an * inline button sized for a form row, too small to aim a drag at. */ get supportsDrop(): boolean; /** Whether the control is disabled (via props or the forms API). */ get isDisabled(): boolean; /** Native `accept` attribute value, or null for no restriction when unset. */ get acceptAttr(): string | null; /** Resolved id for the file input element. */ get resolvedId(): string; /** Resolved name attribute for the file input element. */ get resolvedName(): string | null; /** Tailwind-variant classes for the clickable control. */ get controlClasses(): string; /** The attached form control, if any. */ get control(): _angular_forms.AbstractControl | null; /** Whether to show control validation errors. */ get showError(): boolean; /** All control error messages (used when `showAllErrors` is true). */ get errorMessages(): string[]; /** Single control error message (priority-aware). */ get errorMessage(): string | null; ngOnInit(): void; /** * Writes a value from the form into the control. * @param val A `File`, an array of `File`, or null/undefined. */ writeValue(val: unknown): void; /** * Registers the form's change callback. * @param fn Callback invoked with the new value. */ registerOnChange(fn: (val: unknown) => void): void; /** * Registers the form's touched callback. * @param fn Callback invoked when the control is touched. */ registerOnTouched(fn: () => void): void; /** * Sets the disabled state of the control. * @param isDisabled Whether the control should be disabled. */ setDisabledState(isDisabled: boolean): void; /** * Handles a file-picker change: validates the incoming files against the * configured limits and updates the selection. * @param event The native change event from the hidden file input. */ onFileSelected(event: Event): void; /** * Arms the "release to drop" state when a file drag enters the dropzone. * @param event The native dragenter event. */ onDragEnter(event: DragEvent): void; /** * Keeps the drop target alive; without a prevented dragover the browser never * fires a drop event. * @param event The native dragover event. */ onDragOver(event: DragEvent): void; /** * Disarms the "release to drop" state once the drag has left the dropzone * entirely (and not merely crossed into one of its children). * @param event The native dragleave event. */ onDragLeave(event: DragEvent): void; /** * Accepts the dropped files through the same validation as the file picker. * @param event The native drop event. */ onDrop(event: DragEvent): void; /** * Removes a newly-selected file by index. * @param index Index into the current selection. */ removeFile(index: number): void; /** * Removes an already-saved image and notifies the consumer via `cleared`. * @param index Index of the existing image (0 in single mode). */ removeExisting(index: number): void; /** Whether the attached control carries a `required` validator. */ protected isRequired(): boolean; /** Stable track key for a display item across renders. */ protected itemKey(item: MnFileDisplayItem): string; /** Whether a file should render as an image. */ protected isImage(file: File): boolean; /** Callback to notify Angular forms of value changes. */ private onChange; /** Callback to notify Angular forms when the control is touched. */ private onTouched; /** Resolves UI strings from config, layering built-in defaults and prop overrides. */ private resolveConfig; /** * Validates and merges newly-picked files into the current selection. * @param incoming The files chosen by the user. */ private addFiles; /** Replaces the internal selection and rebuilds image previews. */ private setFiles; /** Emits the current value to the form and any listeners. */ private emit; /** Revokes any outstanding object-URL previews to avoid leaks. */ private revokeAll; /** Builds a display item for an already-saved image. */ private existingItem; /** Picks which control error key to display. */ private pickErrorKey; /** Resolves a control error key to a message, interpolating its args. */ private resolveControlError; /** * Resolves a message for an error key using the same precedence as the other * inputs: custom props > config > built-in > fallback > default. */ private resolveMessage; /** * Whether a drag event should be treated as a file drop on this control. * Ignores disabled controls, modes without a drop target, and drags that * carry something other than files (selected text, a link, …) so the page * keeps its default behaviour. */ private acceptsDrag; /** Clears the drag state and its nesting counter. */ private resetDrag; /** Checks a file against the configured `accept` filter (extensions and MIME globs). */ private matchesAccept; /** Formats a byte count as a human-readable size. */ private humanFileSize; /** Derives a display name from a URL (last path segment). */ private fileNameFromUrl; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare const mnSelectVariants: tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 text-base-content text-sm cursor-pointer hover:bg-base-200 transition-colors duration-300", { shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; }, undefined, tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 text-base-content text-sm cursor-pointer hover:bg-base-200 transition-colors duration-300", unknown, unknown, undefined>>; type MnSelectVariants = VariantProps; type MnSelectErrorMessageData = string | MnErrorMessageFn; type MnSelectErrorMessagesData = Partial>; type MnSelectOption = { /** Display label for the option */ label: string; /** Value associated with the option */ value: TValue; /** Whether the option is disabled */ disabled?: boolean; }; type MnSelectProps = { /** Unique identifier for the select element (required for accessibility) */ id: string; /** Name attribute for the select element (used in form submission) */ name?: string; /** Label text displayed above the select */ label?: string; /** Placeholder text shown when no option is selected */ placeholder?: string; /** Available options to select from */ options: MnSelectOption[]; /** * Whether to show a search/filter input at the top of the panel. When omitted, search * auto-enables once the number of options reaches `searchThreshold`, so long lists stay * filterable without every call site having to opt in. Set explicitly to force it on or off. */ searchable?: boolean; /** * Number of options at which the search input auto-enables (default: 8). * Ignored when `searchable` is set explicitly. */ searchThreshold?: number; /** Placeholder text for the search input */ searchPlaceholder?: string; /** * Whether the option panel renders as a bottom sheet on small screens (< 640px). * Defaults to true. Set to false to keep the trigger-anchored panel on mobile. * * The anchored panel sits at the trigger's bottom edge, which puts it directly in * the path of the soft keyboard as soon as the search input takes focus. The sheet * is anchored to the viewport instead, so the list stays reachable. */ mobileSheet?: boolean; /** Size variant of the select (default: 'md') */ size?: MnSelectVariants['size']; /** Border radius variant (default: 'md') */ borderRadius?: MnSelectVariants['borderRadius']; /** Shadow variant for the select */ shadow?: MnSelectVariants['shadow']; /** Whether the select should take full width of its container */ fullWidth?: MnSelectVariants['fullWidth']; /** Custom error messages mapped by validator error key */ errorMessages?: MnSelectErrorMessagesData; /** Fallback error message when no specific message is found for an error */ defaultErrorMessage?: string; /** Priority order for displaying errors when multiple validation errors exist */ errorPriority?: string[]; /** Whether to use built-in default error messages (default: true) */ useBuiltInErrorMessages?: boolean; /** ARIA label for screen readers (overrides uiConfig.ariaLabel when provided); use it when the select has no visible label, e.g. a table filter. */ ariaLabel?: string; /** Whether to display all validation errors or just the first/priority error (default: false) */ showAllErrors?: boolean; }; type MnSelectUIConfig = { /** Label text displayed above the select */ label?: string; /** Placeholder text shown when no option is selected */ placeholder?: string; /** ARIA label for screen readers (falls back to label if not provided) */ ariaLabel?: string; /** * Error messages resolved from config (supports $translate markers). * These override built-in error messages but are overridden by props.errorMessages. */ errorMessages?: Record; /** Text shown when no options match the search filter */ noOptionsFound?: string; /** Placeholder and accessible name for the dropdown's search input */ searchPlaceholder?: string; }; declare const MN_SELECT_CONFIG: InjectionToken; /** * A single-value picker. The trigger opens a `role="listbox"` of {@link MnSelectOption}s; * choosing one sets the value and closes — this is the value-picker twin of the ⋯ * command menu mn-dropdown, so it *is* a ControlValueAccessor. * * Presentation mirrors mn-multi-select: one custom field trigger at every size, an * anchored popover on desktop and the shared {@link MnBottomSheet} on mobile (< 640px) — * the same sheet mn-dropdown itself wraps. Both the popover and the sheet host are * portalled to `document.body` so their `position: fixed` anchors to the viewport rather * than any transformed/filtered ancestor (a table cell, a card) — the same root-cause fix * the multi-select applies. */ declare class MnSelect implements OnInit { /** Lucide icons the template renders. */ protected readonly icons: Record<"Check" | "ChevronDown", _lucide_angular.LucideIconData>; ngControl: NgControl | null; props: MnSelectProps; /** Currently selected value */ selectedValue: unknown; isOpen: boolean; isDisabled: boolean; searchTerm: string; /** * Position in `filteredOptions` of the option the keyboard is on, or -1 for none. Reset when the * list it indexes changes (a search) or goes away (close), so it never points at a stale row. */ activeIndex: number; protected uiConfig: MnSelectUIConfig; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; private readonly elRef; private readonly lang; private readonly destroyRef; private readonly renderer; private readonly cdr; private readonly injector; /** Lucide data for the trailing check shown on the selected row. */ protected readonly checkIcon: _lucide_angular.LucideIconData; /** Reference to the trigger element for positioning the dropdown. */ triggerRef: ElementRef; /** Layout classes for the anchored popover panel. The mobile sheet is rendered by * mn-bottom-sheet instead, so it no longer needs a branch here. */ readonly panelClasses = "fixed z-9999 w-max bg-base-100 border border-base-300 rounded-md shadow-lg max-h-60 overflow-auto"; /** The panel's own height cap in pixels: the `max-h-60` above, restated for the placement maths. */ static readonly PANEL_MAX_HEIGHT_PX = 240; /** Space kept between a widened panel and the viewport's right edge. */ static readonly PANEL_EDGE_GAP_PX = 8; /** Layout classes for the invisible click shield rendered under the anchored panel. * One step below the panel's z-index so the panel itself stays clickable, and above * any modal/drawer chrome (which tops out well under 9998). */ readonly shieldClasses = "fixed inset-0 z-9998"; /** Option count at which the search input auto-enables when `searchable` is unset. */ private static readonly DEFAULT_SEARCH_THRESHOLD; /** Tailwind's `sm` breakpoint — below this the panel renders as a bottom sheet. * Kept in step with the same constant in mn-bottom-sheet / mn-multi-select. */ private static readonly SHEET_MAX_WIDTH; /** The anchored popover panel currently moved into `document.body`, if any. */ private movedPanel; /** The click shield currently moved into `document.body`, if any. */ private movedShield; /** The bottom-sheet host, for outside-click tests. The sheet owns its own placement. */ private sheetHost; /** Whether the viewport is currently narrow enough for the sheet layout. */ private isNarrowViewport; /** Live breakpoint match, so rotating the device re-evaluates the layout. */ private sheetMedia; /** The listener registered on `sheetMedia`, retained for teardown. */ private sheetMediaListener; /** `document.body`'s inline `overflow` before the sheet locked it, restored on close. */ private previousBodyOverflow; /** * The sheet's height (px) captured the moment it opened, before any search. Re-applied * as a `min-height` floor so filtering the option list shorter cannot shrink the sheet * mid-type. Null while anchored or closed, so the popover and desktop path are untouched. */ sheetFloorPx: number | null; /** * Watches the trigger while the panel is open. The panel lives in `document.body`, so it * survives its own trigger being hidden by an ancestor — a wizard step or a tab switched * away with `display: none`. When the trigger stops being visible the panel goes with it. */ private visibilityObserver; /** * Capture-phase scroll listener installed while open. `window:scroll` only fires for the * document scroller, so scrolling an inner container (a modal body, a scrollable card) * would otherwise leave the portalled panel floating at its stale coordinates. */ private scrollCapture; /** Dropdown position calculated from the trigger's bounding rect. */ /** Inline placement of the anchored panel; `maxHeight` only binds when the viewport is the tighter cap. */ dropdownStyle: { top: string; bottom: string; left: string; minWidth: string; maxWidth: string; maxHeight: string | null; }; private onChange; private onTouched; private readonly builtInErrorMessages; constructor(); /** * The dropdown panel element, queried while it is rendered by the `@if` block. The setter * relocates the panel to `document.body` so that its `position: fixed` coordinates resolve * against the viewport rather than any transformed/filtered ancestor (which would otherwise * become the containing block and push the panel to the middle of the screen — also broken * on iOS). Cleanup is handled when the query clears on close/destroy. */ set dropdownRef(ref: ElementRef | undefined); /** * The click shield sitting under the anchored panel, portalled alongside it for the same * reason: `position: fixed` must resolve against the viewport, not a transformed ancestor. */ set shieldRef(ref: ElementRef | undefined); /** * The bottom-sheet host, kept as a reference for outside-click tests. The sheet relocates * itself to `document.body`, so nothing is moved here. On open its container height is * captured as the sheet's `min-height` floor. */ set sheetRef(ref: ElementRef | undefined); get control(): _angular_forms.AbstractControl | null; get selectedOption(): MnSelectOption | undefined; /** The label shown in the trigger: the selected option, else the placeholder. */ get displayText(): string; /** Trigger text shown while no option is selected. */ get placeholderLabel(): string; /** Placeholder and accessible name of the dropdown's search input. */ get searchPlaceholderLabel(): string; /** Empty text shown when the search filters every option away. */ get noOptionsLabel(): string; /** * Resolves one of the component's own labels, preferring what the caller gave it * and falling back through the config layer, a conventional translation key and * finally a readable English default. * * Mirrors `MnCollectionBase.resolveLabel` and its twin in `MnMultiSelect`. Without * the key step a consumer could only translate these by repeating the same literal * at every call site, and the search box in particular auto-enables on option * count — it appears without anyone asking for it, so it must be translatable * without anyone asking either. * * @param explicit The label the caller passed through `props`, if any. * @param key The conventional translation key to try next. * @param fallback The English text used when neither resolves. * @param configured The value the config layer resolved, if any. * @returns The resolved label. */ private resolveLabel; get showError(): boolean; get errorMessages(): string[]; get errorMessage(): string | null; get resolvedId(): string; get resolvedName(): string | null; get triggerClasses(): string; /** Whether the panel should currently render as a bottom sheet. */ get isSheet(): boolean; /** * Whether the search input is shown: the explicit `searchable` prop when set, otherwise * auto-enabled once the option count reaches the threshold. */ get isSearchable(): boolean; get filteredOptions(): MnSelectOption[]; ngOnInit(): void; writeValue(val: unknown): void; registerOnChange(fn: (val: unknown) => void): void; registerOnTouched(fn: () => void): void; setDisabledState(isDisabled: boolean): void; toggle(): void; /** Selects an option, notifies the form and closes — a single choice ends the interaction. */ selectOption(option: MnSelectOption): void; isSelected(option: MnSelectOption): boolean; /** Filters the options; the first match is highlighted so Enter picks it, none once the box is cleared. */ onSearch(term: string | null): void; /** Id of the keyboard-highlighted option, for `aria-activedescendant`; null when none is. */ get activeOptionId(): string | null; /** * The DOM id of the option rendered at a position in `filteredOptions`. * @param index - The option's position. * @returns The id, unique per select. */ optionId(index: number): string; /** * Keyboard handling for the trigger and the search box, the WAI-ARIA combobox pattern. While * closed, ArrowDown, ArrowUp, Enter and Space open the list with an option highlighted. While * open, the arrows move the highlight past disabled options without wrapping, Home and End jump * to the ends, Enter (and Space outside the search box) chooses the highlighted option and returns focus to the trigger, Escape closes and Tab closes and lets focus move on. Enter and Space * stop here, so they can never submit a surrounding form or close a surrounding modal. * @param event - The keydown. * @param fromSearch - True when it came from the search box, where Space, Home and End edit text. */ onKeydown(event: KeyboardEvent, fromSearch?: boolean): void; /** * Moves the highlight one enabled option from `from` and scrolls it into view. * @param from - Where to step from; -1 to start at an end. * @param step - 1 for down, -1 for up. */ private moveActive; /** * Chooses the highlighted option (or just closes when none is) and hands focus back to the trigger, * because the search box that may hold it is removed with the panel. * @param event - The Enter or Space keydown, claimed so a form around the select is not submitted. */ private chooseActive; /** Scrolls the highlighted option into view once the render that paints its ring has run. */ private revealActiveOption; /** Puts focus back on the trigger. */ private focusTrigger; /** * The single close path. Every trigger (outside click, Escape, scroll, resize, the trigger * being hidden, a choice) funnels through here so the open-only listeners are always torn * down with the panel and never leak. */ close(): void; handleBlur(): void; /** * Dismisses the anchored panel from a shield click, and stops the event there. * * Swallowing it is the point: the shield spans the viewport, so the click would otherwise * land on whatever the panel was floating over. Inside a modal that is the modal's own * backdrop, and "close the dropdown" would double as "throw away the modal". A first click * that only dismisses the overlay is also how native selects and menus behave. */ onShieldClick(event: Event): void; onDocumentClick(event: Event): void; /** Closes the dropdown on Escape for keyboard accessibility. */ onEscape(): void; /** * Closes the dropdown when the page or a scrollable parent is scrolled. * * Skipped for a sheet: it is anchored to the viewport, not to the trigger, so it has no * stale position to escape. Crucially, opening the soft keyboard fires a `resize` on * Android — closing on that would dismiss the sheet the instant search is focused. A * genuine layout switch is handled by the `matchMedia` listener instead. */ onWindowScrollOrResize(): void; protected isRequired(): boolean; /** * Tracks the sheet breakpoint through `matchMedia` rather than reading `innerWidth` once, * so rotating the device switches layout instead of leaving a panel positioned for the * previous orientation. An open panel is closed on the switch — its anchored coordinates * and its sheet layout are not interchangeable. */ private startWatchingViewport; /** Tears down the breakpoint listener. Idempotent. */ private stopWatchingViewport; /** * Freezes the page behind an open sheet. The previous inline value is captured and restored * verbatim so a surrounding modal that set its own lock is left intact. */ private lockBodyScroll; /** Restores the pre-lock `overflow`. Idempotent. */ private unlockBodyScroll; /** * Calculates the fixed position for the dropdown based on the trigger element: below it * while the viewport has room, above it otherwise, never past the viewport's edge. * The panel is never narrower than the trigger but grows to its widest option, so a compact * trigger (the collection page-size picker) cannot squeeze the selected row's check mark * over its label. It stops at the viewport's right edge, where long labels truncate. */ private updateDropdownPosition; /** * Starts the open-only watchers: an `IntersectionObserver` on the trigger (closes the panel * as soon as the trigger stops being rendered/visible) and a capture-phase `scroll` listener * (closes it when any ancestor scroller moves under it). Scrolls that originate inside the * panel's own option list are ignored. */ private startWatchingTrigger; /** Tears down the watchers installed by `startWatchingTrigger`. Idempotent. */ private stopWatchingTrigger; /** * Records the sheet's opened height as its `min-height` floor. Measured on the next frame * so the read reflects the fully-rendered, unfiltered list (the search box is empty on * open) and never forces a reflow mid change-detection. The floor equals the content height * at that instant, so applying it triggers no resize — it only stops a later, shorter * filtered list from pulling the sheet down. * * `hostEl` is the portalled mn-bottom-sheet host (`display: contents`), so the height is * read from its `.mn-sheet-container` child rather than the host itself. */ private captureSheetFloor; /** * Move an overlay element to `document.body` when it appears, and detach it when the query * clears. Appending to the body root makes the element immune to ancestor * `transform`/`filter`/`will-change`, so `position: fixed` anchors to the viewport — without * this the panel lands mid-screen (and breaks outright on iOS). * * Returns the element now portalled, so the caller can store it. Idempotent and safe to * call with `null`. */ private portal; private resolveConfig; private pickErrorKey; private resolveErrorMessageForKey; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } declare const mnMultiSelectVariants: tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 text-base-content text-sm cursor-pointer", { shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; }, undefined, tailwind_variants.TVReturnType<{ shadow: { true: string; }; size: { sm: string; md: string; lg: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; two_xl: string; three_xl: string; four_xl: string; }; fullWidth: { true: string; }; }, undefined, "bg-base-100 border-1 border-base-300 text-base-content text-sm cursor-pointer", unknown, unknown, undefined>>; type MnMultiSelectVariants = VariantProps; type MnMultiSelectErrorMessageData = string | MnErrorMessageFn; type MnMultiSelectErrorMessagesData = Partial>; type MnMultiSelectOption = { /** Display label for the option */ label: string; /** Value associated with the option */ value: TValue; /** Whether the option is disabled */ disabled?: boolean; }; type MnMultiSelectProps = { /** Unique identifier for the multi-select element (required for accessibility) */ id: string; /** Name attribute for the multi-select element (used in form submission) */ name?: string; /** Label text displayed above the multi-select */ label?: string; /** Placeholder text shown when no options are selected */ placeholder?: string; /** Available options to select from */ options: MnMultiSelectOption[]; /** * Whether to show a search/filter input. When omitted, search auto-enables once the * number of options reaches `searchThreshold`, so long lists stay filterable without * every call site having to opt in. Set explicitly to force it on or off. */ searchable?: boolean; /** * Number of options at which the search input auto-enables (default: 8). * Ignored when `searchable` is set explicitly. */ searchThreshold?: number; /** Placeholder text for the search input */ searchPlaceholder?: string; /** * Whether the dropdown renders as a bottom sheet on small screens (< 640px). * Defaults to true. Set to false to keep the trigger-anchored panel on mobile. * * The anchored panel sits at the trigger's bottom edge, which puts it directly in * the path of the soft keyboard as soon as the search input takes focus. The sheet * is anchored to the viewport instead, so the list stays reachable. */ mobileSheet?: boolean; /** Maximum number of items that can be selected (undefined = unlimited) */ maxSelections?: number; /** * Once the number of selected options is strictly greater than this value, the * trigger collapses to a single count summary instead of rendering every chip. * Opt-in: collapsing is active when this or `collapsePlaceholder` is set. When * collapsing is enabled but this is omitted, the effective threshold defaults to 5. */ collapseThreshold?: number; /** * Summary text shown when the trigger is collapsed. The `{count}` token is * replaced with the number of selected options (e.g. `"{count} selected"` → * `"18 selected"`). Setting this enables collapsing on its own; when omitted * while collapsing is active, `"{count} selected"` is used as the fallback. */ collapsePlaceholder?: string; /** * Summary text shown when **every** option is selected, in place of the count summary. * * "Everything" is a meaningful state at any option count, so setting this collapses the * trigger as soon as the full set is selected regardless of `collapseThreshold` — without * it, a three-option select could never say so under the default threshold of 5. * * Setting this enables collapsing on its own. The `{count}` token is replaced the same way * it is in `collapsePlaceholder`. Ignored while the select has no options at all, where * "all of them" would be a claim about nothing. */ allSelectedPlaceholder?: string; /** Size variant of the multi-select (default: 'md') */ size?: MnMultiSelectVariants['size']; /** Border radius variant (default: 'md') */ borderRadius?: MnMultiSelectVariants['borderRadius']; /** Shadow variant for the multi-select */ shadow?: MnMultiSelectVariants['shadow']; /** Whether the multi-select should take full width of its container */ fullWidth?: MnMultiSelectVariants['fullWidth']; /** Custom error messages mapped by validator error key */ errorMessages?: MnMultiSelectErrorMessagesData; /** Fallback error message when no specific message is found for an error */ defaultErrorMessage?: string; /** Priority order for displaying errors when multiple validation errors exist */ errorPriority?: string[]; /** Whether to use built-in default error messages (default: true) */ useBuiltInErrorMessages?: boolean; /** ARIA label for screen readers (overrides uiConfig.ariaLabel when provided); use it when the control has no visible label, e.g. a table filter. */ ariaLabel?: string; /** Whether to display all validation errors or just the first/priority error (default: false) */ showAllErrors?: boolean; }; type MnMultiSelectUIConfig = { /** Label text displayed above the multi-select */ label?: string; /** Placeholder text shown when no options are selected */ placeholder?: string; /** ARIA label for screen readers (falls back to label if not provided) */ ariaLabel?: string; /** * Error messages resolved from config (supports $translate markers). * These override built-in error messages but are overridden by props.errorMessages. */ errorMessages?: Record; /** Text shown when no options match the search filter */ noOptionsFound?: string; /** Placeholder and accessible name for the dropdown's search input */ searchPlaceholder?: string; }; declare const MN_MULTI_SELECT_CONFIG: InjectionToken; declare class MnMultiSelect implements OnInit { /** Lucide icons the template renders. */ protected readonly icons: Record<"X" | "ChevronDown", _lucide_angular.LucideIconData>; ngControl: NgControl | null; protected uiConfig: MnMultiSelectUIConfig; props: MnMultiSelectProps; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; private readonly elRef; private readonly lang; private readonly destroyRef; private readonly renderer; private readonly cdr; /** Injector for the after-render scroll of the highlighted option. */ private readonly injector; /** Reference to the trigger element for positioning the dropdown */ triggerRef: ElementRef; /** Layout classes for the anchored popover panel. The mobile sheet is rendered by * mn-bottom-sheet instead, so it no longer needs a branch here. */ readonly panelClasses = "fixed z-9999 bg-base-100 border border-base-300 rounded-md shadow-lg max-h-60 overflow-auto"; /** The panel's own height cap in pixels: the `max-h-60` above, restated for the placement maths. */ static readonly PANEL_MAX_HEIGHT_PX = 240; /** Layout classes for the invisible click shield rendered under the anchored panel. * One step below the panel's z-index so the panel itself stays clickable, and above * any modal/drawer chrome (which tops out well under 9998). */ readonly shieldClasses = "fixed inset-0 z-9998"; /** The anchored popover panel currently moved into `document.body`, if any. */ private movedPanel; /** The click shield currently moved into `document.body`, if any. */ private movedShield; /** Option count at which the search input auto-enables when `searchable` is unset. */ private static readonly DEFAULT_SEARCH_THRESHOLD; /** Tailwind's `sm` breakpoint — below this the panel renders as a bottom sheet. * Kept in step with the same constant in `MnModalShellComponent`. */ private static readonly SHEET_MAX_WIDTH; /** Whether the viewport is currently narrow enough for the sheet layout. */ private isNarrowViewport; /** Live breakpoint match, so rotating the device re-evaluates the layout. */ private sheetMedia; /** The listener registered on `sheetMedia`, retained for teardown. */ private sheetMediaListener; /** `document.body`'s inline `overflow` before the sheet locked it, restored on close. */ private previousBodyOverflow; /** * The sheet's height (px) captured the moment it opened, before any search. Re-applied * as a `min-height` floor so filtering the option list shorter cannot shrink the sheet * mid-type. Null while anchored or closed, so the popover and desktop path are untouched. */ sheetFloorPx: number | null; /** * Watches the trigger while the panel is open. The panel lives in `document.body`, * so it survives its own trigger being hidden by an ancestor — e.g. a wizard step * or a tab that is switched away with `display: none` instead of being destroyed. * When the trigger stops being visible the panel must go with it. */ private visibilityObserver; /** * Capture-phase scroll listener installed while open. `window:scroll` only fires for * the document scroller, so scrolling an inner container (a modal body, a scrollable * card) used to leave the portalled panel floating at its stale coordinates. */ private scrollCapture; /** The bottom-sheet host, for outside-click tests. The sheet owns its own placement. */ private sheetHost; /** * The dropdown panel element, queried while it is rendered by the `@if` block. * The setter relocates the panel to `document.body` so that its `position: fixed` * coordinates resolve against the viewport rather than any transformed/filtered * ancestor (which would otherwise become the containing block and push the panel * to the middle of the screen — the root cause of the mis-positioning bug, also * broken on iOS). Cleanup is handled when the query clears on close/destroy. */ set dropdownRef(ref: ElementRef | undefined); /** * The click shield sitting under the anchored panel, portalled alongside it for the same * reason: `position: fixed` must resolve against the viewport, not a transformed ancestor. */ set shieldRef(ref: ElementRef | undefined); /** Currently selected values */ selectedValues: unknown[]; isOpen: boolean; isDisabled: boolean; searchTerm: string; /** * Position in `filteredOptions` of the option the keyboard is on, or -1 for none. Reset when the * list it indexes changes (a search) or goes away (close), so it never points at a stale row. */ activeIndex: number; /** Dropdown position calculated from trigger bounding rect */ /** Inline placement of the anchored panel; `maxHeight` only binds when the viewport is the tighter cap. */ dropdownStyle: { top: string; bottom: string; left: string; width: string; maxHeight: string | null; }; private onChange; private onTouched; private readonly builtInErrorMessages; constructor(); /** * The bottom-sheet host, kept as a reference for outside-click tests. The sheet * relocates itself to `document.body`, so nothing is moved here. On open its * container height is captured as the sheet's `min-height` floor. */ set sheetRef(ref: ElementRef | undefined); /** * Tracks the sheet breakpoint through `matchMedia` rather than reading `innerWidth` * once, so rotating the device switches layout instead of leaving a panel positioned * for the previous orientation. An open panel is closed on the switch — its anchored * coordinates and its sheet layout are not interchangeable. */ private startWatchingViewport; /** Tears down the breakpoint listener. Idempotent. */ private stopWatchingViewport; ngOnInit(): void; private resolveConfig; writeValue(val: unknown): void; registerOnChange(fn: (val: unknown) => void): void; registerOnTouched(fn: () => void): void; setDisabledState(isDisabled: boolean): void; toggle(): void; /** Whether the panel should currently render as a bottom sheet. */ get isSheet(): boolean; /** * Whether the search input is shown: the explicit `searchable` prop when set, * otherwise auto-enabled once the option count reaches the threshold. */ get isSearchable(): boolean; /** * Dismisses the anchored panel from a shield click, and stops the event there. * * Swallowing it is the point: the shield spans the viewport, so the click would otherwise * land on whatever the panel was floating over. Inside a modal that is the modal's own * backdrop, and "close the dropdown" would double as "throw away the modal". A first click * that only dismisses the overlay is also how native selects and menus behave. */ onShieldClick(event: Event): void; onDocumentClick(event: Event): void; /** * Records the sheet's opened height as its `min-height` floor. Measured on the next * frame so the read reflects the fully-rendered, unfiltered list (the search box is * empty on open) and never forces a reflow mid change-detection. The floor equals the * content height at that instant, so applying it triggers no resize — it only stops a * later, shorter filtered list from pulling the sheet down. * * `hostEl` is the portalled mn-bottom-sheet host (`display: contents`), so the height * is read from its `.mn-sheet-container` child rather than the host itself. */ private captureSheetFloor; /** Closes the dropdown on Escape for keyboard accessibility. */ onEscape(): void; /** * Closes the dropdown when the page or a scrollable parent is scrolled. * * Skipped for a sheet: it is anchored to the viewport, not to the trigger, so it has * no stale position to escape. Crucially, opening the soft keyboard fires a `resize` * on Android — closing on that would dismiss the sheet the instant search is focused. * A genuine layout switch is handled by the `matchMedia` listener instead. */ onWindowScrollOrResize(): void; /** * The single close path. Every trigger (outside click, Escape, scroll, resize, the * trigger being hidden) funnels through here so the open-only listeners are always * torn down with the panel and never leak. */ close(): void; /** * Freezes the page behind an open sheet. The previous inline value is captured and * restored verbatim so a surrounding modal that set its own lock is left intact. */ private lockBodyScroll; /** Restores the pre-lock `overflow`. Idempotent. */ private unlockBodyScroll; /** * Calculates the fixed position for the dropdown based on the trigger element: below it * while the viewport has room, above it otherwise, never past the viewport's edge. */ private updateDropdownPosition; /** * Starts the open-only watchers: an `IntersectionObserver` on the trigger (closes the * panel as soon as the trigger stops being rendered/visible) and a capture-phase * `scroll` listener (closes it when any ancestor scroller moves under it). Scrolls * that originate inside the panel's own option list are ignored. */ private startWatchingTrigger; /** * Move an overlay element to `document.body` when it appears, and detach it when the * query clears. Appending to the body root makes the element immune to ancestor * `transform`/`filter`/`will-change`, so `position: fixed` anchors to the viewport — * without this the panel lands mid-screen (and breaks outright on iOS). * * Returns the element now portalled, so the caller can store it. Idempotent and safe * to call with `null`. */ private portal; /** Tears down the watchers installed by `startWatchingTrigger`. Idempotent. */ private stopWatchingTrigger; toggleOption(option: MnMultiSelectOption): void; removeOption(option: MnMultiSelectOption, event: Event): void; isSelected(option: MnMultiSelectOption): boolean; isMaxReached(option: MnMultiSelectOption): boolean; /** Filters the options; the first match is highlighted so Enter toggles it, none once the box is cleared. */ onSearch(term: string): void; /** * Whether the keyboard may highlight an option: not disabled, and not blocked by `maxSelections`. * An arrow function so it can be handed to `stepEnabledIndex` as it is. */ private readonly isChoosable; /** Id of the keyboard-highlighted option, for `aria-activedescendant`; null when none is. */ get activeOptionId(): string | null; /** * The DOM id of the option rendered at a position in `filteredOptions`. * @param index - The option's position. * @returns The id, unique per multi-select. */ optionId(index: number): string; /** * Keyboard handling for the trigger and the search box, the WAI-ARIA combobox pattern. While * closed, ArrowDown, ArrowUp, Enter and Space open the list with an option highlighted. While * open, the arrows move the highlight past disabled options without wrapping, Home and End jump * to the ends, Enter (and Space outside the search box) toggles the highlighted option and keeps the list open for the next one, Escape closes and Tab closes and lets focus move on. Enter and Space * stop here, so they can never submit a surrounding form or close a surrounding modal. * @param event - The keydown. * @param fromSearch - True when it came from the search box, where Space, Home and End edit text. */ onKeydown(event: KeyboardEvent, fromSearch?: boolean): void; /** * Moves the highlight one enabled option from `from` and scrolls it into view. * @param from - Where to step from; -1 to start at an end. * @param step - 1 for down, -1 for up. */ private moveActive; /** * Toggles the highlighted option. The list stays open, as it does for a click, so several options * can be picked in a row. * @param event - The Enter or Space keydown, claimed so a form around the field is not submitted. */ private toggleActive; /** * Takes a key for the field: no default action (no scroll, no form submit) and no bubbling to a * surrounding modal's own Enter or Escape handling. * @param event - The keydown to claim. */ private claim; /** Scrolls the highlighted option into view once the render that paints its ring has run. */ private revealActiveOption; /** Puts focus back on the trigger. */ private focusTrigger; get filteredOptions(): MnMultiSelectOption[]; get selectedOptions(): MnMultiSelectOption[]; /** * Whether the collapse-to-summary feature is opted into. Active when any of * `collapsePlaceholder`, `collapseThreshold` or `allSelectedPlaceholder` is * supplied; existing usages with none of them are unaffected. */ get collapseEnabled(): boolean; /** * Whether every available option is currently selected. False for an empty select, where * "all of them" would be a claim about nothing. */ get allSelected(): boolean; /** * The threshold above which the trigger collapses. Defaults to 5 when collapsing * is enabled via `collapsePlaceholder` alone (no explicit `collapseThreshold`). */ get effectiveCollapseThreshold(): number; /** * Whether the trigger should currently render a summary instead of the individual * chips: when the number of selected options exceeds the effective threshold, or * when every option is selected and a summary for that case was supplied. */ get isCollapsed(): boolean; /** * The summary text shown while collapsed, with the `{count}` token replaced by * the number of selected options. `allSelectedPlaceholder` wins while everything * is selected, then `collapsePlaceholder`, then `"{count} selected"`. */ get collapseSummaryText(): string; /** Trigger text shown while nothing is selected. */ get placeholderLabel(): string; /** * Placeholder and accessible name of the dropdown's search input. * * Search auto-enables at `searchThreshold` options, so this box appears without any * call site opting in — which is exactly why it must be translatable without one. */ get searchPlaceholderLabel(): string; /** Empty text shown when the search filters every option away. */ get noOptionsLabel(): string; /** * Resolves one of the component's own labels, preferring what the caller gave it * and falling back through the config layer, a conventional translation key and * finally a readable English default. * * Mirrors `MnCollectionBase.resolveLabel`. Every string this component puts on * screen that is not caller data goes through here: without the key step a * consumer could only translate these by repeating the same literal at every call * site, which is how "Search..." ends up in English on an otherwise Dutch page. * * @param explicit The label the caller passed through `props`, if any. * @param key The conventional translation key to try next. * @param fallback The English text used when neither resolves. * @param configured The value the config layer resolved, if any. * @returns The resolved label. */ private resolveLabel; handleBlur(): void; get control(): _angular_forms.AbstractControl | null; get showError(): boolean; private pickErrorKey; protected isRequired(): boolean; private resolveErrorMessageForKey; get errorMessages(): string[]; get errorMessage(): string | null; get resolvedId(): string; get resolvedName(): string | null; get triggerClasses(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } /** * Layout variants for the trigger button. An icon-only trigger (the default ⋯) is a * square affordance; a trigger with a text label grows to fit its content with * horizontal padding instead. The `labeled` axis switches between the two. */ declare const mnDropdownTriggerVariants: tailwind_variants.TVReturnType<{ size: { sm: string; md: string; lg: string; }; labeled: { true: string; false: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; full: string; }; }, undefined, "inline-flex items-center justify-center gap-x-1.5 text-base-content/80 cursor-pointer", { size: { sm: string; md: string; lg: string; }; labeled: { true: string; false: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; full: string; }; }, undefined, tailwind_variants.TVReturnType<{ size: { sm: string; md: string; lg: string; }; labeled: { true: string; false: string; }; borderRadius: { none: string; xs: string; sm: string; md: string; lg: string; xl: string; full: string; }; }, undefined, "inline-flex items-center justify-center gap-x-1.5 text-base-content/80 cursor-pointer", unknown, unknown, undefined>>; type MnDropdownTriggerVariants = VariantProps; /** * The leading icon of a command — either a `TemplateRef` (full control over the icon * set: an ``, an emoji, a bespoke ``) or lucide icon *data*, i.e. a * lucide icon's static `.icon` (e.g. `LucidePencil.icon`), which the component renders * itself at the right size for its slot. * * The data form exists so an action can be declared in plain TypeScript — a shared * action factory, a config array, a service — without the host component having to * carry an `` stub and a `@ViewChild` for every glyph. Same convention as * {@link MnCollectionDataSource.emptyIcon}. */ type MnActionIcon = TemplateRef | LucideIconData; /** Theme colour tokens an action item can be tinted with, mirroring mn-button's palette. */ type MnDropdownActionColor = 'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'accent' | 'gray'; /** * A single command in a {@link MnDropdownProps} menu. Unlike a select option it holds * no value — choosing it fires {@link run} and closes the menu. This is a *command* * menu, not a value picker, which is why mn-dropdown is not a ControlValueAccessor. */ type MnDropdownAction = { /** Visible label. Falls back to `labelKey`'s resolved text when omitted. */ label?: string; /** * Translation key for the label, resolved via MnLanguageService and kept updated on * locale change. Takes precedence over {@link label} when it resolves to a value. */ labelKey?: string; /** * Optional leading icon: a template, so the consumer keeps full control over which * icon set is used (an ``, an emoji…), or lucide icon data such as * `LucidePencil.icon` for a template-free declaration. See {@link MnActionIcon}. */ icon?: MnActionIcon; /** Invoked when the item is chosen. The menu closes immediately afterwards. */ run: () => void; /** When true the item is shown dimmed and cannot be chosen. */ disabled?: boolean; /** * Marks this item as the current choice — e.g. the active language in a language * picker. Display-only: the item still {@link run}s and closes on choice like any * other, but it renders highlighted with a trailing check so the user can see which * one is selected without reading. The caller owns the flag (there is no single * source of truth inside this command menu, which holds no value); typically at most * one action carries it, though the component does not enforce that. */ active?: boolean; /** * Tints the item's label and icon. When omitted the item uses the default foreground * ({@link danger} still forces the destructive red). Lets a host carry a per-item * colour — e.g. an mn-table actions column keeps the same colours it shows inline. */ color?: MnDropdownActionColor; /** Renders the item in a destructive style (e.g. a "Delete" action). Shorthand for * the red foreground; equivalent to `color: 'danger'`. */ danger?: boolean; /** * Extra text the search filter matches against, beyond the visible label — a summary, * synonyms, a category. Only consulted when the menu is {@link MnDropdownProps.searchable}. * Lets search find a command by more than its label, e.g. a help search that matches a * topic's title *and* its summary. */ keywords?: string; }; /** * A divider between commands, rendered as an `
`. Group related actions — e.g. a * destructive "Logout" set off from a profile menu's navigation, or a name header above * its items. Non-interactive: it is skipped by keyboard nav and hidden while a * {@link MnDropdownProps.searchable} filter is active (a divider stranded between hidden * results is meaningless). */ type MnDropdownSeparator = { separator: true; }; /** An entry in a {@link MnDropdownProps.actions} list: a command or a {@link MnDropdownSeparator}. */ type MnDropdownItem = MnDropdownAction | MnDropdownSeparator; /** * Configuration for {@link MnDropdown}, passed through its single `datasource` input. * (The type keeps the `Props` name; only the input binding is `datasource`.) */ type MnDropdownProps = { /** * Unique identifier for the trigger/menu accessibility wiring. Optional — a stable one is * generated when omitted, so the leanest dropdown is just `{ actions: [...] }`. Set it * explicitly only to target this instance from {@link MnConfigService} `#id` overrides. */ id?: string; /** The commands rendered in the menu, in order. May include {@link MnDropdownSeparator} * entries (`{ separator: true }`) to divide the list into groups. */ actions: MnDropdownItem[]; /** * Text shown inside the trigger button, turning the ⋯ icon into a labelled control * (e.g. "Actions"). When set, {@link triggerIcon} defaults to a trailing chevron * instead of the dots. Omit for the icon-only ⋯ trigger. */ triggerLabel?: string; /** Translation key for {@link triggerLabel}. Resolved via MnLanguageService. */ triggerLabelKey?: string; /** * Which glyph the trigger shows. Defaults to `'dots-vertical'` (⋮) for an icon-only * trigger, or `'chevron'` (▾) when a {@link triggerLabel} is set. Use `'none'` for a * text-only trigger. * * Beyond the three built-in glyphs, this also accepts a custom {@link MnActionIcon} — a * `TemplateRef` (full control: an ``, an emoji, a bespoke ``) or lucide * icon *data* such as `LucideFilter.icon`, rendered by the component at trigger size. * The same convention the per-item {@link MnDropdownAction.icon} uses. (For a horizontal * ellipsis ⋯, pass `LucideEllipsis.icon` here.) */ triggerIcon?: 'dots-vertical' | 'chevron' | 'none' | MnActionIcon; /** * Styles the trigger as a full {@link MnButtonTypes} button instead of the default ghost * ⋯ affordance — `variant`, `color`, `size`, `borderRadius`, `shape`, etc. Merged over * the default `{ size: 'sm', variant: 'text', color: 'gray' }`, so a partial config only * changes what you name (e.g. `{ variant: 'fill', color: 'primary' }` for a solid button). * * When set, mn-button owns the trigger's look entirely: the trigger's own {@link size} * and {@link borderRadius} props no longer apply (use this config's), and mn-button's * `borderRadius` default (`lg`) takes over. Composes with {@link triggerIcon} and * {@link triggerLabel} — the glyph/label render inside the styled button. For a square * icon-only button, set `shape: 'square'` (or `'circle'`) here; otherwise a filled * icon-only trigger is a small padded box rather than a fixed square. */ triggerButton?: Partial; /** Accessible label for the trigger button. Falls back to a translated default. * Ignored for name purposes when {@link triggerLabel} provides visible text. */ ariaLabel?: string; /** Translation key for {@link ariaLabel}. Resolved via MnLanguageService. */ ariaLabelKey?: string; /** * Heading shown above the items — on mobile the sheet covers its own trigger, so a * title tells the user what the menu belongs to. Optional on desktop. */ menuLabel?: string; /** Translation key for {@link menuLabel}. Resolved via MnLanguageService. */ menuLabelKey?: string; /** * Whether the menu renders as a bottom sheet on small screens (< 640px). Defaults * to true; set false to keep the trigger-anchored popover on mobile too. */ mobileSheet?: boolean; /** * Shows a filter input at the top of the menu (and the mobile sheet), narrowing the * actions as the user types. Each action matches on its resolved label and its * {@link MnDropdownAction.keywords}, case-insensitively. On desktop the input is * focused on open; pressing Enter runs the first still-visible, enabled action — * mirroring a help search that opens the top hit. Defaults to false. */ searchable?: boolean; /** Placeholder for the search input. Falls back to a translated default ("Search..."). */ searchPlaceholder?: string; /** Translation key for {@link searchPlaceholder}. Resolved via MnLanguageService. */ searchPlaceholderKey?: string; /** Text shown in place of the list when the filter matches no actions. Falls back to * a translated default ("No results"). */ searchEmptyLabel?: string; /** Translation key for {@link searchEmptyLabel}. Resolved via MnLanguageService. */ searchEmptyLabelKey?: string; /** Size variant of the ⋯ trigger (default: 'md'). */ size?: MnDropdownTriggerVariants['size']; /** Border-radius variant of the ⋯ trigger (default: 'md'). */ borderRadius?: MnDropdownTriggerVariants['borderRadius']; }; /** * Config resolved via {@link MnConfigService} under the `mn-dropdown` section, so an * app can set shared accessible labels once instead of per instance. */ type MnDropdownUIConfig = { /** Default accessible label for the ⋯ trigger (falls back to "Actions"). */ ariaLabel?: string; /** Default heading for the menu/sheet. */ menuLabel?: string; /** Default placeholder for the search input (falls back to "Search..."). */ searchPlaceholder?: string; /** Default empty-state text when the filter matches nothing (falls back to "No results"). */ searchEmptyLabel?: string; }; declare const MN_DROPDOWN_CONFIG: InjectionToken; /** * A ⋯ command menu. The trigger opens a `role="menu"` list of {@link MnDropdownAction}s * that each fire and dismiss on choice — a *command* menu, not a value picker, so it is * intentionally not a ControlValueAccessor. * * Presentation mirrors mn-multi-select: an anchored popover on desktop and the shared * {@link MnBottomSheet} on mobile (< 640px). Both the popover and the sheet host are * portalled to `document.body` so their `position: fixed` anchors to the viewport rather * than any transformed/filtered ancestor (a table cell, a card) — the same root-cause fix * the multi-select applies. */ declare class MnDropdown implements OnInit { /** Lucide icons the template renders. */ protected readonly icons: Record<"Check" | "ChevronDown" | "EllipsisVertical" | "SearchX", LucideIconData>; datasource: MnDropdownProps; protected uiConfig: MnDropdownUIConfig; /** Lucide data for the trailing check shown on the {@link MnDropdownAction.active} row. */ protected readonly checkIcon: LucideIconData; private readonly configService; private readonly sectionPath; private readonly explicitInstanceId; private readonly elRef; private readonly lang; private readonly destroyRef; private readonly renderer; private readonly cdr; /** Reference to the trigger element for positioning the popover. Read as an * `ElementRef` because `button[mnButton]` is a component — the default query would * otherwise return the MnButton instance, which has no `nativeElement`. */ triggerRef: ElementRef; /** * Layout classes for the anchored popover panel. Searchable menus become a flex column * so the search box can be pinned (`shrink-0`) above a single scrolling list region — * paired with {@link panelFloorPx}, that keeps the popover a fixed height while the * filter runs, instead of the panel resizing on every keystroke. The mobile sheet is * rendered by mn-bottom-sheet instead, so it needs no branch here. */ get panelClasses(): string; /** Tailwind's `sm` breakpoint — below this the menu renders as a bottom sheet. * Kept in step with the same constant in mn-bottom-sheet / mn-multi-select. */ private static readonly SHEET_MAX_WIDTH; /** The anchored popover panel currently moved into `document.body`, if any. */ private movedPanel; /** The bottom-sheet host, for outside-click tests. The sheet owns its own placement. */ private sheetHost; /** Whether the viewport is currently narrow enough for the sheet layout. */ private isNarrowViewport; /** Live breakpoint match, so rotating the device re-evaluates the layout. */ private sheetMedia; /** The listener registered on `sheetMedia`, retained for teardown. */ private sheetMediaListener; /** `document.body`'s inline `overflow` before the sheet locked it, restored on close. */ private previousBodyOverflow; /** * The anchored popover's opened height, locked so a shorter filtered list cannot resize * it mid-type. Captured on the frame after the panel appears (with the full, unfiltered * list), so applying it is jump-free — it only stops a later shrink. Null while closed * or when the menu is not searchable, leaving the plain content-height popover untouched. */ panelFloorPx: number | null; /** * The anchored popover's opened width, locked for the same reason as {@link panelFloorPx}: * the panel is content-sized between its `min-w`/`max-w` bounds, so a filtered list that * drops the widest item would otherwise shrink the popover mid-type. Captured on the same * next-frame pass as the height, so applying it is jump-free. Null while closed or when the * menu is not searchable, leaving the plain content-width popover untouched. */ panelWidthPx: number | null; /** * The mobile sheet's opened height, applied as a `min-height` floor for the same reason * as {@link panelFloorPx} — mirroring mn-multi-select's sheet floor. Null while anchored, * closed, or non-searchable. */ sheetFloorPx: number | null; /** Watches the trigger while open, so the panel closes if the trigger is hidden. */ private visibilityObserver; /** Capture-phase scroll listener installed while open, closing on any ancestor scroll. */ private scrollCapture; isOpen: boolean; /** Stable fallback id, used when {@link MnDropdownProps.id} is omitted. Generated once per * instance so the a11y wiring (menu id, `aria-controls`, the search input) stays valid. */ private readonly autoId; /** Current text in the search input, cleared on close. Only meaningful when the menu * is {@link MnDropdownProps.searchable}. */ searchTerm: string; /** Popover position computed from the trigger's bounding rect. */ /** Inline placement of the anchored panel; `maxHeight` only binds when the viewport is the tighter cap. */ dropdownStyle: { top: string; bottom: string; left: string; maxHeight: string | null; }; /** * The popover panel, relocated to `document.body` on appearance (see mn-multi-select's * portal rationale) and detached when the query clears on close/destroy. */ set dropdownRef(ref: ElementRef | undefined); /** * The bottom-sheet host, relocated to `document.body` so its `position: fixed` * children anchor to the viewport rather than a transformed ancestor. */ set sheetRef(ref: ElementRef | undefined); ngOnInit(): void; private resolveConfig; private startWatchingViewport; private stopWatchingViewport; toggle(): void; /** The single close path, so every open-only listener is torn down with the panel. */ close(): void; /** Whether the menu should currently render as a bottom sheet. */ get isSheet(): boolean; /** Fires an action and closes. Ignores disabled items defensively. */ select(action: MnDropdownAction): void; /** Whether the filter input is shown — the explicit `searchable` prop, off by default. */ get isSearchable(): boolean; /** * Records the current filter text as the search input changes. The input's * ControlValueAccessor emits `null` for an empty field (its text adapter maps `''` to * `null`), so coerce to `''` — otherwise clearing or backspacing the box would leave * `searchTerm` null and {@link filteredActions}'s `.trim()` would throw, freezing the menu. */ onSearch(term: string | null): void; /** * The actions currently passing the filter, in their declared order. Every action when * the menu is not searchable or the box is empty; otherwise those whose resolved label * or {@link MnDropdownAction.keywords} contain the (case-insensitive) query. */ get filteredActions(): MnDropdownItem[]; /** * Runs the first still-visible, enabled action — the Enter key's target, matching a * help search where Enter opens the top hit. Skips separators. No-op when nothing matches. */ selectFirstVisible(): void; private updateDropdownPosition; private startWatchingTrigger; private stopWatchingTrigger; onDocumentClick(event: Event): void; onEscape(): void; onWindowScrollOrResize(): void; private lockBodyScroll; private unlockBodyScroll; /** * Records the anchored popover's opened height and width, locking them via * {@link panelFloorPx} / {@link panelWidthPx}. Measured on the next frame so the read * reflects the fully-rendered, unfiltered list (the search box is empty on open) and never * forces a reflow mid change-detection. Both values equal the current dimensions, so * applying them is jump-free — they only stop a later, shorter/narrower filtered list from * shrinking the panel. */ private capturePanelFloor; /** * Records the sheet's opened height as its `min-height` floor, on the same next-frame * basis as {@link capturePanelFloor}. `hostEl` is the portalled mn-bottom-sheet host * (`display: contents`), so the height is read from its `.mn-sheet-container` child. */ private captureSheetFloor; private portal; /** The label shown for an action, preferring a resolved translation key. */ actionLabel(action: MnDropdownAction): string; /** * Whether an icon was supplied as a `TemplateRef` rather than lucide icon data, which * decides how the template renders it. Kept as a method (not a pipe) so the narrowing * is available inline in the item loop. * @param value The icon to test. * @returns True when the icon is a template the caller owns. */ isTemplateRef(value: unknown): value is TemplateRef; /** Whether a list entry is a {@link MnDropdownSeparator} rather than a command. */ isSeparator(item: MnDropdownItem): item is MnDropdownSeparator; /** * Narrows a list entry to a command, or null for a separator. Used as `@if (asAction(item); * as action)` in the template so the item loop gets a reliably-typed {@link MnDropdownAction} * without depending on template narrowing of the {@link isSeparator} guard. * @param item The list entry to narrow. * @returns The command, or null when the entry is a separator. */ asAction(item: MnDropdownItem): MnDropdownAction | null; /** * Foreground class for an item: an explicit {@link MnDropdownAction.color}, else the * destructive red for a {@link MnDropdownAction.danger} item, else the default text. */ actionColorClass(action: MnDropdownAction): string; /** Accessible name for the ⋯ trigger button. */ get triggerAriaLabel(): string; /** The visible text on the trigger, or null for an icon-only ⋯ trigger. */ get triggerLabelText(): string | null; /** * The trigger's glyph, normalised to a single representation so the template renders it * one way — the same template-or-lucide-data path the menu items use — with no per-preset * switch. Resolves, in order: an explicit `'none'` (no glyph); a caller's custom template * or lucide data ({@link MnActionIcon}); otherwise a built-in preset mapped to its own * lucide data (a labelled trigger defaults to the chevron, an icon-only one to the dots). * @returns A template glyph, an icon-data glyph with its render size, or null for none. */ private resolveTriggerGlyph; /** The trigger glyph when it is a caller's template, else null. Split from * {@link triggerIconData} so the template narrows without a discriminated union. */ get triggerIconTemplate(): TemplateRef | null; /** The trigger glyph when it is lucide data (a preset or caller data), with its render * size and dim flag, else null. */ get triggerIconData(): { data: LucideIconData; size: number; dim: boolean; } | null; /** Heading shown above the menu/sheet, or null when none is configured. */ get menuLabel(): string | null; /** Placeholder shown in the search input, preferring a resolved translation key. */ get searchPlaceholder(): string; /** Text shown in place of the list when the filter matches no actions. */ get searchEmptyLabel(): string; /** The ghost look the trigger has always used; a bare or partial `triggerButton` merges * over this, so opting in without overriding anything keeps the current appearance. */ private static readonly DEFAULT_TRIGGER_BUTTON; /** mn-button config for the trigger: the ghost default, overlaid with any * {@link MnDropdownProps.triggerButton} the caller supplied. */ get triggerData(): Partial; get triggerClasses(): string; get resolvedId(): string; static ɵfac: i0.ɵɵFactoryDeclaration; static ɵcmp: i0.ɵɵComponentDeclaration; } export { MN_CHECKBOX_CONFIG, MN_DATETIME_CONFIG, MN_DROPDOWN_CONFIG, MN_INPUT_FIELD_CONFIG, MN_MULTI_SELECT_CONFIG, MN_SELECT_CONFIG, MN_TEXTAREA_CONFIG, MnCheckbox, MnDatetime, MnDropdown, MnFileInput, MnInputField, MnMultiSelect, MnSelect, MnTextarea, dateTimeAdapter, defaultTextAdapter, mnCheckboxVariants, mnCheckboxWrapperVariants, mnDatetimeVariants, mnDropdownTriggerVariants, mnFileInputVariants, mnInputFieldVariants, mnMultiSelectVariants, mnSelectVariants, mnTextareaVariants, numberAdapter, pickAdapter }; export type { MnActionIcon, MnCheckboxErrorMessageData, MnCheckboxErrorMessagesData, MnCheckboxProps, MnCheckboxUIConfig, MnCheckboxVariants, MnCheckboxWrapperVariants, MnDatetimeErrorMessageData, MnDatetimeErrorMessagesData, MnDatetimeMode, MnDatetimeProps, MnDatetimeUIConfig, MnDatetimeVariants, MnDomAttrs, MnDropdownAction, MnDropdownActionColor, MnDropdownItem, MnDropdownProps, MnDropdownSeparator, MnDropdownTriggerVariants, MnDropdownUIConfig, MnErrorMessageData, MnErrorMessagesData, MnFileDisplayItem, MnFileInputDisplayMode, MnFileInputErrorMessageData, MnFileInputErrorMessagesData, MnFileInputProps, MnFileInputUIConfig, MnFileInputVariants, MnInputAdapter, MnInputBaseProps, MnInputDateTimeProps, MnInputFieldProps, MnInputFieldUIConfig, MnInputProps, MnInputType, MnInputVariants, MnMultiSelectErrorMessageData, MnMultiSelectErrorMessagesData, MnMultiSelectOption, MnMultiSelectProps, MnMultiSelectUIConfig, MnMultiSelectVariants, MnSelectErrorMessageData, MnSelectErrorMessagesData, MnSelectOption, MnSelectProps, MnSelectUIConfig, MnSelectVariants, MnTextareaErrorMessageData, MnTextareaErrorMessagesData, MnTextareaProps, MnTextareaUIConfig, MnTextareaVariants };