@slotted/styles 0.1.0-beta.1 → 0.1.0-beta.11

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 (180) hide show
  1. package/package.json +1 -1
  2. package/src/accordion/accordion.css +10 -10
  3. package/src/action-bar/action-bar.css +35 -42
  4. package/src/action-sheet/action-sheet.css +36 -36
  5. package/src/alert/alert.css +43 -35
  6. package/src/alert/alert.tokens.json +5 -0
  7. package/src/app-shell/app-shell.css +356 -301
  8. package/src/aspect-ratio/aspect-ratio.css +9 -9
  9. package/src/attachment/attachment.css +91 -99
  10. package/src/avatar/avatar.css +71 -41
  11. package/src/avatar/avatar.tokens.json +7 -0
  12. package/src/avatar-group/avatar-group.css +21 -22
  13. package/src/badge/badge.css +45 -37
  14. package/src/badge/badge.tokens.json +5 -0
  15. package/src/breadcrumb/breadcrumb.css +37 -37
  16. package/src/button/button.css +149 -68
  17. package/src/button/button.tokens.json +10 -0
  18. package/src/button-group/button-group.css +79 -74
  19. package/src/button-group/button-group.tokens.json +2 -0
  20. package/src/calendar/calendar.css +93 -103
  21. package/src/card/card.css +54 -61
  22. package/src/carousel/carousel.css +150 -161
  23. package/src/cascader/cascader.css +152 -153
  24. package/src/cascader/cascader.tokens.json +1 -0
  25. package/src/chart/chart.css +242 -239
  26. package/src/chart/chart.tokens.json +1 -0
  27. package/src/checkbox/checkbox.css +119 -124
  28. package/src/checkbox-group/checkbox-group.css +7 -7
  29. package/src/code-block/code-block.css +81 -85
  30. package/src/collapsible/collapsible.css +69 -76
  31. package/src/color-picker/color-picker.css +83 -91
  32. package/src/column-manager/column-manager.css +106 -114
  33. package/src/combobox/combobox.css +132 -107
  34. package/src/combobox/combobox.tokens.json +1 -0
  35. package/src/command-palette/command-palette.css +103 -90
  36. package/src/command-palette/command-palette.tokens.json +1 -0
  37. package/src/container/container.css +24 -24
  38. package/src/context-menu/context-menu.css +8 -8
  39. package/src/currency-field/currency-field.css +210 -88
  40. package/src/currency-field/currency-field.tokens.json +13 -0
  41. package/src/dashboard-grid/dashboard-grid.css +148 -116
  42. package/src/data-grid/data-grid.css +535 -470
  43. package/src/data-grid/data-grid.tokens.json +4 -0
  44. package/src/data-list/data-list.css +81 -70
  45. package/src/data-list/data-list.tokens.json +2 -1
  46. package/src/date-field/date-field.css +55 -52
  47. package/src/date-field/date-field.tokens.json +1 -0
  48. package/src/date-picker/date-picker.css +40 -42
  49. package/src/date-range-picker/date-range-picker.css +114 -118
  50. package/src/datetime-field/datetime-field.css +78 -80
  51. package/src/datetime-field/datetime-field.tokens.json +1 -0
  52. package/src/datetime-picker/datetime-picker.css +61 -63
  53. package/src/datetime-range-picker/datetime-range-picker.css +149 -156
  54. package/src/description-list/description-list.css +61 -64
  55. package/src/detail-panel/detail-panel.css +86 -71
  56. package/src/detail-panel/detail-panel.tokens.json +2 -0
  57. package/src/dialog/dialog.css +372 -153
  58. package/src/dialog/dialog.tokens.json +6 -0
  59. package/src/divider/divider.css +18 -18
  60. package/src/drawer/drawer.css +205 -210
  61. package/src/drawer/drawer.tokens.json +1 -0
  62. package/src/entity-picker/entity-picker.css +238 -241
  63. package/src/entity-picker/entity-picker.tokens.json +1 -0
  64. package/src/event-calendar/event-calendar.css +343 -385
  65. package/src/field/field.css +74 -78
  66. package/src/field-group/field-group.css +22 -25
  67. package/src/filter-bar/filter-bar.css +193 -209
  68. package/src/form/form.css +34 -24
  69. package/src/form/form.tokens.json +1 -0
  70. package/src/fullscreen/fullscreen.css +24 -25
  71. package/src/grid/grid.css +28 -28
  72. package/src/highlight/highlight.css +6 -6
  73. package/src/hover-card/hover-card.css +6 -6
  74. package/src/icon/icon.css +19 -15
  75. package/src/icon/icon.tokens.json +1 -0
  76. package/src/image/image.css +39 -39
  77. package/src/import-export-center/import-export-center.css +135 -156
  78. package/src/inline/inline.css +27 -27
  79. package/src/inline-message/inline-message.css +52 -28
  80. package/src/inline-message/inline-message.tokens.json +4 -0
  81. package/src/kbd/kbd.css +30 -26
  82. package/src/link/link.css +15 -15
  83. package/src/list/list.css +44 -17
  84. package/src/list/list.tokens.json +4 -0
  85. package/src/list-item/list-item.css +80 -66
  86. package/src/list-item/list-item.tokens.json +7 -0
  87. package/src/listbox/listbox.css +56 -59
  88. package/src/loading-overlay/loading-overlay.css +75 -92
  89. package/src/markdown/markdown.css +17 -17
  90. package/src/menu/menu.css +83 -63
  91. package/src/menubar/menubar.css +13 -13
  92. package/src/message/message.css +182 -202
  93. package/src/message/message.tokens.json +5 -0
  94. package/src/message-scroller/message-scroller.css +41 -42
  95. package/src/multi-select/multi-select.css +152 -145
  96. package/src/multi-select/multi-select.tokens.json +1 -0
  97. package/src/navigation-menu/navigation-menu.css +167 -188
  98. package/src/notification-center/notification-center.css +140 -148
  99. package/src/notification-center/notification-center.tokens.json +3 -0
  100. package/src/number-field/number-field.css +84 -83
  101. package/src/number-field/number-field.tokens.json +1 -0
  102. package/src/otp-input/otp-input.css +67 -57
  103. package/src/otp-input/otp-input.tokens.json +1 -0
  104. package/src/page/page.css +39 -23
  105. package/src/page/page.tokens.json +1 -0
  106. package/src/page-header/page-header.css +323 -283
  107. package/src/page-header/page-header.tokens.json +5 -0
  108. package/src/pagination/pagination.css +68 -72
  109. package/src/popover/popover.css +40 -49
  110. package/src/progress-indicator/progress-indicator.css +177 -120
  111. package/src/progress-indicator/progress-indicator.tokens.json +1 -1
  112. package/src/prompt-composer/prompt-composer.css +221 -102
  113. package/src/prompt-composer/prompt-composer.tokens.json +15 -0
  114. package/src/prose/prose.css +71 -75
  115. package/src/radio-group/radio-group.css +98 -103
  116. package/src/rating/rating.css +136 -132
  117. package/src/rating/rating.tokens.json +1 -0
  118. package/src/result-state/result-state.css +74 -77
  119. package/src/runtime-properties.mjs +2 -0
  120. package/src/saved-views/saved-views.css +41 -47
  121. package/src/scroll-area/scroll-area.css +39 -32
  122. package/src/section/section.css +161 -41
  123. package/src/section/section.tokens.json +7 -2
  124. package/src/segmented-control/segmented-control.css +254 -97
  125. package/src/segmented-control/segmented-control.tokens.json +15 -11
  126. package/src/select/select.css +118 -117
  127. package/src/select/select.tokens.json +1 -0
  128. package/src/side-navigation/side-navigation.css +179 -182
  129. package/src/side-navigation/side-navigation.tokens.json +1 -0
  130. package/src/skeleton/skeleton.css +47 -48
  131. package/src/slider/slider.css +86 -88
  132. package/src/sparkline/sparkline.css +62 -40
  133. package/src/sparkline/sparkline.tokens.json +2 -0
  134. package/src/spinner/spinner.css +83 -180
  135. package/src/spinner/spinner.tokens.json +0 -1
  136. package/src/split-button/split-button.css +30 -31
  137. package/src/split-button/split-button.tokens.json +1 -0
  138. package/src/splitter/splitter.css +35 -35
  139. package/src/stack/stack.css +24 -24
  140. package/src/stat-card/stat-card.css +341 -224
  141. package/src/stat-card/stat-card.tokens.json +3 -0
  142. package/src/status-indicator/status-indicator.css +28 -28
  143. package/src/stepper/stepper.css +58 -62
  144. package/src/switch/switch.css +86 -92
  145. package/src/table/table.css +310 -165
  146. package/src/table/table.tokens.json +6 -0
  147. package/src/table-of-contents/table-of-contents.css +51 -54
  148. package/src/tabs/tabs.css +337 -302
  149. package/src/tabs/tabs.tokens.json +8 -5
  150. package/src/tag/tag.css +79 -71
  151. package/src/tag/tag.tokens.json +9 -0
  152. package/src/tags-input/tags-input.css +145 -82
  153. package/src/tags-input/tags-input.tokens.json +7 -1
  154. package/src/text-field/text-field.css +132 -136
  155. package/src/text-field/text-field.tokens.json +1 -0
  156. package/src/textarea/textarea.css +31 -28
  157. package/src/textarea/textarea.tokens.json +1 -0
  158. package/src/time-field/time-field.css +72 -69
  159. package/src/time-field/time-field.tokens.json +1 -0
  160. package/src/time-picker/time-picker.css +56 -58
  161. package/src/time-range-picker/time-range-picker.css +126 -133
  162. package/src/timeline/timeline.css +254 -266
  163. package/src/timeline/timeline.tokens.json +5 -0
  164. package/src/toast/toast.css +108 -90
  165. package/src/toast/toast.tokens.json +6 -0
  166. package/src/toggle/toggle.css +62 -25
  167. package/src/toggle/toggle.tokens.json +8 -0
  168. package/src/toggle-group/toggle-group.css +106 -60
  169. package/src/toggle-group/toggle-group.tokens.json +10 -0
  170. package/src/toolbar/toolbar.css +30 -35
  171. package/src/tooltip/tooltip.css +26 -26
  172. package/src/top-navigation/top-navigation.css +243 -259
  173. package/src/tour/tour.css +51 -60
  174. package/src/transfer/transfer.css +160 -164
  175. package/src/tree/tree.css +103 -111
  176. package/src/typography/typography.css +40 -36
  177. package/src/typography/typography.tokens.json +1 -0
  178. package/src/upload/upload.css +224 -224
  179. package/src/visually-hidden/visually-hidden.css +1 -1
  180. package/src/wizard/wizard.css +185 -197
@@ -74,7 +74,7 @@
74
74
 
75
75
  /* ── The control ──────────────────────────────────────────────────────── */
76
76
 
77
- [data-ui='select'][data-part='root'] {
77
+ [data-ui-select][data-part-root] {
78
78
  /**
79
79
  * Type, height, inline padding, gap and glyph size come from the control
80
80
  * scales — the only ones the theme restates per density — so a select in a
@@ -144,7 +144,7 @@
144
144
  }
145
145
 
146
146
  /* And the clear button's own lane, before the chevron's, when there is one. */
147
- [data-ui='select'][data-part='root']:has(> [data-part='clear']) {
147
+ [data-ui-select][data-part-root]:has(> [data-part-clear]) {
148
148
  grid-template-columns: minmax(0, 1fr) auto auto;
149
149
  }
150
150
 
@@ -153,7 +153,7 @@
153
153
  * value, which is what a filter beside a table needs and what a field never
154
154
  * does — hence the default the contract states, `fullWidth: true`.
155
155
  */
156
- [data-ui='select'][data-part='root']:not([data-full-width]) {
156
+ [data-ui-select][data-part-root]:not([data-full-width]) {
157
157
  inline-size: auto;
158
158
  }
159
159
 
@@ -177,7 +177,7 @@
177
177
  * the chevron still lands on the button that opens the popup — which is why
178
178
  * the chevron can be inert and the arrangement costs nothing.
179
179
  */
180
- [data-ui='select'] > [data-part='trigger'] {
180
+ [data-ui-select] > [data-part-trigger] {
181
181
  align-items: center;
182
182
  appearance: none;
183
183
  background-color: transparent;
@@ -218,7 +218,7 @@
218
218
  }
219
219
 
220
220
  /* And the clear button's own box, plus a second gap, when there is one. */
221
- [data-ui='select'][data-part='root']:has(> [data-part='clear']) > [data-part='trigger'] {
221
+ [data-ui-select][data-part-root]:has(> [data-part-clear]) > [data-part-trigger] {
222
222
  padding-inline-end: calc(
223
223
  var(--_padding-inline) + var(--_icon-size) + var(--_gap) + var(--_action-size) + var(--_gap)
224
224
  );
@@ -229,7 +229,7 @@
229
229
  * control's height as the reader chose, and a form that reflows on selection
230
230
  * is a form that moves under the pointer.
231
231
  */
232
- [data-ui='select'] [data-part='value'] {
232
+ [data-ui-select] [data-part-value] {
233
233
  flex: 1 1 auto;
234
234
  min-inline-size: 0;
235
235
  overflow: hidden;
@@ -241,7 +241,7 @@
241
241
  * Nothing chosen yet. The same weight the reader will see once they choose,
242
242
  * one step quieter, so the control does not change shape when it fills.
243
243
  */
244
- [data-ui='select'] [data-part='value'][data-placeholder] {
244
+ [data-ui-select] [data-part-value][data-placeholder] {
245
245
  color: var(--slotted-select-placeholder-color, var(--slotted-text-muted, GrayText));
246
246
  }
247
247
 
@@ -252,7 +252,7 @@
252
252
  * the same face and marked as unresolved for a stylesheet that wants to say
253
253
  * more.
254
254
  */
255
- [data-ui='select'] [data-part='value'][data-unmatched] {
255
+ [data-ui-select] [data-part-value][data-unmatched] {
256
256
  font-variant-numeric: tabular-nums;
257
257
  }
258
258
 
@@ -280,7 +280,7 @@
280
280
  * trigger spanning underneath, so the frame still opens the popup everywhere
281
281
  * a chip is not.
282
282
  */
283
- [data-ui='select'][data-part='root'] > [data-part='tags'] {
283
+ [data-ui-select][data-part-root] > [data-part-tags] {
284
284
  align-items: center;
285
285
  display: flex;
286
286
  gap: var(--slotted-space-2, 0.25rem);
@@ -308,7 +308,7 @@
308
308
  pointer-events: none;
309
309
  }
310
310
 
311
- [data-ui='select'] > [data-part='tags'] > * {
311
+ [data-ui-select] > [data-part-tags] > * {
312
312
  /* Each chip takes its own presses back, and stands above the trigger that
313
313
  spans the lane underneath it. */
314
314
  pointer-events: auto;
@@ -321,7 +321,7 @@
321
321
  * to be a count, and `createCollapse` can measure it the way it measures
322
322
  * every other unit.
323
323
  */
324
- [data-ui='select'] > [data-part='tags'] > [data-overflow] {
324
+ [data-ui-select] > [data-part-tags] > [data-overflow] {
325
325
  flex: none;
326
326
  }
327
327
 
@@ -332,7 +332,7 @@
332
332
  * shown: a button whose accessible name disappeared when the frame grew is a
333
333
  * button that changes what it is called when the window is resized.
334
334
  */
335
- [data-ui='select'] [data-part='summary'] {
335
+ [data-ui-select] [data-part-summary] {
336
336
  display: block;
337
337
  overflow: hidden;
338
338
  text-overflow: ellipsis;
@@ -343,7 +343,7 @@
343
343
  white-space: nowrap;
344
344
  }
345
345
 
346
- [data-ui='select'][data-part='root']:not([data-narrow]) [data-part='summary'] {
346
+ [data-ui-select][data-part-root]:not([data-narrow]) [data-part-summary] {
347
347
  block-size: 1px;
348
348
  clip-path: inset(50%);
349
349
  inline-size: 1px;
@@ -351,7 +351,7 @@
351
351
  white-space: nowrap;
352
352
  }
353
353
 
354
- [data-ui='select'][data-part='root'][data-narrow] > [data-part='tags'] {
354
+ [data-ui-select][data-part-root][data-narrow] > [data-part-tags] {
355
355
  display: none;
356
356
  }
357
357
 
@@ -361,7 +361,7 @@
361
361
  * the popup opens: the one movement in the control, and the only thing on the
362
362
  * closed control that says it opens at all.
363
363
  */
364
- [data-ui='select'] > [data-part='arrow'] {
364
+ [data-ui-select] > [data-part-arrow] {
365
365
  --slotted-icon-size: var(--_icon-size);
366
366
 
367
367
  align-items: center;
@@ -378,12 +378,12 @@
378
378
  pointer-events: none;
379
379
  }
380
380
 
381
- [data-ui='select'] > [data-part='arrow'] > [data-ui='icon'] {
381
+ [data-ui-select] > [data-part-arrow] > [data-ui-icon] {
382
382
  transition: rotate var(--slotted-control-transition-duration)
383
383
  var(--slotted-control-transition-easing);
384
384
  }
385
385
 
386
- [data-ui='select'][data-open] > [data-part='arrow'] > [data-ui='icon'] {
386
+ [data-ui-select][data-open] > [data-part-arrow] > [data-ui-icon] {
387
387
  rotate: 180deg;
388
388
  }
389
389
 
@@ -398,7 +398,7 @@
398
398
  * All this rule does is stand it where the chevron stood and give it the
399
399
  * chevron's size and ink, through the size token the shared sheet reads.
400
400
  */
401
- [data-ui='select'] > [data-part='busy'] {
401
+ [data-ui-select] > [data-part-busy] {
402
402
  --slotted-spinner-size: var(--_icon-size);
403
403
 
404
404
  color: var(--slotted-select-arrow-color, var(--slotted-text-muted, GrayText));
@@ -417,7 +417,7 @@
417
417
  * *glyph* keeps the rhythm the value begins with. `text-field`'s arithmetic,
418
418
  * stated in the terms a track states it.
419
419
  */
420
- [data-ui='select'] > [data-part='clear'] {
420
+ [data-ui-select] > [data-part-clear] {
421
421
  align-items: center;
422
422
  appearance: none;
423
423
  background-color: transparent;
@@ -451,7 +451,7 @@
451
451
  * it can also be 24. This grows the target back in both axes and leaves a
452
452
  * larger one alone.
453
453
  */
454
- [data-ui='select'] > [data-part='clear']::after {
454
+ [data-ui-select] > [data-part-clear]::after {
455
455
  content: '';
456
456
  inset: min(0px, calc((100% - var(--slotted-target-min, 24px)) / 2));
457
457
  position: absolute;
@@ -462,14 +462,14 @@
462
462
  the hit area above grows to 44 pixels around them. It does not reach into
463
463
  the chevron's lane after it, which is the trigger's to answer. */
464
464
  @media (pointer: coarse) {
465
- [data-ui='select'] > [data-part='clear']::after {
465
+ [data-ui-select] > [data-part-clear]::after {
466
466
  inset: min(0px, calc((100% - var(--slotted-target-comfortable, 44px)) / 2));
467
467
  inset-inline-end: 0;
468
468
  }
469
469
  }
470
470
 
471
471
  /* The cross is a `Glyph` the binding draws, at the chevron's size. */
472
- [data-ui='select'] > [data-part='clear'] {
472
+ [data-ui-select] > [data-part-clear] {
473
473
  --slotted-icon-size: var(--_icon-size);
474
474
  }
475
475
 
@@ -481,7 +481,7 @@
481
481
  * and a control disagreeing about one row.
482
482
  */
483
483
 
484
- [data-ui='select'][data-part='root'][data-size='sm'] {
484
+ [data-ui-select][data-part-root][data-size='sm'] {
485
485
  --_font-size: var(--slotted-control-font-size-sm, 12px);
486
486
  --_height: var(--slotted-control-height-sm, 30px);
487
487
  --_padding-inline: var(--slotted-control-padding-inline-sm, 10px);
@@ -490,7 +490,7 @@
490
490
  --_inner-size: var(--slotted-control-inner-size-sm, 22px);
491
491
  }
492
492
 
493
- [data-ui='select'][data-part='root'][data-size='md'] {
493
+ [data-ui-select][data-part-root][data-size='md'] {
494
494
  --_font-size: var(--slotted-control-font-size-md, 13px);
495
495
  --_height: var(--slotted-control-height-md, 34px);
496
496
  --_padding-inline: var(--slotted-control-padding-inline-md, 13px);
@@ -499,7 +499,7 @@
499
499
  --_inner-size: var(--slotted-control-inner-size-md, 24px);
500
500
  }
501
501
 
502
- [data-ui='select'][data-part='root'][data-size='lg'] {
502
+ [data-ui-select][data-part-root][data-size='lg'] {
503
503
  --_font-size: var(--slotted-control-font-size-lg, 14px);
504
504
  --_height: var(--slotted-control-height-lg, 38px);
505
505
  --_padding-inline: var(--slotted-control-padding-inline-lg, 16px);
@@ -517,7 +517,7 @@
517
517
  * does not reflow when the pointer crosses it.
518
518
  */
519
519
 
520
- [data-ui='select'][data-part='root'][data-variant='subtle'] {
520
+ [data-ui-select][data-part-root][data-variant='subtle'] {
521
521
  background-color: var(
522
522
  --slotted-select-subtle-background,
523
523
  var(--slotted-surface-sunken, Canvas)
@@ -531,7 +531,7 @@
531
531
  /* No edge, no lift, no ground and no corner of its own: the cell it sits in
532
532
  is the box, the row is the ground, a cell has no corner, and the resting
533
533
  shadow would draw the cell where there is none. */
534
- [data-ui='select'][data-part='root'][data-variant='plain'] {
534
+ [data-ui-select][data-part-root][data-variant='plain'] {
535
535
  background-color: transparent;
536
536
  border-color: transparent;
537
537
  border-radius: var(--slotted-radius-none, 0px);
@@ -544,7 +544,7 @@
544
544
  * its only edge exactly where an edge matters most.
545
545
  */
546
546
  @media (forced-colors: active) {
547
- [data-ui='select'][data-part='root'][data-variant='plain'] {
547
+ [data-ui-select][data-part-root][data-variant='plain'] {
548
548
  border-color: ButtonBorder;
549
549
  }
550
550
  }
@@ -555,13 +555,13 @@
555
555
  * it can meet, which is the order `STATE_PRECEDENCE` sets.
556
556
  */
557
557
 
558
- [data-ui='select'][data-part='root']:hover:not([data-disabled]):not([data-readonly]):not(
558
+ [data-ui-select][data-part-root]:hover:not([data-disabled]):not([data-readonly]):not(
559
559
  [data-invalid]
560
560
  ) {
561
561
  border-color: var(--slotted-select-hover-border-color, var(--slotted-tone-accent-border));
562
562
  }
563
563
 
564
- [data-ui='select'][data-part='root'][data-variant='subtle']:hover:not([data-disabled]):not(
564
+ [data-ui-select][data-part-root][data-variant='subtle']:hover:not([data-disabled]):not(
565
565
  [data-readonly]
566
566
  ):not([data-invalid]) {
567
567
  background-color: var(
@@ -570,7 +570,7 @@
570
570
  );
571
571
  }
572
572
 
573
- [data-ui='select'][data-part='root'][data-variant='plain']:hover:not([data-disabled]):not(
573
+ [data-ui-select][data-part-root][data-variant='plain']:hover:not([data-disabled]):not(
574
574
  [data-readonly]
575
575
  ):not([data-invalid]) {
576
576
  background-color: var(
@@ -587,13 +587,13 @@
587
587
  * press, which is exactly right here: a reader who pressed the control can
588
588
  * see where they pressed, and the popup is already open under it.
589
589
  */
590
- [data-ui='select'][data-part='root']:has(> [data-part='trigger']:focus-visible) {
590
+ [data-ui-select][data-part-root]:has(> [data-part-trigger]:focus-visible) {
591
591
  /* The resting shadow, recoloured: the geometry is the foundation's and the
592
592
  ink is the ring's, so the lift and the outline are one colour. */
593
593
  box-shadow: var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
594
594
  var(--slotted-focus-ring-color, Highlight);
595
595
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
596
- outline-offset: var(--slotted-focus-ring-offset, 2px);
596
+ outline-offset: var(--slotted-control-focus-ring-offset, var(--slotted-focus-ring-offset, 2px));
597
597
  }
598
598
 
599
599
  /**
@@ -603,9 +603,7 @@
603
603
  * shadow that appears only under focus is a cell that changes size when it
604
604
  * is used.
605
605
  */
606
- [data-ui='select'][data-part='root'][data-variant='plain']:has(
607
- > [data-part='trigger']:focus-visible
608
- ) {
606
+ [data-ui-select][data-part-root][data-variant='plain']:has(> [data-part-trigger]:focus-visible) {
609
607
  box-shadow: none;
610
608
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
611
609
  }
@@ -615,7 +613,7 @@
615
613
  * it. A popup hanging off a control with a resting border reads as two
616
614
  * elements that happen to be adjacent.
617
615
  */
618
- [data-ui='select'][data-part='root'][data-open]:not([data-disabled]) {
616
+ [data-ui-select][data-part-root][data-open]:not([data-disabled]) {
619
617
  border-color: var(--slotted-select-open-border-color, var(--slotted-tone-accent-border));
620
618
  }
621
619
 
@@ -626,7 +624,7 @@
626
624
  * reads `--slotted-focus-ring-color`, so pointing that one name at the
627
625
  * invalid colour moves the outline and the shadow together.
628
626
  */
629
- [data-ui='select'][data-part='root'][data-invalid] {
627
+ [data-ui-select][data-part-root][data-invalid] {
630
628
  --slotted-focus-ring-color: var(
631
629
  --slotted-select-invalid-focus-ring-color,
632
630
  var(--slotted-focus-ring-color-invalid, Highlight)
@@ -651,15 +649,15 @@
651
649
  box-shadow: var(--_invalid-edge);
652
650
  }
653
651
 
654
- [data-ui='select'][data-part='root'][data-invalid]:has(> [data-part='trigger']:focus-visible) {
652
+ [data-ui-select][data-part-root][data-invalid]:has(> [data-part-trigger]:focus-visible) {
655
653
  box-shadow:
656
654
  var(--_invalid-edge),
657
655
  var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px)
658
656
  var(--slotted-focus-ring-color, Highlight);
659
657
  }
660
658
 
661
- [data-ui='select'][data-part='root'][data-variant='plain'][data-invalid]:has(
662
- > [data-part='trigger']:focus-visible
659
+ [data-ui-select][data-part-root][data-variant='plain'][data-invalid]:has(
660
+ > [data-part-trigger]:focus-visible
663
661
  ) {
664
662
  /* The ring lies inside the box here, over the border and an edge as wide as
665
663
  it; the edge reaches past the ring. */
@@ -677,21 +675,24 @@
677
675
  * control draws its ring double, which a valid ring is not.
678
676
  */
679
677
  @media (forced-colors: active) {
680
- [data-ui='select'][data-part='root'][data-invalid] {
678
+ [data-ui-select][data-part-root][data-invalid] {
681
679
  outline: var(--_invalid-edge-width) solid CanvasText;
682
680
  outline-offset: calc(
683
681
  -1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width))
684
682
  );
685
683
  }
686
684
 
687
- [data-ui='select'][data-part='root'][data-invalid]:has(> [data-part='trigger']:focus-visible) {
685
+ [data-ui-select][data-part-root][data-invalid]:has(> [data-part-trigger]:focus-visible) {
688
686
  outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
689
687
  var(--slotted-focus-ring-color, Highlight);
690
- outline-offset: var(--slotted-focus-ring-offset, 2px);
688
+ outline-offset: var(
689
+ --slotted-control-focus-ring-offset,
690
+ var(--slotted-focus-ring-offset, 2px)
691
+ );
691
692
  }
692
693
 
693
- [data-ui='select'][data-part='root'][data-variant='plain'][data-invalid]:has(
694
- > [data-part='trigger']:focus-visible
694
+ [data-ui-select][data-part-root][data-variant='plain'][data-invalid]:has(
695
+ > [data-part-trigger]:focus-visible
695
696
  ) {
696
697
  outline: calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double
697
698
  var(--slotted-focus-ring-color, Highlight);
@@ -708,14 +709,14 @@
708
709
  * `role="combobox"` has a readonly the platform enforces, so the family
709
710
  * refuses the change itself and this is what the refusal looks like.
710
711
  */
711
- [data-ui='select'][data-part='root'][data-readonly] {
712
+ [data-ui-select][data-part-root][data-readonly] {
712
713
  background-color: var(
713
714
  --slotted-select-readonly-background,
714
715
  var(--slotted-tone-secondary-subtle-hover)
715
716
  );
716
717
  }
717
718
 
718
- [data-ui='select'][data-part='root'][data-readonly] [data-part='arrow'] {
719
+ [data-ui-select][data-part-root][data-readonly] [data-part-arrow] {
719
720
  opacity: 0.5;
720
721
  }
721
722
 
@@ -726,8 +727,8 @@
726
727
  * way to say. The attribute alone left such a control looking operable and
727
728
  * answering nothing.
728
729
  */
729
- [data-ui='select'][data-part='root'][data-disabled],
730
- [data-ui='select'][data-part='root']:has(> [data-part='trigger']:disabled) {
730
+ [data-ui-select][data-part-root][data-disabled],
731
+ [data-ui-select][data-part-root]:has(> [data-part-trigger]:disabled) {
731
732
  background-color: var(--slotted-select-disabled-background, var(--slotted-disabled-background));
732
733
  border-color: var(--slotted-select-disabled-border-color, var(--slotted-disabled-border));
733
734
  /* Nothing a person cannot reach is lifted off the page. */
@@ -737,19 +738,19 @@
737
738
  color: var(--slotted-select-disabled-color, var(--slotted-disabled-foreground));
738
739
  }
739
740
 
740
- [data-ui='select'][data-part='root'][data-disabled] > [data-part='trigger'],
741
- [data-ui='select'][data-part='root'] > [data-part='trigger']:disabled {
741
+ [data-ui-select][data-part-root][data-disabled] > [data-part-trigger],
742
+ [data-ui-select][data-part-root] > [data-part-trigger]:disabled {
742
743
  cursor: not-allowed;
743
744
  }
744
745
 
745
- [data-ui='select'] > [data-part='clear']:hover:not(:disabled):not([data-disabled]) {
746
+ [data-ui-select] > [data-part-clear]:hover:not(:disabled):not([data-disabled]) {
746
747
  background-color: var(
747
748
  --slotted-select-action-hover-background,
748
749
  var(--slotted-tone-secondary-subtle-hover)
749
750
  );
750
751
  }
751
752
 
752
- [data-ui='select'] > [data-part='clear']:active:not(:disabled):not([data-disabled]) {
753
+ [data-ui-select] > [data-part-clear]:active:not(:disabled):not([data-disabled]) {
753
754
  background-color: var(
754
755
  --slotted-select-action-active-background,
755
756
  var(--slotted-tone-secondary-subtle-active)
@@ -761,7 +762,7 @@
761
762
  * Tabbing from the trigger to it has to move something visible, and a ring
762
763
  * around the whole frame would sit still while focus moved inside it.
763
764
  */
764
- [data-ui='select'] > [data-part='clear']:focus-visible {
765
+ [data-ui-select] > [data-part-clear]:focus-visible {
765
766
  outline: var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);
766
767
  outline-offset: calc(var(--slotted-focus-ring-offset, 2px) * -1);
767
768
  }
@@ -774,7 +775,7 @@
774
775
  * purpose. The painted surface is one element in, as `tooltip`, `popover` and
775
776
  * `menu` are built.
776
777
  */
777
- [data-ui='select'][data-part='positioner'] {
778
+ [data-ui-select][data-part-positioner] {
778
779
  --_surface: var(--slotted-select-surface, var(--slotted-surface-raised, #ffffff));
779
780
  --_text: var(--slotted-select-content-text, var(--slotted-text, #0f172a));
780
781
  --_muted: var(--slotted-select-content-text-muted, var(--slotted-text-muted, #5b6b7f));
@@ -848,12 +849,12 @@
848
849
  translate var(--slotted-duration-short) var(--slotted-easing-exit);
849
850
  }
850
851
 
851
- [data-ui='select'][data-part='positioner'][data-side='top'] {
852
+ [data-ui-select][data-part-positioner][data-side='top'] {
852
853
  translate: 0 var(--_enter-distance);
853
854
  }
854
855
 
855
856
  /* A lateral side has no block direction to arrive from, so it only fades. */
856
- [data-ui='select'][data-part='positioner']:is([data-side='left'], [data-side='right']) {
857
+ [data-ui-select][data-part-positioner]:is([data-side='left'], [data-side='right']) {
857
858
  translate: 0 0;
858
859
  }
859
860
 
@@ -866,7 +867,7 @@
866
867
  * A keyframe states where it starts. The exit stays a transition: it
867
868
  * leaves from wherever the layer is, on the closed rule's durations.
868
869
  */
869
- [data-ui='select'][data-part='positioner'][data-open] {
870
+ [data-ui-select][data-part-positioner][data-open] {
870
871
  opacity: 1;
871
872
  translate: 0 0;
872
873
  transition: none;
@@ -877,15 +878,15 @@
877
878
  * with the side, and a layer written open in static markup — the harness,
878
879
  * a docs snippet — is simply there, and is photographed where it stands.
879
880
  */
880
- [data-ui='select'][data-part='positioner'][data-open][data-positioned] {
881
+ [data-ui-select][data-part-positioner][data-open][data-positioned] {
881
882
  animation: slotted-select-enter-down var(--slotted-duration-medium) var(--slotted-easing-enter);
882
883
  }
883
884
 
884
- [data-ui='select'][data-part='positioner'][data-open][data-positioned][data-side='top'] {
885
+ [data-ui-select][data-part-positioner][data-open][data-positioned][data-side='top'] {
885
886
  animation-name: slotted-select-enter-up;
886
887
  }
887
888
 
888
- [data-ui='select'][data-part='positioner'][data-open][data-positioned]:is(
889
+ [data-ui-select][data-part-positioner][data-open][data-positioned]:is(
889
890
  [data-side='left'],
890
891
  [data-side='right']
891
892
  ) {
@@ -914,25 +915,25 @@
914
915
 
915
916
  /* Stillness keeps the fade and drops the movement (R7). */
916
917
  @media (prefers-reduced-motion: reduce) {
917
- [data-ui='select'][data-part='positioner'],
918
- [data-ui='select'][data-part='positioner'][data-side='top'],
919
- [data-ui='select'][data-part='positioner'][data-side='left'],
920
- [data-ui='select'][data-part='positioner'][data-side='right'] {
918
+ [data-ui-select][data-part-positioner],
919
+ [data-ui-select][data-part-positioner][data-side='top'],
920
+ [data-ui-select][data-part-positioner][data-side='left'],
921
+ [data-ui-select][data-part-positioner][data-side='right'] {
921
922
  translate: 0 0;
922
923
  transition: opacity var(--slotted-duration-short) var(--slotted-easing-exit);
923
924
  }
924
925
 
925
- [data-ui='select'][data-part='positioner'][data-open][data-positioned],
926
- [data-ui='select'][data-part='positioner'][data-open][data-positioned][data-side='top'],
927
- [data-ui='select'][data-part='positioner'][data-open][data-positioned][data-side='left'],
928
- [data-ui='select'][data-part='positioner'][data-open][data-positioned][data-side='right'] {
926
+ [data-ui-select][data-part-positioner][data-open][data-positioned],
927
+ [data-ui-select][data-part-positioner][data-open][data-positioned][data-side='top'],
928
+ [data-ui-select][data-part-positioner][data-open][data-positioned][data-side='left'],
929
+ [data-ui-select][data-part-positioner][data-open][data-positioned][data-side='right'] {
929
930
  animation-name: slotted-select-fade;
930
931
  }
931
932
  }
932
933
 
933
934
  /* The anchor scrolled out of its own clipper. The popup is still open and
934
935
  its options still belong to a control the reader can no longer see. */
935
- [data-ui='select'][data-part='positioner'][data-detached] {
936
+ [data-ui-select][data-part-positioner][data-detached] {
936
937
  visibility: hidden;
937
938
  }
938
939
 
@@ -942,11 +943,11 @@
942
943
  * narrow control does not wrap its option labels. `anchor` pins the popup to
943
944
  * the control's width exactly.
944
945
  */
945
- [data-ui='select'][data-part='positioner'][data-width='anchor'] {
946
+ [data-ui-select][data-part-positioner][data-width='anchor'] {
946
947
  inline-size: var(--slotted-positioner-anchor-width, auto);
947
948
  }
948
949
 
949
- [data-ui='select'][data-part='positioner'][data-width='content'] {
950
+ [data-ui-select][data-part-positioner][data-width='content'] {
950
951
  inline-size: max-content;
951
952
  max-inline-size: min(var(--_measure), var(--slotted-positioner-available-width, 100vw));
952
953
  /* Never narrower than the control it belongs to: a popup that shrank under
@@ -954,7 +955,7 @@
954
955
  min-inline-size: var(--slotted-positioner-anchor-width, auto);
955
956
  }
956
957
 
957
- [data-ui='select'][data-part='positioner'][data-size='sm'] {
958
+ [data-ui-select][data-part-positioner][data-size='sm'] {
958
959
  --_item-inset: var(--slotted-control-padding-inline-sm, 0.625rem);
959
960
  --_item-height: var(--slotted-control-height-sm, 30px);
960
961
  --_content-font-size: var(--slotted-control-font-size-sm, 12px);
@@ -963,7 +964,7 @@
963
964
  --_column-gap: var(--slotted-control-gap-sm, 0.375rem);
964
965
  }
965
966
 
966
- [data-ui='select'][data-part='positioner'][data-size='lg'] {
967
+ [data-ui-select][data-part-positioner][data-size='lg'] {
967
968
  --_item-inset: var(--slotted-control-padding-inline-lg, 1rem);
968
969
  --_item-height: var(--slotted-control-height-lg, 38px);
969
970
  --_content-font-size: var(--slotted-control-font-size-lg, 14px);
@@ -981,7 +982,7 @@
981
982
  * the screen. `overscroll-behavior` keeps the page still once the surface has
982
983
  * scrolled to its end.
983
984
  */
984
- [data-ui='select'] > [data-part='content'] {
985
+ [data-ui-select] > [data-part-content] {
985
986
  background: var(--_surface);
986
987
  border: var(--_border-width) solid var(--_border-color);
987
988
  border-radius: var(--_radius);
@@ -1010,8 +1011,8 @@
1010
1011
  * `overscroll-behavior` keeps the page still once the scroller has reached
1011
1012
  * its end.
1012
1013
  */
1013
- [data-ui='select'] > [data-part='content']:not([data-search]),
1014
- [data-ui='select'] [data-part='list'] {
1014
+ [data-ui-select] > [data-part-content]:not([data-search]),
1015
+ [data-ui-select] [data-part-list] {
1015
1016
  display: grid;
1016
1017
  grid-template-columns: auto minmax(0, 1fr) auto;
1017
1018
  overflow-y: auto;
@@ -1020,7 +1021,7 @@
1020
1021
  padding-inline: var(--_inset-inline);
1021
1022
  }
1022
1023
 
1023
- [data-ui='select'] > [data-part='content'][data-search] {
1024
+ [data-ui-select] > [data-part-content][data-search] {
1024
1025
  display: flex;
1025
1026
  flex-direction: column;
1026
1027
  /* The field draws to the surface's own edges and the list keeps the inset,
@@ -1030,7 +1031,7 @@
1030
1031
 
1031
1032
  /* `auto` as the flex basis measures the whole list and refuses to shrink;
1032
1033
  the surface is what holds the height, and the list is what gives. */
1033
- [data-ui='select'] [data-part='list'] {
1034
+ [data-ui-select] [data-part-list] {
1034
1035
  flex: 1 1 auto;
1035
1036
  min-block-size: 0;
1036
1037
  }
@@ -1052,7 +1053,7 @@
1052
1053
  * rhythm, with the rule under it drawn from the border scale rather than
1053
1054
  * from a shadow — the same rule the `chosen` band draws above the list.
1054
1055
  */
1055
- [data-ui='select'] [data-part='search'] {
1056
+ [data-ui-select] [data-part-search] {
1056
1057
  align-items: center;
1057
1058
  border-block-end: var(--_border-width) solid var(--_border-color);
1058
1059
  box-sizing: border-box;
@@ -1073,7 +1074,7 @@
1073
1074
  * bare line of placeholder text at the top of a panel reads as a title, and
1074
1075
  * a reader does not type into a title.
1075
1076
  */
1076
- [data-ui='select'] [data-part='search-icon'] {
1077
+ [data-ui-select] [data-part-search-icon] {
1077
1078
  --slotted-icon-size: var(--_content-icon-size);
1078
1079
 
1079
1080
  align-items: center;
@@ -1097,7 +1098,7 @@
1097
1098
  * rather than a state, and the one thing on the surface that never changes
1098
1099
  * would be the loudest. What says where focus is, is the caret.
1099
1100
  */
1100
- [data-ui='select'] [data-part='search-input'] {
1101
+ [data-ui-select] [data-part-search-input] {
1101
1102
  background-color: transparent;
1102
1103
  border: 0;
1103
1104
  color: inherit;
@@ -1111,7 +1112,7 @@
1111
1112
  text-overflow: ellipsis;
1112
1113
  }
1113
1114
 
1114
- [data-ui='select'] [data-part='search-input']::placeholder {
1115
+ [data-ui-select] [data-part-search-input]::placeholder {
1115
1116
  color: var(--slotted-select-placeholder-color, var(--_muted));
1116
1117
  text-overflow: ellipsis;
1117
1118
  }
@@ -1131,7 +1132,7 @@
1131
1132
  * to the surface's own edges, which is where the rule between it and the list
1132
1133
  * has to end — a rule from the border scale, not a shadow.
1133
1134
  */
1134
- [data-ui='select'] [data-part='chosen'] {
1135
+ [data-ui-select] [data-part-chosen] {
1135
1136
  background: var(--_surface);
1136
1137
  border-block-end: var(--_border-width) solid var(--_border-color);
1137
1138
  box-sizing: border-box;
@@ -1169,7 +1170,7 @@
1169
1170
  * interaction — the highlight is `aria-activedescendant`, not focus — so a
1170
1171
  * ring here would draw a box around something nobody is operating.
1171
1172
  */
1172
- [data-ui='select'] > [data-part='content']:focus-visible {
1173
+ [data-ui-select] > [data-part-content]:focus-visible {
1173
1174
  outline: none;
1174
1175
  }
1175
1176
 
@@ -1180,7 +1181,7 @@
1180
1181
  * surface's columns instead of starting a second set. Without the subgrid a
1181
1182
  * group would align its own labels and disagree with the options outside it.
1182
1183
  */
1183
- [data-ui='select'] [data-part='group'] {
1184
+ [data-ui-select] [data-part-group] {
1184
1185
  display: grid;
1185
1186
  grid-column: 1 / -1;
1186
1187
  grid-template-columns: subgrid;
@@ -1194,12 +1195,12 @@
1194
1195
  * author rule wins over the user agent sheet. Without this the search
1195
1196
  * filtered nothing the reader could see.
1196
1197
  */
1197
- [data-ui='select'] [data-part='item'][hidden],
1198
- [data-ui='select'] [data-part='group'][hidden] {
1198
+ [data-ui-select] [data-part-item][hidden],
1199
+ [data-ui-select] [data-part-group][hidden] {
1199
1200
  display: none;
1200
1201
  }
1201
1202
 
1202
- [data-ui='select'] [data-part='group-label'] {
1203
+ [data-ui-select] [data-part-group-label] {
1203
1204
  color: var(--_muted);
1204
1205
  font-size: var(--_secondary-font-size);
1205
1206
  font-weight: var(--slotted-font-weight-semibold, 600);
@@ -1221,7 +1222,7 @@
1221
1222
  * `min-block-size` rather than a height, because an option with a
1222
1223
  * description is two lines tall and still has to clear the target minimum.
1223
1224
  */
1224
- [data-ui='select'] [data-part='item'] {
1225
+ [data-ui-select] [data-part-item] {
1225
1226
  align-content: center;
1226
1227
  border-radius: var(--_item-radius);
1227
1228
  box-sizing: border-box;
@@ -1268,7 +1269,7 @@
1268
1269
  * whichever device is driving, and the state a screen reader announces and
1269
1270
  * the state the eye sees are the same state.
1270
1271
  */
1271
- [data-ui='select'] [data-part='item'][data-current] {
1272
+ [data-ui-select] [data-part-item][data-current] {
1272
1273
  background-color: var(--_highlight);
1273
1274
  /**
1274
1275
  * A ring as well as a ground, because the ground alone carries the whole
@@ -1285,7 +1286,7 @@
1285
1286
  var(--slotted-select-highlight-ring, var(--slotted-tone-accent-border));
1286
1287
  }
1287
1288
 
1288
- [data-ui='select'] [data-part='item']:not([data-disabled]):active {
1289
+ [data-ui-select] [data-part-item]:not([data-disabled]):active {
1289
1290
  background-color: var(--_highlight-active);
1290
1291
  }
1291
1292
 
@@ -1295,7 +1296,7 @@
1295
1296
  * becomes `Canvas` — and the accent ink is the secondary one, so the row a
1296
1297
  * reader is looking for is findable at a glance in a list of forty.
1297
1298
  */
1298
- [data-ui='select'] [data-part='item'][data-selected] {
1299
+ [data-ui-select] [data-part-item][data-selected] {
1299
1300
  color: var(--_selected-color);
1300
1301
  }
1301
1302
 
@@ -1308,17 +1309,17 @@
1308
1309
  * selection begins and ends. `select` and `combobox` draw the same ground
1309
1310
  * and answer the same way; `selection-block.test.mjs` holds the three to it.
1310
1311
  */
1311
- [data-ui='select'] [data-part='item'][data-selected] + [data-part='item'][data-selected] {
1312
+ [data-ui-select] [data-part-item][data-selected] + [data-part-item][data-selected] {
1312
1313
  border-start-end-radius: 0;
1313
1314
  border-start-start-radius: 0;
1314
1315
  }
1315
1316
 
1316
- [data-ui='select'] [data-part='item'][data-selected]:has(+ [data-part='item'][data-selected]) {
1317
+ [data-ui-select] [data-part-item][data-selected]:has(+ [data-part-item][data-selected]) {
1317
1318
  border-end-end-radius: 0;
1318
1319
  border-end-start-radius: 0;
1319
1320
  }
1320
1321
 
1321
- [data-ui='select'] [data-part='item'][data-selected] > [data-part='label'] {
1322
+ [data-ui-select] [data-part-item][data-selected] > [data-part-label] {
1322
1323
  font-weight: var(--slotted-font-weight-medium, 500);
1323
1324
  }
1324
1325
 
@@ -1329,7 +1330,7 @@
1329
1330
  * disabled surface rather than the highlight, and the text stays legible
1330
1331
  * instead of being faded toward it.
1331
1332
  */
1332
- [data-ui='select'] [data-part='item'][data-disabled] {
1333
+ [data-ui-select] [data-part-item][data-disabled] {
1333
1334
  color: var(--slotted-disabled-foreground, #64748b);
1334
1335
  cursor: not-allowed;
1335
1336
  }
@@ -1355,7 +1356,7 @@
1355
1356
  * would watch it disappear. A cursor lifts, always. What the row cannot do is
1356
1357
  * said by the ink and by the ring, which both step down to the disabled pair.
1357
1358
  */
1358
- [data-ui='select'] [data-part='item'][data-disabled][data-current] {
1359
+ [data-ui-select] [data-part-item][data-disabled][data-current] {
1359
1360
  box-shadow: inset 0 0 0 var(--slotted-border-width-thin, 1px)
1360
1361
  var(--slotted-disabled-border, #cbd5e1);
1361
1362
  color: var(--slotted-disabled-foreground, #64748b);
@@ -1369,7 +1370,7 @@
1369
1370
  * states the line box every cell inherits, exactly as tall as the line it
1370
1371
  * sits beside.
1371
1372
  */
1372
- [data-ui='select'] :is([data-part='indicator'], [data-part='icon']) {
1373
+ [data-ui-select] :is([data-part-indicator], [data-part-icon]) {
1373
1374
  block-size: 1lh;
1374
1375
  }
1375
1376
 
@@ -1382,7 +1383,7 @@
1382
1383
  * artwork of the consumer's own, centred and sized from the column through
1383
1384
  * `--slotted-icon-size`. No stylesheet fills it.
1384
1385
  */
1385
- [data-ui='select'] [data-part='icon'] {
1386
+ [data-ui-select] [data-part-icon] {
1386
1387
  --slotted-icon-size: var(--_content-icon-size);
1387
1388
 
1388
1389
  align-items: center;
@@ -1398,7 +1399,7 @@
1398
1399
  /* Column two, and the only column that gives way. It is scoped to the option
1399
1400
  rather than to the family: a chip in the control carries a `label` of its
1400
1401
  own, and this rule would have put it in the popup's second column (SL4). */
1401
- [data-ui='select'] [data-part='item'] > [data-part='label'] {
1402
+ [data-ui-select] [data-part-item] > [data-part-label] {
1402
1403
  grid-column: 2;
1403
1404
  grid-row: 1;
1404
1405
  min-inline-size: 0;
@@ -1419,7 +1420,7 @@
1419
1420
  overflow-wrap: anywhere;
1420
1421
  }
1421
1422
 
1422
- [data-ui='select'] [data-part='description'] {
1423
+ [data-ui-select] [data-part-description] {
1423
1424
  color: var(--_muted);
1424
1425
  font-size: var(--_secondary-font-size);
1425
1426
  grid-column: 2;
@@ -1429,7 +1430,7 @@
1429
1430
  overflow-wrap: anywhere;
1430
1431
  }
1431
1432
 
1432
- [data-ui='select'] [data-part='item'][data-disabled] > [data-part='description'] {
1433
+ [data-ui-select] [data-part-item][data-disabled] > [data-part-description] {
1433
1434
  color: inherit;
1434
1435
  }
1435
1436
 
@@ -1438,7 +1439,7 @@
1438
1439
  * reserved whether or not the check is drawn, so a list does not shift by
1439
1440
  * sixteen pixels as the reader moves through it.
1440
1441
  */
1441
- [data-ui='select'] [data-part='indicator'] {
1442
+ [data-ui-select] [data-part-indicator] {
1442
1443
  --slotted-icon-size: var(--_content-icon-size);
1443
1444
 
1444
1445
  align-items: center;
@@ -1455,13 +1456,13 @@
1455
1456
  transition: opacity var(--slotted-duration-short) var(--slotted-easing-standard);
1456
1457
  }
1457
1458
 
1458
- [data-ui='select'] [data-part='item'][data-selected] > [data-part='indicator'] {
1459
+ [data-ui-select] [data-part-item][data-selected] > [data-part-indicator] {
1459
1460
  opacity: 1;
1460
1461
  }
1461
1462
 
1462
1463
  /* ── Separator, empty, status ─────────────────────────────────────────── */
1463
1464
 
1464
- [data-ui='select'] [data-part='separator'] {
1465
+ [data-ui-select] [data-part-separator] {
1465
1466
  background-color: var(--slotted-select-separator-color, var(--_border-color));
1466
1467
  block-size: var(--_border-width);
1467
1468
  border: 0;
@@ -1477,7 +1478,7 @@
1477
1478
  * refuses to open on an empty collection and Radix paints nothing; the popup
1478
1479
  * here opens onto a sentence.
1479
1480
  */
1480
- [data-ui='select'] :is([data-part='empty'], [data-part='status']) {
1481
+ [data-ui-select] :is([data-part-empty], [data-part-status]) {
1481
1482
  color: var(--_muted);
1482
1483
  /**
1483
1484
  * Its own bidi run, ordered by its own content. "3 results" is a European
@@ -1512,7 +1513,7 @@
1512
1513
  * takes the same space as the empty message beside it. `combobox` draws the
1513
1514
  * count the same way, in the same place, for the same reason.
1514
1515
  */
1515
- [data-ui='select'] [data-part='status']:empty {
1516
+ [data-ui-select] [data-part-status]:empty {
1516
1517
  display: none;
1517
1518
  }
1518
1519
 
@@ -1528,7 +1529,7 @@
1528
1529
  * hidden from assistive technology: the `status` row beside them is the live
1529
1530
  * region and it already says what is happening.
1530
1531
  */
1531
- [data-ui='select'] [data-part='placeholder'] {
1532
+ [data-ui-select] [data-part-placeholder] {
1532
1533
  display: grid;
1533
1534
  /* The surface is a grid of option columns; the rows span all of them, as
1534
1535
  the status and empty rows do. */
@@ -1537,7 +1538,7 @@
1537
1538
  padding-inline: var(--_item-inset);
1538
1539
  }
1539
1540
 
1540
- [data-ui='select'] [data-part='placeholder'] > [data-ui='skeleton'] {
1541
+ [data-ui-select] [data-part-placeholder] > [data-ui-skeleton] {
1541
1542
  align-self: center;
1542
1543
  }
1543
1544
 
@@ -1545,17 +1546,17 @@
1545
1546
  * Each row is an option: the same minimum height, so three of them measure
1546
1547
  * what three options measure and the popup does not resize when they land.
1547
1548
  */
1548
- [data-ui='select'] [data-part='placeholder'] > * {
1549
+ [data-ui-select] [data-part-placeholder] > * {
1549
1550
  align-items: center;
1550
1551
  display: flex;
1551
1552
  min-block-size: var(--_item-height);
1552
1553
  }
1553
1554
 
1554
- [data-ui='select'] [data-part='placeholder'] > :nth-child(2) [data-ui='skeleton'] {
1555
+ [data-ui-select] [data-part-placeholder] > :nth-child(2) [data-ui-skeleton] {
1555
1556
  inline-size: 78%;
1556
1557
  }
1557
1558
 
1558
- [data-ui='select'] [data-part='placeholder'] > :nth-child(3) [data-ui='skeleton'] {
1559
+ [data-ui-select] [data-part-placeholder] > :nth-child(3) [data-ui-skeleton] {
1559
1560
  inline-size: 56%;
1560
1561
  }
1561
1562
 
@@ -1566,7 +1567,7 @@
1566
1567
  * many for one wait (SL6).
1567
1568
  */
1568
1569
 
1569
- [data-ui='select'] > [data-part='content'][data-loading] {
1570
+ [data-ui-select] > [data-part-content][data-loading] {
1570
1571
  cursor: progress;
1571
1572
  }
1572
1573
 
@@ -1579,13 +1580,13 @@
1579
1580
  * with no way to tell.
1580
1581
  */
1581
1582
  @media (forced-colors: active) {
1582
- [data-ui='select'] [data-part='item'][data-current] {
1583
+ [data-ui-select] [data-part-item][data-current] {
1583
1584
  background-color: Highlight;
1584
1585
  color: HighlightText;
1585
1586
  forced-color-adjust: none;
1586
1587
  }
1587
1588
 
1588
- [data-ui='select'] [data-part='item'][data-disabled][data-current] {
1589
+ [data-ui-select] [data-part-item][data-disabled][data-current] {
1589
1590
  background-color: Highlight;
1590
1591
  color: GrayText;
1591
1592
  }