@aquera/nile-elements 1.7.1 → 1.7.3

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 (88) hide show
  1. package/README.md +7 -0
  2. package/dist/index.cjs.js +1 -1
  3. package/dist/index.esm.js +1 -1
  4. package/dist/index.js +1524 -419
  5. package/dist/nile-breadcrumb-item/nile-breadcrumb-item.cjs.js +1 -1
  6. package/dist/nile-breadcrumb-item/nile-breadcrumb-item.cjs.js.map +1 -1
  7. package/dist/nile-breadcrumb-item/nile-breadcrumb-item.esm.js +8 -6
  8. package/dist/nile-combobox/group-utils.cjs.js +2 -0
  9. package/dist/nile-combobox/group-utils.cjs.js.map +1 -0
  10. package/dist/nile-combobox/group-utils.esm.js +1 -0
  11. package/dist/nile-combobox/index.cjs.js +2 -0
  12. package/dist/nile-combobox/index.cjs.js.map +1 -0
  13. package/dist/nile-combobox/index.esm.js +1 -0
  14. package/dist/nile-combobox/nile-combobox.cjs.js +2 -0
  15. package/dist/nile-combobox/nile-combobox.cjs.js.map +1 -0
  16. package/dist/nile-combobox/nile-combobox.css.cjs.js +2 -0
  17. package/dist/nile-combobox/nile-combobox.css.cjs.js.map +1 -0
  18. package/dist/nile-combobox/nile-combobox.css.esm.js +715 -0
  19. package/dist/nile-combobox/nile-combobox.esm.js +238 -0
  20. package/dist/nile-combobox/portal-manager.cjs.js +2 -0
  21. package/dist/nile-combobox/portal-manager.cjs.js.map +1 -0
  22. package/dist/nile-combobox/portal-manager.esm.js +1 -0
  23. package/dist/nile-combobox/renderer.cjs.js +2 -0
  24. package/dist/nile-combobox/renderer.cjs.js.map +1 -0
  25. package/dist/nile-combobox/renderer.esm.js +147 -0
  26. package/dist/nile-combobox/search-manager.cjs.js +2 -0
  27. package/dist/nile-combobox/search-manager.cjs.js.map +1 -0
  28. package/dist/nile-combobox/search-manager.esm.js +1 -0
  29. package/dist/nile-combobox/selection-manager.cjs.js +2 -0
  30. package/dist/nile-combobox/selection-manager.cjs.js.map +1 -0
  31. package/dist/nile-combobox/selection-manager.esm.js +1 -0
  32. package/dist/nile-combobox/types.cjs.js +2 -0
  33. package/dist/nile-combobox/types.cjs.js.map +1 -0
  34. package/dist/nile-combobox/types.esm.js +1 -0
  35. package/dist/src/index.d.ts +1 -0
  36. package/dist/src/index.js +1 -0
  37. package/dist/src/index.js.map +1 -1
  38. package/dist/src/nile-breadcrumb-item/nile-breadcrumb-item.js +4 -2
  39. package/dist/src/nile-breadcrumb-item/nile-breadcrumb-item.js.map +1 -1
  40. package/dist/src/nile-combobox/group-utils.d.ts +26 -0
  41. package/dist/src/nile-combobox/group-utils.js +140 -0
  42. package/dist/src/nile-combobox/group-utils.js.map +1 -0
  43. package/dist/src/nile-combobox/index.d.ts +1 -0
  44. package/dist/src/nile-combobox/index.js +2 -0
  45. package/dist/src/nile-combobox/index.js.map +1 -0
  46. package/dist/src/nile-combobox/nile-combobox.css.d.ts +9 -0
  47. package/dist/src/nile-combobox/nile-combobox.css.js +724 -0
  48. package/dist/src/nile-combobox/nile-combobox.css.js.map +1 -0
  49. package/dist/src/nile-combobox/nile-combobox.d.ts +320 -0
  50. package/dist/src/nile-combobox/nile-combobox.js +1739 -0
  51. package/dist/src/nile-combobox/nile-combobox.js.map +1 -0
  52. package/dist/src/nile-combobox/nile-combobox.test.d.ts +1 -0
  53. package/dist/src/nile-combobox/nile-combobox.test.js +551 -0
  54. package/dist/src/nile-combobox/nile-combobox.test.js.map +1 -0
  55. package/dist/src/nile-combobox/portal-manager.d.ts +26 -0
  56. package/dist/src/nile-combobox/portal-manager.js +218 -0
  57. package/dist/src/nile-combobox/portal-manager.js.map +1 -0
  58. package/dist/src/nile-combobox/renderer.d.ts +24 -0
  59. package/dist/src/nile-combobox/renderer.js +279 -0
  60. package/dist/src/nile-combobox/renderer.js.map +1 -0
  61. package/dist/src/nile-combobox/search-manager.d.ts +15 -0
  62. package/dist/src/nile-combobox/search-manager.js +41 -0
  63. package/dist/src/nile-combobox/search-manager.js.map +1 -0
  64. package/dist/src/nile-combobox/selection-manager.d.ts +12 -0
  65. package/dist/src/nile-combobox/selection-manager.js +44 -0
  66. package/dist/src/nile-combobox/selection-manager.js.map +1 -0
  67. package/dist/src/nile-combobox/types.d.ts +53 -0
  68. package/dist/src/nile-combobox/types.js +8 -0
  69. package/dist/src/nile-combobox/types.js.map +1 -0
  70. package/dist/src/version.js +1 -1
  71. package/dist/src/version.js.map +1 -1
  72. package/dist/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +3 -1
  74. package/src/index.ts +1 -0
  75. package/src/nile-breadcrumb-item/nile-breadcrumb-item.ts +4 -2
  76. package/src/nile-combobox/group-utils.ts +157 -0
  77. package/src/nile-combobox/index.ts +1 -0
  78. package/src/nile-combobox/nile-combobox.css.ts +726 -0
  79. package/src/nile-combobox/nile-combobox.test.ts +704 -0
  80. package/src/nile-combobox/nile-combobox.ts +1816 -0
  81. package/src/nile-combobox/portal-manager.ts +263 -0
  82. package/src/nile-combobox/renderer.ts +466 -0
  83. package/src/nile-combobox/search-manager.ts +53 -0
  84. package/src/nile-combobox/selection-manager.ts +57 -0
  85. package/src/nile-combobox/types.ts +63 -0
  86. package/vscode-html-custom-data.json +311 -4
  87. package/web-dev-server.config.mjs +9 -0
  88. package/web-test-runner.config.mjs +11 -0
@@ -0,0 +1,726 @@
1
+ /**
2
+ * Copyright Aquera Inc 2025
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { css } from 'lit';
9
+
10
+ export const styles = css`
11
+ :host {
12
+ display: block;
13
+ box-sizing: border-box;
14
+ -webkit-font-smoothing: var(--nile-webkit-font-smoothing, var(--ng-webkit-font-smoothing));
15
+ -moz-osx-font-smoothing: var(--nile-moz-osx-font-smoothing, var(--ng-moz-osx-font-smoothing));
16
+ text-rendering: var(--nile-text-rendering, var(--ng-text-rendering));
17
+ }
18
+
19
+ :host *,
20
+ :host *::before,
21
+ :host *::after {
22
+ box-sizing: inherit;
23
+ }
24
+
25
+ [hidden] {
26
+ display: none;
27
+ }
28
+
29
+ /* ── Form control ── */
30
+
31
+ .form-control .form-control__label {
32
+ display: none;
33
+ }
34
+
35
+ .form-control--has-label .form-control__label {
36
+ display: block;
37
+ margin-bottom: var(--nile-spacing-sm, var(--ng-spacing-sm));
38
+ color: var(--nile-colors-dark-900, var(--ng-colors-text-secondary-700));
39
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
40
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-md));
41
+ font-style: normal;
42
+ font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-medium));
43
+ line-height: var(--nile-spacing-2xl, var(--ng-line-height-text-sm));
44
+ letter-spacing: 0.2px;
45
+ }
46
+
47
+ .form-control--has-label.form-control--medium .form-control__label {
48
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
49
+ }
50
+
51
+ :host([required]) .form-control--has-label .form-control__label::after {
52
+ content: '*';
53
+ margin-inline-start: -2px;
54
+ color: var(--nile-colors-red-700, var(--ng-colors-text-error-primary-600));
55
+ }
56
+
57
+ :host([disabled]) .form-control--has-label .form-control__label {
58
+ user-select: none;
59
+ -webkit-user-select: none;
60
+ }
61
+
62
+ /* ── Popup ── */
63
+
64
+ .combobox-popup {
65
+ flex: 1 1 auto;
66
+ display: inline-flex;
67
+ width: 100%;
68
+ position: relative;
69
+ vertical-align: middle;
70
+ }
71
+
72
+ .combobox-popup::part(popup) {
73
+ z-index: 9999;
74
+ }
75
+
76
+ .combobox-popup[data-current-placement^='top']::part(popup) {
77
+ transform-origin: bottom;
78
+ }
79
+
80
+ .combobox-popup[data-current-placement^='bottom']::part(popup) {
81
+ transform-origin: top;
82
+ }
83
+
84
+ /* ── Trigger: outer row that never scrolls ── */
85
+
86
+ .combobox__trigger {
87
+ display: flex;
88
+ align-items: center;
89
+ width: 100%;
90
+ min-width: 0;
91
+ position: relative;
92
+ font-family: var(--nile-font-family-sans-serif, var(--ng-font-family-body));
93
+ font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-medium));
94
+ letter-spacing: normal;
95
+ cursor: text;
96
+ transition: 150ms color, 150ms border, 150ms box-shadow, 150ms background-color;
97
+ background-color: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
98
+ border: solid 1px var(--nile-colors-neutral-500, var(--ng-colors-border-primary));
99
+ outline: none;
100
+ }
101
+
102
+ .combobox__trigger:hover {
103
+ border-color: var(--nile-colors-dark-900, var(--ng-colors-border-neutral));
104
+ }
105
+
106
+ .combobox--open .combobox__trigger,
107
+ .combobox--focused .combobox__trigger {
108
+ border-color: var(--ng-colors-border-brand);
109
+ box-shadow: 0 0 0 1px var(--ng-colors-border-brand) inset;
110
+ background-color: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
111
+ }
112
+
113
+ .combobox--disabled .combobox__trigger {
114
+ background-color: var(--nile-colors-dark-200, var(--ng-colors-bg-disabled-subtle));
115
+ border-color: var(--nile-colors-neutral-500, var(--ng-colors-border-primary));
116
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-disabled));
117
+ cursor: not-allowed;
118
+ user-select: none;
119
+ }
120
+
121
+ .combobox--warning .combobox__trigger {
122
+ border-color: var(--nile-colors-yellow-500, var(--ng-colors-border-warning));
123
+ }
124
+
125
+ .combobox--error .combobox__trigger {
126
+ border-color: var(--nile-colors-red-500, var(--ng-colors-border-error));
127
+ }
128
+
129
+ .combobox--success .combobox__trigger {
130
+ border-color: var(--nile-colors-green-500, var(--ng-componentcolors-utility-success-500));
131
+ }
132
+
133
+ /* Size: small */
134
+ .combobox--small .combobox__trigger {
135
+ border-radius: var(--nile-radius-sm, var(--ng-radius-md));
136
+ font-size: var(--nile-type-scale-2, var(--ng-font-size-text-xs));
137
+ padding: var(--nile-spacing-md, var(--ng-spacing-sm)) var(--nile-spacing-md, var(--ng-spacing-md));
138
+ min-height: var(--nile-height-32px, var(--ng-height-32px));
139
+ }
140
+
141
+ /* Size: medium */
142
+ .combobox--medium .combobox__trigger {
143
+ border-radius: var(--nile-radius-sm, var(--ng-radius-md));
144
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-md));
145
+ padding: var(--nile-spacing-lg, var(--ng-spacing-md)) var(--nile-spacing-lg, var(--ng-spacing-lg));
146
+ min-height: var(--nile-height-40px, var(--ng-height-40px));
147
+ box-sizing: border-box;
148
+ }
149
+
150
+ /* Size: large */
151
+ .combobox--large .combobox__trigger {
152
+ border-radius: var(--nile-radius-sm, var(--ng-radius-md));
153
+ font-size: var(--nile-type-scale-4, var(--ng-font-size-text-md));
154
+ padding: var(--nile-spacing-xl, var(--ng-spacing-lg)) var(--nile-spacing-xl, var(--ng-spacing-xl));
155
+ min-height: var(--nile-height-48px, var(--ng-height-48px));
156
+ }
157
+
158
+ .combobox--pill .combobox__trigger {
159
+ border-radius: var(--nile-radius-3xl, var(--ng-radius-3xl));
160
+ }
161
+
162
+ .combobox--filled .combobox__trigger {
163
+ border: none;
164
+ background-color: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
165
+ }
166
+
167
+ .combobox--filled.combobox--open .combobox__trigger,
168
+ .combobox--filled.combobox--focused .combobox__trigger {
169
+ outline: 3px solid rgba(0, 89, 255, 0.4);
170
+ }
171
+
172
+ /* ── Inner area: holds tags + input ── */
173
+
174
+ .combobox__scroll-area {
175
+ flex: 1;
176
+ min-width: 0;
177
+ display: flex;
178
+ flex-wrap: wrap;
179
+ align-items: center;
180
+ gap: 4px;
181
+ overflow: hidden;
182
+ }
183
+
184
+ /* Single-line: horizontal scroll for overflowing tags */
185
+ .combobox__scroll-area--single-line {
186
+ flex-wrap: nowrap;
187
+ overflow-x: auto;
188
+ overflow-y: hidden;
189
+ -webkit-overflow-scrolling: touch;
190
+ scrollbar-width: thin;
191
+ scrollbar-color: var(--nile-colors-neutral-500, var(--ng-colors-border-primary)) transparent;
192
+ }
193
+
194
+ .combobox__scroll-area--single-line::-webkit-scrollbar {
195
+ height: 3px;
196
+ }
197
+
198
+ .combobox__scroll-area--single-line::-webkit-scrollbar-track {
199
+ background: transparent;
200
+ }
201
+
202
+ .combobox__scroll-area--single-line::-webkit-scrollbar-thumb {
203
+ background: var(--nile-colors-neutral-500, var(--ng-colors-bg-quaternary));
204
+ border-radius: 3px;
205
+ }
206
+
207
+ .combobox__scroll-area--single-line::-webkit-scrollbar-thumb:hover {
208
+ background: var(--nile-colors-dark-500, var(--ng-colors-fg-quaternary-400));
209
+ }
210
+
211
+ /* Wrap: tags flow to multiple lines, trigger grows in height */
212
+ .combobox__scroll-area--wrap {
213
+ flex-wrap: wrap;
214
+ overflow: visible;
215
+ }
216
+
217
+ /* ── Tags inside the scroll area ── */
218
+
219
+ .combobox__scroll-area nile-tag {
220
+ cursor: pointer;
221
+ flex-shrink: 0;
222
+ }
223
+
224
+ .combobox--disabled .combobox__scroll-area nile-tag {
225
+ cursor: not-allowed;
226
+ }
227
+
228
+ .combobox__tags-count {
229
+ color: var(--nile-colors-primary-600, var(--ng-colors-text-brand-secondary-700));
230
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
231
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
232
+ font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-medium));
233
+ line-height: var(--nile-line-height-xsmall, var(--ng-line-height-text-sm));
234
+ letter-spacing: 0.2px;
235
+ white-space: nowrap;
236
+ flex-shrink: 0;
237
+ }
238
+
239
+ /* ── Input wrapper inside scroll area ── */
240
+
241
+ .combobox__input-wrapper {
242
+ flex: 1;
243
+ min-width: 60px;
244
+ display: flex;
245
+ align-items: center;
246
+ }
247
+
248
+ .combobox__input {
249
+ width: 100%;
250
+ font: inherit;
251
+ border: none;
252
+ background: none;
253
+ color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
254
+ cursor: inherit;
255
+ overflow: hidden;
256
+ padding: 0;
257
+ margin: 0;
258
+ -webkit-appearance: none;
259
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
260
+ font-size: inherit;
261
+ font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-regular));
262
+ text-overflow: ellipsis;
263
+ line-height: var(--nile-line-height-xsmall, var(--ng-line-height-text-sm));
264
+ }
265
+
266
+ .combobox__input::placeholder {
267
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
268
+ color: var(--nile-colors-text-placeholder, var(--ng-colors-text-placeholder));
269
+ }
270
+
271
+ .combobox__input:focus {
272
+ outline: none;
273
+ }
274
+
275
+ .combobox--disabled .combobox__input {
276
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-disabled));
277
+ pointer-events: none;
278
+ }
279
+
280
+ /* ── Hidden form value input ── */
281
+
282
+ .combobox__value-input {
283
+ position: absolute;
284
+ top: 0;
285
+ left: 0;
286
+ width: 100%;
287
+ height: 100%;
288
+ padding: 0;
289
+ margin: 0;
290
+ opacity: 0;
291
+ z-index: -1;
292
+ }
293
+
294
+ /* ── Action icons (clear, expand) ── */
295
+
296
+ .combobox__actions {
297
+ display: flex;
298
+ align-items: center;
299
+ flex-shrink: 0;
300
+ gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
301
+ margin-inline-start: auto;
302
+ }
303
+
304
+ .combobox__clear {
305
+ display: inline-flex;
306
+ align-items: center;
307
+ justify-content: center;
308
+ border: none;
309
+ background: none;
310
+ padding: 0;
311
+ cursor: pointer;
312
+ color: var(--nile-colors-dark-500, var(--ng-colors-fg-quaternary-400));
313
+ transition: 150ms color;
314
+ }
315
+
316
+ .combobox__clear:hover {
317
+ color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
318
+ }
319
+
320
+ .combobox__clear:focus {
321
+ outline: none;
322
+ }
323
+
324
+ .combobox__expand-icon {
325
+ display: flex;
326
+ align-items: center;
327
+ flex-shrink: 0;
328
+ transition: 250ms rotate ease;
329
+ rotate: 0;
330
+ }
331
+
332
+ .combobox--open .combobox__expand-icon {
333
+ rotate: -180deg;
334
+ }
335
+
336
+ /* ── Prefix / suffix ── */
337
+
338
+ .combobox__prefix,
339
+ .combobox__suffix {
340
+ flex: 0;
341
+ display: inline-flex;
342
+ align-items: center;
343
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-tertiary-600));
344
+ }
345
+
346
+ .combobox__prefix {
347
+ margin-inline-end: var(--nile-spacing-md, var(--ng-spacing-md));
348
+ }
349
+
350
+ /* ── Listbox (dropdown) ── */
351
+
352
+ .combobox__listbox {
353
+ display: block;
354
+ position: relative;
355
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-md));
356
+ font-weight: var(--nile-font-weight-regular, var(--ng-font-weight-regular));
357
+ background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
358
+ border: solid 1px var(--nile-colors-neutral-500, var(--ng-colors-border-secondary-alt));
359
+ border-radius: var(--nile-radius-sm, var(--ng-radius-md));
360
+ padding-block: var(--nile-spacing-none, var(--ng-spacing-xs));
361
+ padding-inline: var(--nile-spacing-none, var(--ng-spacing-xs));
362
+ overscroll-behavior: none;
363
+ overflow-y: auto;
364
+ max-width: var(--auto-size-available-width);
365
+ max-height: var(--auto-size-available-height);
366
+ box-shadow: 0px 2px 4px 0px rgba(119, 125, 130, 0.15);
367
+ }
368
+
369
+ /* ── Options ── */
370
+
371
+ .combobox__options {
372
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
373
+ color: rgb(133, 129, 129);
374
+ width: 100%;
375
+ }
376
+
377
+ .combobox__options.loading {
378
+ opacity: 0.5;
379
+ pointer-events: none;
380
+ }
381
+
382
+ .combobox__no-results {
383
+ padding: var(--nile-spacing-lg, var(--ng-spacing-lg));
384
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
385
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
386
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-tertiary-600));
387
+ text-align: center;
388
+ }
389
+
390
+ .combobox__no-results-title {
391
+ font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-medium));
392
+ color: var(--nile-colors-dark-700, var(--ng-colors-text-secondary-700));
393
+ }
394
+
395
+ .combobox__no-results-subtitle {
396
+ margin-top: var(--nile-spacing-xs, var(--ng-spacing-xs));
397
+ font-size: var(--nile-type-scale-2, var(--ng-font-size-text-xs));
398
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-tertiary-600));
399
+ }
400
+
401
+ /* ── Options (both virtual and plain) ── */
402
+
403
+ .combobox__options nile-option {
404
+ width: 100%;
405
+ display: block;
406
+ }
407
+
408
+ .combobox__options nile-option[selected] {
409
+ background-color: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
410
+ }
411
+
412
+ .combobox__options nile-option[selected]::part(base) {
413
+ color: var(--nile-colors-primary-600, var(--ng-colors-text-brand-secondary-700));
414
+ }
415
+
416
+ .combobox__options-plain {
417
+ display: flex;
418
+ flex-direction: column;
419
+ }
420
+
421
+ .combobox__options-plain nile-option {
422
+ flex-shrink: 0;
423
+ }
424
+
425
+ /* ── Top actions (Select All + Selected/All filter toggle) ── */
426
+
427
+ .combobox__top-actions {
428
+ position: sticky;
429
+ top: 0;
430
+ z-index: 2;
431
+ display: flex;
432
+ flex-direction: row;
433
+ align-items: center;
434
+ justify-content: space-between;
435
+ gap: var(--nile-spacing-lg, var(--ng-spacing-lg));
436
+ background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
437
+ border-bottom: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
438
+ padding: var(--nile-spacing-lg, var(--ng-spacing-lg));
439
+ user-select: none;
440
+ }
441
+
442
+ .combobox__top-actions--disabled {
443
+ opacity: 0.6;
444
+ pointer-events: none;
445
+ }
446
+
447
+ .combobox__select-all {
448
+ display: flex;
449
+ align-items: center;
450
+ gap: var(--nile-spacing-md, var(--ng-spacing-md));
451
+ cursor: pointer;
452
+ flex: 1 1 auto;
453
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
454
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
455
+ line-height: 14px;
456
+ letter-spacing: 0.2px;
457
+ color: var(--nile-colors-dark-900, var(--ng-colors-text-primary));
458
+ }
459
+
460
+ .combobox__show-toggle {
461
+ display: inline-flex;
462
+ align-items: center;
463
+ gap: var(--nile-spacing-md, var(--ng-spacing-md));
464
+ border: none;
465
+ background: none;
466
+ padding: 0;
467
+ border-radius: var(--nile-radius-sm, var(--ng-radius-sm));
468
+ cursor: pointer;
469
+ color: var(--nile-colors-primary-600, var(--ng-colors-text-brand-secondary-700));
470
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
471
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
472
+ line-height: 14px;
473
+ letter-spacing: 0.2px;
474
+ white-space: nowrap;
475
+ }
476
+
477
+ .combobox__show-toggle[disabled] {
478
+ color: var(--nile-colors-primary-500, var(--ng-colors-fg-quaternary-400));
479
+ cursor: not-allowed;
480
+ }
481
+
482
+ /* ── Footer ── */
483
+
484
+ .combobox__footer {
485
+ position: sticky;
486
+ bottom: 0;
487
+ background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
488
+ border-top: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
489
+ display: flex;
490
+ flex-direction: row;
491
+ align-items: flex-start;
492
+ padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-lg, var(--ng-spacing-lg)) var(--nile-spacing-xl, var(--ng-spacing-xl));
493
+ gap: var(--nile-spacing-lg, var(--ng-spacing-lg));
494
+ justify-content: space-between;
495
+ }
496
+
497
+ .combobox__footer.loading {
498
+ opacity: 0.5;
499
+ pointer-events: none;
500
+ }
501
+
502
+ .combobox__footer-clear {
503
+ display: inline-flex;
504
+ align-items: center;
505
+ color: var(--nile-colors-primary-600, var(--ng-colors-text-brand-secondary-700));
506
+ border: none;
507
+ background: none;
508
+ padding: 0;
509
+ cursor: pointer;
510
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
511
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
512
+ letter-spacing: 0.2px;
513
+ }
514
+
515
+ .combobox__footer-clear:hover {
516
+ text-decoration: underline;
517
+ }
518
+
519
+ /* ── Loader ── */
520
+
521
+ .combobox__loader {
522
+ width: 100%;
523
+ text-align: center;
524
+ display: block;
525
+ }
526
+
527
+ .combobox__loader--icon {
528
+ margin-top: var(--nile-spacing-xl, var(--ng-spacing-xl));
529
+ animation: combobox-spin 0.6s linear infinite;
530
+ }
531
+
532
+ .combobox__loader--center {
533
+ position: absolute;
534
+ display: flex;
535
+ justify-content: center;
536
+ align-items: center;
537
+ width: 100%;
538
+ height: 75%;
539
+ }
540
+
541
+ @keyframes combobox-spin {
542
+ 0% { transform: rotate(0deg); }
543
+ 100% { transform: rotate(360deg); }
544
+ }
545
+
546
+ .combobox__add-option::part(base) {
547
+ color: var(--nile-colors-primary-600, var(--ng-colors-text-brand-secondary-700));
548
+ }
549
+
550
+ /* ── Grid layout ── */
551
+
552
+ :host([grid-columns]) .combobox__listbox {
553
+ overflow-y: auto;
554
+ }
555
+
556
+ .combobox__grid-row {
557
+ width: 100%;
558
+ }
559
+
560
+ .combobox__grid-row nile-option {
561
+ min-width: 0;
562
+ overflow: hidden;
563
+ }
564
+
565
+ .combobox__grid-row nile-option::part(base) {
566
+ border-radius: var(--nile-radius-xs, var(--ng-radius-sm));
567
+ }
568
+
569
+ /* ── Bidirectional grid layout (vertical + horizontal scroll) ── */
570
+
571
+ .combobox__listbox.combobox__listbox--bidirectional {
572
+ overflow: auto;
573
+ max-width: none;
574
+ scrollbar-width: thin;
575
+ scrollbar-color: var(--nile-colors-neutral-500, var(--ng-colors-bg-quaternary)) transparent;
576
+ }
577
+
578
+ .combobox__listbox--bidirectional .combobox__options {
579
+ width: max-content;
580
+ min-width: 100%;
581
+ }
582
+
583
+ .combobox__listbox--bidirectional .combobox__grid-row {
584
+ width: max-content;
585
+ min-width: 100%;
586
+ }
587
+
588
+ /* ── Horizontal grid layout ── */
589
+
590
+ .combobox__listbox.combobox__listbox--horizontal {
591
+ overflow-x: auto;
592
+ overflow-y: hidden;
593
+ max-height: none;
594
+ max-width: none;
595
+ width: 100%;
596
+ scrollbar-width: thin;
597
+ scrollbar-color: var(--nile-colors-neutral-500, var(--ng-colors-bg-quaternary)) transparent;
598
+ }
599
+
600
+ .combobox__listbox--horizontal::-webkit-scrollbar {
601
+ height: 6px;
602
+ }
603
+
604
+ .combobox__listbox--horizontal::-webkit-scrollbar-track {
605
+ background: transparent;
606
+ }
607
+
608
+ .combobox__listbox--horizontal::-webkit-scrollbar-thumb {
609
+ background: var(--nile-colors-neutral-500, var(--ng-colors-bg-quaternary));
610
+ border-radius: 3px;
611
+ }
612
+
613
+ .combobox__listbox--horizontal::-webkit-scrollbar-thumb:hover {
614
+ background: var(--nile-colors-dark-500, var(--ng-colors-fg-quaternary-400));
615
+ }
616
+
617
+ .combobox__options--horizontal {
618
+ display: block;
619
+ width: max-content;
620
+ min-width: 100%;
621
+ }
622
+
623
+ .combobox__grid-col {
624
+ border-right: 1px solid var(--nile-colors-neutral-200, var(--ng-colors-border-secondary));
625
+ }
626
+
627
+ .combobox__grid-col:last-child {
628
+ border-right: none;
629
+ }
630
+
631
+ .combobox__grid-col nile-option {
632
+ width: 100%;
633
+ display: block;
634
+ }
635
+
636
+ .combobox__grid-col nile-option::part(base) {
637
+ border-radius: 0;
638
+ }
639
+
640
+ /* ── Group headers (data-driven grouping) ── */
641
+
642
+ /* Plain (non-virtualized) listbox: sticky relative to the scroll container.
643
+ * Activated only when the host has [sticky-group-header]. */
644
+ :host([sticky-group-header]) .combobox__options-plain .combobox__group-header {
645
+ position: sticky;
646
+ top: calc(var(--group-depth, 0) * 28px);
647
+ z-index: 1;
648
+ }
649
+
650
+ /* Virtualized listbox: each row is absolutely positioned by the virtualizer.
651
+ * Sticky doesn't pin against the scroll container because the row wrapper's
652
+ * transform creates a containing block. Instead we render a separate
653
+ * overlay inside the listbox that mirrors the currently-active group
654
+ * header (computed on scroll). */
655
+ .combobox__group-header-slot {
656
+ pointer-events: none;
657
+ }
658
+ .combobox__group-header-slot .combobox__group-header {
659
+ height: 100%;
660
+ box-sizing: border-box;
661
+ }
662
+
663
+ .combobox__group-sticky-overlay {
664
+ position: sticky;
665
+ top: 0;
666
+ z-index: 2;
667
+ pointer-events: none;
668
+ }
669
+ .combobox__group-sticky-overlay .combobox__group-header {
670
+ box-shadow: 0 1px 0 0 var(--nile-colors-neutral-300, var(--ng-colors-border-secondary));
671
+ }
672
+
673
+ .combobox__group-header {
674
+ display: flex;
675
+ align-items: center;
676
+ gap: 6px;
677
+ box-sizing: border-box;
678
+ width: 100%;
679
+ height: 100%;
680
+ /* Match the listbox's natural inline padding so the header sits like a
681
+ * section divider, edge-to-edge with options. Nested groups indent by
682
+ * depth. Override with --combobox-group-header-indent if needed. */
683
+ padding-block: 8px;
684
+ padding-inline-end: var(--nile-spacing-lg, var(--ng-spacing-lg));
685
+ padding-inline-start: calc(var(--combobox-group-header-indent, var(--nile-spacing-lg, var(--ng-spacing-lg))) + var(--group-depth, 0) * 16px);
686
+ font-family: var(--nile-font-family-sans-serif, var(--ng-font-family-body));
687
+ font-size: var(--nile-type-scale-2, var(--ng-font-size-text-xs));
688
+ font-weight: var(--nile-font-weight-semibold, var(--ng-font-weight-semibold));
689
+ line-height: 1;
690
+ text-transform: uppercase;
691
+ letter-spacing: 0.06em;
692
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-tertiary-600));
693
+ background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
694
+ border-bottom: 1px solid var(--nile-colors-neutral-300, var(--ng-colors-border-secondary));
695
+ pointer-events: none;
696
+ user-select: none;
697
+ }
698
+
699
+ .combobox__group-label {
700
+ flex: 1;
701
+ min-width: 0;
702
+ overflow: hidden;
703
+ text-overflow: ellipsis;
704
+ white-space: nowrap;
705
+ }
706
+
707
+ .combobox__group-prefix {
708
+ flex-shrink: 0;
709
+ color: inherit;
710
+ }
711
+
712
+ /* ── Help / Error ── */
713
+
714
+ .form-control__help-text {
715
+ display: none;
716
+ }
717
+
718
+ .form-control--has-help-text .form-control__help-text {
719
+ display: block;
720
+ color: var(--nile-colors-dark-500, var(--ng-colors-text-tertiary-600));
721
+ margin-top: var(--nile-spacing-lg, var(--ng-spacing-lg));
722
+ font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
723
+ }
724
+ `;
725
+
726
+ export default [styles];