@redvars/peacock 3.3.2 → 3.4.0

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.
Files changed (160) hide show
  1. package/dist/IndividualComponent-DUINtMGK.js +67 -0
  2. package/dist/IndividualComponent-DUINtMGK.js.map +1 -0
  3. package/dist/assets/images/empty-state/no-document.svg +11 -12
  4. package/dist/assets/images/empty-state/page.svg +15 -9
  5. package/dist/bottom-sheet.js +238 -0
  6. package/dist/bottom-sheet.js.map +1 -0
  7. package/dist/{button-ClzS8JLq.js → button-COYCtuA8.js} +306 -149
  8. package/dist/button-COYCtuA8.js.map +1 -0
  9. package/dist/button-group-DsXquZQn.js +440 -0
  10. package/dist/button-group-DsXquZQn.js.map +1 -0
  11. package/dist/button-group.js +6 -4
  12. package/dist/button-group.js.map +1 -1
  13. package/dist/button.js +5 -3
  14. package/dist/button.js.map +1 -1
  15. package/dist/card-content.js +29 -0
  16. package/dist/card-content.js.map +1 -0
  17. package/dist/card.js +418 -44
  18. package/dist/card.js.map +1 -1
  19. package/dist/{chart-bar-DbnXQgvS.js → chart-bar-cn6rrna-.js} +2 -2
  20. package/dist/{chart-bar-DbnXQgvS.js.map → chart-bar-cn6rrna-.js.map} +1 -1
  21. package/dist/chart-bar.js +4 -3
  22. package/dist/chart-bar.js.map +1 -1
  23. package/dist/chart-doughnut.js +2 -1
  24. package/dist/chart-doughnut.js.map +1 -1
  25. package/dist/chart-pie.js +2 -1
  26. package/dist/chart-pie.js.map +1 -1
  27. package/dist/chart-stacked-bar.js +4 -3
  28. package/dist/chart-stacked-bar.js.map +1 -1
  29. package/dist/{class-map-59YGWLnx.js → class-map-3TAnCMAX.js} +3 -9
  30. package/dist/class-map-3TAnCMAX.js.map +1 -0
  31. package/dist/clock.js +2 -1
  32. package/dist/clock.js.map +1 -1
  33. package/dist/code-editor.js +6 -4
  34. package/dist/code-editor.js.map +1 -1
  35. package/dist/code-highlighter.js +5 -3
  36. package/dist/code-highlighter.js.map +1 -1
  37. package/dist/custom-elements-jsdocs.json +2458 -2753
  38. package/dist/custom-elements.json +3185 -777
  39. package/dist/dispatch-event-utils-B4odODQf.js.map +1 -1
  40. package/dist/index.js +14 -10
  41. package/dist/index.js.map +1 -1
  42. package/dist/number-counter.js +3 -2
  43. package/dist/number-counter.js.map +1 -1
  44. package/dist/{observe-theme-change-pALI5fmV.js → observe-theme-change-DKAIv5BB.js} +3 -2
  45. package/dist/observe-theme-change-DKAIv5BB.js.map +1 -0
  46. package/dist/peacock-loader.js +37 -8
  47. package/dist/peacock-loader.js.map +1 -1
  48. package/dist/property-1psGvXOq.js +10 -0
  49. package/dist/property-1psGvXOq.js.map +1 -0
  50. package/dist/{snackbar-74YCdMPL.js → select-C3XAzenC.js} +2158 -191
  51. package/dist/select-C3XAzenC.js.map +1 -0
  52. package/dist/side-sheet.js +186 -0
  53. package/dist/side-sheet.js.map +1 -0
  54. package/dist/src/bottom-sheet/bottom-sheet.d.ts +42 -0
  55. package/dist/src/bottom-sheet/index.d.ts +1 -0
  56. package/dist/src/button/BaseButton.d.ts +4 -3
  57. package/dist/src/button/button/button.d.ts +4 -0
  58. package/dist/src/button/button-group/button-group.d.ts +32 -3
  59. package/dist/src/button/icon-button/icon-button.d.ts +4 -0
  60. package/dist/src/card/card-content.d.ts +15 -0
  61. package/dist/src/card/card.d.ts +37 -3
  62. package/dist/src/card/index.d.ts +1 -0
  63. package/dist/src/container/container.d.ts +1 -1
  64. package/dist/src/empty-state/empty-state.d.ts +1 -1
  65. package/dist/src/focus-ring/focus-ring.d.ts +4 -1
  66. package/dist/src/index.d.ts +7 -1
  67. package/dist/src/menu/menu/menu.d.ts +1 -0
  68. package/dist/src/menu/menu-item/menu-item.d.ts +0 -1
  69. package/dist/src/radio/index.d.ts +1 -0
  70. package/dist/src/radio/radio.d.ts +73 -0
  71. package/dist/src/ripple/ripple.d.ts +19 -3
  72. package/dist/src/segmented-button/index.d.ts +2 -0
  73. package/dist/src/segmented-button/segmented-button-group.d.ts +46 -0
  74. package/dist/src/segmented-button/segmented-button.d.ts +65 -0
  75. package/dist/src/select/index.d.ts +3 -0
  76. package/dist/src/select/option.d.ts +55 -0
  77. package/dist/src/select/select.d.ts +116 -0
  78. package/dist/src/side-sheet/index.d.ts +1 -0
  79. package/dist/src/side-sheet/side-sheet.d.ts +41 -0
  80. package/dist/src/tabs/tab-group.d.ts +0 -1
  81. package/dist/src/tabs/tab.d.ts +8 -2
  82. package/dist/src/tabs/tabs.d.ts +13 -1
  83. package/dist/state-DwbEjqVk.js +10 -0
  84. package/dist/state-DwbEjqVk.js.map +1 -0
  85. package/dist/{style-map-DcB52w-l.js → style-map-CRFEoCEg.js} +2 -2
  86. package/dist/{style-map-DcB52w-l.js.map → style-map-CRFEoCEg.js.map} +1 -1
  87. package/dist/tsconfig.tsbuildinfo +1 -1
  88. package/dist/{unsafe-html-C2r3PyzF.js → unsafe-html-D3GHRaGQ.js} +2 -2
  89. package/dist/{unsafe-html-C2r3PyzF.js.map → unsafe-html-D3GHRaGQ.js.map} +1 -1
  90. package/package.json +1 -1
  91. package/readme.md +2 -2
  92. package/src/bottom-sheet/bottom-sheet.scss +88 -0
  93. package/src/bottom-sheet/bottom-sheet.ts +135 -0
  94. package/src/bottom-sheet/index.ts +1 -0
  95. package/src/button/BaseButton.ts +16 -7
  96. package/src/button/button/button-colors.scss +76 -5
  97. package/src/button/button/button-sizes.scss +39 -19
  98. package/src/button/button/button.scss +117 -116
  99. package/src/button/button/button.ts +23 -1
  100. package/src/button/button-group/button-group.scss +25 -22
  101. package/src/button/button-group/button-group.ts +121 -4
  102. package/src/button/icon-button/icon-button-sizes.scss +35 -15
  103. package/src/button/icon-button/icon-button.ts +21 -1
  104. package/src/card/card-colors.scss +10 -0
  105. package/src/card/card-content.ts +26 -0
  106. package/src/card/card.scss +221 -41
  107. package/src/card/card.ts +240 -7
  108. package/src/card/index.ts +1 -0
  109. package/src/code-editor/code-editor.ts +1 -1
  110. package/src/container/container.ts +1 -1
  111. package/src/empty-state/empty-state.scss +8 -0
  112. package/src/empty-state/empty-state.ts +2 -2
  113. package/src/focus-ring/focus-ring.ts +37 -19
  114. package/src/index.ts +8 -1
  115. package/src/menu/menu/menu.scss +24 -3
  116. package/src/menu/menu/menu.ts +23 -2
  117. package/src/menu/menu-item/menu-item.scss +1 -0
  118. package/src/menu/menu-item/menu-item.ts +1 -9
  119. package/src/peacock-loader.ts +32 -0
  120. package/src/radio/index.ts +1 -0
  121. package/src/radio/radio.scss +181 -0
  122. package/src/radio/radio.ts +362 -0
  123. package/src/ripple/ripple.ts +19 -3
  124. package/src/segmented-button/index.ts +2 -0
  125. package/src/segmented-button/segmented-button-group.scss +21 -0
  126. package/src/segmented-button/segmented-button-group.ts +110 -0
  127. package/src/segmented-button/segmented-button.scss +115 -0
  128. package/src/segmented-button/segmented-button.ts +175 -0
  129. package/src/select/index.ts +3 -0
  130. package/src/select/option.ts +109 -0
  131. package/src/select/select.scss +120 -0
  132. package/src/select/select.ts +486 -0
  133. package/src/side-sheet/index.ts +1 -0
  134. package/src/side-sheet/side-sheet.scss +79 -0
  135. package/src/side-sheet/side-sheet.ts +100 -0
  136. package/src/slider/slider.scss +0 -1
  137. package/src/tabs/demo/index.html +90 -0
  138. package/src/tabs/tab-group.ts +0 -3
  139. package/src/tabs/tab.scss +237 -25
  140. package/src/tabs/tab.ts +86 -12
  141. package/src/tabs/tabs.scss +37 -3
  142. package/src/tabs/tabs.ts +118 -2
  143. package/src/utils/dispatch-event-utils.ts +1 -0
  144. package/dist/IndividualComponent-Dt5xirYG.js +0 -73
  145. package/dist/IndividualComponent-Dt5xirYG.js.map +0 -1
  146. package/dist/button-ClzS8JLq.js.map +0 -1
  147. package/dist/button-group-BMS5WvaF.js +0 -292
  148. package/dist/button-group-BMS5WvaF.js.map +0 -1
  149. package/dist/chart-donut.js +0 -309
  150. package/dist/chart-donut.js.map +0 -1
  151. package/dist/class-map-59YGWLnx.js.map +0 -1
  152. package/dist/observe-theme-change-pALI5fmV.js.map +0 -1
  153. package/dist/snackbar-74YCdMPL.js.map +0 -1
  154. package/dist/src/chart-donut/chart-donut.d.ts +0 -53
  155. package/dist/src/chart-donut/index.d.ts +0 -1
  156. package/dist/test/card.test.d.ts +0 -1
  157. package/src/chart-donut/chart-donut.scss +0 -37
  158. package/src/chart-donut/chart-donut.ts +0 -287
  159. package/src/chart-donut/demo/index.html +0 -51
  160. package/src/chart-donut/index.ts +0 -1
@@ -0,0 +1,115 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: contents;
7
+
8
+ --_segmented-button-height: 2.5rem;
9
+ --_segmented-button-outline-color: var(--color-outline, #79747e);
10
+ --_segmented-button-selected-container-color: var(--color-secondary-container, #e8def8);
11
+ --_segmented-button-selected-label-text-color: var(--color-on-secondary-container, #1d192b);
12
+ --_segmented-button-unselected-label-text-color: var(--color-on-surface, #1c1b1f);
13
+ --_segmented-button-disabled-opacity: 0.38;
14
+ --_segmented-button-state-layer-color: var(--color-on-surface, #1c1b1f);
15
+ --_segmented-button-selected-state-layer-color: var(--color-on-secondary-container, #1d192b);
16
+ }
17
+
18
+ .segment {
19
+ position: relative;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ height: var(--segmented-button-height, var(--_segmented-button-height));
24
+ padding: 0 1.5rem;
25
+ cursor: pointer;
26
+ flex: 1;
27
+ min-width: 0;
28
+ outline: none;
29
+ user-select: none;
30
+ -webkit-user-select: none;
31
+ background: transparent;
32
+ overflow: hidden;
33
+ transition:
34
+ background-color 200ms ease,
35
+ color 200ms ease;
36
+
37
+ .content {
38
+ position: relative;
39
+ z-index: 1;
40
+ display: flex;
41
+ align-items: center;
42
+ gap: 0.5rem;
43
+ @include mixin.get-typography(label-large);
44
+ color: var(--segmented-button-unselected-label-text-color, var(--_segmented-button-unselected-label-text-color));
45
+
46
+ .check-icon,
47
+ .leading-icon {
48
+ --icon-size: 1.125rem;
49
+ --icon-color: currentColor;
50
+ flex-shrink: 0;
51
+ }
52
+
53
+ .label {
54
+ overflow: hidden;
55
+ text-overflow: ellipsis;
56
+ white-space: nowrap;
57
+ }
58
+ }
59
+
60
+ .state-layer {
61
+ position: absolute;
62
+ inset: 0;
63
+ background: var(--_segmented-button-state-layer-color);
64
+ opacity: 0;
65
+ pointer-events: none;
66
+ transition: opacity 200ms ease;
67
+ }
68
+
69
+ /* right-side divider between segments */
70
+ .segment-outline {
71
+ position: absolute;
72
+ top: 0;
73
+ right: 0;
74
+ width: 1px;
75
+ height: 100%;
76
+ background: var(--segmented-button-outline-color, var(--_segmented-button-outline-color));
77
+ pointer-events: none;
78
+ }
79
+
80
+ &:hover:not(.disabled) .state-layer {
81
+ opacity: 0.08;
82
+ }
83
+
84
+ &.has-focus:not(.disabled) .state-layer {
85
+ opacity: 0.12;
86
+ }
87
+
88
+ &.active:not(.disabled) .state-layer {
89
+ opacity: 0.16;
90
+ }
91
+
92
+ /* Selected state */
93
+ &.selected {
94
+ background-color: var(--segmented-button-selected-container-color, var(--_segmented-button-selected-container-color));
95
+
96
+ .content {
97
+ color: var(--segmented-button-selected-label-text-color, var(--_segmented-button-selected-label-text-color));
98
+ }
99
+
100
+ .state-layer {
101
+ background: var(--_segmented-button-selected-state-layer-color);
102
+ }
103
+ }
104
+
105
+ /* Disabled state */
106
+ &.disabled {
107
+ cursor: not-allowed;
108
+ opacity: var(--segmented-button-disabled-opacity, var(--_segmented-button-disabled-opacity));
109
+ pointer-events: none;
110
+ }
111
+ }
112
+
113
+ :host(:last-child) .segment-outline {
114
+ display: none;
115
+ }
@@ -0,0 +1,175 @@
1
+ import { html, LitElement, nothing } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+ import { classMap } from 'lit/directives/class-map.js';
4
+ import styles from './segmented-button.scss';
5
+
6
+ /**
7
+ * @label Segmented Button
8
+ * @tag wc-segmented-button
9
+ * @rawTag segmented-button
10
+ * @summary An individual segment within a segmented button group.
11
+ * @parentRawTag segmented-button-group
12
+ * @overview
13
+ * <p>Segmented buttons help people select options, switch views, or sort elements. They are used within a <code>wc-segmented-button-group</code>.</p>
14
+ *
15
+ * @cssprop --segmented-button-height: Height of the segmented button.
16
+ * @cssprop --segmented-button-selected-container-color: Background color when the segment is selected.
17
+ * @cssprop --segmented-button-selected-label-text-color: Text color when the segment is selected.
18
+ * @cssprop --segmented-button-unselected-label-text-color: Text color when the segment is unselected.
19
+ * @cssprop --segmented-button-outline-color: Outline / border color.
20
+ * @cssprop --segmented-button-disabled-opacity: Opacity when the segment is disabled.
21
+ *
22
+ * @fires {CustomEvent} segmented-button--change - Dispatched when the selected state changes.
23
+ *
24
+ * @example
25
+ * ```html
26
+ * <wc-segmented-button-group>
27
+ * <wc-segmented-button value="day">Day</wc-segmented-button>
28
+ * <wc-segmented-button value="week" selected>Week</wc-segmented-button>
29
+ * <wc-segmented-button value="month">Month</wc-segmented-button>
30
+ * </wc-segmented-button-group>
31
+ * ```
32
+ *
33
+ * @tags controls
34
+ */
35
+ export class SegmentedButton extends LitElement {
36
+ static styles = [styles];
37
+
38
+ /**
39
+ * The value associated with this segment.
40
+ */
41
+ @property({ type: String, reflect: true })
42
+ value: string = '';
43
+
44
+ /**
45
+ * Whether this segment is currently selected.
46
+ */
47
+ @property({ type: Boolean, reflect: true })
48
+ selected: boolean = false;
49
+
50
+ /**
51
+ * If true, the user cannot interact with this segment.
52
+ */
53
+ @property({ type: Boolean, reflect: true })
54
+ disabled: boolean = false;
55
+
56
+ /**
57
+ * Optional icon name to display (uses wc-icon).
58
+ */
59
+ @property({ type: String })
60
+ icon?: string;
61
+
62
+ @state()
63
+ private hasFocus = false;
64
+
65
+ @state()
66
+ private isActive = false;
67
+
68
+ connectedCallback() {
69
+ super.connectedCallback();
70
+ window.addEventListener('mouseup', this._windowMouseUp);
71
+ }
72
+
73
+ disconnectedCallback() {
74
+ super.disconnectedCallback();
75
+ window.removeEventListener('mouseup', this._windowMouseUp);
76
+ }
77
+
78
+ private _windowMouseUp = () => {
79
+ if (this.isActive) {
80
+ this.isActive = false;
81
+ }
82
+ };
83
+
84
+ private _mouseDownHandler = () => {
85
+ this.isActive = true;
86
+ };
87
+
88
+ private _keyDownHandler = (evt: KeyboardEvent) => {
89
+ if (evt.key === ' ' || evt.key === 'Enter') {
90
+ evt.preventDefault();
91
+ this.isActive = true;
92
+ this._toggle(evt);
93
+ }
94
+ };
95
+
96
+ private _clickHandler = (ev: MouseEvent) => {
97
+ this._toggle(ev);
98
+ };
99
+
100
+ private _toggle(ev: MouseEvent | KeyboardEvent) {
101
+ if (this.disabled) return;
102
+ this.dispatchEvent(
103
+ new CustomEvent('segmented-button--change', {
104
+ detail: {
105
+ value: this.value || this.textContent?.trim(),
106
+ selected: !this.selected,
107
+ originalEvent: ev,
108
+ },
109
+ bubbles: true,
110
+ composed: true,
111
+ }),
112
+ );
113
+ }
114
+
115
+ private _blurHandler = (ev: FocusEvent) => {
116
+ this.hasFocus = false;
117
+ this.dispatchEvent(
118
+ new CustomEvent('blur', { detail: ev, bubbles: true, composed: true }),
119
+ );
120
+ };
121
+
122
+ private _focusHandler = (ev: FocusEvent) => {
123
+ this.hasFocus = true;
124
+ this.dispatchEvent(
125
+ new CustomEvent('focus', { detail: ev, bubbles: true, composed: true }),
126
+ );
127
+ };
128
+
129
+ /** Sets focus on the segment. */
130
+ focus() {
131
+ this.renderRoot.querySelector<HTMLElement>('.segment')?.focus();
132
+ }
133
+
134
+ /** Removes focus from the segment. */
135
+ blur() {
136
+ this.renderRoot.querySelector<HTMLElement>('.segment')?.blur();
137
+ }
138
+
139
+ render() {
140
+ const cssClasses = {
141
+ segment: true,
142
+ selected: this.selected,
143
+ disabled: this.disabled,
144
+ 'has-focus': this.hasFocus,
145
+ active: this.isActive,
146
+ 'has-icon': !!this.icon,
147
+ };
148
+
149
+ return html`
150
+ <div
151
+ class=${classMap(cssClasses)}
152
+ role="button"
153
+ tabindex=${this.disabled ? -1 : 0}
154
+ aria-pressed=${this.selected}
155
+ aria-disabled=${this.disabled}
156
+ @click=${this._clickHandler}
157
+ @mousedown=${this._mouseDownHandler}
158
+ @keydown=${this._keyDownHandler}
159
+ @blur=${this._blurHandler}
160
+ @focus=${this._focusHandler}
161
+ >
162
+ <div class="state-layer"></div>
163
+ <div class="content">
164
+ ${this.selected
165
+ ? html`<wc-icon class="check-icon" name="check"></wc-icon>`
166
+ : this.icon
167
+ ? html`<wc-icon class="leading-icon" name=${this.icon}></wc-icon>`
168
+ : nothing}
169
+ <span class="label"><slot></slot></span>
170
+ </div>
171
+ <div class="segment-outline"></div>
172
+ </div>
173
+ `;
174
+ }
175
+ }
@@ -0,0 +1,3 @@
1
+ export { Select } from './select.js';
2
+ export type { SelectOption } from './select.js';
3
+ export { SelectOptionElement } from './option.js';
@@ -0,0 +1,109 @@
1
+ import { css, html, LitElement, nothing } from 'lit';
2
+ import { property, query } from 'lit/decorators.js';
3
+ import type { MenuItem } from '../menu/menu-item/menu-item.js';
4
+
5
+ /**
6
+ * @label Select Option
7
+ * @tag wc-option
8
+ * @rawTag option
9
+ * @parentRawTag select
10
+ *
11
+ * @summary A declarative option element for use inside wc-select.
12
+ *
13
+ * @example
14
+ * ```html
15
+ * <wc-select label="Fruit">
16
+ * <wc-option value="apple">Apple</wc-option>
17
+ * <wc-option value="banana">Banana</wc-option>
18
+ * </wc-select>
19
+ * ```
20
+ */
21
+ export class SelectOptionElement extends LitElement {
22
+ static override styles = [
23
+ css`
24
+ :host {
25
+ display: contents;
26
+ }
27
+ :host([filtered]) {
28
+ display: none;
29
+ }
30
+ `,
31
+ ];
32
+
33
+ /**
34
+ * The option's submitted value.
35
+ */
36
+ @property({ type: String, reflect: true })
37
+ value: string = '';
38
+
39
+ /**
40
+ * Optional Material Symbol icon name shown before the label.
41
+ */
42
+ @property({ type: String, reflect: true })
43
+ icon: string = '';
44
+
45
+ /**
46
+ * Disables the option so it cannot be selected.
47
+ */
48
+ @property({ type: Boolean, reflect: true })
49
+ disabled: boolean = false;
50
+
51
+ // ── Managed by wc-select ──────────────────────────────────────────────────
52
+
53
+ /** Reflects whether this option is currently selected. Set by wc-select. */
54
+ @property({ type: Boolean, reflect: true })
55
+ selected: boolean = false;
56
+
57
+ /**
58
+ * When true the menu stays open after selection (used for multi-select).
59
+ * Set by wc-select.
60
+ */
61
+ @property({ type: Boolean, attribute: 'keep-open' })
62
+ keepOpen: boolean = false;
63
+
64
+ /**
65
+ * When true the option is hidden and excluded from keyboard navigation
66
+ * because it does not match the current typeahead search query.
67
+ * Set by wc-select.
68
+ */
69
+ @property({ type: Boolean, reflect: true })
70
+ filtered: boolean = false;
71
+
72
+ @query('wc-menu-item')
73
+ private readonly _menuItemEl?: HTMLElement;
74
+
75
+ /**
76
+ * Returns the inner `wc-menu-item` element.
77
+ * `wc-menu` discovers this via its `items` getter which checks `el.item`
78
+ * as a `MenuItem` proxy, so keyboard navigation and activation work
79
+ * without `wc-option` extending `MenuItem` directly.
80
+ */
81
+ get item(): MenuItem | null {
82
+ const el = this._menuItemEl;
83
+ // Narrow to MenuItem — the shadow DOM only ever contains a wc-menu-item
84
+ // (a MenuItem subclass), so this cast is safe by construction.
85
+ return el != null ? (el as unknown as MenuItem) : null;
86
+ }
87
+
88
+ override render() {
89
+ return html`
90
+ <wc-menu-item
91
+ value=${this.value}
92
+ ?disabled=${this.disabled || this.filtered}
93
+ ?selected=${this.selected}
94
+ ?keep-open=${this.keepOpen}
95
+ >
96
+ ${this.icon
97
+ ? html`<wc-icon name=${this.icon} slot="leading-icon"></wc-icon>`
98
+ : nothing}
99
+ <slot></slot>
100
+ ${this.selected && this.keepOpen
101
+ ? html`<wc-icon
102
+ name="check"
103
+ slot="trailing-supporting-text"
104
+ ></wc-icon>`
105
+ : nothing}
106
+ </wc-menu-item>
107
+ `;
108
+ }
109
+ }
@@ -0,0 +1,120 @@
1
+ @use '../../scss/mixin';
2
+
3
+ @include mixin.base-styles;
4
+
5
+ :host {
6
+ display: block;
7
+ width: 100%;
8
+ }
9
+
10
+ /* Make the field wrapper behave as a select (pointer cursor) */
11
+ .select-field {
12
+ cursor: pointer;
13
+ }
14
+
15
+ .select-trigger {
16
+ flex: 1;
17
+ display: flex;
18
+ align-items: center;
19
+ min-height: 1.5rem;
20
+ outline: none;
21
+ cursor: pointer;
22
+ user-select: none;
23
+ overflow: hidden;
24
+ min-width: 0;
25
+
26
+ &:focus-visible {
27
+ outline: none;
28
+ }
29
+ }
30
+
31
+ .display-value {
32
+ @include mixin.get-typography(body-large);
33
+ color: var(--color-on-surface);
34
+ overflow: hidden;
35
+ text-overflow: ellipsis;
36
+ white-space: nowrap;
37
+ }
38
+
39
+ .placeholder {
40
+ @include mixin.get-typography(body-large);
41
+ color: var(--color-on-surface-variant);
42
+ overflow: hidden;
43
+ text-overflow: ellipsis;
44
+ white-space: nowrap;
45
+ }
46
+
47
+ /* Typeahead search input */
48
+ .search-input {
49
+ flex: 1;
50
+ width: 100%;
51
+ border: none;
52
+ outline: none;
53
+ background: transparent;
54
+ margin: 0;
55
+ padding: 0;
56
+ @include mixin.get-typography(body-large);
57
+ color: var(--color-on-surface);
58
+ cursor: pointer;
59
+
60
+ &::placeholder {
61
+ color: var(--color-on-surface-variant);
62
+ }
63
+
64
+ &:focus {
65
+ cursor: text;
66
+ }
67
+ }
68
+
69
+ /* Field end slot wrapper */
70
+ .field-end-wrapper {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: var(--spacing-050);
74
+ }
75
+
76
+ /* Dropdown chevron icon */
77
+ .dropdown-icon {
78
+ --icon-size: 1.5rem;
79
+ --icon-color: var(--color-on-surface-variant);
80
+ transition: transform 200ms ease;
81
+ flex-shrink: 0;
82
+
83
+ &.dropdown-icon--open {
84
+ transform: rotate(180deg);
85
+ }
86
+ }
87
+
88
+ /* Clear button */
89
+ .clear-btn {
90
+ --button-container-shape: var(--shape-corner-full);
91
+ }
92
+
93
+ /* Multi-select chips area — single scrollable row, no vertical growth */
94
+ .chips-container {
95
+ display: flex;
96
+ flex-wrap: nowrap;
97
+ overflow-x: auto;
98
+ scrollbar-width: none;
99
+ gap: var(--spacing-050);
100
+ padding-block: var(--spacing-050);
101
+ align-items: center;
102
+ flex: 1;
103
+ min-width: 0;
104
+
105
+ &::-webkit-scrollbar {
106
+ display: none;
107
+ }
108
+ }
109
+
110
+ /* Disabled state */
111
+ :host([disabled]) .select-trigger,
112
+ :host([disabled]) .select-field {
113
+ cursor: not-allowed;
114
+ }
115
+
116
+ /* Readonly state */
117
+ :host([readonly]) .select-trigger,
118
+ :host([readonly]) .select-field {
119
+ cursor: default;
120
+ }