UNPKG

@sixbell-telco/sdk

Version:

A collection of reusable components designed for use in Sixbell Telco Angular projects

516 lines (515 loc) 19.4 kB
/** * @fileoverview Combobox Component * * A comprehensive combobox component with advanced features including: * - Single and multiple selection modes * - Real-time search with debouncing * - Keyboard navigation support (Arrow keys, Enter, Space) * - Form validation integration * - Accessibility compliance with CDK Listbox * - Customizable styling variants and sizes * - Animation states for smooth transitions */ import { CdkListbox } from '@angular/cdk/listbox'; import { ConnectedOverlayPositionChange } from '@angular/cdk/overlay'; import { AfterViewInit, ElementRef } from '@angular/core'; import { ControlValueAccessor, FormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; import { BadgeSizeProps } from '@sixbell-telco/sdk/components/badge'; import * as i0 from "@angular/core"; /** * Available style variants for the combobox component */ export type ComboboxVariantProps = 'primary' | 'secondary' | 'tertiary' | 'accent' | 'info' | 'success' | 'error' | 'warning' | null | undefined; /** * Available size variants for the combobox component */ export type ComboboxSizeProps = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | null | undefined; /** * Props interface for the combobox component */ export type ComboboxProps = { variant?: ComboboxVariantProps; size?: ComboboxSizeProps; }; /** * Animation states for the combobox overlay */ type AnimationState = 'closed' | 'opening' | 'open' | 'closing'; /** * Selection type for the combobox */ type SelectionType = 'single' | 'multiple'; /** * Event emitted when the search query changes */ export type ComboboxSearchQueryEvent = { query: string; results: any[]; }; /** * A customizable combobox component with search functionality, multiple selection modes, * and keyboard navigation support. Implements Angular's ControlValueAccessor interface * for seamless integration with reactive forms. * * @example * ```html * <st-combobox * [(value)]="selectedValue" * [options]="availableOptions" * displayKey="name" * valueKey="id" * placeholder="Select an option" * variant="primary" * size="md"> * </st-combobox> * ``` * * @example * ```typescript * // Multiple selection * <st-combobox * [(value)]="selectedValues" * [options]="options" * selectionType="multiple" * [allowClear]="true"> * </st-combobox> * ``` */ export declare class ComboboxComponent implements AfterViewInit, ControlValueAccessor { /** * Angular translation service for internationalization * @internal */ translateService: TranslateService; /** * The visual style variant of the combobox * @default 'secondary' */ variant: import("@angular/core").InputSignal<ComboboxVariantProps>; /** * The size variant of the combobox * @default 'md' */ size: import("@angular/core").InputSignal<ComboboxSizeProps>; /** * Whether to use ghost (transparent) styling * @default false */ ghost: import("@angular/core").InputSignal<boolean>; /** * The HTML name attribute for the underlying form control */ name: import("@angular/core").InputSignal<string | null>; /** * Placeholder text displayed when no option is selected */ placeholder: import("@angular/core").InputSignal<string>; /** * Whether the combobox is disabled * @default false */ disabled: import("@angular/core").ModelSignal<boolean>; /** * Label text displayed above the combobox */ label: import("@angular/core").InputSignal<string>; /** * Parent form group for reactive forms integration */ parentForm: import("@angular/core").InputSignal<FormGroup<any> | null>; /** * The form control name when used within a reactive form */ formControlName: import("@angular/core").InputSignal<string>; /** * Whether to show a clear button next to the selected value(s) in the trigger * Works for both single and multiple selection modes * @default true */ allowClear: import("@angular/core").InputSignal<boolean>; /** * Whether to show a "Clear All" button at the bottom of the dropdown for multiple selection * Only applies when selectionType is 'multiple' * @default true */ allowClearAll: import("@angular/core").InputSignal<boolean>; /** * Placeholder text for the search input field * @default 'Search...' */ searchPlaceholder: import("@angular/core").InputSignal<string>; /** * Text displayed when no search results are found * @default 'No results found' */ noResultsText: import("@angular/core").InputSignal<string>; /** * The current selected value(s) * For single selection: any | null * For multiple selection: any[] */ value: import("@angular/core").ModelSignal<any>; /** * Array of available options to select from */ options: import("@angular/core").InputSignal<any[]>; /** * The object property to use for display text when options are objects * Falls back to common property names if not specified */ displayKey: import("@angular/core").InputSignal<string>; /** * The object property to use as the value when options are objects * Uses the entire object if not specified */ valueKey: import("@angular/core").InputSignal<string>; /** * Selection mode: 'single' for single selection, 'multiple' for multi-select * @default 'single' */ selectionType: import("@angular/core").InputSignal<SelectionType>; /** * Whether to enable debounced search functionality * @default false */ searchDebounced: import("@angular/core").InputSignal<boolean>; /** * Debounce time in milliseconds for search input * @default 300 */ searchDebounceTime: import("@angular/core").InputSignal<number>; /** * Event emitted when combobox loses focus */ blurred: import("@angular/core").OutputEmitterRef<unknown>; /** * Event emitted when selection changes */ valueUpdated: import("@angular/core").OutputEmitterRef<any>; /** * Event emitted when search query changes with filtered results */ searchQuery: import("@angular/core").OutputEmitterRef<ComboboxSearchQueryEvent>; /** Search icon for the search input */ iconSearch: string; /** Dropdown chevron icon */ iconChevronDown: string; /** Check icon for selected options */ iconCheck: string; /** Close/clear icon */ iconClose: string; /** Internal search input value */ private readonly searchValue; /** Processed search term after debouncing */ private readonly searchTerm; /** RxJS subject for search input handling */ private readonly searchSubject; /** Current animation state of the overlay */ private readonly animationState; /** Trigger for blur events in form validation */ private readonly blurTrigger; /** Active option index for keyboard navigation */ private readonly activeOptionIndex; /** Reference to the trigger button element */ triggerRef: import("@angular/core").Signal<ElementRef<HTMLButtonElement> | undefined>; /** Reference to the search input element */ searchInputRef: import("@angular/core").Signal<ElementRef<HTMLInputElement> | undefined>; /** Reference to the options list container */ optionsList: import("@angular/core").Signal<ElementRef<HTMLDivElement> | undefined>; /** Reference to the CDK listbox for keyboard navigation */ listbox: import("@angular/core").Signal<CdkListbox<unknown> | undefined>; /** Width of the trigger button for overlay positioning */ triggerWidth: import("@angular/core").WritableSignal<number>; /** Current active position configuration from CDK overlay */ private readonly currentPosition; /** * Static class mappings for different animation directions * Maps animation directions to complete Tailwind class names * All class names are static and detectable by Tailwind at build time */ private readonly animationClassMap; /** * Computed animation direction based on current overlay position * Dynamically detects position and returns appropriate direction: 'top', 'bottom', 'left', or 'right' */ animationDirection: import("@angular/core").Signal<"bottom" | "top" | "left" | "right">; /** * Computed class string for animations * Applies the correct animation based on position using static class names */ animationClasses: import("@angular/core").Signal<string>; /** Form control reference for reactive forms */ private readonly formControl; /** Observable stream of form control */ private readonly formControl$; /** Stream of form control status changes */ private readonly statusChanges$; /** Stream of form control value changes */ private readonly stateChanges$; /** Signal for form control status */ private readonly statusSignal; /** Signal for form control state */ private readonly stateSignal; /** Callback function for value changes */ private onChange; /** Callback function for touch events */ private onTouched; constructor(); /** * Filtered options based on current search term * @returns Array of options that match the search criteria */ filteredOptions: import("@angular/core").Signal<any[]>; /** * Whether the overlay is currently open or in the process of opening/closing * @returns True if overlay is visible or animating */ isOpen: import("@angular/core").Signal<boolean>; /** * Whether the overlay is currently animating to open state * @returns True if overlay is opening or open */ isAnimatingOpen: import("@angular/core").Signal<boolean>; /** * Current animation state for template binding * @returns Current animation state */ dataState: import("@angular/core").Signal<AnimationState>; /** * Display value for the selected option(s) * @returns Formatted display string based on selection type and current value */ displayValue: import("@angular/core").Signal<any>; /** * Display information for multiple selection showing first item and additional count * @returns Object with first item display and additional count, or null for single selection */ multipleDisplayInfo: import("@angular/core").Signal<{ firstItem: string; additionalCount: number; } | null>; /** * Whether the clear button should be shown * @returns True if there's a valid selected value and clear is allowed */ showClearButton: import("@angular/core").Signal<boolean>; /** * Base CSS classes for the combobox component * @internal */ componentClass: import("@angular/core").Signal<string>; /** * Error state CSS classes * @internal */ errorClass: import("@angular/core").Signal<string>; /** * Success state CSS classes * @internal */ successClass: import("@angular/core").Signal<string>; /** * Validation-aware CSS classes based on form control state * @internal */ validationClass: import("@angular/core").Signal<string>; /** * CSS classes for the search input field * @internal */ searchInputClass: import("@angular/core").Signal<string>; /** * CSS classes for the options menu * @internal */ menuClass: import("@angular/core").Signal<string>; /** * CSS classes for the badge * @internal */ badgeClass: import("@angular/core").Signal<BadgeSizeProps>; /** * Translated search placeholder text * @returns Translated placeholder or input value */ translatedSearchPlaceholder: import("@angular/core").Signal<any>; /** * Translated main placeholder text * @returns Translated placeholder or input value */ translatedPlaceholder: import("@angular/core").Signal<any>; /** * Translated no results text * @returns Translated no results text or input value */ translatedNoResultsText: import("@angular/core").Signal<any>; /** * Current search input value for template binding * @returns Current search value */ get currentSearchValue(): string; /** * Angular lifecycle hook called after view initialization * Updates the trigger width for proper overlay positioning */ ngAfterViewInit(): void; /** * Writes a new value to the component * @param value - The new value to set */ writeValue(value: any): void; /** * Registers a callback function to be called when the value changes * @param fn - The callback function */ registerOnChange(fn: (value: any) => void): void; /** * Registers a callback function to be called when the component is touched * @param fn - The callback function */ registerOnTouched(fn: () => void): void; /** * Toggles the overlay open/closed state * Handles focus management and animation state transitions */ toggleOverlay(): void; /** * Handles animation end events to update state * @param event - The animation event */ onAnimationEnd(event: AnimationEvent): void; /** * Handles overlay detachment * Cleans up state and triggers blur */ handleDetach(): void; /** * Handles overlay position changes to determine animation direction * @param event - The position change event from CDK overlay */ onPositionChange(event: ConnectedOverlayPositionChange): void; /** * Handles clicks outside the component * @param event - The mouse event */ handleClickOutside(event: MouseEvent): void; /** * Handles search input changes * @param event - The input event */ handleSearchInput(event: Event): void; /** * Handles option selection * @param option - The selected option */ handleOptionSelect(option: any): void; /** * Handles CDK listbox selection changes * @param event - The selection change event */ handleSelectionChange(event: any): void; /** * Handles keyboard events for option selection * @param event - The keyboard event */ handleListboxKeydown(event: KeyboardEvent): void; /** * Handles keyboard events on the search input for navigation and selection * @param event - The keyboard event */ handleSearchKeydown(event: KeyboardEvent): void; /** * Handles keyboard events on the clear all button * @param event - The keyboard event */ handleClearButtonKeydown(event: KeyboardEvent): void; /** * Handles keyboard events on the trigger button * @param event - The keyboard event */ handleTriggerKeydown(event: KeyboardEvent): void; /** * Clears the current selection */ clearSelection(): void; /** * Handles clear selection button click * @param event - The click event */ handleClearSelection(event: Event): void; /** * Checks if an option is currently selected * @param option - The option to check * @returns True if the option is selected */ isOptionSelected(option: any): boolean; /** * Checks if an option is currently active for keyboard navigation * @param index - The option index * @returns True if the option is active */ isActiveOption(index: number): boolean; /** * Gets the display value for an option * @param option - The option to get display value for * @returns The display string for the option */ getDisplayValue(option: any): string; /** * Type guard to check if a value is an array * @param value - The value to check * @returns True if the value is an array */ isArray(value: any): value is any[]; /** * Updates the trigger button width for overlay positioning */ private updateTriggerWidth; /** * Gets the value property from an option * @param option - The option to get value from * @returns The option value */ private getOptionValue; /** * Checks if a value is valid (exists in options) * @param value - The value to validate * @returns True if the value exists in the options array */ private isValidValue; /** * Triggers blur event for form validation */ private triggerBlur; /** * Clears the search input and term */ private clearSearch; /** * Sets up reactive search handling with debouncing * The debounce time updates reactively when the input changes */ private setupSearchHandling; /** * Sets the active option for keyboard navigation * @param index - The index of the option to make active */ private setActiveOption; /** * Sets the first option as active by default */ private setDefaultActiveOption; /** * Updates the visual state of the active option */ private updateActiveOptionVisually; /** * Sets up the search query emission effect * Emits search results whenever the search term or options change */ private setupSearchQueryEmission; static ɵfac: i0.ɵɵFactoryDeclaration<ComboboxComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<ComboboxComponent, "st-combobox", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "ghost": { "alias": "ghost"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "parentForm": { "alias": "parentForm"; "required": false; "isSignal": true; }; "formControlName": { "alias": "formControlName"; "required": false; "isSignal": true; }; "allowClear": { "alias": "allowClear"; "required": false; "isSignal": true; }; "allowClearAll": { "alias": "allowClearAll"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "noResultsText": { "alias": "noResultsText"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "displayKey": { "alias": "displayKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "selectionType": { "alias": "selectionType"; "required": false; "isSignal": true; }; "searchDebounced": { "alias": "searchDebounced"; "required": false; "isSignal": true; }; "searchDebounceTime": { "alias": "searchDebounceTime"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; "value": "valueChange"; "blurred": "blurred"; "valueUpdated": "valueUpdated"; "searchQuery": "searchQuery"; }, never, ["*"], true, never>; } export {};