@streamscloud/kit 0.86.0 → 0.88.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 (27) hide show
  1. package/dist/styles/_mixins.scss +71 -17
  2. package/dist/styles/reset.css +19 -12
  3. package/dist/ui/ai-panel/cmp.ai-panel.svelte +27 -0
  4. package/dist/ui/date-picker/cmp.date-time-picker.svelte +67 -8
  5. package/dist/ui/date-picker/cmp.date-time-picker.svelte.d.ts +8 -5
  6. package/dist/ui/date-picker/cmp.time-picker.svelte +3 -2
  7. package/dist/ui/date-picker/cmp.time-picker.svelte.d.ts +2 -0
  8. package/dist/ui/dialog/cmp.dialog-container.svelte +19 -12
  9. package/dist/ui/dialog/cmp.dialog.svelte +19 -12
  10. package/dist/ui/dialog/layout/cmp.stepper-dialog.svelte +54 -0
  11. package/dist/ui/emoji-picker/cmp.emoji-panel.svelte +19 -12
  12. package/dist/ui/file-uploader/cmp.upload-progress-toaster.svelte +20 -11
  13. package/dist/ui/grouped-sidebar/cmp.grouped-sidebar.svelte +20 -11
  14. package/dist/ui/navigation/cmp.nav-menu.svelte +20 -11
  15. package/dist/ui/page-layout/cmp.page-layout.svelte +38 -24
  16. package/dist/ui/page-layout/cmp.page-panel-sidebars.svelte +40 -22
  17. package/dist/ui/page-layout/cmp.page-panel.svelte +20 -11
  18. package/dist/ui/popover/cmp.popover.svelte +19 -12
  19. package/dist/ui/select/cmp.input-suggest.svelte +1 -0
  20. package/dist/ui/select/cmp.singleselect-async.svelte +1 -0
  21. package/dist/ui/select/multiselect-base.svelte +1 -0
  22. package/dist/ui/select/select-core.svelte.js +41 -11
  23. package/dist/ui/select/select-listbox.svelte +42 -19
  24. package/dist/ui/select/select-listbox.svelte.d.ts +5 -3
  25. package/dist/ui/table/table-core.svelte +19 -12
  26. package/dist/ui/textarea/cmp.textarea.svelte +20 -11
  27. package/package.json +6 -6
@@ -70,19 +70,28 @@ routing, or feature gating. Compose with `NavMenuGroup`, `NavMenuHeader`, `NavMe
70
70
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border--strong);
71
71
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
72
72
  }
73
- .nav-menu__body::-webkit-scrollbar {
74
- width: 6px;
75
- height: 6px;
76
- }
77
- .nav-menu__body::-webkit-scrollbar-track {
78
- background: var(--_cross-browser-scrollbar--track-color);
79
- border-radius: 100vw;
73
+ .nav-menu__body {
74
+ --_cross-browser-scrollbar--gutter: 0px;
80
75
  }
81
- .nav-menu__body::-webkit-scrollbar-thumb {
82
- background: var(--_cross-browser-scrollbar--thumb-color);
83
- border-radius: 100vw;
76
+ @supports selector(::-webkit-scrollbar) {
77
+ .nav-menu__body {
78
+ scrollbar-color: auto;
79
+ scrollbar-width: auto;
80
+ }
81
+ .nav-menu__body::-webkit-scrollbar {
82
+ width: 6px;
83
+ height: 6px;
84
+ }
85
+ .nav-menu__body::-webkit-scrollbar-track {
86
+ background: var(--_cross-browser-scrollbar--track-color);
87
+ border-radius: 100vw;
88
+ }
89
+ .nav-menu__body::-webkit-scrollbar-thumb {
90
+ background: var(--_cross-browser-scrollbar--thumb-color);
91
+ border-radius: 100vw;
92
+ }
84
93
  }
85
- @supports (scrollbar-color: transparent transparent) {
94
+ @supports not selector(::-webkit-scrollbar) {
86
95
  .nav-menu__body {
87
96
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
88
97
  scrollbar-width: thin;
@@ -135,20 +135,27 @@ A loading `PagePanel` inside a loading layout draws its own spinner and overlay
135
135
  overflow-y: var(--_page-layout--body-overflow, auto);
136
136
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border);
137
137
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
138
+ --_cross-browser-scrollbar--gutter: 0px;
138
139
  }
139
- .page-layout__body::-webkit-scrollbar {
140
- width: 6px;
141
- height: 6px;
142
- }
143
- .page-layout__body::-webkit-scrollbar-track {
144
- background: var(--_cross-browser-scrollbar--track-color);
145
- border-radius: 100vw;
146
- }
147
- .page-layout__body::-webkit-scrollbar-thumb {
148
- background: var(--_cross-browser-scrollbar--thumb-color);
149
- border-radius: 100vw;
140
+ @supports selector(::-webkit-scrollbar) {
141
+ .page-layout__body {
142
+ scrollbar-color: auto;
143
+ scrollbar-width: auto;
144
+ }
145
+ .page-layout__body::-webkit-scrollbar {
146
+ width: 6px;
147
+ height: 6px;
148
+ }
149
+ .page-layout__body::-webkit-scrollbar-track {
150
+ background: var(--_cross-browser-scrollbar--track-color);
151
+ border-radius: 100vw;
152
+ }
153
+ .page-layout__body::-webkit-scrollbar-thumb {
154
+ background: var(--_cross-browser-scrollbar--thumb-color);
155
+ border-radius: 100vw;
156
+ }
150
157
  }
151
- @supports (scrollbar-color: transparent transparent) {
158
+ @supports not selector(::-webkit-scrollbar) {
152
159
  .page-layout__body {
153
160
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
154
161
  scrollbar-width: thin;
@@ -158,20 +165,27 @@ A loading `PagePanel` inside a loading layout draws its own spinner and overlay
158
165
  overflow-y: auto;
159
166
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border);
160
167
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
168
+ --_cross-browser-scrollbar--gutter: 0px;
161
169
  }
162
- .page-layout--scrollable::-webkit-scrollbar {
163
- width: 6px;
164
- height: 6px;
165
- }
166
- .page-layout--scrollable::-webkit-scrollbar-track {
167
- background: var(--_cross-browser-scrollbar--track-color);
168
- border-radius: 100vw;
169
- }
170
- .page-layout--scrollable::-webkit-scrollbar-thumb {
171
- background: var(--_cross-browser-scrollbar--thumb-color);
172
- border-radius: 100vw;
170
+ @supports selector(::-webkit-scrollbar) {
171
+ .page-layout--scrollable {
172
+ scrollbar-color: auto;
173
+ scrollbar-width: auto;
174
+ }
175
+ .page-layout--scrollable::-webkit-scrollbar {
176
+ width: 6px;
177
+ height: 6px;
178
+ }
179
+ .page-layout--scrollable::-webkit-scrollbar-track {
180
+ background: var(--_cross-browser-scrollbar--track-color);
181
+ border-radius: 100vw;
182
+ }
183
+ .page-layout--scrollable::-webkit-scrollbar-thumb {
184
+ background: var(--_cross-browser-scrollbar--thumb-color);
185
+ border-radius: 100vw;
186
+ }
173
187
  }
174
- @supports (scrollbar-color: transparent transparent) {
188
+ @supports not selector(::-webkit-scrollbar) {
175
189
  .page-layout--scrollable {
176
190
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
177
191
  scrollbar-width: thin;
@@ -145,19 +145,28 @@ line instead of doubling it. The collapse button stays put outside that track.
145
145
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border--strong);
146
146
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
147
147
  }
148
- .page-panel-sidebars__sidebar::-webkit-scrollbar {
149
- width: 6px;
150
- height: 6px;
151
- }
152
- .page-panel-sidebars__sidebar::-webkit-scrollbar-track {
153
- background: var(--_cross-browser-scrollbar--track-color);
154
- border-radius: 100vw;
148
+ .page-panel-sidebars__sidebar {
149
+ --_cross-browser-scrollbar--gutter: 0px;
155
150
  }
156
- .page-panel-sidebars__sidebar::-webkit-scrollbar-thumb {
157
- background: var(--_cross-browser-scrollbar--thumb-color);
158
- border-radius: 100vw;
151
+ @supports selector(::-webkit-scrollbar) {
152
+ .page-panel-sidebars__sidebar {
153
+ scrollbar-color: auto;
154
+ scrollbar-width: auto;
155
+ }
156
+ .page-panel-sidebars__sidebar::-webkit-scrollbar {
157
+ width: 6px;
158
+ height: 6px;
159
+ }
160
+ .page-panel-sidebars__sidebar::-webkit-scrollbar-track {
161
+ background: var(--_cross-browser-scrollbar--track-color);
162
+ border-radius: 100vw;
163
+ }
164
+ .page-panel-sidebars__sidebar::-webkit-scrollbar-thumb {
165
+ background: var(--_cross-browser-scrollbar--thumb-color);
166
+ border-radius: 100vw;
167
+ }
159
168
  }
160
- @supports (scrollbar-color: transparent transparent) {
169
+ @supports not selector(::-webkit-scrollbar) {
161
170
  .page-panel-sidebars__sidebar {
162
171
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
163
172
  scrollbar-width: thin;
@@ -181,19 +190,28 @@ line instead of doubling it. The collapse button stays put outside that track.
181
190
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border--strong);
182
191
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
183
192
  }
184
- .page-panel-sidebars__main::-webkit-scrollbar {
185
- width: 6px;
186
- height: 6px;
187
- }
188
- .page-panel-sidebars__main::-webkit-scrollbar-track {
189
- background: var(--_cross-browser-scrollbar--track-color);
190
- border-radius: 100vw;
193
+ .page-panel-sidebars__main {
194
+ --_cross-browser-scrollbar--gutter: 0px;
191
195
  }
192
- .page-panel-sidebars__main::-webkit-scrollbar-thumb {
193
- background: var(--_cross-browser-scrollbar--thumb-color);
194
- border-radius: 100vw;
196
+ @supports selector(::-webkit-scrollbar) {
197
+ .page-panel-sidebars__main {
198
+ scrollbar-color: auto;
199
+ scrollbar-width: auto;
200
+ }
201
+ .page-panel-sidebars__main::-webkit-scrollbar {
202
+ width: 6px;
203
+ height: 6px;
204
+ }
205
+ .page-panel-sidebars__main::-webkit-scrollbar-track {
206
+ background: var(--_cross-browser-scrollbar--track-color);
207
+ border-radius: 100vw;
208
+ }
209
+ .page-panel-sidebars__main::-webkit-scrollbar-thumb {
210
+ background: var(--_cross-browser-scrollbar--thumb-color);
211
+ border-radius: 100vw;
212
+ }
195
213
  }
196
- @supports (scrollbar-color: transparent transparent) {
214
+ @supports not selector(::-webkit-scrollbar) {
197
215
  .page-panel-sidebars__main {
198
216
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
199
217
  scrollbar-width: thin;
@@ -469,19 +469,28 @@ to min / max; Enter / Space toggle collapsed.
469
469
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border--strong);
470
470
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
471
471
  }
472
- .page-panel__content::-webkit-scrollbar {
473
- width: 6px;
474
- height: 6px;
475
- }
476
- .page-panel__content::-webkit-scrollbar-track {
477
- background: var(--_cross-browser-scrollbar--track-color);
478
- border-radius: 100vw;
472
+ .page-panel__content {
473
+ --_cross-browser-scrollbar--gutter: 0px;
479
474
  }
480
- .page-panel__content::-webkit-scrollbar-thumb {
481
- background: var(--_cross-browser-scrollbar--thumb-color);
482
- border-radius: 100vw;
475
+ @supports selector(::-webkit-scrollbar) {
476
+ .page-panel__content {
477
+ scrollbar-color: auto;
478
+ scrollbar-width: auto;
479
+ }
480
+ .page-panel__content::-webkit-scrollbar {
481
+ width: 6px;
482
+ height: 6px;
483
+ }
484
+ .page-panel__content::-webkit-scrollbar-track {
485
+ background: var(--_cross-browser-scrollbar--track-color);
486
+ border-radius: 100vw;
487
+ }
488
+ .page-panel__content::-webkit-scrollbar-thumb {
489
+ background: var(--_cross-browser-scrollbar--thumb-color);
490
+ border-radius: 100vw;
491
+ }
483
492
  }
484
- @supports (scrollbar-color: transparent transparent) {
493
+ @supports not selector(::-webkit-scrollbar) {
485
494
  .page-panel__content {
486
495
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
487
496
  scrollbar-width: thin;
@@ -399,20 +399,27 @@ Props for keeping the popover open during interaction:
399
399
  overflow: var(--_dd--content-overflow);
400
400
  --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
401
401
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
402
+ --_cross-browser-scrollbar--gutter: 0px;
402
403
  }
403
- .popover__panel--styled::-webkit-scrollbar {
404
- width: 6px;
405
- height: 6px;
406
- }
407
- .popover__panel--styled::-webkit-scrollbar-track {
408
- background: var(--_cross-browser-scrollbar--track-color);
409
- border-radius: 100vw;
410
- }
411
- .popover__panel--styled::-webkit-scrollbar-thumb {
412
- background: var(--_cross-browser-scrollbar--thumb-color);
413
- border-radius: 100vw;
404
+ @supports selector(::-webkit-scrollbar) {
405
+ .popover__panel--styled {
406
+ scrollbar-color: auto;
407
+ scrollbar-width: auto;
408
+ }
409
+ .popover__panel--styled::-webkit-scrollbar {
410
+ width: 6px;
411
+ height: 6px;
412
+ }
413
+ .popover__panel--styled::-webkit-scrollbar-track {
414
+ background: var(--_cross-browser-scrollbar--track-color);
415
+ border-radius: 100vw;
416
+ }
417
+ .popover__panel--styled::-webkit-scrollbar-thumb {
418
+ background: var(--_cross-browser-scrollbar--thumb-color);
419
+ border-radius: 100vw;
420
+ }
414
421
  }
415
- @supports (scrollbar-color: transparent transparent) {
422
+ @supports not selector(::-webkit-scrollbar) {
416
423
  .popover__panel--styled {
417
424
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
418
425
  scrollbar-width: thin;
@@ -261,6 +261,7 @@ const handlePickRow = (row) => {
261
261
  <SelectListbox
262
262
  triggerEl={rootEl}
263
263
  isOpen={isPanelOpen}
264
+ size={size}
264
265
  rows={rows}
265
266
  highlight={activeIndex}
266
267
  listboxId={listboxId}
@@ -136,6 +136,7 @@ const showClear = $derived(mode.clearable && hasValue && isInteractive && !core.
136
136
  <SelectListbox
137
137
  triggerEl={rootEl}
138
138
  isOpen={core.isOpen}
139
+ size={size}
139
140
  rows={core.rows}
140
141
  highlight={core.highlight}
141
142
  loading={core.loading}
@@ -257,6 +257,7 @@ const handleDndFinalize = (e) => {
257
257
  <SelectListbox
258
258
  triggerEl={rootEl}
259
259
  isOpen={core.isOpen}
260
+ size={size}
260
261
  rows={core.rows}
261
262
  highlight={core.highlight}
262
263
  loading={core.loading}
@@ -11,6 +11,7 @@ export function createSelectCore(config) {
11
11
  let isOpen = $state(false);
12
12
  let query = $state('');
13
13
  let highlight = $state(0);
14
+ let highlightMovedByUser = false;
14
15
  let isFiltering = $state(false);
15
16
  let items = $state.raw([]);
16
17
  let loadToken = 0;
@@ -152,13 +153,28 @@ export function createSelectCore(config) {
152
153
  return out;
153
154
  });
154
155
  const navigableIndices = $derived(getNavigableIndices(rows));
155
- const openPopover = () => {
156
- if (!config.getInteractive() || isOpen) {
157
- return;
156
+ const findSelectedRowIndex = () => {
157
+ const selected = config.getSelectedOptions()[0];
158
+ if (!selected) {
159
+ return navigableIndices[0] ?? 0;
158
160
  }
159
- isOpen = true;
160
- query = '';
161
- isFiltering = false;
161
+ const compare = config.getCompare();
162
+ const idx = rows.findIndex((r) => r.kind === 'option' && compare(r.option.value, selected.value));
163
+ return idx >= 0 ? idx : (navigableIndices[0] ?? 0);
164
+ };
165
+ const moveHighlightByUser = (index) => {
166
+ highlight = index;
167
+ highlightMovedByUser = true;
168
+ };
169
+ const loadAndHighlightSelected = async () => {
170
+ highlight = findSelectedRowIndex();
171
+ highlightMovedByUser = false;
172
+ await runLoad('');
173
+ if (isOpen && !query && !highlightMovedByUser) {
174
+ highlight = findSelectedRowIndex();
175
+ }
176
+ };
177
+ const highlightFirstSelectedAndLoad = () => {
162
178
  const selected = config.getSelectedOptions()[0];
163
179
  if (selected) {
164
180
  const idx = rows.findIndex((r) => r.kind === 'option' && r.option === selected);
@@ -168,6 +184,20 @@ export function createSelectCore(config) {
168
184
  highlight = navigableIndices[0] ?? 0;
169
185
  }
170
186
  void runLoad('');
187
+ };
188
+ const openPopover = () => {
189
+ if (!config.getInteractive() || isOpen) {
190
+ return;
191
+ }
192
+ isOpen = true;
193
+ query = '';
194
+ isFiltering = false;
195
+ if (config.picker === 'single') {
196
+ void loadAndHighlightSelected();
197
+ }
198
+ else {
199
+ highlightFirstSelectedAndLoad();
200
+ }
171
201
  // Clicks land on the trigger root (div role=presentation) — focus the inner input so the
172
202
  // user can start typing immediately without a second click.
173
203
  config.getInputEl()?.focus();
@@ -292,7 +322,7 @@ export function createSelectCore(config) {
292
322
  if (!isOpen) {
293
323
  isOpen = true;
294
324
  }
295
- highlight = navigableIndices[0] ?? 0;
325
+ moveHighlightByUser(navigableIndices[0] ?? 0);
296
326
  debouncedLoad(query);
297
327
  };
298
328
  const handleKeydown = (e) => {
@@ -308,11 +338,11 @@ export function createSelectCore(config) {
308
338
  }
309
339
  if (e.key === 'ArrowDown') {
310
340
  e.preventDefault();
311
- highlight = moveHighlightIndex(navigableIndices, highlight, 1);
341
+ moveHighlightByUser(moveHighlightIndex(navigableIndices, highlight, 1));
312
342
  }
313
343
  else if (e.key === 'ArrowUp') {
314
344
  e.preventDefault();
315
- highlight = moveHighlightIndex(navigableIndices, highlight, -1);
345
+ moveHighlightByUser(moveHighlightIndex(navigableIndices, highlight, -1));
316
346
  }
317
347
  else if (e.key === 'Enter') {
318
348
  e.preventDefault();
@@ -337,7 +367,7 @@ export function createSelectCore(config) {
337
367
  e.preventDefault();
338
368
  isFiltering = true;
339
369
  query = e.key;
340
- highlight = navigableIndices[0] ?? 0;
370
+ moveHighlightByUser(navigableIndices[0] ?? 0);
341
371
  debouncedLoad(query);
342
372
  }
343
373
  };
@@ -381,7 +411,7 @@ export function createSelectCore(config) {
381
411
  closePopover,
382
412
  pickRow,
383
413
  setHighlight(i) {
384
- highlight = i;
414
+ moveHighlightByUser(i);
385
415
  },
386
416
  refresh() {
387
417
  if (isOpen) {
@@ -6,7 +6,7 @@ import IconCheckboxChecked from '@fluentui/svg-icons/icons/checkbox_checked_16_f
6
6
  import IconCheckboxIndeterminate from '@fluentui/svg-icons/icons/checkbox_indeterminate_16_filled.svg?raw';
7
7
  import IconCheckboxUnchecked from '@fluentui/svg-icons/icons/checkbox_unchecked_16_regular.svg?raw';
8
8
  import IconCheckmark from '@fluentui/svg-icons/icons/checkmark_16_regular.svg?raw';
9
- let { triggerEl, isOpen, rows, highlight, loading = false, listboxId, matchTriggerWidth = true, selectedDisplay = 'checkmark', optionSnippet, headerSnippet, bodySnippet, hideCreateRows = false, createPrefix, suppressEmpty = false, on } = $props();
9
+ let { triggerEl, isOpen, rows, highlight, loading = false, size = 'md', listboxId, matchTriggerWidth = true, selectedDisplay = 'checkmark', optionSnippet, headerSnippet, bodySnippet, hideCreateRows = false, createPrefix, suppressEmpty = false, on } = $props();
10
10
  const localization = new SelectListboxLocalization();
11
11
  // rows keep their index into the full `rows` array — `highlight` and row ids are core-side indices,
12
12
  // so filtering without preserving them shifts every row by one and Enter acts on the wrong row
@@ -115,7 +115,7 @@ $effect(() => {
115
115
  {#if isOpen && (hasRows || showEmpty)}
116
116
  <div
117
117
  bind:this={panelEl}
118
- class="select-listbox select-listbox--display-{selectedDisplay}"
118
+ class="select-listbox select-listbox--{size} select-listbox--display-{selectedDisplay}"
119
119
  role="listbox"
120
120
  id={listboxId}
121
121
  tabindex="-1"
@@ -237,10 +237,10 @@ dismiss events upward. Floating UI handles placement with autoUpdate on scroll/r
237
237
  | `--sc-kit--select--panel--border-color` | Panel border | `var(--sc-kit--color--border)` |
238
238
  | `--sc-kit--select--panel--border-radius` | Panel radius | `var(--sc-kit--radius--md)` |
239
239
  | `--sc-kit--select--panel--box-shadow` | Panel shadow | `var(--sc-kit--shadow--lg)` |
240
- | `--sc-kit--select--panel--font-size` | Option / group / empty-state text size | `var(--sc-kit--font-size--md)` |
240
+ | `--sc-kit--select--panel--font-size` | Option / group / empty-state text size | per size — `var(--sc-kit--font-size--{sm,md,lg})` |
241
241
  | `--sc-kit--select--panel--max-height` | Panel max height | `18rem` |
242
- | `--sc-kit--select--panel--padding` | Panel inner padding | `var(--sc-kit--space--1)` |
243
- | `--sc-kit--select--option--height` | Option row height | `var(--sc-kit--field--height--md)` (32px) |
242
+ | `--sc-kit--select--panel--padding` | Panel inner padding; in Chrome / Safari the 4px scrollbar takes its share of the end side | `var(--sc-kit--space--1)` |
243
+ | `--sc-kit--select--option--height` | Option row height | per size — `var(--sc-kit--field--height--{sm,md,lg})` |
244
244
  | `--sc-kit--select--option--padding-inline` | Option horizontal padding | `var(--sc-kit--space--3)` |
245
245
  | `--sc-kit--select--option--background--active` | Active / focused row background | `var(--sc-kit--color--accent--softer)` |
246
246
  | `--sc-kit--select--option--color` | Row text color | `var(--sc-kit--color--text--primary)` |
@@ -257,8 +257,8 @@ dismiss events upward. Floating UI handles placement with autoUpdate on scroll/r
257
257
  --_lb--box-shadow: var(--sc-kit--select--panel--box-shadow, var(--sc-kit--shadow--lg));
258
258
  --_lb--max-height: var(--sc-kit--select--panel--max-height, 18rem);
259
259
  --_lb--padding: var(--sc-kit--select--panel--padding, var(--sc-kit--space--1));
260
- --_lb--font-size: var(--sc-kit--select--panel--font-size, var(--sc-kit--font-size--md));
261
- --_lb--row-height: var(--sc-kit--select--option--height, var(--sc-kit--field--height--md));
260
+ --_lb--font-size: var(--sc-kit--select--panel--font-size, var(--_lb--size-font-size, var(--sc-kit--font-size--md)));
261
+ --_lb--row-height: var(--sc-kit--select--option--height, var(--_lb--size-row-height, var(--sc-kit--field--height--md)));
262
262
  --_lb--row-padding-inline: var(--sc-kit--select--option--padding-inline, var(--sc-kit--space--3));
263
263
  --_lb--row-background-active: var(--sc-kit--select--option--background--active, var(--sc-kit--color--accent--softer));
264
264
  --_lb--row-color: var(--sc-kit--select--option--color, var(--sc-kit--color--text--primary));
@@ -278,28 +278,51 @@ dismiss events upward. Floating UI handles placement with autoUpdate on scroll/r
278
278
  box-shadow: var(--_lb--box-shadow);
279
279
  max-height: var(--_lb--max-height);
280
280
  padding: var(--_lb--padding);
281
+ padding-inline-start: max(var(--_lb--padding), var(--_cross-browser-scrollbar--gutter, 0px));
282
+ padding-inline-end: max(0px, var(--_lb--padding) - var(--_cross-browser-scrollbar--gutter, 0px));
281
283
  overflow-y: auto;
282
284
  --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
283
285
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
286
+ --_cross-browser-scrollbar--gutter: 0px;
284
287
  }
285
- .select-listbox::-webkit-scrollbar {
286
- width: 6px;
287
- height: 6px;
288
- }
289
- .select-listbox::-webkit-scrollbar-track {
290
- background: var(--_cross-browser-scrollbar--track-color);
291
- border-radius: 100vw;
292
- }
293
- .select-listbox::-webkit-scrollbar-thumb {
294
- background: var(--_cross-browser-scrollbar--thumb-color);
295
- border-radius: 100vw;
288
+ @supports selector(::-webkit-scrollbar) {
289
+ .select-listbox {
290
+ scrollbar-color: auto;
291
+ scrollbar-width: auto;
292
+ }
293
+ .select-listbox::-webkit-scrollbar {
294
+ width: 4px;
295
+ height: 4px;
296
+ }
297
+ .select-listbox::-webkit-scrollbar-track {
298
+ background: var(--_cross-browser-scrollbar--track-color);
299
+ border-radius: 100vw;
300
+ }
301
+ .select-listbox::-webkit-scrollbar-thumb {
302
+ background: var(--_cross-browser-scrollbar--thumb-color);
303
+ border-radius: 100vw;
304
+ }
296
305
  }
297
- @supports (scrollbar-color: transparent transparent) {
306
+ @supports not selector(::-webkit-scrollbar) {
298
307
  .select-listbox {
299
308
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
300
309
  scrollbar-width: thin;
301
310
  }
302
311
  }
312
+ @supports selector(::-webkit-scrollbar) {
313
+ .select-listbox {
314
+ --_cross-browser-scrollbar--gutter: 4px;
315
+ overflow-y: scroll;
316
+ }
317
+ }
318
+ .select-listbox--sm {
319
+ --_lb--size-font-size: var(--sc-kit--font-size--sm);
320
+ --_lb--size-row-height: var(--sc-kit--field--height--sm);
321
+ }
322
+ .select-listbox--lg {
323
+ --_lb--size-font-size: var(--sc-kit--font-size--lg);
324
+ --_lb--size-row-height: var(--sc-kit--field--height--lg);
325
+ }
303
326
  .select-listbox__row {
304
327
  display: flex;
305
328
  align-items: center;
@@ -9,6 +9,8 @@ declare function $$render<T>(): {
9
9
  /** Index into `rows` — highlighted row gets the active background and scrolls into view. */
10
10
  highlight: number;
11
11
  loading?: boolean;
12
+ /** Field size the rows follow (font size + row height). @default 'md' */
13
+ size?: "sm" | "md" | "lg";
12
14
  /** Stable id for aria-controls + aria-activedescendant. */
13
15
  listboxId: string;
14
16
  /** When true, panel width equals trigger width. @default true */
@@ -79,10 +81,10 @@ interface $$IsomorphicComponent {
79
81
  * | `--sc-kit--select--panel--border-color` | Panel border | `var(--sc-kit--color--border)` |
80
82
  * | `--sc-kit--select--panel--border-radius` | Panel radius | `var(--sc-kit--radius--md)` |
81
83
  * | `--sc-kit--select--panel--box-shadow` | Panel shadow | `var(--sc-kit--shadow--lg)` |
82
- * | `--sc-kit--select--panel--font-size` | Option / group / empty-state text size | `var(--sc-kit--font-size--md)` |
84
+ * | `--sc-kit--select--panel--font-size` | Option / group / empty-state text size | per size — `var(--sc-kit--font-size--{sm,md,lg})` |
83
85
  * | `--sc-kit--select--panel--max-height` | Panel max height | `18rem` |
84
- * | `--sc-kit--select--panel--padding` | Panel inner padding | `var(--sc-kit--space--1)` |
85
- * | `--sc-kit--select--option--height` | Option row height | `var(--sc-kit--field--height--md)` (32px) |
86
+ * | `--sc-kit--select--panel--padding` | Panel inner padding; in Chrome / Safari the 4px scrollbar takes its share of the end side | `var(--sc-kit--space--1)` |
87
+ * | `--sc-kit--select--option--height` | Option row height | per size — `var(--sc-kit--field--height--{sm,md,lg})` |
86
88
  * | `--sc-kit--select--option--padding-inline` | Option horizontal padding | `var(--sc-kit--space--3)` |
87
89
  * | `--sc-kit--select--option--background--active` | Active / focused row background | `var(--sc-kit--color--accent--softer)` |
88
90
  * | `--sc-kit--select--option--color` | Row text color | `var(--sc-kit--color--text--primary)` |
@@ -290,20 +290,27 @@ Not exported from `index.ts` — for kit-internal use only.
290
290
  overflow: auto;
291
291
  --_cross-browser-scrollbar--thumb-color: var(--scrollbar--thumb-color, light-dark(#d1d5db, #4b5563));
292
292
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
293
+ --_cross-browser-scrollbar--gutter: 0px;
293
294
  }
294
- .table-container__scroll::-webkit-scrollbar {
295
- width: 6px;
296
- height: 6px;
297
- }
298
- .table-container__scroll::-webkit-scrollbar-track {
299
- background: var(--_cross-browser-scrollbar--track-color);
300
- border-radius: 100vw;
301
- }
302
- .table-container__scroll::-webkit-scrollbar-thumb {
303
- background: var(--_cross-browser-scrollbar--thumb-color);
304
- border-radius: 100vw;
295
+ @supports selector(::-webkit-scrollbar) {
296
+ .table-container__scroll {
297
+ scrollbar-color: auto;
298
+ scrollbar-width: auto;
299
+ }
300
+ .table-container__scroll::-webkit-scrollbar {
301
+ width: 6px;
302
+ height: 6px;
303
+ }
304
+ .table-container__scroll::-webkit-scrollbar-track {
305
+ background: var(--_cross-browser-scrollbar--track-color);
306
+ border-radius: 100vw;
307
+ }
308
+ .table-container__scroll::-webkit-scrollbar-thumb {
309
+ background: var(--_cross-browser-scrollbar--thumb-color);
310
+ border-radius: 100vw;
311
+ }
305
312
  }
306
- @supports (scrollbar-color: transparent transparent) {
313
+ @supports not selector(::-webkit-scrollbar) {
307
314
  .table-container__scroll {
308
315
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
309
316
  scrollbar-width: thin;
@@ -285,19 +285,28 @@ what the field shows. Blank lines inside the text are left alone. Typing is unto
285
285
  --_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border--strong);
286
286
  --_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
287
287
  }
288
- .textarea__el::-webkit-scrollbar {
289
- width: 6px;
290
- height: 6px;
291
- }
292
- .textarea__el::-webkit-scrollbar-track {
293
- background: var(--_cross-browser-scrollbar--track-color);
294
- border-radius: 100vw;
288
+ .textarea__el {
289
+ --_cross-browser-scrollbar--gutter: 0px;
295
290
  }
296
- .textarea__el::-webkit-scrollbar-thumb {
297
- background: var(--_cross-browser-scrollbar--thumb-color);
298
- border-radius: 100vw;
291
+ @supports selector(::-webkit-scrollbar) {
292
+ .textarea__el {
293
+ scrollbar-color: auto;
294
+ scrollbar-width: auto;
295
+ }
296
+ .textarea__el::-webkit-scrollbar {
297
+ width: 6px;
298
+ height: 6px;
299
+ }
300
+ .textarea__el::-webkit-scrollbar-track {
301
+ background: var(--_cross-browser-scrollbar--track-color);
302
+ border-radius: 100vw;
303
+ }
304
+ .textarea__el::-webkit-scrollbar-thumb {
305
+ background: var(--_cross-browser-scrollbar--thumb-color);
306
+ border-radius: 100vw;
307
+ }
299
308
  }
300
- @supports (scrollbar-color: transparent transparent) {
309
+ @supports not selector(::-webkit-scrollbar) {
301
310
  .textarea__el {
302
311
  scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
303
312
  scrollbar-width: thin;