@nuralyui/select 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle.js +152 -32
- package/package.json +1 -1
- package/select.component.d.ts +8 -0
- package/select.component.js +27 -3
- package/select.component.js.map +1 -1
- package/select.style.js +114 -5
- package/select.style.js.map +1 -1
- package/select.style.variables.js +1 -0
- package/select.style.variables.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuralyui/select",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A comprehensive select component with advanced features including multi-selection, keyboard navigation, validation, and accessibility support.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
package/select.component.d.ts
CHANGED
|
@@ -32,6 +32,9 @@ declare const HySelectComponent_base: (new (...args: any[]) => import("../../sha
|
|
|
32
32
|
*
|
|
33
33
|
* <!-- With search functionality -->
|
|
34
34
|
* <hy-select searchable search-placeholder="Search options..."></hy-select>
|
|
35
|
+
*
|
|
36
|
+
* <!-- Without clear button -->
|
|
37
|
+
* <hy-select clearable="false"></hy-select>
|
|
35
38
|
* ```
|
|
36
39
|
*
|
|
37
40
|
* @fires nr-change - Selection changed
|
|
@@ -50,6 +53,7 @@ declare const HySelectComponent_base: (new (...args: any[]) => import("../../sha
|
|
|
50
53
|
* @cssproperty --select-text-color - Text color
|
|
51
54
|
* @cssproperty --select-focus-color - Focus indicator color
|
|
52
55
|
* @cssproperty --select-dropdown-shadow - Dropdown shadow
|
|
56
|
+
* @cssproperty --select-dropdown-max-height - Maximum height of dropdown
|
|
53
57
|
* @cssproperty --select-no-options-color - No options message text color
|
|
54
58
|
* @cssproperty --select-no-options-icon-color - No options icon color
|
|
55
59
|
* @cssproperty --select-no-options-padding - Padding for no options message
|
|
@@ -91,10 +95,14 @@ export declare class HySelectComponent extends HySelectComponent_base implements
|
|
|
91
95
|
noOptionsIcon: string;
|
|
92
96
|
/** Enable search/filter functionality */
|
|
93
97
|
searchable: boolean;
|
|
98
|
+
/** Enable clear button to clear all selections */
|
|
99
|
+
clearable: boolean;
|
|
94
100
|
/** Placeholder text for the search input */
|
|
95
101
|
searchPlaceholder: string;
|
|
96
102
|
/** Current search query */
|
|
97
103
|
searchQuery: string;
|
|
104
|
+
/** Maximum height of the options dropdown */
|
|
105
|
+
maxHeight: string;
|
|
98
106
|
/** Options dropdown container element */
|
|
99
107
|
optionsElement: HTMLElement;
|
|
100
108
|
/** Main wrapper element */
|
package/select.component.js
CHANGED
|
@@ -46,6 +46,9 @@ import { SelectSelectionController, SelectKeyboardController, SelectDropdownCont
|
|
|
46
46
|
*
|
|
47
47
|
* <!-- With search functionality -->
|
|
48
48
|
* <hy-select searchable search-placeholder="Search options..."></hy-select>
|
|
49
|
+
*
|
|
50
|
+
* <!-- Without clear button -->
|
|
51
|
+
* <hy-select clearable="false"></hy-select>
|
|
49
52
|
* ```
|
|
50
53
|
*
|
|
51
54
|
* @fires nr-change - Selection changed
|
|
@@ -64,6 +67,7 @@ import { SelectSelectionController, SelectKeyboardController, SelectDropdownCont
|
|
|
64
67
|
* @cssproperty --select-text-color - Text color
|
|
65
68
|
* @cssproperty --select-focus-color - Focus indicator color
|
|
66
69
|
* @cssproperty --select-dropdown-shadow - Dropdown shadow
|
|
70
|
+
* @cssproperty --select-dropdown-max-height - Maximum height of dropdown
|
|
67
71
|
* @cssproperty --select-no-options-color - No options message text color
|
|
68
72
|
* @cssproperty --select-no-options-icon-color - No options icon color
|
|
69
73
|
* @cssproperty --select-no-options-padding - Padding for no options message
|
|
@@ -106,10 +110,14 @@ let HySelectComponent = class HySelectComponent extends NuralyUIBaseMixin(LitEle
|
|
|
106
110
|
this.noOptionsIcon = 'circle-info';
|
|
107
111
|
/** Enable search/filter functionality */
|
|
108
112
|
this.searchable = false;
|
|
113
|
+
/** Enable clear button to clear all selections */
|
|
114
|
+
this.clearable = true;
|
|
109
115
|
/** Placeholder text for the search input */
|
|
110
116
|
this.searchPlaceholder = 'Search options...';
|
|
111
117
|
/** Current search query */
|
|
112
118
|
this.searchQuery = '';
|
|
119
|
+
/** Maximum height of the options dropdown */
|
|
120
|
+
this.maxHeight = '';
|
|
113
121
|
/** Handles option selection logic */
|
|
114
122
|
this.selectionController = new SelectSelectionController(this);
|
|
115
123
|
/** Manages dropdown visibility and positioning */
|
|
@@ -381,6 +389,7 @@ let HySelectComponent = class HySelectComponent extends NuralyUIBaseMixin(LitEle
|
|
|
381
389
|
<slot name="label"></slot>
|
|
382
390
|
<div
|
|
383
391
|
class="${classMap(Object.assign({ 'wrapper': true }, validationClasses))}"
|
|
392
|
+
data-theme="${this.currentTheme}"
|
|
384
393
|
tabindex="0"
|
|
385
394
|
role="combobox"
|
|
386
395
|
aria-expanded="${this.show}"
|
|
@@ -411,6 +420,7 @@ let HySelectComponent = class HySelectComponent extends NuralyUIBaseMixin(LitEle
|
|
|
411
420
|
class="options"
|
|
412
421
|
role="listbox"
|
|
413
422
|
aria-multiselectable="${this.multiple}"
|
|
423
|
+
style=${this.maxHeight ? styleMap({ 'max-height': this.maxHeight }) : nothing}
|
|
414
424
|
>
|
|
415
425
|
${this.searchable ? this.renderSearchInput() : nothing}
|
|
416
426
|
${this.renderSelectOptions()}
|
|
@@ -448,7 +458,11 @@ let HySelectComponent = class HySelectComponent extends NuralyUIBaseMixin(LitEle
|
|
|
448
458
|
<hy-icon name="angle-down" class="arrow-icon"></hy-icon>
|
|
449
459
|
</button>
|
|
450
460
|
|
|
451
|
-
<div
|
|
461
|
+
<div
|
|
462
|
+
class="options"
|
|
463
|
+
role="listbox"
|
|
464
|
+
style=${this.maxHeight ? styleMap({ 'max-height': this.maxHeight }) : nothing}
|
|
465
|
+
>
|
|
452
466
|
${this.searchable ? this.renderSearchInput() : nothing}
|
|
453
467
|
${this.renderSelectOptions()}
|
|
454
468
|
</div>
|
|
@@ -460,7 +474,11 @@ let HySelectComponent = class HySelectComponent extends NuralyUIBaseMixin(LitEle
|
|
|
460
474
|
renderSlot() {
|
|
461
475
|
return html `
|
|
462
476
|
<slot name="trigger" @click=${this.handleTriggerClick}></slot>
|
|
463
|
-
<div
|
|
477
|
+
<div
|
|
478
|
+
class="options"
|
|
479
|
+
role="listbox"
|
|
480
|
+
style=${this.maxHeight ? styleMap({ 'max-height': this.maxHeight }) : nothing}
|
|
481
|
+
>
|
|
464
482
|
${this.searchable ? this.renderSearchInput() : nothing}
|
|
465
483
|
${this.renderSelectOptions()}
|
|
466
484
|
</div>
|
|
@@ -509,7 +527,7 @@ let HySelectComponent = class HySelectComponent extends NuralyUIBaseMixin(LitEle
|
|
|
509
527
|
* Renders the clear all selections button when applicable
|
|
510
528
|
*/
|
|
511
529
|
renderClearButton(selectedOptions) {
|
|
512
|
-
if (selectedOptions.length === 0 || this.disabled) {
|
|
530
|
+
if (!this.clearable || selectedOptions.length === 0 || this.disabled) {
|
|
513
531
|
return nothing;
|
|
514
532
|
}
|
|
515
533
|
return html `
|
|
@@ -653,12 +671,18 @@ __decorate([
|
|
|
653
671
|
__decorate([
|
|
654
672
|
property({ type: Boolean, reflect: true })
|
|
655
673
|
], HySelectComponent.prototype, "searchable", void 0);
|
|
674
|
+
__decorate([
|
|
675
|
+
property({ type: Boolean, reflect: true })
|
|
676
|
+
], HySelectComponent.prototype, "clearable", void 0);
|
|
656
677
|
__decorate([
|
|
657
678
|
property({ type: String, attribute: 'search-placeholder' })
|
|
658
679
|
], HySelectComponent.prototype, "searchPlaceholder", void 0);
|
|
659
680
|
__decorate([
|
|
660
681
|
property({ type: String })
|
|
661
682
|
], HySelectComponent.prototype, "searchQuery", void 0);
|
|
683
|
+
__decorate([
|
|
684
|
+
property({ type: String, attribute: 'max-height' })
|
|
685
|
+
], HySelectComponent.prototype, "maxHeight", void 0);
|
|
662
686
|
__decorate([
|
|
663
687
|
query('.options')
|
|
664
688
|
], HySelectComponent.prototype, "optionsElement", void 0);
|
package/select.component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.component.js","sourceRoot":"","sources":["../../../src/components/select/select.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { LitElement, html, nothing } from 'lit';\nimport { property, customElement, query } from 'lit/decorators.js';\nimport { styles } from './select.style.js';\nimport { map } from 'lit/directives/map.js';\nimport { choose } from 'lit/directives/choose.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { NuralyUIBaseMixin } from '../../shared/base-mixin.js';\n\n// Import types\nimport {\n SelectOption,\n SelectType,\n SelectSize,\n SelectStatus\n} from './select.types.js';\n\n// Import controllers\nimport {\n SelectSelectionController,\n SelectKeyboardController,\n SelectDropdownController,\n SelectFocusController,\n SelectValidationController,\n SelectSearchController,\n SelectEventController\n} from './controllers/index.js';\n\n// Import interfaces\nimport { SelectHost } from './interfaces/index.js';\n\n/**\n * Advanced select component with multiple selection modes, validation, and accessibility features.\n * \n * Supports single and multiple selection, custom rendering, validation states, keyboard navigation,\n * and various display types including default, inline, button, and slot-based configurations.\n * \n * @example\n * ```html\n * <!-- Basic select -->\n * <hy-select placeholder=\"Choose an option\">\n * <option value=\"1\">Option 1</option>\n * <option value=\"2\">Option 2</option>\n * </hy-select>\n * \n * <!-- Multiple selection -->\n * <hy-select multiple placeholder=\"Choose multiple options\"></hy-select>\n * \n * <!-- With validation -->\n * <hy-select required status=\"error\"></hy-select>\n * \n * <!-- Button style -->\n * <hy-select type=\"button\"></hy-select>\n * \n * <!-- With search functionality -->\n * <hy-select searchable search-placeholder=\"Search options...\"></hy-select>\n * ```\n * \n * @fires nr-change - Selection changed\n * @fires nr-focus - Component focused \n * @fires nr-blur - Component blurred\n * @fires nr-dropdown-open - Dropdown opened\n * @fires nr-dropdown-close - Dropdown closed\n * @fires nr-validation - Validation state changed\n * \n * @slot label - Select label content\n * @slot helper-text - Helper text below select\n * @slot trigger - Custom trigger content (slot type only)\n * \n * @cssproperty --select-border-color - Border color\n * @cssproperty --select-background - Background color\n * @cssproperty --select-text-color - Text color\n * @cssproperty --select-focus-color - Focus indicator color\n * @cssproperty --select-dropdown-shadow - Dropdown shadow\n * @cssproperty --select-no-options-color - No options message text color\n * @cssproperty --select-no-options-icon-color - No options icon color\n * @cssproperty --select-no-options-padding - Padding for no options message\n * @cssproperty --select-no-options-gap - Gap between icon and text\n * @cssproperty --select-search-border - Search input border\n * @cssproperty --select-search-background - Search input background\n * @cssproperty --select-search-padding - Search input padding\n */\n@customElement('hy-select')\nexport class HySelectComponent extends NuralyUIBaseMixin(LitElement) implements SelectHost {\n static override styles = styles;\n \n override requiredComponents = [ \"nr-input\", \"hy-icon\" ];\n\n /** Array of options to display in the select dropdown */\n @property({ type: Array }) \n options: SelectOption[] = [];\n \n /** Default selected values (for initialization) */\n @property({ type: Array, attribute: 'default-value' }) \n defaultValue: string[] = [];\n \n /** Placeholder text shown when no option is selected */\n @property({ type: String }) \n placeholder: string = 'Select an option';\n \n /** Disables the select component */\n @property({ type: Boolean, reflect: true }) \n disabled: boolean = false;\n \n /** Select display type (default, inline, button, slot) */\n @property({ type: String, reflect: true }) \n type: SelectType = SelectType.Default;\n \n /** Enables multiple option selection */\n @property({ type: Boolean, attribute: 'multiple' }) \n multiple: boolean = false;\n \n /** Controls dropdown visibility */\n @property({ type: Boolean, reflect: true }) \n show: boolean = false;\n \n /** Validation status (default, warning, error, success) */\n @property({ type: String, reflect: true }) \n status: SelectStatus = SelectStatus.Default;\n \n /** Select size (small, medium, large) */\n @property({ type: String, reflect: true }) \n size: SelectSize = SelectSize.Medium;\n \n /** Makes the select required for form validation */\n @property({ type: Boolean, reflect: true }) \n required: boolean = false;\n \n /** Form field name */\n @property({ type: String }) \n name: string = '';\n \n /** Current selected value(s) */\n @property({ type: String }) \n value: string | string[] = '';\n \n /** Message to display when no options are available */\n @property({ type: String, attribute: 'no-options-message' })\n noOptionsMessage: string = 'No options available';\n \n /** Icon to display with the no options message */\n @property({ type: String, attribute: 'no-options-icon' })\n noOptionsIcon: string = 'circle-info';\n \n /** Enable search/filter functionality */\n @property({ type: Boolean, reflect: true })\n searchable: boolean = false;\n \n /** Placeholder text for the search input */\n @property({ type: String, attribute: 'search-placeholder' })\n searchPlaceholder: string = 'Search options...';\n \n /** Current search query */\n @property({ type: String })\n searchQuery: string = '';\n\n /** Options dropdown container element */\n @query('.options') \n optionsElement!: HTMLElement;\n \n /** Main wrapper element */\n @query('.wrapper') \n wrapper!: HTMLElement;\n \n /** Search input element */\n @query('.search-input')\n searchInput?: HTMLInputElement;\n\n /** Handles option selection logic */\n private selectionController = new SelectSelectionController(this);\n \n /** Manages dropdown visibility and positioning */\n private dropdownController = new SelectDropdownController(this);\n \n /** Handles keyboard navigation */\n private keyboardController = new SelectKeyboardController(this, this.selectionController, this.dropdownController);\n \n /** Manages focus states */\n private focusController = new SelectFocusController(this);\n \n /** Handles validation logic */\n private validationController = new SelectValidationController(this, this.selectionController);\n \n /** Handles search/filter functionality */\n private searchController = new SelectSearchController(this);\n \n /** Handles all event management */\n private eventController = new SelectEventController(this);\n\n /**\n * Component connected to DOM - initialize base functionality\n */\n override connectedCallback(): void {\n super.connectedCallback();\n }\n\n /**\n * Component disconnected from DOM - cleanup event listeners\n */\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n\n /**\n * First render complete - setup controllers and initialize state\n */\n override firstUpdated(changedProperties: any): void {\n super.firstUpdated(changedProperties);\n \n // Configure dropdown controller with DOM element references\n if (this.optionsElement && this.wrapper) {\n this.dropdownController.setElements(this.optionsElement, this.wrapper);\n } else {\n // Retry element setup if DOM isn't ready yet\n setTimeout(() => {\n if (this.optionsElement && this.wrapper) {\n this.dropdownController.setElements(this.optionsElement, this.wrapper);\n }\n }, 100);\n }\n\n // Apply default selection if specified\n if (this.defaultValue.length > 0) {\n this.selectionController.initializeFromDefaultValue();\n }\n }\n\n // === Public API Methods ===\n\n /**\n * Gets the currently selected options\n * @returns Array of selected options\n */\n get selectedOptions(): SelectOption[] {\n return this.selectionController.getSelectedOptions();\n }\n\n /**\n * Gets the first selected option (for single selection mode)\n * @returns Selected option or undefined if none selected\n */\n get selectedOption(): SelectOption | undefined {\n return this.selectionController.getSelectedOption();\n }\n\n /**\n * Selects an option programmatically\n * @param option - The option to select\n */\n selectOption(option: SelectOption): void {\n this.selectionController.selectOption(option);\n }\n\n /**\n * Unselects an option programmatically\n * @param option - The option to unselect\n */\n unselectOption(option: SelectOption): void {\n this.selectionController.unselectOption(option);\n }\n\n /**\n * Clears all current selections\n */\n clearSelection(): void {\n this.selectionController.clearSelection();\n }\n\n /**\n * Checks if a specific option is currently selected\n * @param option - The option to check\n * @returns True if the option is selected\n */\n isOptionSelected(option: SelectOption): boolean {\n return this.selectionController.isOptionSelected(option);\n }\n\n /**\n * Toggles the dropdown visibility\n */\n toggleDropdown(): void {\n this.dropdownController.toggle();\n }\n\n /**\n * Opens the dropdown programmatically\n */\n openDropdown(): void {\n this.dropdownController.open();\n }\n\n /**\n * Closes the dropdown programmatically\n */\n closeDropdown(): void {\n this.dropdownController.close();\n }\n\n /**\n * Focuses the select component\n */\n override focus(): void {\n this.focusController.focus();\n }\n\n /**\n * Removes focus from the select component\n */\n override blur(): void {\n this.focusController.blur();\n }\n\n /**\n * Validates the current selection according to component rules\n * @returns True if valid, false otherwise\n */\n validate(): boolean {\n return this.validationController.validate();\n }\n\n /**\n * Checks if the current selection is valid without showing validation UI\n * @returns True if valid, false otherwise\n */\n checkValidity(): boolean {\n return this.validationController.checkValidity();\n }\n\n /**\n * Reports the current validation state and shows validation UI if invalid\n * @returns True if valid, false otherwise\n */\n reportValidity(): boolean {\n return this.validationController.reportValidity();\n }\n\n /**\n * Sets a custom validation message\n * @param message - Custom validation message (empty string to clear)\n */\n setCustomValidity(message: string): void {\n this.validationController.setCustomValidity(message);\n }\n\n /**\n * Searches for options with the given query\n * @param query - Search query string\n */\n searchOptions(query: string): void {\n this.searchController.search(query);\n }\n\n /**\n * Clears the current search query\n */\n clearSearch(): void {\n this.searchController.clearSearch();\n }\n\n /**\n * Gets the filtered options based on current search\n * @returns Array of filtered options\n */\n getSearchFilteredOptions(): SelectOption[] {\n return this.searchController.getFilteredOptions(this.options);\n }\n\n /**\n * Gets the current search query\n * @returns Current search query string\n */\n getCurrentSearchQuery(): string {\n return this.searchController.searchQuery;\n }\n\n /**\n * Manually trigger setup of global event listeners\n */\n setupGlobalEventListeners(): void {\n this.eventController.setupEventListeners();\n }\n\n /**\n * Manually trigger removal of global event listeners\n */\n removeGlobalEventListeners(): void {\n this.eventController.removeEventListeners();\n }\n\n \n /**\n * Handles clicks on the select trigger element\n */\n private handleTriggerClick = (event: Event): void => {\n this.eventController.handleTriggerClick(event);\n };\n\n /**\n * Handles clicks on individual options\n */\n private handleOptionClick = (event: Event, option: SelectOption): void => {\n this.eventController.handleOptionClick(event, option);\n };\n\n /**\n * Handles removal of selected tags in multiple selection mode\n */\n private handleTagRemove = (event: Event, option: SelectOption): void => {\n this.eventController.handleTagRemove(event, option);\n };\n\n /**\n * Handles the clear all selections button\n */\n private handleClearAll = (event: Event): void => {\n this.eventController.handleClearAll(event);\n };\n\n /**\n * Handles keyboard navigation and interactions\n */\n private handleKeyDown = (event: KeyboardEvent): void => {\n this.eventController.handleKeyDown(event);\n };\n\n /**\n * Handles focus events\n */\n private handleFocus = (): void => {\n this.eventController.handleFocus();\n };\n\n /**\n * Handles blur events\n */\n private handleBlur = (): void => {\n this.eventController.handleBlur();\n };\n\n /**\n * Filters options based on search query\n */\n private getFilteredOptions(): SelectOption[] {\n return this.searchController.getFilteredOptions(this.options);\n };\n\n /**\n * Sets up global event listeners (called when dropdown opens)\n */\n public setupEventListeners(): void {\n this.eventController.setupEventListeners();\n }\n\n /**\n * Removes global event listeners (called on disconnect or dropdown close)\n */\n public removeEventListeners(): void {\n this.eventController.removeEventListeners();\n }\n \n /**\n * Main render method that delegates to specific type renderers\n */\n protected override render() {\n return html`${choose(this.type, [\n [SelectType.Default, () => this.renderDefault()],\n [SelectType.Inline, () => this.renderInline()],\n [SelectType.Button, () => this.renderButton()],\n [SelectType.Slot, () => this.renderSlot()],\n ])}`;\n }\n /**\n * Renders the default select appearance with full features\n */\n private renderDefault() {\n const selectedOptions = this.selectedOptions;\n const validationClasses = this.validationController.getValidationClasses();\n \n return html`\n <slot name=\"label\"></slot>\n <div \n class=\"${classMap({\n 'wrapper': true,\n ...validationClasses\n })}\"\n tabindex=\"0\"\n role=\"combobox\"\n aria-expanded=\"${this.show}\"\n aria-haspopup=\"listbox\"\n aria-labelledby=\"select-label\"\n\n @click=${this.handleTriggerClick}\n @keydown=${this.handleKeyDown}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n >\n <div class=\"select\">\n <div class=\"select-trigger\">\n ${this.renderSelectedContent(selectedOptions)}\n </div>\n \n <div class=\"icons-container\">\n ${this.renderStatusIcon()}\n ${this.renderClearButton(selectedOptions)}\n <hy-icon \n name=\"angle-down\" \n class=\"arrow-icon\"\n aria-hidden=\"true\"\n ></hy-icon>\n </div>\n \n <div \n class=\"options\"\n role=\"listbox\"\n aria-multiselectable=\"${this.multiple}\"\n >\n ${this.searchable ? this.renderSearchInput() : nothing}\n ${this.renderSelectOptions()}\n </div>\n </div>\n </div>\n \n ${this.renderValidationMessage()}\n <slot name=\"helper-text\"></slot>\n `;\n }\n\n /**\n * Renders inline select with integrated label and helper text\n */\n private renderInline() {\n return html`\n <slot name=\"label\"></slot>\n ${this.renderDefault()}\n <slot name=\"helper-text\"></slot>\n `;\n }\n\n /**\n * Renders select as a button-style component\n */\n private renderButton() {\n const selectedOptions = this.selectedOptions;\n return html`\n <button\n class=\"select-button\"\n ?disabled=${this.disabled}\n @click=${this.handleTriggerClick}\n @keydown=${this.handleKeyDown}\n >\n ${selectedOptions.length > 0 ? selectedOptions[0].label : this.placeholder}\n <hy-icon name=\"angle-down\" class=\"arrow-icon\"></hy-icon>\n </button>\n \n <div class=\"options\" role=\"listbox\">\n ${this.searchable ? this.renderSearchInput() : nothing}\n ${this.renderSelectOptions()}\n </div>\n `;\n }\n\n /**\n * Renders select with custom trigger content via slots\n */\n private renderSlot() {\n return html`\n <slot name=\"trigger\" @click=${this.handleTriggerClick}></slot>\n <div class=\"options\" role=\"listbox\">\n ${this.searchable ? this.renderSearchInput() : nothing}\n ${this.renderSelectOptions()}\n </div>\n `;\n }\n\n /**\n * Renders the selected content in the trigger area\n */\n private renderSelectedContent(selectedOptions: SelectOption[]) {\n if (selectedOptions.length === 0) {\n return html`<span class=\"placeholder\" aria-hidden=\"true\">${this.placeholder}</span>`;\n }\n\n if (this.multiple) {\n return map(selectedOptions, (option) => html`\n <span class=\"tag\">\n <span class=\"tag-label\">${option.label}</span>\n <hy-icon \n name=\"remove\"\n class=\"tag-close\"\n @click=${(e: Event) => this.handleTagRemove(e, option)}\n aria-label=\"Remove ${option.label}\"\n ></hy-icon>\n </span>\n `);\n } else {\n return html`${selectedOptions[0].label}`;\n }\n }\n\n /**\n * Renders status/validation icons based on current status\n */\n private renderStatusIcon() {\n switch (this.status) {\n case SelectStatus.Warning:\n return html`<hy-icon name=\"warning\" class=\"status-icon warning\"></hy-icon>`;\n case SelectStatus.Error:\n return html`<hy-icon name=\"exclamation-circle\" class=\"status-icon error\"></hy-icon>`;\n case SelectStatus.Success:\n return html`<hy-icon name=\"check-circle\" class=\"status-icon success\"></hy-icon>`;\n default:\n return nothing;\n }\n }\n\n /**\n * Renders the clear all selections button when applicable\n */\n private renderClearButton(selectedOptions: SelectOption[]) {\n if (selectedOptions.length === 0 || this.disabled) {\n return nothing;\n }\n\n return html`\n <hy-icon\n name=\"remove\"\n class=\"clear-icon\"\n @click=${this.handleClearAll}\n aria-label=\"Clear selection\"\n tabindex=\"-1\"\n ></hy-icon>\n `;\n }\n\n /**\n * Renders all available options in the dropdown\n */\n private renderSelectOptions() {\n const filteredOptions = this.getFilteredOptions();\n \n // Show \"no options\" message when no options are available (original array empty)\n if (!this.options || this.options.length === 0) {\n return html`\n <div class=\"no-options\" role=\"option\" aria-disabled=\"true\">\n <div class=\"no-options-content\">\n <hy-icon \n name=\"${this.noOptionsIcon}\" \n class=\"no-options-icon\"\n aria-hidden=\"true\">\n </hy-icon>\n <span class=\"no-options-text\">${this.noOptionsMessage}</span>\n </div>\n </div>\n `;\n }\n \n // Show \"no results\" message when search returns no results\n if (this.searchController.hasNoResults(this.options)) {\n return this.searchController.renderNoResults();\n }\n \n // Cache the focused option to avoid multiple controller accesses\n const focusedOption = this.keyboardController.focusedOption;\n \n return map(filteredOptions, (option) => {\n const isSelected = this.isOptionSelected(option);\n const isFocused = focusedOption && focusedOption.value === option.value;\n \n return html`\n <div\n class=\"${classMap({\n 'option': true,\n 'selected': isSelected,\n 'focused': isFocused,\n 'disabled': Boolean(option.disabled)\n })}\"\n role=\"option\"\n aria-selected=\"${isSelected}\"\n aria-disabled=\"${Boolean(option.disabled)}\"\n data-value=\"${option.value}\"\n @click=${(e: Event) => this.handleOptionClick(e, option)}\n style=${styleMap(option.style ? { style: option.style } : {})}\n title=\"${option.title || ''}\"\n >\n <div class=\"option-content\">\n ${option.icon ? html`<hy-icon name=\"${option.icon}\" class=\"option-icon\"></hy-icon>` : nothing}\n <div class=\"option-text\">\n ${option.htmlContent ? html`<div .innerHTML=${option.htmlContent}></div>` : option.label}\n ${option.description ? html`<div class=\"option-description\">${option.description}</div>` : nothing}\n </div>\n </div>\n \n ${isSelected ? html`<hy-icon name=\"check\" class=\"check-icon\" aria-hidden=\"true\"></hy-icon>` : nothing}\n \n ${option.state && option.message ? html`\n <div class=\"option-message ${option.state}\">\n <hy-icon name=\"${option.state === 'error' ? 'exclamation-circle' : 'warning'}\"></hy-icon>\n <span>${option.message}</span>\n </div>\n ` : nothing}\n </div>\n `;\n });\n }\n\n /**\n * Renders the search input when searchable is enabled\n */\n private renderSearchInput() {\n return this.searchController.renderSearchInput();\n }\n\n /**\n * Renders validation message when present\n */\n private renderValidationMessage() {\n const validationMessage = this.validationController.validationMessage;\n if (!validationMessage) return nothing;\n\n return html`\n <div class=\"validation-message ${this.status}\" id=\"validation-message\">\n ${validationMessage}\n </div>\n `;\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"select.component.js","sourceRoot":"","sources":["../../../src/components/select/select.component.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Nuraly, Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { LitElement, html, nothing } from 'lit';\nimport { property, customElement, query } from 'lit/decorators.js';\nimport { styles } from './select.style.js';\nimport { map } from 'lit/directives/map.js';\nimport { choose } from 'lit/directives/choose.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { NuralyUIBaseMixin } from '../../shared/base-mixin.js';\n\n// Import types\nimport {\n SelectOption,\n SelectType,\n SelectSize,\n SelectStatus\n} from './select.types.js';\n\n// Import controllers\nimport {\n SelectSelectionController,\n SelectKeyboardController,\n SelectDropdownController,\n SelectFocusController,\n SelectValidationController,\n SelectSearchController,\n SelectEventController\n} from './controllers/index.js';\n\n// Import interfaces\nimport { SelectHost } from './interfaces/index.js';\n\n/**\n * Advanced select component with multiple selection modes, validation, and accessibility features.\n * \n * Supports single and multiple selection, custom rendering, validation states, keyboard navigation,\n * and various display types including default, inline, button, and slot-based configurations.\n * \n * @example\n * ```html\n * <!-- Basic select -->\n * <hy-select placeholder=\"Choose an option\">\n * <option value=\"1\">Option 1</option>\n * <option value=\"2\">Option 2</option>\n * </hy-select>\n * \n * <!-- Multiple selection -->\n * <hy-select multiple placeholder=\"Choose multiple options\"></hy-select>\n * \n * <!-- With validation -->\n * <hy-select required status=\"error\"></hy-select>\n * \n * <!-- Button style -->\n * <hy-select type=\"button\"></hy-select>\n * \n * <!-- With search functionality -->\n * <hy-select searchable search-placeholder=\"Search options...\"></hy-select>\n * \n * <!-- Without clear button -->\n * <hy-select clearable=\"false\"></hy-select>\n * ```\n * \n * @fires nr-change - Selection changed\n * @fires nr-focus - Component focused \n * @fires nr-blur - Component blurred\n * @fires nr-dropdown-open - Dropdown opened\n * @fires nr-dropdown-close - Dropdown closed\n * @fires nr-validation - Validation state changed\n * \n * @slot label - Select label content\n * @slot helper-text - Helper text below select\n * @slot trigger - Custom trigger content (slot type only)\n * \n * @cssproperty --select-border-color - Border color\n * @cssproperty --select-background - Background color\n * @cssproperty --select-text-color - Text color\n * @cssproperty --select-focus-color - Focus indicator color\n * @cssproperty --select-dropdown-shadow - Dropdown shadow\n * @cssproperty --select-dropdown-max-height - Maximum height of dropdown\n * @cssproperty --select-no-options-color - No options message text color\n * @cssproperty --select-no-options-icon-color - No options icon color\n * @cssproperty --select-no-options-padding - Padding for no options message\n * @cssproperty --select-no-options-gap - Gap between icon and text\n * @cssproperty --select-search-border - Search input border\n * @cssproperty --select-search-background - Search input background\n * @cssproperty --select-search-padding - Search input padding\n */\n@customElement('hy-select')\nexport class HySelectComponent extends NuralyUIBaseMixin(LitElement) implements SelectHost {\n static override styles = styles;\n \n override requiredComponents = [ \"nr-input\", \"hy-icon\" ];\n\n /** Array of options to display in the select dropdown */\n @property({ type: Array }) \n options: SelectOption[] = [];\n \n /** Default selected values (for initialization) */\n @property({ type: Array, attribute: 'default-value' }) \n defaultValue: string[] = [];\n \n /** Placeholder text shown when no option is selected */\n @property({ type: String }) \n placeholder: string = 'Select an option';\n \n /** Disables the select component */\n @property({ type: Boolean, reflect: true }) \n disabled: boolean = false;\n \n /** Select display type (default, inline, button, slot) */\n @property({ type: String, reflect: true }) \n type: SelectType = SelectType.Default;\n \n /** Enables multiple option selection */\n @property({ type: Boolean, attribute: 'multiple' }) \n multiple: boolean = false;\n \n /** Controls dropdown visibility */\n @property({ type: Boolean, reflect: true }) \n show: boolean = false;\n \n /** Validation status (default, warning, error, success) */\n @property({ type: String, reflect: true }) \n status: SelectStatus = SelectStatus.Default;\n \n /** Select size (small, medium, large) */\n @property({ type: String, reflect: true }) \n size: SelectSize = SelectSize.Medium;\n \n /** Makes the select required for form validation */\n @property({ type: Boolean, reflect: true }) \n required: boolean = false;\n \n /** Form field name */\n @property({ type: String }) \n name: string = '';\n \n /** Current selected value(s) */\n @property({ type: String }) \n value: string | string[] = '';\n \n /** Message to display when no options are available */\n @property({ type: String, attribute: 'no-options-message' })\n noOptionsMessage: string = 'No options available';\n \n /** Icon to display with the no options message */\n @property({ type: String, attribute: 'no-options-icon' })\n noOptionsIcon: string = 'circle-info';\n \n /** Enable search/filter functionality */\n @property({ type: Boolean, reflect: true })\n searchable: boolean = false;\n \n /** Enable clear button to clear all selections */\n @property({ type: Boolean, reflect: true })\n clearable: boolean = true;\n \n /** Placeholder text for the search input */\n @property({ type: String, attribute: 'search-placeholder' })\n searchPlaceholder: string = 'Search options...';\n \n /** Current search query */\n @property({ type: String })\n searchQuery: string = '';\n\n /** Maximum height of the options dropdown */\n @property({ type: String, attribute: 'max-height' })\n maxHeight: string = '';\n\n /** Options dropdown container element */\n @query('.options') \n optionsElement!: HTMLElement;\n \n /** Main wrapper element */\n @query('.wrapper') \n wrapper!: HTMLElement;\n \n /** Search input element */\n @query('.search-input')\n searchInput?: HTMLInputElement;\n\n /** Handles option selection logic */\n private selectionController = new SelectSelectionController(this);\n \n /** Manages dropdown visibility and positioning */\n private dropdownController = new SelectDropdownController(this);\n \n /** Handles keyboard navigation */\n private keyboardController = new SelectKeyboardController(this, this.selectionController, this.dropdownController);\n \n /** Manages focus states */\n private focusController = new SelectFocusController(this);\n \n /** Handles validation logic */\n private validationController = new SelectValidationController(this, this.selectionController);\n \n /** Handles search/filter functionality */\n private searchController = new SelectSearchController(this);\n \n /** Handles all event management */\n private eventController = new SelectEventController(this);\n\n /**\n * Component connected to DOM - initialize base functionality\n */\n override connectedCallback(): void {\n super.connectedCallback();\n }\n\n /**\n * Component disconnected from DOM - cleanup event listeners\n */\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n }\n\n /**\n * First render complete - setup controllers and initialize state\n */\n override firstUpdated(changedProperties: any): void {\n super.firstUpdated(changedProperties);\n \n // Configure dropdown controller with DOM element references\n if (this.optionsElement && this.wrapper) {\n this.dropdownController.setElements(this.optionsElement, this.wrapper);\n } else {\n // Retry element setup if DOM isn't ready yet\n setTimeout(() => {\n if (this.optionsElement && this.wrapper) {\n this.dropdownController.setElements(this.optionsElement, this.wrapper);\n }\n }, 100);\n }\n\n // Apply default selection if specified\n if (this.defaultValue.length > 0) {\n this.selectionController.initializeFromDefaultValue();\n }\n }\n\n // === Public API Methods ===\n\n /**\n * Gets the currently selected options\n * @returns Array of selected options\n */\n get selectedOptions(): SelectOption[] {\n return this.selectionController.getSelectedOptions();\n }\n\n /**\n * Gets the first selected option (for single selection mode)\n * @returns Selected option or undefined if none selected\n */\n get selectedOption(): SelectOption | undefined {\n return this.selectionController.getSelectedOption();\n }\n\n /**\n * Selects an option programmatically\n * @param option - The option to select\n */\n selectOption(option: SelectOption): void {\n this.selectionController.selectOption(option);\n }\n\n /**\n * Unselects an option programmatically\n * @param option - The option to unselect\n */\n unselectOption(option: SelectOption): void {\n this.selectionController.unselectOption(option);\n }\n\n /**\n * Clears all current selections\n */\n clearSelection(): void {\n this.selectionController.clearSelection();\n }\n\n /**\n * Checks if a specific option is currently selected\n * @param option - The option to check\n * @returns True if the option is selected\n */\n isOptionSelected(option: SelectOption): boolean {\n return this.selectionController.isOptionSelected(option);\n }\n\n /**\n * Toggles the dropdown visibility\n */\n toggleDropdown(): void {\n this.dropdownController.toggle();\n }\n\n /**\n * Opens the dropdown programmatically\n */\n openDropdown(): void {\n this.dropdownController.open();\n }\n\n /**\n * Closes the dropdown programmatically\n */\n closeDropdown(): void {\n this.dropdownController.close();\n }\n\n /**\n * Focuses the select component\n */\n override focus(): void {\n this.focusController.focus();\n }\n\n /**\n * Removes focus from the select component\n */\n override blur(): void {\n this.focusController.blur();\n }\n\n /**\n * Validates the current selection according to component rules\n * @returns True if valid, false otherwise\n */\n validate(): boolean {\n return this.validationController.validate();\n }\n\n /**\n * Checks if the current selection is valid without showing validation UI\n * @returns True if valid, false otherwise\n */\n checkValidity(): boolean {\n return this.validationController.checkValidity();\n }\n\n /**\n * Reports the current validation state and shows validation UI if invalid\n * @returns True if valid, false otherwise\n */\n reportValidity(): boolean {\n return this.validationController.reportValidity();\n }\n\n /**\n * Sets a custom validation message\n * @param message - Custom validation message (empty string to clear)\n */\n setCustomValidity(message: string): void {\n this.validationController.setCustomValidity(message);\n }\n\n /**\n * Searches for options with the given query\n * @param query - Search query string\n */\n searchOptions(query: string): void {\n this.searchController.search(query);\n }\n\n /**\n * Clears the current search query\n */\n clearSearch(): void {\n this.searchController.clearSearch();\n }\n\n /**\n * Gets the filtered options based on current search\n * @returns Array of filtered options\n */\n getSearchFilteredOptions(): SelectOption[] {\n return this.searchController.getFilteredOptions(this.options);\n }\n\n /**\n * Gets the current search query\n * @returns Current search query string\n */\n getCurrentSearchQuery(): string {\n return this.searchController.searchQuery;\n }\n\n /**\n * Manually trigger setup of global event listeners\n */\n setupGlobalEventListeners(): void {\n this.eventController.setupEventListeners();\n }\n\n /**\n * Manually trigger removal of global event listeners\n */\n removeGlobalEventListeners(): void {\n this.eventController.removeEventListeners();\n }\n\n \n /**\n * Handles clicks on the select trigger element\n */\n private handleTriggerClick = (event: Event): void => {\n this.eventController.handleTriggerClick(event);\n };\n\n /**\n * Handles clicks on individual options\n */\n private handleOptionClick = (event: Event, option: SelectOption): void => {\n this.eventController.handleOptionClick(event, option);\n };\n\n /**\n * Handles removal of selected tags in multiple selection mode\n */\n private handleTagRemove = (event: Event, option: SelectOption): void => {\n this.eventController.handleTagRemove(event, option);\n };\n\n /**\n * Handles the clear all selections button\n */\n private handleClearAll = (event: Event): void => {\n this.eventController.handleClearAll(event);\n };\n\n /**\n * Handles keyboard navigation and interactions\n */\n private handleKeyDown = (event: KeyboardEvent): void => {\n this.eventController.handleKeyDown(event);\n };\n\n /**\n * Handles focus events\n */\n private handleFocus = (): void => {\n this.eventController.handleFocus();\n };\n\n /**\n * Handles blur events\n */\n private handleBlur = (): void => {\n this.eventController.handleBlur();\n };\n\n /**\n * Filters options based on search query\n */\n private getFilteredOptions(): SelectOption[] {\n return this.searchController.getFilteredOptions(this.options);\n };\n\n /**\n * Sets up global event listeners (called when dropdown opens)\n */\n public setupEventListeners(): void {\n this.eventController.setupEventListeners();\n }\n\n /**\n * Removes global event listeners (called on disconnect or dropdown close)\n */\n public removeEventListeners(): void {\n this.eventController.removeEventListeners();\n }\n \n /**\n * Main render method that delegates to specific type renderers\n */\n protected override render() {\n return html`${choose(this.type, [\n [SelectType.Default, () => this.renderDefault()],\n [SelectType.Inline, () => this.renderInline()],\n [SelectType.Button, () => this.renderButton()],\n [SelectType.Slot, () => this.renderSlot()],\n ])}`;\n }\n /**\n * Renders the default select appearance with full features\n */\n private renderDefault() {\n const selectedOptions = this.selectedOptions;\n const validationClasses = this.validationController.getValidationClasses();\n \n return html`\n <slot name=\"label\"></slot>\n <div \n class=\"${classMap({\n 'wrapper': true,\n ...validationClasses\n })}\"\n data-theme=\"${this.currentTheme}\"\n tabindex=\"0\"\n role=\"combobox\"\n aria-expanded=\"${this.show}\"\n aria-haspopup=\"listbox\"\n aria-labelledby=\"select-label\"\n\n @click=${this.handleTriggerClick}\n @keydown=${this.handleKeyDown}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n >\n <div class=\"select\">\n <div class=\"select-trigger\">\n ${this.renderSelectedContent(selectedOptions)}\n </div>\n \n <div class=\"icons-container\">\n ${this.renderStatusIcon()}\n ${this.renderClearButton(selectedOptions)}\n <hy-icon \n name=\"angle-down\" \n class=\"arrow-icon\"\n aria-hidden=\"true\"\n ></hy-icon>\n </div>\n \n <div \n class=\"options\"\n role=\"listbox\"\n aria-multiselectable=\"${this.multiple}\"\n style=${this.maxHeight ? styleMap({ 'max-height': this.maxHeight }) : nothing}\n >\n ${this.searchable ? this.renderSearchInput() : nothing}\n ${this.renderSelectOptions()}\n </div>\n </div>\n </div>\n \n ${this.renderValidationMessage()}\n <slot name=\"helper-text\"></slot>\n `;\n }\n\n /**\n * Renders inline select with integrated label and helper text\n */\n private renderInline() {\n return html`\n <slot name=\"label\"></slot>\n ${this.renderDefault()}\n <slot name=\"helper-text\"></slot>\n `;\n }\n\n /**\n * Renders select as a button-style component\n */\n private renderButton() {\n const selectedOptions = this.selectedOptions;\n return html`\n <button\n class=\"select-button\"\n ?disabled=${this.disabled}\n @click=${this.handleTriggerClick}\n @keydown=${this.handleKeyDown}\n >\n ${selectedOptions.length > 0 ? selectedOptions[0].label : this.placeholder}\n <hy-icon name=\"angle-down\" class=\"arrow-icon\"></hy-icon>\n </button>\n \n <div \n class=\"options\" \n role=\"listbox\"\n style=${this.maxHeight ? styleMap({ 'max-height': this.maxHeight }) : nothing}\n >\n ${this.searchable ? this.renderSearchInput() : nothing}\n ${this.renderSelectOptions()}\n </div>\n `;\n }\n\n /**\n * Renders select with custom trigger content via slots\n */\n private renderSlot() {\n return html`\n <slot name=\"trigger\" @click=${this.handleTriggerClick}></slot>\n <div \n class=\"options\" \n role=\"listbox\"\n style=${this.maxHeight ? styleMap({ 'max-height': this.maxHeight }) : nothing}\n >\n ${this.searchable ? this.renderSearchInput() : nothing}\n ${this.renderSelectOptions()}\n </div>\n `;\n }\n\n /**\n * Renders the selected content in the trigger area\n */\n private renderSelectedContent(selectedOptions: SelectOption[]) {\n if (selectedOptions.length === 0) {\n return html`<span class=\"placeholder\" aria-hidden=\"true\">${this.placeholder}</span>`;\n }\n\n if (this.multiple) {\n return map(selectedOptions, (option) => html`\n <span class=\"tag\">\n <span class=\"tag-label\">${option.label}</span>\n <hy-icon \n name=\"remove\"\n class=\"tag-close\"\n @click=${(e: Event) => this.handleTagRemove(e, option)}\n aria-label=\"Remove ${option.label}\"\n ></hy-icon>\n </span>\n `);\n } else {\n return html`${selectedOptions[0].label}`;\n }\n }\n\n /**\n * Renders status/validation icons based on current status\n */\n private renderStatusIcon() {\n switch (this.status) {\n case SelectStatus.Warning:\n return html`<hy-icon name=\"warning\" class=\"status-icon warning\"></hy-icon>`;\n case SelectStatus.Error:\n return html`<hy-icon name=\"exclamation-circle\" class=\"status-icon error\"></hy-icon>`;\n case SelectStatus.Success:\n return html`<hy-icon name=\"check-circle\" class=\"status-icon success\"></hy-icon>`;\n default:\n return nothing;\n }\n }\n\n /**\n * Renders the clear all selections button when applicable\n */\n private renderClearButton(selectedOptions: SelectOption[]) {\n if (!this.clearable || selectedOptions.length === 0 || this.disabled) {\n return nothing;\n }\n\n return html`\n <hy-icon\n name=\"remove\"\n class=\"clear-icon\"\n @click=${this.handleClearAll}\n aria-label=\"Clear selection\"\n tabindex=\"-1\"\n ></hy-icon>\n `;\n }\n\n /**\n * Renders all available options in the dropdown\n */\n private renderSelectOptions() {\n const filteredOptions = this.getFilteredOptions();\n \n // Show \"no options\" message when no options are available (original array empty)\n if (!this.options || this.options.length === 0) {\n return html`\n <div class=\"no-options\" role=\"option\" aria-disabled=\"true\">\n <div class=\"no-options-content\">\n <hy-icon \n name=\"${this.noOptionsIcon}\" \n class=\"no-options-icon\"\n aria-hidden=\"true\">\n </hy-icon>\n <span class=\"no-options-text\">${this.noOptionsMessage}</span>\n </div>\n </div>\n `;\n }\n \n // Show \"no results\" message when search returns no results\n if (this.searchController.hasNoResults(this.options)) {\n return this.searchController.renderNoResults();\n }\n \n // Cache the focused option to avoid multiple controller accesses\n const focusedOption = this.keyboardController.focusedOption;\n \n return map(filteredOptions, (option) => {\n const isSelected = this.isOptionSelected(option);\n const isFocused = focusedOption && focusedOption.value === option.value;\n \n return html`\n <div\n class=\"${classMap({\n 'option': true,\n 'selected': isSelected,\n 'focused': isFocused,\n 'disabled': Boolean(option.disabled)\n })}\"\n role=\"option\"\n aria-selected=\"${isSelected}\"\n aria-disabled=\"${Boolean(option.disabled)}\"\n data-value=\"${option.value}\"\n @click=${(e: Event) => this.handleOptionClick(e, option)}\n style=${styleMap(option.style ? { style: option.style } : {})}\n title=\"${option.title || ''}\"\n >\n <div class=\"option-content\">\n ${option.icon ? html`<hy-icon name=\"${option.icon}\" class=\"option-icon\"></hy-icon>` : nothing}\n <div class=\"option-text\">\n ${option.htmlContent ? html`<div .innerHTML=${option.htmlContent}></div>` : option.label}\n ${option.description ? html`<div class=\"option-description\">${option.description}</div>` : nothing}\n </div>\n </div>\n \n ${isSelected ? html`<hy-icon name=\"check\" class=\"check-icon\" aria-hidden=\"true\"></hy-icon>` : nothing}\n \n ${option.state && option.message ? html`\n <div class=\"option-message ${option.state}\">\n <hy-icon name=\"${option.state === 'error' ? 'exclamation-circle' : 'warning'}\"></hy-icon>\n <span>${option.message}</span>\n </div>\n ` : nothing}\n </div>\n `;\n });\n }\n\n /**\n * Renders the search input when searchable is enabled\n */\n private renderSearchInput() {\n return this.searchController.renderSearchInput();\n }\n\n /**\n * Renders validation message when present\n */\n private renderValidationMessage() {\n const validationMessage = this.validationController.validationMessage;\n if (!validationMessage) return nothing;\n\n return html`\n <div class=\"validation-message ${this.status}\" id=\"validation-message\">\n ${validationMessage}\n </div>\n `;\n }\n}"]}
|
package/select.style.js
CHANGED
|
@@ -25,18 +25,66 @@ export const styles = css `
|
|
|
25
25
|
cursor: not-allowed;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/*
|
|
29
|
-
|
|
28
|
+
/*
|
|
29
|
+
* Light theme styles using data-theme attribute on wrapper element
|
|
30
|
+
* These are explicit light theme overrides when data-theme="light" is applied
|
|
31
|
+
*/
|
|
32
|
+
.wrapper[data-theme="light"] {
|
|
33
|
+
/* Select wrapper light theme overrides */
|
|
34
|
+
--hybrid-select-local-background-color: #ffffff;
|
|
35
|
+
--hybrid-select-local-border-color: #d9d9d9;
|
|
36
|
+
--hybrid-select-local-text-color: #262626;
|
|
37
|
+
--hybrid-select-local-placeholder-color: #8c8c8c;
|
|
38
|
+
--hybrid-select-local-hover-border-color: #1677ff;
|
|
39
|
+
--hybrid-select-local-focus-border-color: #1677ff;
|
|
40
|
+
|
|
41
|
+
/* Dropdown light theme overrides */
|
|
42
|
+
--hybrid-select-local-dropdown-background: #ffffff;
|
|
43
|
+
--hybrid-select-local-dropdown-border-color: #d9d9d9;
|
|
44
|
+
--hybrid-select-local-option-hover-background: #f5f5f5;
|
|
45
|
+
--hybrid-select-local-option-selected-background: #e6f7ff;
|
|
46
|
+
--hybrid-select-local-option-selected-color: #1677ff;
|
|
47
|
+
|
|
48
|
+
/* Tag styles for multi-select light theme */
|
|
49
|
+
--hybrid-select-local-tag-background: #f0f0f0;
|
|
50
|
+
--hybrid-select-local-tag-color: #262626;
|
|
51
|
+
--hybrid-select-local-tag-close-color: #8c8c8c;
|
|
52
|
+
--hybrid-select-local-tag-close-hover-color: #da1e28;
|
|
53
|
+
|
|
54
|
+
/* Icon colors for light theme */
|
|
55
|
+
--hybrid-select-local-icon-color: #8c8c8c;
|
|
56
|
+
--hybrid-select-local-icon-hover-color: #1677ff;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/*
|
|
60
|
+
* Dark theme styles using data-theme attribute on wrapper element
|
|
61
|
+
* These override the light theme defaults when data-theme="dark" is applied
|
|
62
|
+
*/
|
|
63
|
+
.wrapper[data-theme="dark"] {
|
|
64
|
+
/* Select wrapper dark theme overrides */
|
|
30
65
|
--hybrid-select-local-background-color: #262626;
|
|
31
66
|
--hybrid-select-local-border-color: #424242;
|
|
32
67
|
--hybrid-select-local-text-color: #ffffff;
|
|
33
68
|
--hybrid-select-local-placeholder-color: #8c8c8c;
|
|
69
|
+
--hybrid-select-local-hover-border-color: #4096ff;
|
|
70
|
+
--hybrid-select-local-focus-border-color: #4096ff;
|
|
71
|
+
|
|
72
|
+
/* Dropdown dark theme overrides */
|
|
34
73
|
--hybrid-select-local-dropdown-background: #262626;
|
|
35
74
|
--hybrid-select-local-dropdown-border-color: #424242;
|
|
36
75
|
--hybrid-select-local-option-hover-background: #393939;
|
|
37
76
|
--hybrid-select-local-option-selected-background: #1e3a5f;
|
|
38
|
-
--hybrid-select-local-
|
|
39
|
-
|
|
77
|
+
--hybrid-select-local-option-selected-color: #4096ff;
|
|
78
|
+
|
|
79
|
+
/* Tag styles for multi-select dark theme */
|
|
80
|
+
--hybrid-select-local-tag-background: #393939;
|
|
81
|
+
--hybrid-select-local-tag-color: #ffffff;
|
|
82
|
+
--hybrid-select-local-tag-close-color: #8c8c8c;
|
|
83
|
+
--hybrid-select-local-tag-close-hover-color: #ff4d4f;
|
|
84
|
+
|
|
85
|
+
/* Icon colors for dark theme */
|
|
86
|
+
--hybrid-select-local-icon-color: #8c8c8c;
|
|
87
|
+
--hybrid-select-local-icon-hover-color: #4096ff;
|
|
40
88
|
}
|
|
41
89
|
|
|
42
90
|
/* Size variants */
|
|
@@ -239,7 +287,7 @@ export const styles = css `
|
|
|
239
287
|
border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));
|
|
240
288
|
box-shadow: var(--hybrid-select-dropdown-shadow, var(--hybrid-select-local-dropdown-shadow));
|
|
241
289
|
z-index: var(--hybrid-select-dropdown-z-index, var(--hybrid-select-local-dropdown-z-index));
|
|
242
|
-
max-height:
|
|
290
|
+
max-height: var(--hybrid-select-dropdown-max-height, var(--hybrid-select-local-dropdown-max-height));
|
|
243
291
|
overflow-y: auto;
|
|
244
292
|
overflow-x: hidden;
|
|
245
293
|
display: none;
|
|
@@ -287,6 +335,62 @@ export const styles = css `
|
|
|
287
335
|
}
|
|
288
336
|
}
|
|
289
337
|
|
|
338
|
+
/* Search container - sticky at top of dropdown */
|
|
339
|
+
.search-container {
|
|
340
|
+
position: sticky;
|
|
341
|
+
top: 0;
|
|
342
|
+
z-index: 10;
|
|
343
|
+
background-color: var(--hybrid-select-dropdown-background, var(--hybrid-select-local-dropdown-background));
|
|
344
|
+
border-bottom: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid
|
|
345
|
+
var(--hybrid-select-dropdown-border-color, var(--hybrid-select-local-dropdown-border-color));
|
|
346
|
+
padding: 8px;
|
|
347
|
+
margin: 0;
|
|
348
|
+
/* Ensure it stays above options during scroll */
|
|
349
|
+
backdrop-filter: blur(8px);
|
|
350
|
+
-webkit-backdrop-filter: blur(8px);
|
|
351
|
+
/* Ensure proper stacking and smooth scrolling */
|
|
352
|
+
will-change: transform;
|
|
353
|
+
transform: translateZ(0);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* Search input styling */
|
|
357
|
+
.search-container .search-input {
|
|
358
|
+
width: 100%;
|
|
359
|
+
--hybrid-input-border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));
|
|
360
|
+
--hybrid-input-background-color: var(--hybrid-select-background-color, var(--hybrid-select-local-background-color));
|
|
361
|
+
--hybrid-input-border-color: var(--hybrid-select-border-color, var(--hybrid-select-local-border-color));
|
|
362
|
+
--hybrid-input-text-color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));
|
|
363
|
+
--hybrid-input-placeholder-color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color));
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* Search icon in the search input */
|
|
367
|
+
.search-container .search-icon {
|
|
368
|
+
--hybrid-icon-color: var(--hybrid-select-icon-color, var(--hybrid-select-local-icon-color));
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* Dark theme overrides for search container */
|
|
372
|
+
.wrapper[data-theme="dark"] .search-container {
|
|
373
|
+
background-color: var(--hybrid-select-local-dropdown-background);
|
|
374
|
+
border-bottom-color: var(--hybrid-select-local-dropdown-border-color);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.wrapper[data-theme="dark"] .search-container .search-input {
|
|
378
|
+
--hybrid-input-background-color: var(--hybrid-select-local-background-color);
|
|
379
|
+
--hybrid-input-border-color: var(--hybrid-select-local-border-color);
|
|
380
|
+
--hybrid-input-text-color: var(--hybrid-select-local-text-color);
|
|
381
|
+
--hybrid-input-placeholder-color: var(--hybrid-select-local-placeholder-color);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.wrapper[data-theme="dark"] .search-container .search-icon {
|
|
385
|
+
--hybrid-icon-color: var(--hybrid-select-local-icon-color);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Options list container - ensure proper scroll behavior with sticky search */
|
|
389
|
+
.options:has(.search-container) {
|
|
390
|
+
/* Add small padding-top when search is present to ensure proper separation */
|
|
391
|
+
padding-top: 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
290
394
|
/* Option items */
|
|
291
395
|
.option {
|
|
292
396
|
display: flex;
|
|
@@ -300,6 +404,11 @@ export const styles = css `
|
|
|
300
404
|
position: relative;
|
|
301
405
|
}
|
|
302
406
|
|
|
407
|
+
/* First option after search container should have no extra margin */
|
|
408
|
+
.search-container + .option {
|
|
409
|
+
margin-top: 0;
|
|
410
|
+
}
|
|
411
|
+
|
|
303
412
|
.option:hover {
|
|
304
413
|
background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background));
|
|
305
414
|
}
|
package/select.style.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.style.js","sourceRoot":"","sources":["../../../src/components/select/select.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;IACrB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgclB,CAAC","sourcesContent":["import { css } from 'lit';\nimport { selectVariables } from './select.style.variables.js';\n\nexport const styles = css`\n ${selectVariables}\n\n :host {\n width: fit-content;\n display: block;\n font-family: var(--hybrid-select-font-family, var(--hybrid-select-local-font-family));\n font-size: var(--hybrid-select-font-size, var(--hybrid-select-local-font-size));\n line-height: var(--hybrid-select-line-height, var(--hybrid-select-local-line-height));\n margin: var(--hybrid-select-margin, var(--hybrid-select-local-wrapper-margin));\n }\n\n /* Host attribute selectors for configuration */\n :host([disabled]) {\n opacity: var(--hybrid-select-disabled-opacity, var(--hybrid-select-local-disabled-opacity));\n pointer-events: none;\n }\n\n :host([disabled]) .wrapper {\n background-color: var(--hybrid-select-disabled-background, var(--hybrid-select-local-disabled-background));\n border-color: var(--hybrid-select-disabled-border-color, var(--hybrid-select-local-disabled-border-color));\n color: var(--hybrid-select-disabled-text-color, var(--hybrid-select-local-disabled-text-color));\n cursor: not-allowed;\n }\n\n /* Theme-specific styles */\n :host([theme='dark']) {\n --hybrid-select-local-background-color: #262626;\n --hybrid-select-local-border-color: #424242;\n --hybrid-select-local-text-color: #ffffff;\n --hybrid-select-local-placeholder-color: #8c8c8c;\n --hybrid-select-local-dropdown-background: #262626;\n --hybrid-select-local-dropdown-border-color: #424242;\n --hybrid-select-local-option-hover-background: #393939;\n --hybrid-select-local-option-selected-background: #1e3a5f;\n --hybrid-select-local-hover-border-color: #4096ff;\n --hybrid-select-local-focus-border-color: #4096ff;\n }\n\n /* Size variants */\n :host([size='small']) .wrapper {\n min-height: var(--hybrid-select-small-height, var(--hybrid-select-local-small-height));\n font-size: var(--hybrid-select-small-font-size, var(--hybrid-select-local-small-font-size));\n }\n\n :host([size='small']) .select-trigger {\n padding: var(--hybrid-select-small-padding, var(--hybrid-select-local-small-padding));\n padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px);\n }\n\n :host([size='medium']) .wrapper {\n min-height: var(--hybrid-select-medium-height, var(--hybrid-select-local-medium-height));\n font-size: var(--hybrid-select-medium-font-size, var(--hybrid-select-local-medium-font-size));\n }\n\n :host([size='medium']) .select-trigger {\n padding: var(--hybrid-select-medium-padding, var(--hybrid-select-local-medium-padding));\n padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px);\n }\n\n :host([size='large']) .wrapper {\n min-height: var(--hybrid-select-large-height, var(--hybrid-select-local-large-height));\n font-size: var(--hybrid-select-large-font-size, var(--hybrid-select-local-large-font-size));\n }\n\n :host([size='large']) .select-trigger {\n padding: var(--hybrid-select-large-padding, var(--hybrid-select-local-large-padding));\n padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px);\n }\n\n /* Status variants */\n :host([status='error']) .wrapper {\n border-color: var(--hybrid-select-error-border-color, var(--hybrid-select-local-error-border-color));\n }\n\n :host([status='warning']) .wrapper {\n border-color: var(--hybrid-select-warning-border-color, var(--hybrid-select-local-warning-border-color));\n }\n\n :host([status='success']) .wrapper {\n border-color: var(--hybrid-select-success-border-color, var(--hybrid-select-local-success-border-color));\n }\n\n /* Type variants */\n :host([type='inline']) {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n :host([type='inline']) .wrapper {\n flex: 1;\n }\n\n /* Show dropdown */\n :host([show]) .options {\n display: flex !important;\n }\n\n /* Main wrapper container */\n .wrapper {\n position: relative;\n width: var(--hybrid-select-width, var(--hybrid-select-local-width));\n background-color: var(--hybrid-select-background-color, var(--hybrid-select-local-background-color));\n border: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid \n var(--hybrid-select-border-color, var(--hybrid-select-local-border-color));\n border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));\n transition: all var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)) \n var(--hybrid-select-transition-timing, var(--hybrid-select-local-transition-timing));\n cursor: pointer;\n outline: none;\n margin: var(--hybrid-select-wrapper-margin, 0);\n min-height: var(--hybrid-select-min-height, var(--hybrid-select-local-min-height));\n /* Ensure dropdown can overflow the wrapper */\n overflow: visible;\n }\n\n .wrapper:hover:not(:disabled) {\n border-color: var(--hybrid-select-hover-border-color, var(--hybrid-select-local-hover-border-color));\n }\n\n .wrapper:focus,\n .wrapper:focus-within {\n border-color: var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color));\n box-shadow: 0 0 0 2px var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color))33;\n }\n\n /* Select container */\n .select {\n display: flex;\n flex-direction: column;\n }\n\n /* Select trigger (main display area) */\n .select-trigger {\n display: flex;\n align-items: center;\n padding: var(--hybrid-select-padding-top, var(--hybrid-select-local-padding-top)) \n calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px) \n var(--hybrid-select-padding-bottom, var(--hybrid-select-local-padding-bottom)) \n var(--hybrid-select-padding-left, var(--hybrid-select-local-padding-left));\n color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n font-size: inherit;\n line-height: inherit;\n word-break: break-word;\n min-height: inherit;\n flex-wrap: wrap;\n gap: var(--hybrid-select-tag-margin, var(--hybrid-select-local-tag-margin));\n }\n\n .select-trigger:empty:before {\n content: attr(data-placeholder);\n color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color));\n font-size: var(--hybrid-select-placeholder-font-size, var(--hybrid-select-local-placeholder-font-size));\n }\n\n /* Multi-select tags */\n .tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background-color: var(--hybrid-select-tag-background, var(--hybrid-select-local-tag-background));\n color: var(--hybrid-select-tag-color, var(--hybrid-select-local-tag-color));\n padding: var(--hybrid-select-tag-padding, var(--hybrid-select-local-tag-padding));\n border-radius: var(--hybrid-select-tag-border-radius, var(--hybrid-select-local-tag-border-radius));\n font-size: calc(var(--hybrid-select-font-size, var(--hybrid-select-local-font-size)) - 1px);\n max-width: 100%;\n }\n\n .tag-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tag-close {\n color: var(--hybrid-select-tag-close-color, var(--hybrid-select-local-tag-close-color));\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n height: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n border-radius: 50%;\n transition: color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n }\n\n .tag-close:hover {\n color: var(--hybrid-select-tag-close-hover-color, var(--hybrid-select-local-tag-close-hover-color));\n }\n\n /* Icons container */\n .icons-container {\n position: absolute;\n top: 50%;\n right: 12px;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n gap: 4px;\n pointer-events: none;\n }\n\n .icons-container hy-icon {\n --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n --hybrid-icon-color: var(--hybrid-select-icon-color, var(--hybrid-select-local-icon-color));\n pointer-events: auto;\n cursor: pointer;\n transition: color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n }\n\n .icons-container hy-icon:hover {\n --hybrid-icon-color: var(--hybrid-select-icon-hover-color, var(--hybrid-select-local-icon-hover-color));\n }\n\n .arrow-icon {\n --hybrid-icon-width: var(--hybrid-select-arrow-icon-size, var(--hybrid-select-local-arrow-icon-size));\n transition: transform var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n pointer-events: none !important;\n }\n\n :host([show]) .arrow-icon {\n transform: rotate(180deg);\n }\n\n /* Dropdown options */\n .options {\n /* Default positioning - will be overridden by controller when opened */\n position: absolute;\n top: 100%;\n margin-top: 1px;\n left: 0;\n right: 0;\n background-color: var(--hybrid-select-dropdown-background, var(--hybrid-select-local-dropdown-background));\n border: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid \n var(--hybrid-select-dropdown-border-color, var(--hybrid-select-local-dropdown-border-color));\n border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));\n box-shadow: var(--hybrid-select-dropdown-shadow, var(--hybrid-select-local-dropdown-shadow));\n z-index: var(--hybrid-select-dropdown-z-index, var(--hybrid-select-local-dropdown-z-index));\n max-height: 200px;\n overflow-y: auto;\n overflow-x: hidden;\n display: none;\n flex-direction: column;\n animation: dropdown-enter var(--hybrid-select-dropdown-animation-duration, var(--hybrid-select-local-dropdown-animation-duration)) ease-out;\n /* Ensure proper containment and exact wrapper width */\n box-sizing: border-box;\n width: 100%;\n /* Create new stacking context to prevent layering issues */\n isolation: isolate;\n /* Ensure solid background to prevent visual bleed-through */\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n /* Force above other elements */\n transform: translateZ(0);\n }\n\n .options.placement-top {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n margin-top: 0;\n animation: dropdown-enter-top var(--hybrid-select-dropdown-animation-duration, var(--hybrid-select-local-dropdown-animation-duration)) ease-out;\n }\n\n @keyframes dropdown-enter {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes dropdown-enter-top {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n /* Option items */\n .option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size));\n cursor: pointer;\n transition: background-color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n position: relative;\n }\n\n .option:hover {\n background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background));\n }\n\n .option.selected {\n background-color: var(--hybrid-select-option-selected-background, var(--hybrid-select-local-option-selected-background));\n color: var(--hybrid-select-option-selected-color, var(--hybrid-select-local-option-selected-color));\n }\n\n .option.focused {\n background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background));\n outline: 2px solid var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color));\n outline-offset: -2px;\n }\n\n .option.disabled {\n opacity: var(--hybrid-select-disabled-opacity, var(--hybrid-select-local-disabled-opacity));\n cursor: not-allowed;\n }\n\n .option-content {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .option-icon {\n --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n --hybrid-icon-color: currentColor;\n }\n\n .option-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .option-description {\n font-size: calc(var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size)) - 1px);\n opacity: 0.7;\n margin-top: 2px;\n }\n\n .check-icon {\n --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n --hybrid-icon-color: var(--hybrid-select-option-selected-color, var(--hybrid-select-local-option-selected-color));\n }\n\n /* No options message - styled like Ant Design */\n .no-options {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--select-no-options-padding, 24px 16px);\n color: var(--select-no-options-color, #8c8c8c);\n font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size));\n cursor: default;\n user-select: none;\n }\n\n .no-options-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--select-no-options-gap, 8px);\n text-align: center;\n }\n\n .no-options-icon {\n --hybrid-icon-width: 24px;\n --hybrid-icon-color: var(--select-no-options-icon-color, #d9d9d9);\n opacity: 0.8;\n }\n\n .no-options-text {\n font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size));\n color: var(--select-no-options-color, #8c8c8c);\n line-height: 1.4;\n }\n\n /* Dark theme adjustments for no-options */\n :host([theme='dark']) .no-options {\n color: var(--select-no-options-color, #595959);\n }\n\n :host([theme='dark']) .no-options-icon {\n --hybrid-icon-color: var(--select-no-options-icon-color, #434343);\n }\n\n :host([theme='dark']) .no-options-text {\n color: var(--select-no-options-color, #595959);\n }\n\n /* Validation message */\n .validation-message {\n display: block;\n margin-top: var(--hybrid-select-message-margin-top, var(--hybrid-select-local-message-margin-top));\n font-size: var(--hybrid-select-message-font-size, var(--hybrid-select-local-message-font-size));\n color: var(--hybrid-select-error-message-color, var(--hybrid-select-local-error-message-color));\n }\n\n .validation-message.warning {\n color: var(--hybrid-select-warning-message-color, var(--hybrid-select-local-warning-message-color));\n }\n\n .validation-message.success {\n color: var(--hybrid-select-success-message-color, var(--hybrid-select-local-success-message-color));\n }\n\n /* Slotted content styles */\n ::slotted([slot='label']) {\n display: block;\n margin-bottom: 4px;\n font-weight: 500;\n color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n }\n\n ::slotted([slot='helper-text']) {\n display: block;\n margin-top: var(--hybrid-select-message-margin-top, var(--hybrid-select-local-message-margin-top));\n font-size: var(--hybrid-select-message-font-size, var(--hybrid-select-local-message-font-size));\n color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color));\n }\n\n /* Accessibility improvements */\n @media (prefers-reduced-motion: reduce) {\n .options,\n .wrapper,\n .tag-close,\n .arrow-icon,\n .option {\n transition: none;\n animation: none;\n }\n }\n\n /* High contrast mode support */\n @media (prefers-contrast: high) {\n .wrapper {\n border-width: 2px;\n }\n \n .wrapper:focus,\n .wrapper:focus-within {\n outline: 3px solid;\n }\n }\n`;\n"]}
|
|
1
|
+
{"version":3,"file":"select.style.js","sourceRoot":"","sources":["../../../src/components/select/select.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;IACrB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6iBlB,CAAC","sourcesContent":["import { css } from 'lit';\nimport { selectVariables } from './select.style.variables.js';\n\nexport const styles = css`\n ${selectVariables}\n\n :host {\n width: fit-content;\n display: block;\n font-family: var(--hybrid-select-font-family, var(--hybrid-select-local-font-family));\n font-size: var(--hybrid-select-font-size, var(--hybrid-select-local-font-size));\n line-height: var(--hybrid-select-line-height, var(--hybrid-select-local-line-height));\n margin: var(--hybrid-select-margin, var(--hybrid-select-local-wrapper-margin));\n }\n\n /* Host attribute selectors for configuration */\n :host([disabled]) {\n opacity: var(--hybrid-select-disabled-opacity, var(--hybrid-select-local-disabled-opacity));\n pointer-events: none;\n }\n\n :host([disabled]) .wrapper {\n background-color: var(--hybrid-select-disabled-background, var(--hybrid-select-local-disabled-background));\n border-color: var(--hybrid-select-disabled-border-color, var(--hybrid-select-local-disabled-border-color));\n color: var(--hybrid-select-disabled-text-color, var(--hybrid-select-local-disabled-text-color));\n cursor: not-allowed;\n }\n\n /* \n * Light theme styles using data-theme attribute on wrapper element\n * These are explicit light theme overrides when data-theme=\"light\" is applied\n */\n .wrapper[data-theme=\"light\"] {\n /* Select wrapper light theme overrides */\n --hybrid-select-local-background-color: #ffffff;\n --hybrid-select-local-border-color: #d9d9d9;\n --hybrid-select-local-text-color: #262626;\n --hybrid-select-local-placeholder-color: #8c8c8c;\n --hybrid-select-local-hover-border-color: #1677ff;\n --hybrid-select-local-focus-border-color: #1677ff;\n \n /* Dropdown light theme overrides */\n --hybrid-select-local-dropdown-background: #ffffff;\n --hybrid-select-local-dropdown-border-color: #d9d9d9;\n --hybrid-select-local-option-hover-background: #f5f5f5;\n --hybrid-select-local-option-selected-background: #e6f7ff;\n --hybrid-select-local-option-selected-color: #1677ff;\n \n /* Tag styles for multi-select light theme */\n --hybrid-select-local-tag-background: #f0f0f0;\n --hybrid-select-local-tag-color: #262626;\n --hybrid-select-local-tag-close-color: #8c8c8c;\n --hybrid-select-local-tag-close-hover-color: #da1e28;\n \n /* Icon colors for light theme */\n --hybrid-select-local-icon-color: #8c8c8c;\n --hybrid-select-local-icon-hover-color: #1677ff;\n }\n\n /* \n * Dark theme styles using data-theme attribute on wrapper element\n * These override the light theme defaults when data-theme=\"dark\" is applied\n */\n .wrapper[data-theme=\"dark\"] {\n /* Select wrapper dark theme overrides */\n --hybrid-select-local-background-color: #262626;\n --hybrid-select-local-border-color: #424242;\n --hybrid-select-local-text-color: #ffffff;\n --hybrid-select-local-placeholder-color: #8c8c8c;\n --hybrid-select-local-hover-border-color: #4096ff;\n --hybrid-select-local-focus-border-color: #4096ff;\n \n /* Dropdown dark theme overrides */\n --hybrid-select-local-dropdown-background: #262626;\n --hybrid-select-local-dropdown-border-color: #424242;\n --hybrid-select-local-option-hover-background: #393939;\n --hybrid-select-local-option-selected-background: #1e3a5f;\n --hybrid-select-local-option-selected-color: #4096ff;\n \n /* Tag styles for multi-select dark theme */\n --hybrid-select-local-tag-background: #393939;\n --hybrid-select-local-tag-color: #ffffff;\n --hybrid-select-local-tag-close-color: #8c8c8c;\n --hybrid-select-local-tag-close-hover-color: #ff4d4f;\n \n /* Icon colors for dark theme */\n --hybrid-select-local-icon-color: #8c8c8c;\n --hybrid-select-local-icon-hover-color: #4096ff;\n }\n\n /* Size variants */\n :host([size='small']) .wrapper {\n min-height: var(--hybrid-select-small-height, var(--hybrid-select-local-small-height));\n font-size: var(--hybrid-select-small-font-size, var(--hybrid-select-local-small-font-size));\n }\n\n :host([size='small']) .select-trigger {\n padding: var(--hybrid-select-small-padding, var(--hybrid-select-local-small-padding));\n padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px);\n }\n\n :host([size='medium']) .wrapper {\n min-height: var(--hybrid-select-medium-height, var(--hybrid-select-local-medium-height));\n font-size: var(--hybrid-select-medium-font-size, var(--hybrid-select-local-medium-font-size));\n }\n\n :host([size='medium']) .select-trigger {\n padding: var(--hybrid-select-medium-padding, var(--hybrid-select-local-medium-padding));\n padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px);\n }\n\n :host([size='large']) .wrapper {\n min-height: var(--hybrid-select-large-height, var(--hybrid-select-local-large-height));\n font-size: var(--hybrid-select-large-font-size, var(--hybrid-select-local-large-font-size));\n }\n\n :host([size='large']) .select-trigger {\n padding: var(--hybrid-select-large-padding, var(--hybrid-select-local-large-padding));\n padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px);\n }\n\n /* Status variants */\n :host([status='error']) .wrapper {\n border-color: var(--hybrid-select-error-border-color, var(--hybrid-select-local-error-border-color));\n }\n\n :host([status='warning']) .wrapper {\n border-color: var(--hybrid-select-warning-border-color, var(--hybrid-select-local-warning-border-color));\n }\n\n :host([status='success']) .wrapper {\n border-color: var(--hybrid-select-success-border-color, var(--hybrid-select-local-success-border-color));\n }\n\n /* Type variants */\n :host([type='inline']) {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n :host([type='inline']) .wrapper {\n flex: 1;\n }\n\n /* Show dropdown */\n :host([show]) .options {\n display: flex !important;\n }\n\n /* Main wrapper container */\n .wrapper {\n position: relative;\n width: var(--hybrid-select-width, var(--hybrid-select-local-width));\n background-color: var(--hybrid-select-background-color, var(--hybrid-select-local-background-color));\n border: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid \n var(--hybrid-select-border-color, var(--hybrid-select-local-border-color));\n border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));\n transition: all var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)) \n var(--hybrid-select-transition-timing, var(--hybrid-select-local-transition-timing));\n cursor: pointer;\n outline: none;\n margin: var(--hybrid-select-wrapper-margin, 0);\n min-height: var(--hybrid-select-min-height, var(--hybrid-select-local-min-height));\n /* Ensure dropdown can overflow the wrapper */\n overflow: visible;\n }\n\n .wrapper:hover:not(:disabled) {\n border-color: var(--hybrid-select-hover-border-color, var(--hybrid-select-local-hover-border-color));\n }\n\n .wrapper:focus,\n .wrapper:focus-within {\n border-color: var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color));\n box-shadow: 0 0 0 2px var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color))33;\n }\n\n /* Select container */\n .select {\n display: flex;\n flex-direction: column;\n }\n\n /* Select trigger (main display area) */\n .select-trigger {\n display: flex;\n align-items: center;\n padding: var(--hybrid-select-padding-top, var(--hybrid-select-local-padding-top)) \n calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px) \n var(--hybrid-select-padding-bottom, var(--hybrid-select-local-padding-bottom)) \n var(--hybrid-select-padding-left, var(--hybrid-select-local-padding-left));\n color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n font-size: inherit;\n line-height: inherit;\n word-break: break-word;\n min-height: inherit;\n flex-wrap: wrap;\n gap: var(--hybrid-select-tag-margin, var(--hybrid-select-local-tag-margin));\n }\n\n .select-trigger:empty:before {\n content: attr(data-placeholder);\n color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color));\n font-size: var(--hybrid-select-placeholder-font-size, var(--hybrid-select-local-placeholder-font-size));\n }\n\n /* Multi-select tags */\n .tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background-color: var(--hybrid-select-tag-background, var(--hybrid-select-local-tag-background));\n color: var(--hybrid-select-tag-color, var(--hybrid-select-local-tag-color));\n padding: var(--hybrid-select-tag-padding, var(--hybrid-select-local-tag-padding));\n border-radius: var(--hybrid-select-tag-border-radius, var(--hybrid-select-local-tag-border-radius));\n font-size: calc(var(--hybrid-select-font-size, var(--hybrid-select-local-font-size)) - 1px);\n max-width: 100%;\n }\n\n .tag-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tag-close {\n color: var(--hybrid-select-tag-close-color, var(--hybrid-select-local-tag-close-color));\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n height: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n border-radius: 50%;\n transition: color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n }\n\n .tag-close:hover {\n color: var(--hybrid-select-tag-close-hover-color, var(--hybrid-select-local-tag-close-hover-color));\n }\n\n /* Icons container */\n .icons-container {\n position: absolute;\n top: 50%;\n right: 12px;\n transform: translateY(-50%);\n display: flex;\n align-items: center;\n gap: 4px;\n pointer-events: none;\n }\n\n .icons-container hy-icon {\n --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n --hybrid-icon-color: var(--hybrid-select-icon-color, var(--hybrid-select-local-icon-color));\n pointer-events: auto;\n cursor: pointer;\n transition: color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n }\n\n .icons-container hy-icon:hover {\n --hybrid-icon-color: var(--hybrid-select-icon-hover-color, var(--hybrid-select-local-icon-hover-color));\n }\n\n .arrow-icon {\n --hybrid-icon-width: var(--hybrid-select-arrow-icon-size, var(--hybrid-select-local-arrow-icon-size));\n transition: transform var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n pointer-events: none !important;\n }\n\n :host([show]) .arrow-icon {\n transform: rotate(180deg);\n }\n\n /* Dropdown options */\n .options {\n /* Default positioning - will be overridden by controller when opened */\n position: absolute;\n top: 100%;\n margin-top: 1px;\n left: 0;\n right: 0;\n background-color: var(--hybrid-select-dropdown-background, var(--hybrid-select-local-dropdown-background));\n border: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid \n var(--hybrid-select-dropdown-border-color, var(--hybrid-select-local-dropdown-border-color));\n border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));\n box-shadow: var(--hybrid-select-dropdown-shadow, var(--hybrid-select-local-dropdown-shadow));\n z-index: var(--hybrid-select-dropdown-z-index, var(--hybrid-select-local-dropdown-z-index));\n max-height: var(--hybrid-select-dropdown-max-height, var(--hybrid-select-local-dropdown-max-height));\n overflow-y: auto;\n overflow-x: hidden;\n display: none;\n flex-direction: column;\n animation: dropdown-enter var(--hybrid-select-dropdown-animation-duration, var(--hybrid-select-local-dropdown-animation-duration)) ease-out;\n /* Ensure proper containment and exact wrapper width */\n box-sizing: border-box;\n width: 100%;\n /* Create new stacking context to prevent layering issues */\n isolation: isolate;\n /* Ensure solid background to prevent visual bleed-through */\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n /* Force above other elements */\n transform: translateZ(0);\n }\n\n .options.placement-top {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n margin-top: 0;\n animation: dropdown-enter-top var(--hybrid-select-dropdown-animation-duration, var(--hybrid-select-local-dropdown-animation-duration)) ease-out;\n }\n\n @keyframes dropdown-enter {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes dropdown-enter-top {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n /* Search container - sticky at top of dropdown */\n .search-container {\n position: sticky;\n top: 0;\n z-index: 10;\n background-color: var(--hybrid-select-dropdown-background, var(--hybrid-select-local-dropdown-background));\n border-bottom: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid \n var(--hybrid-select-dropdown-border-color, var(--hybrid-select-local-dropdown-border-color));\n padding: 8px;\n margin: 0;\n /* Ensure it stays above options during scroll */\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n /* Ensure proper stacking and smooth scrolling */\n will-change: transform;\n transform: translateZ(0);\n }\n\n /* Search input styling */\n .search-container .search-input {\n width: 100%;\n --hybrid-input-border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius));\n --hybrid-input-background-color: var(--hybrid-select-background-color, var(--hybrid-select-local-background-color));\n --hybrid-input-border-color: var(--hybrid-select-border-color, var(--hybrid-select-local-border-color));\n --hybrid-input-text-color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n --hybrid-input-placeholder-color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color));\n }\n\n /* Search icon in the search input */\n .search-container .search-icon {\n --hybrid-icon-color: var(--hybrid-select-icon-color, var(--hybrid-select-local-icon-color));\n }\n\n /* Dark theme overrides for search container */\n .wrapper[data-theme=\"dark\"] .search-container {\n background-color: var(--hybrid-select-local-dropdown-background);\n border-bottom-color: var(--hybrid-select-local-dropdown-border-color);\n }\n\n .wrapper[data-theme=\"dark\"] .search-container .search-input {\n --hybrid-input-background-color: var(--hybrid-select-local-background-color);\n --hybrid-input-border-color: var(--hybrid-select-local-border-color);\n --hybrid-input-text-color: var(--hybrid-select-local-text-color);\n --hybrid-input-placeholder-color: var(--hybrid-select-local-placeholder-color);\n }\n\n .wrapper[data-theme=\"dark\"] .search-container .search-icon {\n --hybrid-icon-color: var(--hybrid-select-local-icon-color);\n }\n\n /* Options list container - ensure proper scroll behavior with sticky search */\n .options:has(.search-container) {\n /* Add small padding-top when search is present to ensure proper separation */\n padding-top: 0;\n }\n\n /* Option items */\n .option {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size));\n cursor: pointer;\n transition: background-color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration));\n position: relative;\n }\n\n /* First option after search container should have no extra margin */\n .search-container + .option {\n margin-top: 0;\n }\n\n .option:hover {\n background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background));\n }\n\n .option.selected {\n background-color: var(--hybrid-select-option-selected-background, var(--hybrid-select-local-option-selected-background));\n color: var(--hybrid-select-option-selected-color, var(--hybrid-select-local-option-selected-color));\n }\n\n .option.focused {\n background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background));\n outline: 2px solid var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color));\n outline-offset: -2px;\n }\n\n .option.disabled {\n opacity: var(--hybrid-select-disabled-opacity, var(--hybrid-select-local-disabled-opacity));\n cursor: not-allowed;\n }\n\n .option-content {\n flex: 1;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .option-icon {\n --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n --hybrid-icon-color: currentColor;\n }\n\n .option-text {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .option-description {\n font-size: calc(var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size)) - 1px);\n opacity: 0.7;\n margin-top: 2px;\n }\n\n .check-icon {\n --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size));\n --hybrid-icon-color: var(--hybrid-select-option-selected-color, var(--hybrid-select-local-option-selected-color));\n }\n\n /* No options message - styled like Ant Design */\n .no-options {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--select-no-options-padding, 24px 16px);\n color: var(--select-no-options-color, #8c8c8c);\n font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size));\n cursor: default;\n user-select: none;\n }\n\n .no-options-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--select-no-options-gap, 8px);\n text-align: center;\n }\n\n .no-options-icon {\n --hybrid-icon-width: 24px;\n --hybrid-icon-color: var(--select-no-options-icon-color, #d9d9d9);\n opacity: 0.8;\n }\n\n .no-options-text {\n font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size));\n color: var(--select-no-options-color, #8c8c8c);\n line-height: 1.4;\n }\n\n /* Dark theme adjustments for no-options */\n :host([theme='dark']) .no-options {\n color: var(--select-no-options-color, #595959);\n }\n\n :host([theme='dark']) .no-options-icon {\n --hybrid-icon-color: var(--select-no-options-icon-color, #434343);\n }\n\n :host([theme='dark']) .no-options-text {\n color: var(--select-no-options-color, #595959);\n }\n\n /* Validation message */\n .validation-message {\n display: block;\n margin-top: var(--hybrid-select-message-margin-top, var(--hybrid-select-local-message-margin-top));\n font-size: var(--hybrid-select-message-font-size, var(--hybrid-select-local-message-font-size));\n color: var(--hybrid-select-error-message-color, var(--hybrid-select-local-error-message-color));\n }\n\n .validation-message.warning {\n color: var(--hybrid-select-warning-message-color, var(--hybrid-select-local-warning-message-color));\n }\n\n .validation-message.success {\n color: var(--hybrid-select-success-message-color, var(--hybrid-select-local-success-message-color));\n }\n\n /* Slotted content styles */\n ::slotted([slot='label']) {\n display: block;\n margin-bottom: 4px;\n font-weight: 500;\n color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color));\n }\n\n ::slotted([slot='helper-text']) {\n display: block;\n margin-top: var(--hybrid-select-message-margin-top, var(--hybrid-select-local-message-margin-top));\n font-size: var(--hybrid-select-message-font-size, var(--hybrid-select-local-message-font-size));\n color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color));\n }\n\n /* Accessibility improvements */\n @media (prefers-reduced-motion: reduce) {\n .options,\n .wrapper,\n .tag-close,\n .arrow-icon,\n .option {\n transition: none;\n animation: none;\n }\n }\n\n /* High contrast mode support */\n @media (prefers-contrast: high) {\n .wrapper {\n border-width: 2px;\n }\n \n .wrapper:focus,\n .wrapper:focus-within {\n outline: 3px solid;\n }\n }\n`;\n"]}
|
|
@@ -32,6 +32,7 @@ export const selectVariables = css `
|
|
|
32
32
|
--hybrid-select-local-dropdown-border-color: #d9d9d9;
|
|
33
33
|
--hybrid-select-local-dropdown-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08);
|
|
34
34
|
--hybrid-select-local-dropdown-z-index: 9999;
|
|
35
|
+
--hybrid-select-local-dropdown-max-height: 200px;
|
|
35
36
|
--hybrid-select-local-option-hover-background: #f5f5f5;
|
|
36
37
|
--hybrid-select-local-option-selected-background: #e6f7ff;
|
|
37
38
|
--hybrid-select-local-option-selected-color: #1677ff;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.style.variables.js","sourceRoot":"","sources":["../../../src/components/select/select.style.variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"select.style.variables.js","sourceRoot":"","sources":["../../../src/components/select/select.style.variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFjC,CAAC","sourcesContent":["import { css } from 'lit';\n\n/**\n * CSS custom properties for select component (light theme defaults)\n * These are the local component defaults that can be overridden globally\n */\nexport const selectVariables = css`\n :host {\n /* Layout and sizing */\n --hybrid-select-local-width: 300px;\n --hybrid-select-local-min-height: 40px;\n --hybrid-select-local-padding-top: 8px;\n --hybrid-select-local-padding-bottom: 8px;\n --hybrid-select-local-padding-left: 12px;\n --hybrid-select-local-padding-right: 12px;\n --hybrid-select-local-wrapper-margin: 0;\n --hybrid-select-local-border-radius: 6px;\n --hybrid-select-local-border-width: 1px;\n \n /* Colors - Light theme defaults */\n --hybrid-select-local-background-color: #ffffff;\n --hybrid-select-local-border-color: #d9d9d9;\n --hybrid-select-local-text-color: #262626;\n --hybrid-select-local-placeholder-color: #8c8c8c;\n --hybrid-select-local-hover-border-color: #1677ff;\n --hybrid-select-local-focus-border-color: #1677ff;\n --hybrid-select-local-error-border-color: #da1e28;\n --hybrid-select-local-warning-border-color: #f0c300;\n --hybrid-select-local-success-border-color: #52c41a;\n \n /* Dropdown colors */\n --hybrid-select-local-dropdown-background: #ffffff;\n --hybrid-select-local-dropdown-border-color: #d9d9d9;\n --hybrid-select-local-dropdown-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08);\n --hybrid-select-local-dropdown-z-index: 9999;\n --hybrid-select-local-dropdown-max-height: 200px;\n --hybrid-select-local-option-hover-background: #f5f5f5;\n --hybrid-select-local-option-selected-background: #e6f7ff;\n --hybrid-select-local-option-selected-color: #1677ff;\n \n /* Typography */\n --hybrid-select-local-font-family: Inter, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif;\n --hybrid-select-local-font-size: 14px;\n --hybrid-select-local-line-height: 1.5;\n --hybrid-select-local-placeholder-font-size: 14px;\n --hybrid-select-local-option-font-size: 14px;\n \n /* Icon settings */\n --hybrid-select-local-icon-size: 16px;\n --hybrid-select-local-icon-color: #8c8c8c;\n --hybrid-select-local-icon-hover-color: #1677ff;\n --hybrid-select-local-arrow-icon-size: 12px;\n \n /* Sizes */\n --hybrid-select-local-small-height: 24px;\n --hybrid-select-local-small-font-size: 12px;\n --hybrid-select-local-small-padding: 4px 8px;\n \n --hybrid-select-local-medium-height: 32px;\n --hybrid-select-local-medium-font-size: 14px;\n --hybrid-select-local-medium-padding: 4px 12px;\n \n --hybrid-select-local-large-height: 40px;\n --hybrid-select-local-large-font-size: 16px;\n --hybrid-select-local-large-padding: 6px 12px;\n \n /* States */\n --hybrid-select-local-disabled-opacity: 0.5;\n --hybrid-select-local-disabled-background: #f5f5f5;\n --hybrid-select-local-disabled-border-color: #d9d9d9;\n --hybrid-select-local-disabled-text-color: #8c8c8c;\n \n /* Animation and transitions */\n --hybrid-select-local-transition-duration: 0.2s;\n --hybrid-select-local-transition-timing: ease-in-out;\n --hybrid-select-local-dropdown-animation-duration: 0.15s;\n \n /* Multi-select specific */\n --hybrid-select-local-tag-background: #f0f0f0;\n --hybrid-select-local-tag-color: #262626;\n --hybrid-select-local-tag-border-radius: 4px;\n --hybrid-select-local-tag-padding: 2px 6px;\n --hybrid-select-local-tag-margin: 2px;\n --hybrid-select-local-tag-close-color: #8c8c8c;\n --hybrid-select-local-tag-close-hover-color: #da1e28;\n \n /* Validation message */\n --hybrid-select-local-message-font-size: 12px;\n --hybrid-select-local-message-margin-top: 4px;\n --hybrid-select-local-error-message-color: #da1e28;\n --hybrid-select-local-warning-message-color: #f0c300;\n --hybrid-select-local-success-message-color: #52c41a;\n }\n`;\n"]}
|