UNPKG

@nuralyui/select

Version:

A comprehensive select component with advanced features including multi-selection, keyboard navigation, validation, and accessibility support.

562 lines (487 loc) 20.8 kB
import { css } from 'lit'; import { selectVariables } from './select.style.variables.js'; export const styles = css ` ${selectVariables} :host { width: fit-content; display: block; font-family: var(--hybrid-select-font-family, var(--hybrid-select-local-font-family)); font-size: var(--hybrid-select-font-size, var(--hybrid-select-local-font-size)); line-height: var(--hybrid-select-line-height, var(--hybrid-select-local-line-height)); margin: var(--hybrid-select-margin, var(--hybrid-select-local-wrapper-margin)); } /* Host attribute selectors for configuration */ :host([disabled]) { opacity: var(--hybrid-select-disabled-opacity, var(--hybrid-select-local-disabled-opacity)); pointer-events: none; } :host([disabled]) .wrapper { background-color: var(--hybrid-select-disabled-background, var(--hybrid-select-local-disabled-background)); border-color: var(--hybrid-select-disabled-border-color, var(--hybrid-select-local-disabled-border-color)); color: var(--hybrid-select-disabled-text-color, var(--hybrid-select-local-disabled-text-color)); cursor: not-allowed; } /* * Light theme styles using data-theme attribute on wrapper element * These are explicit light theme overrides when data-theme="light" is applied */ .wrapper[data-theme="light"] { /* Select wrapper light theme overrides */ --hybrid-select-local-background-color: #ffffff; --hybrid-select-local-border-color: #d9d9d9; --hybrid-select-local-text-color: #262626; --hybrid-select-local-placeholder-color: #8c8c8c; --hybrid-select-local-hover-border-color: #1677ff; --hybrid-select-local-focus-border-color: #1677ff; /* Dropdown light theme overrides */ --hybrid-select-local-dropdown-background: #ffffff; --hybrid-select-local-dropdown-border-color: #d9d9d9; --hybrid-select-local-option-hover-background: #f5f5f5; --hybrid-select-local-option-selected-background: #e6f7ff; --hybrid-select-local-option-selected-color: #1677ff; /* Tag styles for multi-select light theme */ --hybrid-select-local-tag-background: #f0f0f0; --hybrid-select-local-tag-color: #262626; --hybrid-select-local-tag-close-color: #8c8c8c; --hybrid-select-local-tag-close-hover-color: #da1e28; /* Icon colors for light theme */ --hybrid-select-local-icon-color: #8c8c8c; --hybrid-select-local-icon-hover-color: #1677ff; } /* * Dark theme styles using data-theme attribute on wrapper element * These override the light theme defaults when data-theme="dark" is applied */ .wrapper[data-theme="dark"] { /* Select wrapper dark theme overrides */ --hybrid-select-local-background-color: #262626; --hybrid-select-local-border-color: #424242; --hybrid-select-local-text-color: #ffffff; --hybrid-select-local-placeholder-color: #8c8c8c; --hybrid-select-local-hover-border-color: #4096ff; --hybrid-select-local-focus-border-color: #4096ff; /* Dropdown dark theme overrides */ --hybrid-select-local-dropdown-background: #262626; --hybrid-select-local-dropdown-border-color: #424242; --hybrid-select-local-option-hover-background: #393939; --hybrid-select-local-option-selected-background: #1e3a5f; --hybrid-select-local-option-selected-color: #4096ff; /* Tag styles for multi-select dark theme */ --hybrid-select-local-tag-background: #393939; --hybrid-select-local-tag-color: #ffffff; --hybrid-select-local-tag-close-color: #8c8c8c; --hybrid-select-local-tag-close-hover-color: #ff4d4f; /* Icon colors for dark theme */ --hybrid-select-local-icon-color: #8c8c8c; --hybrid-select-local-icon-hover-color: #4096ff; } /* Size variants */ :host([size='small']) .wrapper { min-height: var(--hybrid-select-small-height, var(--hybrid-select-local-small-height)); font-size: var(--hybrid-select-small-font-size, var(--hybrid-select-local-small-font-size)); } :host([size='small']) .select-trigger { padding: var(--hybrid-select-small-padding, var(--hybrid-select-local-small-padding)); padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px); } :host([size='medium']) .wrapper { min-height: var(--hybrid-select-medium-height, var(--hybrid-select-local-medium-height)); font-size: var(--hybrid-select-medium-font-size, var(--hybrid-select-local-medium-font-size)); } :host([size='medium']) .select-trigger { padding: var(--hybrid-select-medium-padding, var(--hybrid-select-local-medium-padding)); padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px); } :host([size='large']) .wrapper { min-height: var(--hybrid-select-large-height, var(--hybrid-select-local-large-height)); font-size: var(--hybrid-select-large-font-size, var(--hybrid-select-local-large-font-size)); } :host([size='large']) .select-trigger { padding: var(--hybrid-select-large-padding, var(--hybrid-select-local-large-padding)); padding-right: calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px); } /* Status variants */ :host([status='error']) .wrapper { border-color: var(--hybrid-select-error-border-color, var(--hybrid-select-local-error-border-color)); } :host([status='warning']) .wrapper { border-color: var(--hybrid-select-warning-border-color, var(--hybrid-select-local-warning-border-color)); } :host([status='success']) .wrapper { border-color: var(--hybrid-select-success-border-color, var(--hybrid-select-local-success-border-color)); } /* Type variants */ :host([type='inline']) { display: flex; align-items: center; gap: 8px; } :host([type='inline']) .wrapper { flex: 1; } /* Show dropdown */ :host([show]) .options { display: flex !important; } /* Main wrapper container */ .wrapper { position: relative; width: var(--hybrid-select-width, var(--hybrid-select-local-width)); background-color: var(--hybrid-select-background-color, var(--hybrid-select-local-background-color)); border: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid var(--hybrid-select-border-color, var(--hybrid-select-local-border-color)); border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius)); transition: all var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)) var(--hybrid-select-transition-timing, var(--hybrid-select-local-transition-timing)); cursor: pointer; outline: none; margin: var(--hybrid-select-wrapper-margin, 0); min-height: var(--hybrid-select-min-height, var(--hybrid-select-local-min-height)); /* Ensure dropdown can overflow the wrapper */ overflow: visible; } .wrapper:hover:not(:disabled) { border-color: var(--hybrid-select-hover-border-color, var(--hybrid-select-local-hover-border-color)); } .wrapper:focus, .wrapper:focus-within { border-color: var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color)); box-shadow: 0 0 0 2px var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color))33; } /* Select container */ .select { display: flex; flex-direction: column; } /* Select trigger (main display area) */ .select-trigger { display: flex; align-items: center; padding: var(--hybrid-select-padding-top, var(--hybrid-select-local-padding-top)) calc(var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)) + 20px) var(--hybrid-select-padding-bottom, var(--hybrid-select-local-padding-bottom)) var(--hybrid-select-padding-left, var(--hybrid-select-local-padding-left)); color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color)); font-size: inherit; line-height: inherit; word-break: break-word; min-height: inherit; flex-wrap: wrap; gap: var(--hybrid-select-tag-margin, var(--hybrid-select-local-tag-margin)); } .select-trigger:empty:before { content: attr(data-placeholder); color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color)); font-size: var(--hybrid-select-placeholder-font-size, var(--hybrid-select-local-placeholder-font-size)); } /* Multi-select tags */ .tag { display: inline-flex; align-items: center; gap: 4px; background-color: var(--hybrid-select-tag-background, var(--hybrid-select-local-tag-background)); color: var(--hybrid-select-tag-color, var(--hybrid-select-local-tag-color)); padding: var(--hybrid-select-tag-padding, var(--hybrid-select-local-tag-padding)); border-radius: var(--hybrid-select-tag-border-radius, var(--hybrid-select-local-tag-border-radius)); font-size: calc(var(--hybrid-select-font-size, var(--hybrid-select-local-font-size)) - 1px); max-width: 100%; } .tag-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tag-close { color: var(--hybrid-select-tag-close-color, var(--hybrid-select-local-tag-close-color)); cursor: pointer; display: flex; align-items: center; justify-content: center; width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)); height: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)); border-radius: 50%; transition: color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)); } .tag-close:hover { color: var(--hybrid-select-tag-close-hover-color, var(--hybrid-select-local-tag-close-hover-color)); } /* Icons container */ .icons-container { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); display: flex; align-items: center; gap: 4px; pointer-events: none; } .icons-container hy-icon { --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)); --hybrid-icon-color: var(--hybrid-select-icon-color, var(--hybrid-select-local-icon-color)); pointer-events: auto; cursor: pointer; transition: color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)); } .icons-container hy-icon:hover { --hybrid-icon-color: var(--hybrid-select-icon-hover-color, var(--hybrid-select-local-icon-hover-color)); } .arrow-icon { --hybrid-icon-width: var(--hybrid-select-arrow-icon-size, var(--hybrid-select-local-arrow-icon-size)); transition: transform var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)); pointer-events: none !important; } :host([show]) .arrow-icon { transform: rotate(180deg); } /* Dropdown options */ .options { /* Default positioning - will be overridden by controller when opened */ position: absolute; top: 100%; margin-top: 1px; left: 0; right: 0; background-color: var(--hybrid-select-dropdown-background, var(--hybrid-select-local-dropdown-background)); border: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid var(--hybrid-select-dropdown-border-color, var(--hybrid-select-local-dropdown-border-color)); border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius)); box-shadow: var(--hybrid-select-dropdown-shadow, var(--hybrid-select-local-dropdown-shadow)); z-index: var(--hybrid-select-dropdown-z-index, var(--hybrid-select-local-dropdown-z-index)); max-height: var(--hybrid-select-dropdown-max-height, var(--hybrid-select-local-dropdown-max-height)); overflow-y: auto; overflow-x: hidden; display: none; flex-direction: column; animation: dropdown-enter var(--hybrid-select-dropdown-animation-duration, var(--hybrid-select-local-dropdown-animation-duration)) ease-out; /* Ensure proper containment and exact wrapper width */ box-sizing: border-box; width: 100%; /* Create new stacking context to prevent layering issues */ isolation: isolate; /* Ensure solid background to prevent visual bleed-through */ backdrop-filter: none; -webkit-backdrop-filter: none; /* Force above other elements */ transform: translateZ(0); } .options.placement-top { top: auto; bottom: 100%; margin-bottom: 1px; margin-top: 0; animation: dropdown-enter-top var(--hybrid-select-dropdown-animation-duration, var(--hybrid-select-local-dropdown-animation-duration)) ease-out; } @keyframes dropdown-enter { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } } @keyframes dropdown-enter-top { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } /* Search container - sticky at top of dropdown */ .search-container { position: sticky; top: 0; z-index: 10; background-color: var(--hybrid-select-dropdown-background, var(--hybrid-select-local-dropdown-background)); border-bottom: var(--hybrid-select-border-width, var(--hybrid-select-local-border-width)) solid var(--hybrid-select-dropdown-border-color, var(--hybrid-select-local-dropdown-border-color)); padding: 8px; margin: 0; /* Ensure it stays above options during scroll */ backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); /* Ensure proper stacking and smooth scrolling */ will-change: transform; transform: translateZ(0); } /* Search input styling */ .search-container .search-input { width: 100%; --hybrid-input-border-radius: var(--hybrid-select-border-radius, var(--hybrid-select-local-border-radius)); --hybrid-input-background-color: var(--hybrid-select-background-color, var(--hybrid-select-local-background-color)); --hybrid-input-border-color: var(--hybrid-select-border-color, var(--hybrid-select-local-border-color)); --hybrid-input-text-color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color)); --hybrid-input-placeholder-color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color)); } /* Search icon in the search input */ .search-container .search-icon { --hybrid-icon-color: var(--hybrid-select-icon-color, var(--hybrid-select-local-icon-color)); } /* Dark theme overrides for search container */ .wrapper[data-theme="dark"] .search-container { background-color: var(--hybrid-select-local-dropdown-background); border-bottom-color: var(--hybrid-select-local-dropdown-border-color); } .wrapper[data-theme="dark"] .search-container .search-input { --hybrid-input-background-color: var(--hybrid-select-local-background-color); --hybrid-input-border-color: var(--hybrid-select-local-border-color); --hybrid-input-text-color: var(--hybrid-select-local-text-color); --hybrid-input-placeholder-color: var(--hybrid-select-local-placeholder-color); } .wrapper[data-theme="dark"] .search-container .search-icon { --hybrid-icon-color: var(--hybrid-select-local-icon-color); } /* Options list container - ensure proper scroll behavior with sticky search */ .options:has(.search-container) { /* Add small padding-top when search is present to ensure proper separation */ padding-top: 0; } /* Option items */ .option { display: flex; align-items: center; gap: 8px; padding: 8px 12px; color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color)); font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size)); cursor: pointer; transition: background-color var(--hybrid-select-transition-duration, var(--hybrid-select-local-transition-duration)); position: relative; } /* First option after search container should have no extra margin */ .search-container + .option { margin-top: 0; } .option:hover { background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background)); } .option.selected { background-color: var(--hybrid-select-option-selected-background, var(--hybrid-select-local-option-selected-background)); color: var(--hybrid-select-option-selected-color, var(--hybrid-select-local-option-selected-color)); } .option.focused { background-color: var(--hybrid-select-option-hover-background, var(--hybrid-select-local-option-hover-background)); outline: 2px solid var(--hybrid-select-focus-border-color, var(--hybrid-select-local-focus-border-color)); outline-offset: -2px; } .option.disabled { opacity: var(--hybrid-select-disabled-opacity, var(--hybrid-select-local-disabled-opacity)); cursor: not-allowed; } .option-content { flex: 1; display: flex; align-items: center; gap: 8px; } .option-icon { --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)); --hybrid-icon-color: currentColor; } .option-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .option-description { font-size: calc(var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size)) - 1px); opacity: 0.7; margin-top: 2px; } .check-icon { --hybrid-icon-width: var(--hybrid-select-icon-size, var(--hybrid-select-local-icon-size)); --hybrid-icon-color: var(--hybrid-select-option-selected-color, var(--hybrid-select-local-option-selected-color)); } /* No options message - styled like Ant Design */ .no-options { display: flex; align-items: center; justify-content: center; padding: var(--select-no-options-padding, 24px 16px); color: var(--select-no-options-color, #8c8c8c); font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size)); cursor: default; user-select: none; } .no-options-content { display: flex; flex-direction: column; align-items: center; gap: var(--select-no-options-gap, 8px); text-align: center; } .no-options-icon { --hybrid-icon-width: 24px; --hybrid-icon-color: var(--select-no-options-icon-color, #d9d9d9); opacity: 0.8; } .no-options-text { font-size: var(--hybrid-select-option-font-size, var(--hybrid-select-local-option-font-size)); color: var(--select-no-options-color, #8c8c8c); line-height: 1.4; } /* Dark theme adjustments for no-options */ :host([theme='dark']) .no-options { color: var(--select-no-options-color, #595959); } :host([theme='dark']) .no-options-icon { --hybrid-icon-color: var(--select-no-options-icon-color, #434343); } :host([theme='dark']) .no-options-text { color: var(--select-no-options-color, #595959); } /* Validation message */ .validation-message { display: block; margin-top: var(--hybrid-select-message-margin-top, var(--hybrid-select-local-message-margin-top)); font-size: var(--hybrid-select-message-font-size, var(--hybrid-select-local-message-font-size)); color: var(--hybrid-select-error-message-color, var(--hybrid-select-local-error-message-color)); } .validation-message.warning { color: var(--hybrid-select-warning-message-color, var(--hybrid-select-local-warning-message-color)); } .validation-message.success { color: var(--hybrid-select-success-message-color, var(--hybrid-select-local-success-message-color)); } /* Slotted content styles */ ::slotted([slot='label']) { display: block; margin-bottom: 4px; font-weight: 500; color: var(--hybrid-select-text-color, var(--hybrid-select-local-text-color)); } ::slotted([slot='helper-text']) { display: block; margin-top: var(--hybrid-select-message-margin-top, var(--hybrid-select-local-message-margin-top)); font-size: var(--hybrid-select-message-font-size, var(--hybrid-select-local-message-font-size)); color: var(--hybrid-select-placeholder-color, var(--hybrid-select-local-placeholder-color)); } /* Accessibility improvements */ @media (prefers-reduced-motion: reduce) { .options, .wrapper, .tag-close, .arrow-icon, .option { transition: none; animation: none; } } /* High contrast mode support */ @media (prefers-contrast: high) { .wrapper { border-width: 2px; } .wrapper:focus, .wrapper:focus-within { outline: 3px solid; } } `; //# sourceMappingURL=select.style.js.map