/** * Due to the composed nature of the fielddropdown, we need to disable the event * bubbling and native event listener rules for this component. */ import { EventEmitter } from '../../stencil-public-runtime'; import { TextInputAutocomplete } from '../../utils/constants'; import type { FilterMode } from '../../utils/search-engine'; /** * @slot content - Use a tag for the slot, and place elements inside. * @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 NvFielddropdown { el: HTMLNvFielddropdownElement; private inputElement; private selectElement; private toggleElement; private clearElement; private debounceTimer; /** 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; /****************************************************************************/ /** * 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; /** * 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; /** * Add helpful hints or extra information under the text input field. This is * where you can clarify what users should enter or provide additional * instructions, making the form easier to fill out correctly. */ readonly description: string; /** * Display temporary text inside the input field to give users a hint about * what to type. It's a great way to provide examples or suggestions directly * in the field before they start typing. * The placeholder is displayed only when the filterable option is enabled. */ 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}`; /** * Specifies the value of the input field, which determines the text displayed * within the field. This prop is typically used in controlled components * where the input's value is managed by the component's state. */ value: string; /** * Marks the input field as required, ensuring that the user must fill it out * before submitting the form. * @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. * Users can still click on it, select, and copy the text, but they won't be * able to type or delete anything. */ readonly readonly: boolean; /** * The disabled prop lets you turn off the input field so that users can't * type in it. When disabled, the field is grayed out and won't respond to * clicks or touches. */ 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 dropdown * field. * @validator message */ readonly errorDescription: string; /** * Defines the maximum height of the multiselect list when open. */ readonly maxHeight: string; /** * The text to display when no items match the filter. */ readonly emptyResult: string; /** * Enables or disables the filtering feature for the dropdown items. */ readonly filterable: boolean; /** * Shows the inline clear (×) button when a value is selected (or when * filterable and the user has typed). The programmatic `clear()` method * works regardless of this prop — leave it off when you want to manage * clearing the selection from outside the component. */ readonly clearable: boolean; /** * When an item is selected by the user, the dropdown will continue to stay * open. */ readonly openOnSelect: boolean; /** * Determines if the component’s filtering behavior is managed externally. * When set to true and filterable is enabled, the component won’t * automatically filter items. Instead, you must implement your own filtering * logic (e.g., server-side search or custom matching) using the * filterTextChanged event. */ readonly controlledFilter: 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", * "selected": true, * }, * { * "label": "Option 2", * "value": "option2", * }] */ readonly options?: { /** Label to display for the option */ label: string; /** Value associated with the option */ value: string; /** Whether this option is disabled */ disabled?: boolean; }[]; /** * 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; /** * Allows the field to stretch and fill the entire width of its container. */ readonly fluid: boolean; /** * Filter mode for dropdown 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; /****************************************************************************/ /** * The text entered by the user for filtering dropdown items. */ filterText: string; selectedValues: Set; open: boolean; /** * 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 (shows loading indicator). */ isSearching: boolean; /****************************************************************************/ /** * Emitted when the input value changes. * @bind value */ valueChanged: EventEmitter; /** * Event emitted when the filter input value changes. */ filterTextChanged: EventEmitter; /** * Emitted when the field is cleared via the inline clear button or the * programmatic `clear()` method. Useful for reacting to user-initiated * clears without subscribing to every `valueChanged` emission. */ cleared: EventEmitter; /** * Event emitted when the dropdown opened or closed. */ openChanged: EventEmitter; /** * Event emitted when an item is clicked. Propagation prevented in listener. */ dropdownItemSelected: EventEmitter; /****************************************************************************/ handleOpenChange(newOpen: boolean): void; handleValueChange(): void; handleOptionsChange(): void; /****************************************************************************/ handleDropdownItemSelected(event: CustomEvent): void; handleFocus(event: FocusEvent): void; handleFocusOut(event: FocusEvent): void; handleKeyDown(event: KeyboardEvent): void; handleDocumentClick(event: MouseEvent): void; /** * Closes the popover when a click is detected outside the component. * @param {MouseEvent} event - The click event. */ private handleClickOutside; /****************************************************************************/ /** Clears the filter text */ clearFilter(): Promise; /** * Clears the current selection. Resets the value to an empty string, * removes the selected state from items, clears the filter text (when * filterable) and emits `valueChanged` (and `filterTextChanged` when the * filter was reset). Emits `cleared` when anything was actually reset. */ clear(): Promise; /** * Toggles the dropdown popover open state * @param {boolean} open - The open state to set, if null, toggles the state */ toggleDropdown(open?: boolean): Promise; private syncToggleDropdown; /** * Handles clicks on the inline clear button. When a value is already * selected and the user has typed in a filter, clearing should dismiss * the filter and revert the input to the selected label rather than * wipe the selection. Always emits `cleared` so subscribers see one * consistent signal regardless of which path ran. * @param {MouseEvent} [event] - The click event from the clear button. */ private handleClearButtonClick; private handleFilterInput; private setFilterInputToSelectedValue; private getSelectedLabel; /** * Finds the item that matches the current value. Falls back to matching by * label when no item matches by value, so that consumers who pass a value * matching only the label (e.g. `` * with `value="Item 2"`) still get the correct selected item. * @param {HTMLNvFielddropdownitemElement[]} items - The dropdown items to search. * @returns {HTMLNvFielddropdownitemElement | undefined} The matching item, or undefined if no match is found. */ private findItemMatchingValue; private getFilterableItems; private getNavigableItems; private getAllItems; private getHighlightedItemIndex; private updateHighlightedItem; private focusField; /** * 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 initWorker; /** * Terminates the Web Worker and cleans up resources. */ private terminateWorker; /** * Filter dropdown items based on the text entered by the user. * Uses the search engine for optimized filtering with configurable modes. * If no items are found, display a message indicating no results. */ private filterItems; /** * Applies search results to the DOM, showing/hiding items as needed. * @param {SearchResult} result - The search result. * @param {HTMLNvFielddropdownitemElement[]} items - The items to apply the search results to. * @example * const result: SearchResult = { * ids: ['item-1', 'item-2'], * total: 2, * truncated: false, * }; * const items = Array.from( * this.el.querySelectorAll('nv-fielddropdownitem'), * ) as HTMLNvFielddropdownitemElement[]; * this.applySearchResults(result, items); * // Matching items are shown, non-matching items are hidden. * // If no items match, a "no results" item is prepended to the list. */ private applySearchResults; /** * Adds a non-selectable item showing truncation info. * @param {number} shown - The number of items shown. * @param {number} total - The total number of items. * @example * // Show a truncation message like "10 of 100 results". * this.addTruncatedMessage(10, 100); */ private addTruncatedMessage; private updateSelectedItem; /****************************************************************************/ componentDidLoad(): void; disconnectedCallback(): void; componentDidRender(): void; /****************************************************************************/ render(): any; }