/**
* 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;
}