import { EventEmitter } from '../../stencil-public-runtime'; import { TextInputAutocomplete } from '../../utils/constants'; import type { FilterMode } from '../../utils/search-engine'; /** * @slot content - The content of the list. * @slot leading-input - Content to be placed before the input text, within the input container. * @slot before-input - Content to be placed before the input text, outside the input container. * @slot after-input - Content to be placed after the input text, outside the input container. * @slot label - Content to be placed as the label, will override the label prop. * @slot description - Content to be placed as the description, will override the description prop. * @slot error-description - Content to be placed as the error description, will override the errorDescription prop. */ export declare class NvFieldmultiselect { el: HTMLNvFieldmultiselectElement; private inputElement; private popoverElement; private isBulkOperation; /** * Timer for debouncing input events. * Private property preferred over @State as it: * - Doesn't need to trigger re-renders * - Is purely for internal logic * - Improves performance by avoiding Stencil's reactivity system */ private debounceTimer; private preventBlurClose; private _boundHandleClickOutside?; /** Pre-computed search index for efficient filtering */ private indexedItems; /** Raw items for worker initialization */ private rawItems; /** Web Worker client for async search operations */ private workerClient; /** Effective filter mode (may differ from prop if fuzzy falls back to smart) */ private effectiveFilterMode; /****************************************************************************/ /** * Lets you define the text that explains what users should enter in the text * input field. It's a crucial element for making forms clear and user-friendly. */ readonly label: string; /** * Sets the ID for the input element and the for attribute of the associated * label. If no ID is provided, a random one will be automatically generated * to ensure unique identification, facilitating proper label association and * accessibility. */ readonly inputId: string; /** * Defines the name attribute of the input field, which is crucial for form * submission. This value is used as the key in the key-value pair sent to * the server, representing the input's data in form submissions. It should be * unique within the form to avoid conflicts. */ readonly name: string; /** * Add helpful hints or extra information under the text input field. */ readonly description: string; /** * Display temporary text inside the input field. */ readonly placeholder: string; /** * The autocomplete prop helps users fill out the input field faster by * suggesting entries they've used before, like their email or address. * You can turn it on to make forms more convenient or off to ensure users * always type in fresh data. */ readonly autocomplete: `${TextInputAutocomplete}`; /** * Marks the input field as required. * @note This uses the native HTML `required` attribute, which triggers browser validation. */ readonly required: boolean; /** * Marks the input field as required for accessibility purposes without triggering * native HTML validation. Use this when implementing custom validation logic. * @note When set, this uses `aria-required` instead of the native `required` attribute. * This allows developers to implement custom validation while maintaining accessibility. * @note If this prop is not explicitly set, the component will check for the HTML attribute * 'aria-required' directly to determine if it should be applied. */ readonly ariaRequiredAttr: boolean; /** * Display the input field's content without allowing users to change it. */ readonly readonly: boolean; /** * Disables the input field. */ readonly disabled: boolean; /** * Alters the input field's appearance to indicate an error, helping users * identify fields that need correction. * @validator error */ readonly error: boolean; /** * A description that appears when there is an error related to the multiselect * field. * @validator message */ readonly errorDescription: string; /** * Defines the maximum height of the multiselect list when open. */ readonly maxHeight: string; /** * State of the multiselect popover. */ open: boolean; /** * Allows the field to stretch and fill the entire width of its container. */ readonly fluid: boolean; /** * List of options used to automatically generate dropdown items. This * provides an alternative to using the slot manually. * * @example * options=[{ * "label": "Option 1", * "value": "option1", * }, * { * "label": "Option 2", * "value": "option2", * }] */ options?: { /** Label to display for the option */ label: string; /** Value associated with the option */ value: string; /** Whether this option is a divider */ isDivider?: boolean; /** Whether this option is disabled */ disabled?: boolean; /** Additional description for the option */ description?: string; /** Whether this option is pre-checked */ checked?: boolean; }[]; /** * Specifies the selected values of the multiselect field. * This is the canonical value for the component and is used for form submission. */ value: string[]; /** * Enables or disables the filtering feature for the multiselect items. */ readonly filterable: boolean; /** * The text to display when no items match the filter. */ readonly emptyResult: string; /** * Delay in milliseconds before the search is triggered when typing in the filter input. * @default 300 */ readonly debounceDelay: number; /** * Applies focus to the input field as soon as the component is mounted. This * is equivalent to setting the native autofocus attribute on an * element. */ readonly autofocus: boolean; /** * Text for the badge showing the number of selected items. */ readonly badgeLabel: string; /** * The text entered by the user for filtering multiselect items. */ filterText: string; /** * Enables or disables the "Select All / Deselect All" toggle functionality. */ readonly enableSelectAll: boolean; /** * Text for the "Select All" button. */ readonly selectAllLabel: string; /** * Text for the "Deselect All" button. */ readonly deselectAllLabel: string; /** * Filter mode for multiselect search: * - 'strict': Simple substring matching (normalized includes) * - 'smart': Token-based matching (all query tokens must exist, order ignored) * - 'fuzzy': Typo-tolerant matching using Fuse.js (runs in Web Worker) * @default 'strict' */ readonly filterMode: FilterMode; /** * Maximum number of results to display. Protects UI performance on large datasets. * Values are clamped between 10 and 500 (hard cap). * @default 25 */ readonly maxResults: number; /** * Minimum number of characters required before filtering starts. * Useful for preventing overwhelming results on very large datasets. * @default 0 */ readonly startFilterAt: number; /** * Locale for automatic translation of truncated results text. * If not provided, automatically detects browser locale. * @example 'en', 'fr', 'de', 'es' */ readonly locale?: string; /** * The text to display when results are truncated due to maxResults limit. * Supports placeholders: {shown} and {total} will be replaced with actual values. * If not provided, automatically uses a localized translation based on the locale prop * or browser language. * @example '{shown} results shown out of {total} — refine your search' */ readonly truncatedResultsText?: string; /** * Number of items above which filtering is offloaded to a Web Worker. * This keeps the main thread responsive for large datasets. * @default 2000 */ readonly workerThreshold: number; /** * Threshold for fuzzy matching (0-1). Lower values are stricter. * Only applies when filterMode is 'fuzzy'. * @default 0.3 * @see {@link https://fusejs.io/api/options.html#threshold} Fuse.js threshold documentation */ readonly fuzzyThreshold: number; /****************************************************************************/ /** * Sorted options for display. */ sortedOptions: Array<{ /** Label to display for the option */ label: string; /** Value associated with the option */ value: string; /** Whether this option is a divider */ isDivider?: boolean; }>; private isHandlingEscape; /** * Indicates whether the current filter has visible results. * Used to control the visibility of the "Select All" button. */ private hasFilterResults; /** * Controls the visibility of the select all section. */ private isSelectAllSectionVisible; /** * Whether search results were truncated due to maxResults limit. */ resultsTruncated: boolean; /** * Total number of matches before truncation. */ totalResults: number; /** * Whether a worker search is in progress. */ isSearching: boolean; /****************************************************************************/ /** * Emitted when the selected values change. * @bind value */ valueChanged: EventEmitter; /** * Emitted when the filter text changes. */ filterTextChanged: EventEmitter; /****************************************************************************/ handleOptionsChange(newValue: typeof this.options): void; watchValueHandler(): void; handleOpenChange(newOpen: boolean): void; /****************************************************************************/ /** * Listen for the `itemChecked` event emitted by child items. * @param {CustomEvent} event - The event object containing the selected value and its checked state. */ handleItemChecked(event: CustomEvent<{ /** Value associated with the option */ value: string; /** Whether this option is checked */ checked: boolean; }>): void; handleSlotChange(event: Event): void; /** * Close the dropdown when keyboard focus leaves the component. * Uses focusout (which bubbles) so it covers every internal focusable * (filter input, hidden input, trigger `

`, chevron iconbutton, * clear-filter iconbutton, dropdown items, badge close button) without * needing per-element onBlur wiring. * @param {FocusEvent} event - The focus event. */ handleFocusOut(event: FocusEvent): void; /** * Handle keyboard events & arrow key navigation. * If the multiselect is not open, opens it and focuses on the first item if the list is not filterable. * If the multiselect is open, handles arrow key navigation and closes it if the focus is outside the component. * @param {KeyboardEvent} event - The keyboard event. */ handleKeyDown(event: KeyboardEvent): Promise; /****************************************************************************/ /** * Subscribe to click outside event. */ connectedCallback(): void; /** * Set the mode state and handle options change. */ componentWillLoad(): void; /** * Force reorder if options mode in componentDidLoad because of the initial render not trigger @watch */ componentDidLoad(): void; /** * Unsubscribe from click outside event and clean up worker. */ disconnectedCallback(): void; /****************************************************************************/ /** * Retrieves the current filter text entered by the user. * @returns {string} The filter text. */ getFilterText(): Promise; /** * Reset the filter and make all items visible. */ resetFilter(): Promise; /** * Returns the list of selected values. * @returns {string[]} The selected values. */ getSelectedValues(): Promise; /** * Select all visible and enabled items. * Works for both options and slots mode. * @returns {Promise} */ selectAll(): Promise; /** * Deselect all visible and enabled items. * Works for both options and slots mode. * @returns {Promise} */ deselectAll(): Promise; /** * Toggle selection state of all visible and enabled items. * If all items are selected, deselects all. Otherwise, selects all. * Works for both options and slots mode. * @returns {Promise} */ toggleSelectAll(): Promise; /** * Reorder the content of the slot using CSS flex `order` so the * underlying DOM order is preserved (clearing the selection restores * the original visual order automatically). */ private reorderSlotContent; /** * Reorder the content for options mode using CSS flex `order` so the * underlying DOM order is preserved (clearing the selection restores * the original visual order automatically). */ private reorderOptionsContent; /** * Filter multiselect items based on the text entered by the user. * Uses the search engine for optimized filtering with configurable modes. */ private filterItems; /** * Handle badge close for options mode. */ private handleBadgeCloseOptions; /** * Handle badge close for slots mode. */ private handleBadgeCloseSlots; /** * Rebuilds the search index from current items (options prop or slot items). */ private rebuildSearchIndex; /** * Initializes the Web Worker for search operations. * Falls back to main thread if worker is not available. * Note: Fuzzy search now works on main thread with Fuse.js, so no mode change needed. */ private initSearchWorker; /** * Terminates the Web Worker and cleans up resources. */ private terminateSearchWorker; /** * Performs a search over the indexed items, using a Web Worker when available * and falling back to the main thread otherwise. * @returns {Promise} Resolves with the search results. */ private performAdvancedSearch; /** * Adds a non-selectable list item showing truncation information. * @param {HTMLElement} ul - The list element to which the truncation message will be appended. * @param {number} shown - The number of items currently shown. * @param {number} total - The total number of available items. */ private addTruncatedMessage; private handleClickOutside; /** * Handle popover close */ private handlePopoverClose; /** * Clear the filter text */ private clearFilterText; /** * Updates the highlighted item in the dropdown list. * * @param {(HTMLNvFielddropdownitemElement | HTMLNvFielddropdownitemcheckElement)[]} items - The items to update. * @param {number} index - The index of the item to highlight. */ private updateHighlightedItem; /** * Focus on the first item in the dropdown list (visual order). */ private focusFirstItem; /** * Handle click on the input container for options mode. * @param {MouseEvent} event - The click event. */ private handleInputContainerClickOptions; /** * Handle click on the input container for slots mode. * @param {MouseEvent} event - The click event. */ private handleInputContainerClickSlots; /** * Handle input change for options mode. * @param {Event} event - The input event. */ private readonly handleInputOptions; /** * Handle input change for slots mode * @param {Event} event - The input event. */ private readonly handleInputSlots; /** * Handle input focus for options mode. */ private handleInputFocusOptions; /** * Handle input focus for slots mode. */ private handleInputFocusSlots; /** * Toggle the multiselect popover for options mode. */ private togglePopoverOptions; /** * Toggle the multiselect popover for slots mode. */ private togglePopoverSlots; private manageDivider; /** * Synchronizes the checked state of all child nv-fielddropdownitemcheck components * with the current selectedValues state. */ private syncChildComponents; /** * Gets visible and enabled slot items using consistent logic. * @returns {Element[]} Array of visible and enabled items */ private getVisibleEnabledSlotItems; /** * Gets visible and enabled option items by checking DOM elements. * @returns {string[]} Array of visible and enabled option values */ private getVisibleEnabledOptionItems; /** * Determines if the toggle all button should be shown in options mode. * @returns {boolean} True if there are visible items and no "No results found" message */ private shouldShowToggleAllOptionsButton; /** * Toggles the selection state of all non-disabled options in options mode. * Respects filtering by only selecting/deselecting visible items. * @param {boolean} selectAll - Whether to select all items (true) or deselect all (false) */ private toggleSelectAllOptions; /** * Gets the checkbox state for the select all checkbox in options mode. * @returns {'checked' | 'unchecked' | 'indeterminate'} The checkbox state */ private getSelectAllCheckboxStateOptions; /** * Gets the checkbox state for the select all checkbox in slots mode. * @returns {'checked' | 'unchecked' | 'indeterminate'} The checkbox state */ private getSelectAllCheckboxStateSlots; /** * Toggles the selection state of all non-disabled slot items. * @param {boolean} selectAll - Whether to select all items (true) or deselect all (false) */ private toggleSelectAllSlots; /** * Handle click on the select all checkbox in options mode. * @param {Event} event - The click event. */ private handleSelectAllCheckboxOptionsClick; /** * Handle click on the select all checkbox in slots mode. * @param {Event} event - The click event. */ private handleSelectAllCheckboxSlotsClick; /** * Determines if the toggle all button should be shown in slots mode. * @returns {boolean} True if there are visible items and no "No results found" message */ private shouldShowToggleAllSlotButton; /** * Initializes the value array from checked slotted nv-fielddropdownitemcheck elements (slots mode only). */ private initializeValueFromSlots; private handleMouseDownPreventBlur; /** * Calculates aria-required and native required values based on props and attributes * @returns {object} Object with ariaRequiredValue and useNativeRequired */ private getRequiredAttributes; /** * Emitted when the input loses focus. * @param {CustomEvent} event - The event object containing the focus state. */ private handleOpenChanged; /****************************************************************************/ /** * Renders the component in options mode * @returns {any} The JSX for options mode */ private renderOptionsMode; /** * Renders the component in slots mode * @returns {any} The JSX for slots mode */ private renderSlotsMode; /** * Renders description and error description sections * @returns {any} The JSX for descriptions */ private renderDescriptions; /** * Main render method that decides which mode to render * @returns {any} The JSX for the component */ render(): any; }