@vialiq/flux-ui 0.10.0 → 0.11.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.
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Combobox component base styles.
3
+ *
4
+ * Provides the host-agnostic foundation for combobox / searchable dropdown controls:
5
+ * control layout, input/trigger, listbox popover panel, option items, tags, and states.
6
+ * All styling strictly uses semantic design tokens from flux-ui.
7
+ */
8
+
9
+ @use '../styles/variables' as tokens;
10
+
11
+ @layer components {
12
+ // -------------------------------------------------------------------------
13
+ // Field wrapper — stacks helper / validation below control
14
+ // -------------------------------------------------------------------------
15
+ .combobox-field {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: var(--vi-combobox-spacing-field-gap, #{tokens.$spacing-xs});
19
+ width: 100%;
20
+ position: relative;
21
+ }
22
+
23
+ // -------------------------------------------------------------------------
24
+ // Outer Control Wrapper (contains tags, input/trigger, spinner, clear & chevron)
25
+ // -------------------------------------------------------------------------
26
+ .combobox-control {
27
+ display: flex;
28
+ align-items: center;
29
+ flex-wrap: wrap;
30
+ gap: var(--vi-combobox-tag-gap, #{tokens.$spacing-xs});
31
+ box-sizing: border-box;
32
+ width: 100%;
33
+ min-height: var(--vi-combobox-min-height, 40px);
34
+ padding: var(--vi-combobox-padding-block, #{tokens.$spacing-xs})
35
+ var(--vi-combobox-padding-inline, #{tokens.$spacing-sm});
36
+ background-color: var(--vi-combobox-background, #{tokens.$color-background});
37
+ border: var(--vi-combobox-border-width, #{tokens.$border-width-thin}) solid var(--vi-combobox-border-color, #{tokens.$border-03});
38
+ border-radius: var(--vi-combobox-border-radius, #{tokens.$border-radius-lg});
39
+ font-family: #{tokens.$font-family-base};
40
+ font-size: var(--vi-combobox-font-size, #{tokens.$font-size-base});
41
+ color: var(--vi-combobox-text-color, #{tokens.$text-primary});
42
+ transition: border-color 150ms ease, box-shadow 150ms ease;
43
+ cursor: text;
44
+ position: relative;
45
+
46
+ &:hover:not(.is-disabled):not(.is-focused) {
47
+ border-color: var(--vi-combobox-border-color-hover, #{tokens.$border-04});
48
+ }
49
+
50
+ &.is-focused,
51
+ &:focus-within {
52
+ border-color: var(--vi-combobox-border-color-focus, #{tokens.$focus});
53
+ outline: var(--vi-combobox-border-width-focus, #{tokens.$border-width-base}) solid var(--vi-combobox-focus-ring-color, #{tokens.$focus});
54
+ outline-offset: 0;
55
+ box-shadow: 0 0 0 3px var(--vi-combobox-focus-ring-glow, #{tokens.$color-blue-200});
56
+ }
57
+
58
+ &.is-disabled {
59
+ opacity: var(--vi-combobox-disabled-opacity, 0.6);
60
+ pointer-events: none;
61
+ cursor: not-allowed;
62
+ }
63
+
64
+ &.is-invalid {
65
+ border-color: var(--vi-combobox-error-color, #{tokens.$color-error});
66
+
67
+ &.is-focused,
68
+ &:focus-within {
69
+ outline-color: var(--vi-combobox-error-color, #{tokens.$color-error});
70
+ }
71
+ }
72
+
73
+ &.is-valid {
74
+ border-color: var(--vi-combobox-success-color, #{tokens.$color-success});
75
+ }
76
+ }
77
+
78
+ // -------------------------------------------------------------------------
79
+ // Searchable Text Input
80
+ // -------------------------------------------------------------------------
81
+ .combobox-input {
82
+ appearance: none;
83
+ -webkit-appearance: none;
84
+ flex: 1 1 60px;
85
+ min-width: 60px;
86
+ border: none;
87
+ outline: none;
88
+ background: transparent;
89
+ padding: 0;
90
+ margin: 0;
91
+ font-family: inherit;
92
+ font-size: inherit;
93
+ color: inherit;
94
+ line-height: #{tokens.$line-height-normal};
95
+
96
+ &::placeholder {
97
+ color: var(--vi-combobox-placeholder-color, #{tokens.$text-secondary});
98
+ }
99
+ }
100
+
101
+ // Chevron icon styling with smooth 180deg rotation
102
+ .combobox-chevron {
103
+ margin-left: auto;
104
+ color: var(--vi-combobox-chevron-color, #{tokens.$text-secondary});
105
+ flex-shrink: 0;
106
+ transition: transform 200ms cubic-bezier(0.2, 0, 0, 1);
107
+ transform-origin: center center;
108
+ pointer-events: auto;
109
+ cursor: pointer;
110
+ width: 18px;
111
+ height: 18px;
112
+ }
113
+
114
+ .combobox-control.is-open .combobox-chevron {
115
+ transform: rotate(180deg);
116
+ }
117
+
118
+ // Clear selection button (X icon)
119
+ .combobox-clear-btn {
120
+ appearance: none;
121
+ -webkit-appearance: none;
122
+ background: transparent;
123
+ border: none;
124
+ padding: 2px;
125
+ margin: 0;
126
+ display: inline-flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ color: var(--vi-combobox-clear-color, #{tokens.$text-secondary});
130
+ cursor: pointer;
131
+ border-radius: #{tokens.$border-radius-sm};
132
+ transition: color 150ms ease, background-color 150ms ease;
133
+ width: 20px;
134
+ height: 20px;
135
+ flex-shrink: 0;
136
+
137
+ &:hover {
138
+ color: var(--vi-combobox-clear-hover-color, #{tokens.$text-primary});
139
+ background-color: var(--vi-combobox-clear-hover-bg, #{tokens.$layer-hover-01});
140
+ }
141
+ }
142
+
143
+ // -------------------------------------------------------------------------
144
+ // Non-searchable Trigger Button (when searchable="false")
145
+ // -------------------------------------------------------------------------
146
+ .combobox-trigger {
147
+ appearance: none;
148
+ -webkit-appearance: none;
149
+ flex: 1 1 0px;
150
+ min-width: 0;
151
+ display: inline-flex;
152
+ align-items: center;
153
+ border: none;
154
+ outline: none;
155
+ background: transparent;
156
+ padding: 0;
157
+ margin: 0;
158
+ font-family: inherit;
159
+ font-size: inherit;
160
+ color: inherit;
161
+ line-height: inherit;
162
+ text-align: left;
163
+ white-space: nowrap;
164
+ overflow: hidden;
165
+ text-overflow: ellipsis;
166
+ cursor: pointer;
167
+
168
+ &.is-placeholder {
169
+ color: var(--vi-combobox-placeholder-color, #{tokens.$text-secondary});
170
+ }
171
+ }
172
+
173
+ // -------------------------------------------------------------------------
174
+ // Tags container (multi / tags mode)
175
+ // -------------------------------------------------------------------------
176
+ .combobox-tags {
177
+ display: flex;
178
+ flex-wrap: wrap;
179
+ align-items: center;
180
+ gap: var(--vi-combobox-tag-gap, #{tokens.$spacing-xs});
181
+ }
182
+
183
+ // -------------------------------------------------------------------------
184
+ // Dropdown Listbox Panel (Popover with smooth entrance/exit transition)
185
+ // -------------------------------------------------------------------------
186
+ .combobox-listbox {
187
+ box-sizing: border-box;
188
+ position: absolute; /* Floating UI will override with fixed if needed */
189
+ top: 0;
190
+ left: 0;
191
+ z-index: var(--vi-combobox-listbox-z-index, 1000);
192
+ height: var(--vi-combobox-listbox-height, auto);
193
+ max-height: var(--vi-combobox-listbox-max-height, 280px);
194
+ overflow-y: auto;
195
+ background-color: var(--vi-combobox-listbox-background, #{tokens.$layer-01});
196
+ border: 1px solid var(--vi-combobox-listbox-border-color, #{tokens.$border-02});
197
+ border-radius: var(--vi-combobox-listbox-border-radius, #{tokens.$border-radius-lg});
198
+ box-shadow: var(--vi-combobox-listbox-shadow, #{tokens.$shadow-md});
199
+ padding: 4px 0;
200
+ margin: 0;
201
+ opacity: 0;
202
+ visibility: hidden;
203
+ transform: translateY(-6px) scale(0.98);
204
+ transform-origin: top center;
205
+ transition: opacity 160ms cubic-bezier(0.2, 0, 0, 1),
206
+ transform 160ms cubic-bezier(0.2, 0, 0, 1),
207
+ visibility 160ms cubic-bezier(0.2, 0, 0, 1);
208
+ pointer-events: none;
209
+
210
+ &[data-placement^="top"] {
211
+ transform-origin: bottom center;
212
+ transform: translateY(6px) scale(0.98);
213
+ }
214
+
215
+ &[open],
216
+ &.is-open {
217
+ opacity: 1;
218
+ visibility: visible;
219
+ transform: translateY(0) scale(1);
220
+ pointer-events: auto;
221
+ }
222
+ }
223
+
224
+ // -------------------------------------------------------------------------
225
+ // Option List (<ul>)
226
+ // -------------------------------------------------------------------------
227
+ .combobox-list {
228
+ list-style: none;
229
+ margin: 0;
230
+ padding: 0;
231
+ }
232
+
233
+ // -------------------------------------------------------------------------
234
+ // Option Item (<li>)
235
+ // -------------------------------------------------------------------------
236
+ .combobox-option {
237
+ display: flex;
238
+ align-items: center;
239
+ justify-content: space-between;
240
+ gap: var(--vi-combobox-option-gap, #{tokens.$spacing-xs});
241
+ min-height: var(--vi-combobox-option-height, 40px);
242
+ padding: var(--vi-combobox-option-padding-block, #{tokens.$spacing-xs})
243
+ var(--vi-combobox-option-padding-inline, #{tokens.$spacing-sm});
244
+ font-size: var(--vi-combobox-option-font-size, #{tokens.$font-size-base});
245
+ color: var(--vi-combobox-option-color, #{tokens.$text-primary});
246
+ cursor: pointer;
247
+ user-select: none;
248
+
249
+ &:hover,
250
+ &.is-active {
251
+ background-color: var(--vi-combobox-option-hover-bg, #{tokens.$layer-hover-01});
252
+ }
253
+
254
+ &.is-selected {
255
+ background-color: var(--vi-combobox-option-selected-bg, #{tokens.$layer-02});
256
+ color: var(--vi-combobox-option-selected-color, #{tokens.$color-primary});
257
+ font-weight: #{tokens.$font-weight-semibold};
258
+ }
259
+
260
+ &.is-disabled {
261
+ color: var(--vi-combobox-option-disabled-color, #{tokens.$text-disabled});
262
+ cursor: not-allowed;
263
+ pointer-events: none;
264
+ opacity: 0.6;
265
+ }
266
+ }
267
+
268
+ // Option text layout
269
+ .combobox-option-content {
270
+ display: flex;
271
+ flex-direction: column;
272
+ flex: 1 1 auto;
273
+ overflow: hidden;
274
+ }
275
+
276
+ .combobox-option-label {
277
+ white-space: nowrap;
278
+ overflow: hidden;
279
+ text-overflow: ellipsis;
280
+ }
281
+
282
+ .combobox-option-description {
283
+ font-size: var(--vi-combobox-option-description-font-size, #{tokens.$font-size-sm});
284
+ color: var(--vi-combobox-option-description-color, #{tokens.$text-secondary});
285
+ white-space: nowrap;
286
+ overflow: hidden;
287
+ text-overflow: ellipsis;
288
+ }
289
+
290
+ .combobox-option-action {
291
+ display: flex;
292
+ align-items: center;
293
+ margin-left: auto;
294
+ z-index: 1;
295
+ }
296
+
297
+ // Highlight search match
298
+ .combobox-mark {
299
+ background-color: var(--vi-combobox-mark-background, #{tokens.$bg-warning});
300
+ color: var(--vi-combobox-mark-color, #{tokens.$text-primary});
301
+ border-radius: #{tokens.$border-radius-sm};
302
+ padding: 0 1px;
303
+ }
304
+
305
+ // -------------------------------------------------------------------------
306
+ // Group Header
307
+ // -------------------------------------------------------------------------
308
+ .combobox-group-header {
309
+ padding: 8px var(--vi-combobox-group-padding-inline, #{tokens.$spacing-sm}) 4px;
310
+ font-size: var(--vi-combobox-group-font-size, #{tokens.$font-size-xs});
311
+ font-weight: var(--vi-combobox-group-font-weight, #{tokens.$font-weight-semibold});
312
+ color: var(--vi-combobox-group-color, #{tokens.$text-secondary});
313
+ text-transform: uppercase;
314
+ letter-spacing: #{tokens.$letter-spacing-wide};
315
+ user-select: none;
316
+ }
317
+
318
+ // -------------------------------------------------------------------------
319
+ // Empty State & Loading State
320
+ // -------------------------------------------------------------------------
321
+ .combobox-empty,
322
+ .combobox-loading {
323
+ padding: #{tokens.$spacing-sm};
324
+ text-align: center;
325
+ font-size: #{tokens.$font-size-sm};
326
+ color: #{tokens.$text-secondary};
327
+ }
328
+
329
+ // -------------------------------------------------------------------------
330
+ // Helper & Validation Messages
331
+ // -------------------------------------------------------------------------
332
+ .combobox-helper {
333
+ font-size: var(--vi-combobox-validation-font-size, #{tokens.$font-size-xs});
334
+ color: var(--vi-combobox-helper-color, #{tokens.$text-helper});
335
+ }
336
+
337
+ .combobox-validation {
338
+ font-size: var(--vi-combobox-validation-font-size, #{tokens.$font-size-xs});
339
+ color: var(--vi-combobox-error-color, #{tokens.$color-error});
340
+
341
+ &.is-valid {
342
+ color: var(--vi-combobox-success-color, #{tokens.$color-success});
343
+ }
344
+ }
345
+
346
+ // -------------------------------------------------------------------------
347
+ // Reduced motion
348
+ // -------------------------------------------------------------------------
349
+ @media (prefers-reduced-motion: reduce) {
350
+ .combobox-control,
351
+ .combobox-option {
352
+ transition: none;
353
+ }
354
+ }
355
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vialiq/flux-ui",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"