@ropav/styles 0.3.0 → 0.5.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 (163) hide show
  1. package/README.md +160 -19
  2. package/dist/components/accordion.css +12 -5
  3. package/dist/components/alert-dialog.css +1 -1
  4. package/dist/components/alert.css +9 -1
  5. package/dist/components/autocomplete/autocomplete.styles.d.ts +33 -0
  6. package/dist/components/autocomplete/autocomplete.styles.d.ts.map +1 -1
  7. package/dist/components/autocomplete/autocomplete.styles.js +12 -0
  8. package/dist/components/autocomplete.css +39 -3
  9. package/dist/components/avatar.css +9 -0
  10. package/dist/components/badge.css +7 -0
  11. package/dist/components/button-group.css +6 -6
  12. package/dist/components/button.css +34 -11
  13. package/dist/components/calendar-year-picker.css +2 -1
  14. package/dist/components/calendar.css +8 -0
  15. package/dist/components/card.css +22 -1
  16. package/dist/components/chip.css +21 -0
  17. package/dist/components/close-button.css +8 -0
  18. package/dist/components/color-input-group/color-input-group.styles.d.ts +27 -0
  19. package/dist/components/color-input-group/color-input-group.styles.d.ts.map +1 -1
  20. package/dist/components/color-input-group/color-input-group.styles.js +6 -0
  21. package/dist/components/color-input-group.css +30 -1
  22. package/dist/components/color-swatch-picker.css +11 -0
  23. package/dist/components/combo-box/combo-box.styles.d.ts +27 -0
  24. package/dist/components/combo-box/combo-box.styles.d.ts.map +1 -1
  25. package/dist/components/combo-box/combo-box.styles.js +17 -7
  26. package/dist/components/combo-box.css +21 -1
  27. package/dist/components/date-input-group/date-input-group.styles.d.ts +27 -0
  28. package/dist/components/date-input-group/date-input-group.styles.d.ts.map +1 -1
  29. package/dist/components/date-input-group/date-input-group.styles.js +6 -0
  30. package/dist/components/date-input-group.css +30 -1
  31. package/dist/components/dropdown/dropdown.styles.d.ts.map +1 -1
  32. package/dist/components/dropdown/dropdown.styles.js +1 -1
  33. package/dist/components/dropdown.css +17 -12
  34. package/dist/components/index.css +4 -0
  35. package/dist/components/index.d.ts +4 -0
  36. package/dist/components/index.d.ts.map +1 -1
  37. package/dist/components/input/input.styles.d.ts +15 -0
  38. package/dist/components/input/input.styles.d.ts.map +1 -1
  39. package/dist/components/input/input.styles.js +6 -0
  40. package/dist/components/input-group/input-group.styles.d.ts +27 -0
  41. package/dist/components/input-group/input-group.styles.d.ts.map +1 -1
  42. package/dist/components/input-group/input-group.styles.js +6 -0
  43. package/dist/components/input-group.css +32 -1
  44. package/dist/components/input.css +23 -1
  45. package/dist/components/list-box/list-box.styles.d.ts +15 -0
  46. package/dist/components/list-box/list-box.styles.d.ts.map +1 -1
  47. package/dist/components/list-box/list-box.styles.js +15 -5
  48. package/dist/components/list-box-item.css +4 -2
  49. package/dist/components/list-box.css +19 -0
  50. package/dist/components/menu/menu.styles.d.ts +19 -1
  51. package/dist/components/menu/menu.styles.d.ts.map +1 -1
  52. package/dist/components/menu/menu.styles.js +9 -1
  53. package/dist/components/menu.css +25 -0
  54. package/dist/components/meter.css +12 -0
  55. package/dist/components/modal.css +1 -1
  56. package/dist/components/number-field/number-field.styles.d.ts +27 -0
  57. package/dist/components/number-field/number-field.styles.d.ts.map +1 -1
  58. package/dist/components/number-field/number-field.styles.js +6 -0
  59. package/dist/components/number-field.css +68 -1
  60. package/dist/components/pagination.css +10 -6
  61. package/dist/components/popover.css +15 -1
  62. package/dist/components/progress-bar.css +12 -0
  63. package/dist/components/progress-circle.css +12 -0
  64. package/dist/components/radio.css +7 -0
  65. package/dist/components/range-calendar.css +28 -0
  66. package/dist/components/search-field/search-field.styles.d.ts +27 -0
  67. package/dist/components/search-field/search-field.styles.d.ts.map +1 -1
  68. package/dist/components/search-field/search-field.styles.js +6 -0
  69. package/dist/components/search-field.css +33 -1
  70. package/dist/components/segmented-control/index.d.ts +2 -0
  71. package/dist/components/segmented-control/index.d.ts.map +1 -0
  72. package/dist/components/segmented-control/index.js +2 -0
  73. package/dist/components/segmented-control/segmented-control.styles.d.ts +73 -0
  74. package/dist/components/segmented-control/segmented-control.styles.d.ts.map +1 -0
  75. package/dist/components/segmented-control/segmented-control.styles.js +27 -0
  76. package/dist/components/segmented-control.css +193 -0
  77. package/dist/components/select/select.styles.d.ts +33 -0
  78. package/dist/components/select/select.styles.d.ts.map +1 -1
  79. package/dist/components/select/select.styles.js +12 -0
  80. package/dist/components/select.css +40 -3
  81. package/dist/components/separator.css +18 -1
  82. package/dist/components/sidebar/index.d.ts +2 -0
  83. package/dist/components/sidebar/index.d.ts.map +1 -0
  84. package/dist/components/sidebar/index.js +2 -0
  85. package/dist/components/sidebar/sidebar.styles.d.ts +190 -0
  86. package/dist/components/sidebar/sidebar.styles.d.ts.map +1 -0
  87. package/dist/components/sidebar/sidebar.styles.js +52 -0
  88. package/dist/components/sidebar.css +510 -0
  89. package/dist/components/skeleton.css +9 -0
  90. package/dist/components/slider.css +61 -0
  91. package/dist/components/splitter/index.d.ts +2 -0
  92. package/dist/components/splitter/index.d.ts.map +1 -0
  93. package/dist/components/splitter/index.js +2 -0
  94. package/dist/components/splitter/splitter.styles.d.ts +61 -0
  95. package/dist/components/splitter/splitter.styles.d.ts.map +1 -0
  96. package/dist/components/splitter/splitter.styles.js +26 -0
  97. package/dist/components/splitter.css +241 -0
  98. package/dist/components/surface.css +24 -0
  99. package/dist/components/switch.css +30 -0
  100. package/dist/components/table.css +11 -3
  101. package/dist/components/tabs.css +30 -2
  102. package/dist/components/tag.css +10 -0
  103. package/dist/components/textarea/textarea.styles.d.ts +15 -0
  104. package/dist/components/textarea/textarea.styles.d.ts.map +1 -1
  105. package/dist/components/textarea/textarea.styles.js +6 -0
  106. package/dist/components/textarea.css +23 -1
  107. package/dist/components/toast.css +1 -1
  108. package/dist/components/toggle-button-group.css +7 -7
  109. package/dist/components/toggle-button.css +17 -11
  110. package/dist/components/toolbar.css +8 -1
  111. package/dist/components/tooltip.css +15 -2
  112. package/dist/components/typography.css +21 -0
  113. package/dist/components/virtualizer/index.d.ts +2 -0
  114. package/dist/components/virtualizer/index.d.ts.map +1 -0
  115. package/dist/components/virtualizer/index.js +2 -0
  116. package/dist/components/virtualizer/virtualizer.styles.d.ts +44 -0
  117. package/dist/components/virtualizer/virtualizer.styles.d.ts.map +1 -0
  118. package/dist/components/virtualizer/virtualizer.styles.js +15 -0
  119. package/dist/components/virtualizer.css +64 -0
  120. package/dist/index.css +7 -2
  121. package/dist/index.js +5 -1
  122. package/dist/ropav.min.css +2 -2
  123. package/dist/themes/airbnb.css +231 -0
  124. package/dist/themes/all.css +17 -0
  125. package/dist/themes/coinbase.css +231 -0
  126. package/dist/themes/{default/variables.css → default.css} +28 -9
  127. package/dist/themes/discord.css +231 -0
  128. package/dist/themes/hero.css +262 -0
  129. package/dist/themes/lavender.css +231 -0
  130. package/dist/themes/mint.css +231 -0
  131. package/dist/themes/netflix.css +231 -0
  132. package/dist/themes/rabbit.css +231 -0
  133. package/dist/themes/shared/theme.css +19 -2
  134. package/dist/themes/sky.css +231 -0
  135. package/dist/themes/spotify.css +231 -0
  136. package/dist/themes/uber.css +231 -0
  137. package/dist/utilities/index.css +97 -0
  138. package/dist/variants/index.css +5 -15
  139. package/package.json +2 -3
  140. package/src/components/autocomplete/autocomplete.styles.ts +12 -0
  141. package/src/components/color-input-group/color-input-group.styles.ts +10 -0
  142. package/src/components/combo-box/combo-box.styles.ts +12 -0
  143. package/src/components/date-input-group/date-input-group.styles.ts +10 -0
  144. package/src/components/dropdown/dropdown.styles.ts +3 -1
  145. package/src/components/index.ts +4 -0
  146. package/src/components/input/input.styles.ts +6 -0
  147. package/src/components/input-group/input-group.styles.ts +10 -0
  148. package/src/components/list-box/list-box.styles.ts +6 -0
  149. package/src/components/menu/menu.styles.ts +10 -0
  150. package/src/components/number-field/number-field.styles.ts +10 -0
  151. package/src/components/search-field/search-field.styles.ts +10 -0
  152. package/src/components/segmented-control/index.ts +1 -0
  153. package/src/components/segmented-control/segmented-control.styles.ts +37 -0
  154. package/src/components/select/select.styles.ts +12 -0
  155. package/src/components/sidebar/index.ts +1 -0
  156. package/src/components/sidebar/sidebar.styles.ts +94 -0
  157. package/src/components/splitter/index.ts +1 -0
  158. package/src/components/splitter/splitter.styles.ts +44 -0
  159. package/src/components/textarea/textarea.styles.ts +6 -0
  160. package/src/components/virtualizer/index.ts +1 -0
  161. package/src/components/virtualizer/virtualizer.styles.ts +15 -0
  162. package/dist/themes/default/components/index.css +0 -6
  163. package/dist/themes/default/index.css +0 -8
@@ -17,11 +17,23 @@
17
17
 
18
18
  .progress-circle__track-circle {
19
19
  stroke: var(--progress-circle-track-stroke);
20
+
21
+ /* Forced colors leaves SVG strokes alone, so the ring renders but in the library's own
22
+ * palette rather than the user's. The track steps out of the way entirely: every keyword
23
+ * dark enough to read against `Canvas` is also close enough to `Highlight` to swallow the
24
+ * arc in one palette or the other, and the arc is the part carrying the value. */
25
+ @media (forced-colors: active) {
26
+ stroke: Canvas;
27
+ }
20
28
  }
21
29
 
22
30
  .progress-circle__fill-circle {
23
31
  stroke: var(--progress-circle-stroke);
24
32
 
33
+ @media (forced-colors: active) {
34
+ stroke: Highlight;
35
+ }
36
+
25
37
  /**
26
38
  * Transitions
27
39
  * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
@@ -162,6 +162,13 @@
162
162
  .radio:has(input:checked) .radio__indicator:empty::before {
163
163
  @apply bg-accent-foreground;
164
164
  scale: 0.4286; /* 6px */
165
+
166
+ /* Forced Colors Mode paints the control and this dot the same `Canvas`, which leaves a
167
+ * checked radio looking exactly like an unchecked one - the scale change shows nothing on
168
+ * its own. */
169
+ @media (forced-colors: active) {
170
+ background-color: CanvasText;
171
+ }
165
172
  }
166
173
 
167
174
  /* Selected + Pressed state */
@@ -218,6 +218,12 @@
218
218
  &[data-today="true"] {
219
219
  .range-calendar__cell-button {
220
220
  @apply bg-accent-soft text-accent-soft-foreground;
221
+
222
+ /* An edge rather than a fill, so today still reads as itself once it is also in range */
223
+ @media (forced-colors: active) {
224
+ outline: 1px solid CanvasText;
225
+ outline-offset: -1px;
226
+ }
221
227
  }
222
228
 
223
229
  @media (hover: hover) {
@@ -233,6 +239,20 @@
233
239
  /* Range selected track (middle segment) */
234
240
  &[data-selected="true"]:not([data-outside-month="true"]) {
235
241
  @apply rounded-none bg-accent-soft;
242
+
243
+ /* The track is a background and nothing else, so Forced Colors Mode flattens it into the
244
+ * page and the range stops being visible. The day button declares its own `color`, so
245
+ * `HighlightText` has to be restated there rather than left to inherit. */
246
+ @media (forced-colors: active) {
247
+ background-color: Highlight;
248
+
249
+ .range-calendar__cell-button {
250
+ /* Suppresses the `Canvas` backplate behind the day number, which would otherwise cover
251
+ * the track and leave the digits invisible against it. */
252
+ forced-color-adjust: none;
253
+ color: HighlightText;
254
+ }
255
+ }
236
256
  }
237
257
 
238
258
  /* Round row boundaries so the range track looks continuous across weeks */
@@ -257,6 +277,14 @@
257
277
 
258
278
  .range-calendar__cell-button {
259
279
  @apply bg-accent text-accent-foreground;
280
+
281
+ /* Caps read the same as the track here. Forced colors offers one selection colour, and
282
+ * spending it on the shape that matters - the range - beats splitting it. */
283
+ @media (forced-colors: active) {
284
+ forced-color-adjust: none;
285
+ background-color: Highlight;
286
+ color: HighlightText;
287
+ }
260
288
  }
261
289
  }
262
290
 
@@ -7,6 +7,15 @@ export declare const searchFieldVariants: import("tailwind-variants").TVReturnTy
7
7
  group: string;
8
8
  };
9
9
  };
10
+ size: {
11
+ lg: {
12
+ base: string;
13
+ };
14
+ md: {};
15
+ sm: {
16
+ base: string;
17
+ };
18
+ };
10
19
  variant: {
11
20
  primary: {
12
21
  base: string;
@@ -29,6 +38,15 @@ export declare const searchFieldVariants: import("tailwind-variants").TVReturnTy
29
38
  group: string;
30
39
  };
31
40
  };
41
+ size: {
42
+ lg: {
43
+ base: string;
44
+ };
45
+ md: {};
46
+ sm: {
47
+ base: string;
48
+ };
49
+ };
32
50
  variant: {
33
51
  primary: {
34
52
  base: string;
@@ -51,6 +69,15 @@ export declare const searchFieldVariants: import("tailwind-variants").TVReturnTy
51
69
  group: string;
52
70
  };
53
71
  };
72
+ size: {
73
+ lg: {
74
+ base: string;
75
+ };
76
+ md: {};
77
+ sm: {
78
+ base: string;
79
+ };
80
+ };
54
81
  variant: {
55
82
  primary: {
56
83
  base: string;
@@ -1 +1 @@
1
- {"version":3,"file":"search-field.styles.d.ts","sourceRoot":"","sources":["../../../src/components/search-field/search-field.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,mBAAmB;;QAc1B,KAAK;QACL,IAAI;YACF,IAAI;YACJ,KAAK;;;;QAIP,OAAO;YACL,IAAI;;QAEN,SAAS;YACP,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAIV,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"search-field.styles.d.ts","sourceRoot":"","sources":["../../../src/components/search-field/search-field.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,mBAAmB;;QAe1B,KAAK;QACL,IAAI;YACF,IAAI;YACJ,KAAK;;;;QAIP,EAAE;YACA,IAAI;;QAEN,EAAE;QACF,EAAE;YACA,IAAI;;;;QAIN,OAAO;YACL,IAAI;;QAEN,SAAS;YACP,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAIV,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -3,6 +3,7 @@ import { tv } from "tailwind-variants";
3
3
  const searchFieldVariants = tv({
4
4
  defaultVariants: {
5
5
  fullWidth: false,
6
+ size: "md",
6
7
  variant: "primary"
7
8
  },
8
9
  slots: {
@@ -20,6 +21,11 @@ const searchFieldVariants = tv({
20
21
  group: "search-field__group--full-width"
21
22
  }
22
23
  },
24
+ size: {
25
+ lg: { base: "search-field--lg" },
26
+ md: {},
27
+ sm: { base: "search-field--sm" }
28
+ },
23
29
  variant: {
24
30
  primary: { base: "search-field--primary" },
25
31
  secondary: { base: "search-field--secondary" }
@@ -25,6 +25,14 @@
25
25
  border-width: var(--border-width-field);
26
26
  border-color: var(--field-border);
27
27
 
28
+ /* Forced Colors Mode flattens the fill onto the page and strips the shadow, leaving a control
29
+ * with nothing to say it is one. `ButtonBorder` is the keyword the platform uses for a
30
+ * control's edge. */
31
+ @media (forced-colors: active) {
32
+ outline: 1px solid ButtonBorder;
33
+ outline-offset: -1px;
34
+ }
35
+
28
36
  /**
29
37
  * Transitions
30
38
  * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
@@ -80,7 +88,7 @@
80
88
  }
81
89
 
82
90
  .search-field__input {
83
- @apply flex-1 rounded-none border-0 bg-transparent px-3 py-2 text-base shadow-none outline-none sm:text-sm;
91
+ @apply flex-1 rounded-none border-0 bg-transparent px-3 field-line-md shadow-none outline-none;
84
92
 
85
93
  /* Hide browser default search clear button */
86
94
  &::-webkit-search-cancel-button,
@@ -184,3 +192,27 @@
184
192
  .search-field__group--full-width {
185
193
  @apply w-full;
186
194
  }
195
+
196
+ /* ==========================================================================
197
+ Size variants
198
+ ========================================================================== */
199
+
200
+ .search-field--sm {
201
+ .search-field__group {
202
+ @apply h-8;
203
+ }
204
+
205
+ .search-field__input {
206
+ @apply field-line-sm;
207
+ }
208
+ }
209
+
210
+ .search-field--lg {
211
+ .search-field__group {
212
+ @apply h-10;
213
+ }
214
+
215
+ .search-field__input {
216
+ @apply field-line-lg;
217
+ }
218
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./segmented-control.styles";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { segmentedControlVariants } from "./segmented-control.styles.js";
2
+ export { segmentedControlVariants };
@@ -0,0 +1,73 @@
1
+ import type { VariantProps } from "tailwind-variants";
2
+ export declare const segmentedControlVariants: import("tailwind-variants").TVReturnType<{
3
+ fullWidth: {
4
+ false: {};
5
+ true: {
6
+ base: string;
7
+ };
8
+ };
9
+ size: {
10
+ lg: {
11
+ base: string;
12
+ };
13
+ md: {
14
+ base: string;
15
+ };
16
+ sm: {
17
+ base: string;
18
+ };
19
+ };
20
+ }, {
21
+ base: string;
22
+ indicator: string;
23
+ item: string;
24
+ separator: string;
25
+ }, undefined, {
26
+ fullWidth: {
27
+ false: {};
28
+ true: {
29
+ base: string;
30
+ };
31
+ };
32
+ size: {
33
+ lg: {
34
+ base: string;
35
+ };
36
+ md: {
37
+ base: string;
38
+ };
39
+ sm: {
40
+ base: string;
41
+ };
42
+ };
43
+ }, {
44
+ base: string;
45
+ indicator: string;
46
+ item: string;
47
+ separator: string;
48
+ }, import("tailwind-variants").TVReturnTypeLike<{
49
+ fullWidth: {
50
+ false: {};
51
+ true: {
52
+ base: string;
53
+ };
54
+ };
55
+ size: {
56
+ lg: {
57
+ base: string;
58
+ };
59
+ md: {
60
+ base: string;
61
+ };
62
+ sm: {
63
+ base: string;
64
+ };
65
+ };
66
+ }, {
67
+ base: string;
68
+ indicator: string;
69
+ item: string;
70
+ separator: string;
71
+ }>>;
72
+ export type SegmentedControlVariants = VariantProps<typeof segmentedControlVariants>;
73
+ //# sourceMappingURL=segmented-control.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-control.styles.d.ts","sourceRoot":"","sources":["../../../src/components/segmented-control/segmented-control.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,wBAAwB;;QAa/B,KAAK;QACL,IAAI;YACF,IAAI;;;;QAIN,EAAE;YACA,IAAI;;QAEN,EAAE;YACA,IAAI;;QAEN,EAAE;YACA,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAIV,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,YAAY,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { tv } from "tailwind-variants";
2
+ //#region src/components/segmented-control/segmented-control.styles.ts
3
+ const segmentedControlVariants = tv({
4
+ defaultVariants: {
5
+ fullWidth: false,
6
+ size: "md"
7
+ },
8
+ slots: {
9
+ base: "segmented-control",
10
+ indicator: "segmented-control__indicator",
11
+ item: "segmented-control__item",
12
+ separator: "segmented-control__separator"
13
+ },
14
+ variants: {
15
+ fullWidth: {
16
+ false: {},
17
+ true: { base: "segmented-control--full-width" }
18
+ },
19
+ size: {
20
+ lg: { base: "segmented-control--lg" },
21
+ md: { base: "segmented-control--md" },
22
+ sm: { base: "segmented-control--sm" }
23
+ }
24
+ }
25
+ });
26
+ //#endregion
27
+ export { segmentedControlVariants };
@@ -0,0 +1,193 @@
1
+ /* ==========================================================================
2
+ SegmentedControl - one choice out of a few, drawn as a pill that slides
3
+
4
+ Structure (explicit composition):
5
+ .segmented-control → role="radiogroup", the track the pill slides in
6
+ .segmented-control__item → button[role="radio"]
7
+ .segmented-control__indicator
8
+ ========================================================================== */
9
+
10
+ .segmented-control {
11
+ @apply relative inline-flex w-max items-center bg-default p-1;
12
+
13
+ /* The same corner a button of this size wears, not a larger one stepped out by the padding.
14
+ * The size scale already lines the track up with a button and a field; a corner of its own
15
+ * would break that agreement at exactly the place two of them sit side by side.
16
+ *
17
+ * Read through `var(--component-radius)` rather than the `rounded-component` utility, because
18
+ * raw CSS resolves the alias on `:root` and then inherits the root theme's radius into every
19
+ * `data-theme` subtree. */
20
+ border-radius: min(32px, var(--component-radius));
21
+
22
+ /* Forced Colors Mode flattens the track's fill onto the page, which leaves the pill sitting
23
+ * in nothing. `CanvasText` is the platform's own edge; an outline rather than a border so
24
+ * nothing shifts. */
25
+ @media (forced-colors: active) {
26
+ outline: 1px solid CanvasText;
27
+ outline-offset: -1px;
28
+ }
29
+
30
+ /* Disabled state */
31
+ &[data-disabled="true"] {
32
+ @apply status-disabled;
33
+ }
34
+ }
35
+
36
+ /* ==========================================================================
37
+ Segment
38
+ ========================================================================== */
39
+
40
+ .segmented-control__item {
41
+ @apply relative inline-flex h-7 min-w-0 shrink-0 appearance-none items-center justify-center gap-2 rounded-component border-0 bg-transparent px-3 text-center text-sm font-medium whitespace-nowrap text-muted outline-none select-none no-highlight;
42
+
43
+ z-index: 1;
44
+ cursor: var(--cursor-interactive);
45
+
46
+ /**
47
+ * Transitions
48
+ * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
49
+ */
50
+ transition:
51
+ color 150ms var(--ease-smooth),
52
+ opacity 150ms var(--ease-smooth);
53
+ @apply motion-reduce:transition-none;
54
+
55
+ /* Selected state */
56
+ &[data-selected="true"] {
57
+ @apply text-segment-foreground;
58
+
59
+ /* Sits on top of the indicator, which forced colors paints `Highlight`. `forced-color-adjust`
60
+ * suppresses the `Canvas` backplate Chromium would otherwise paint behind this label - it
61
+ * covers the indicator, and black-on-black is exactly what it would leave. */
62
+ @media (forced-colors: active) {
63
+ forced-color-adjust: none;
64
+ color: HighlightText;
65
+ }
66
+ }
67
+
68
+ /* Hover states - both approaches for compatibility */
69
+ @media (hover: hover) {
70
+ &:not([data-selected="true"]):not([data-disabled="true"]):hover,
71
+ &[data-hovered="true"]:not([data-selected="true"]):not([data-disabled="true"]) {
72
+ @apply text-foreground;
73
+ }
74
+ }
75
+
76
+ /* Pressed states - both approaches for compatibility */
77
+ &:not([data-disabled="true"]):active,
78
+ &[data-pressed="true"]:not([data-disabled="true"]) {
79
+ @apply opacity-70;
80
+ }
81
+
82
+ /* Focus states - comprehensive fallback */
83
+ &:focus-visible:not(:focus),
84
+ &[data-focus-visible="true"] {
85
+ @apply status-focused;
86
+
87
+ /* Written after the utility, which sets this same property. Inset and offsetless so the ring
88
+ * stays inside the track's padding instead of spilling over its rounded edge - the same
89
+ * correction ToggleButtonGroup makes for an attached row. */
90
+ --tw-ring-offset-width: 0px;
91
+ @apply ring-inset;
92
+ }
93
+
94
+ /* Disabled state */
95
+ &:disabled,
96
+ &[data-disabled="true"] {
97
+ @apply status-disabled;
98
+ }
99
+ }
100
+
101
+ /* ==========================================================================
102
+ Separator - a hairline between adjacent segments. Rendered inside each
103
+ segment and pinned to its leading edge, so it divides that segment from the
104
+ one before it rather than being a node between the two.
105
+ ========================================================================== */
106
+
107
+ .segmented-control__separator {
108
+ @apply pointer-events-none absolute start-0 top-1/4 h-1/2 w-px rounded-sm bg-muted/25;
109
+
110
+ /**
111
+ * Transitions
112
+ * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
113
+ */
114
+ transition: opacity 150ms var(--ease-smooth);
115
+ @apply motion-reduce:transition-none;
116
+
117
+ /* Nothing to divide in front of the first segment. */
118
+ .segmented-control__item:first-child & {
119
+ @apply opacity-0;
120
+ }
121
+ }
122
+
123
+ /* The pill covers its own leading divider, and the divider on the segment that follows would
124
+ otherwise sit hard against the pill's trailing edge. Both step aside as it arrives. */
125
+ .segmented-control__item[data-selected="true"] .segmented-control__separator,
126
+ .segmented-control__item[data-selected="true"]
127
+ + .segmented-control__item
128
+ .segmented-control__separator {
129
+ @apply opacity-0;
130
+ }
131
+
132
+ /* ==========================================================================
133
+ Indicator - React Aria's SelectionIndicator. One is rendered inside every
134
+ segment and only the selected one is present, so what looks like a pill
135
+ sliding along is one element handing its place to the next.
136
+ ========================================================================== */
137
+
138
+ .segmented-control__indicator {
139
+ @apply absolute start-0 top-0 size-full rounded-component bg-segment shadow-surface;
140
+
141
+ z-index: -1;
142
+
143
+ /* The indicator is a background and nothing else, so Forced Colors Mode flattens it away
144
+ * and nothing marks the selected segment. `Highlight` behind `HighlightText` is the
145
+ * platform's own pairing for a selected segment. */
146
+ @media (forced-colors: active) {
147
+ background-color: Highlight;
148
+ }
149
+
150
+ /**
151
+ * Transitions
152
+ * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
153
+ *
154
+ * `useSharedElement` reads this very declaration to decide what to carry across the handoff,
155
+ * so the stylesheet stays the only place that decides what animates. `height` is listed even
156
+ * though the pill only travels along one axis today, so a vertical orientation needs no
157
+ * change here.
158
+ */
159
+ transition-duration: 250ms;
160
+ transition-property: translate, width, height;
161
+ transition-timing-function: var(--ease-out-fluid);
162
+ @apply motion-reduce:transition-none;
163
+ }
164
+
165
+ /* ==========================================================================
166
+ Sizes - the outer track lands on the control scale (32/36/40px), so a
167
+ segmented control lines up with a button or a field of the same size. The
168
+ track's own `p-1` is the 8px difference.
169
+ ========================================================================== */
170
+
171
+ .segmented-control--sm .segmented-control__item {
172
+ @apply h-6 px-2.5 text-xs;
173
+ }
174
+
175
+ .segmented-control--md {
176
+ /* No styles as this is the default size */
177
+ }
178
+
179
+ .segmented-control--lg .segmented-control__item {
180
+ @apply h-8 px-4;
181
+ }
182
+
183
+ /* ==========================================================================
184
+ Full width modifier
185
+ ========================================================================== */
186
+
187
+ .segmented-control--full-width {
188
+ @apply flex w-full;
189
+
190
+ .segmented-control__item {
191
+ @apply flex-1;
192
+ }
193
+ }
@@ -7,6 +7,17 @@ export declare const selectVariants: import("tailwind-variants").TVReturnType<{
7
7
  trigger: string;
8
8
  };
9
9
  };
10
+ size: {
11
+ lg: {
12
+ base: string;
13
+ popover: string;
14
+ };
15
+ md: {};
16
+ sm: {
17
+ base: string;
18
+ popover: string;
19
+ };
20
+ };
10
21
  variant: {
11
22
  primary: {
12
23
  base: string;
@@ -29,6 +40,17 @@ export declare const selectVariants: import("tailwind-variants").TVReturnType<{
29
40
  trigger: string;
30
41
  };
31
42
  };
43
+ size: {
44
+ lg: {
45
+ base: string;
46
+ popover: string;
47
+ };
48
+ md: {};
49
+ sm: {
50
+ base: string;
51
+ popover: string;
52
+ };
53
+ };
32
54
  variant: {
33
55
  primary: {
34
56
  base: string;
@@ -51,6 +73,17 @@ export declare const selectVariants: import("tailwind-variants").TVReturnType<{
51
73
  trigger: string;
52
74
  };
53
75
  };
76
+ size: {
77
+ lg: {
78
+ base: string;
79
+ popover: string;
80
+ };
81
+ md: {};
82
+ sm: {
83
+ base: string;
84
+ popover: string;
85
+ };
86
+ };
54
87
  variant: {
55
88
  primary: {
56
89
  base: string;
@@ -1 +1 @@
1
- {"version":3,"file":"select.styles.d.ts","sourceRoot":"","sources":["../../../src/components/select/select.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,cAAc;;QAcrB,KAAK;QACL,IAAI;YACF,IAAI;YACJ,OAAO;;;;QAIT,OAAO;YACL,IAAI;;QAEN,SAAS;YACP,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAIV,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"select.styles.d.ts","sourceRoot":"","sources":["../../../src/components/select/select.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,cAAc;;QAerB,KAAK;QACL,IAAI;YACF,IAAI;YACJ,OAAO;;;;QAIT,EAAE;YACA,IAAI;YACJ,OAAO;;QAET,EAAE;QACF,EAAE;YACA,IAAI;YACJ,OAAO;;;;QAIT,OAAO;YACL,IAAI;;QAEN,SAAS;YACP,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAIV,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -3,6 +3,7 @@ import { tv } from "tailwind-variants";
3
3
  const selectVariants = tv({
4
4
  defaultVariants: {
5
5
  fullWidth: false,
6
+ size: "md",
6
7
  variant: "primary"
7
8
  },
8
9
  slots: {
@@ -20,6 +21,17 @@ const selectVariants = tv({
20
21
  trigger: "select__trigger--full-width"
21
22
  }
22
23
  },
24
+ size: {
25
+ lg: {
26
+ base: "select--lg",
27
+ popover: "select__popover--lg"
28
+ },
29
+ md: {},
30
+ sm: {
31
+ base: "select--sm",
32
+ popover: "select__popover--sm"
33
+ }
34
+ },
23
35
  variant: {
24
36
  primary: { base: "select--primary" },
25
37
  secondary: { base: "select--secondary" }
@@ -15,7 +15,16 @@
15
15
  }
16
16
 
17
17
  .select__trigger {
18
- @apply relative isolate inline-flex min-h-9 rounded-field border bg-field px-3 py-2 text-sm text-field-foreground shadow-field outline-none select-none no-highlight;
18
+ @apply relative isolate inline-flex min-h-9 rounded-field border bg-field px-3 field-line-md text-field-foreground shadow-field outline-none select-none no-highlight;
19
+
20
+ /* Forced Colors Mode flattens the fill onto the page and strips the shadow, leaving a field that
21
+ * reads as bare text - `--border-width-field` is 0, so the declared border brings nothing back on
22
+ * its own. An outline rather than a width so nothing shifts, and the focus ring replaces it while
23
+ * focused, which is the right order of importance. */
24
+ @media (forced-colors: active) {
25
+ outline: 1px solid ButtonBorder;
26
+ outline-offset: -1px;
27
+ }
19
28
 
20
29
  /**
21
30
  * Transitions
@@ -111,7 +120,7 @@
111
120
  }
112
121
 
113
122
  .select__value {
114
- @apply flex-1 text-start text-base wrap-break-word text-current sm:text-sm;
123
+ @apply flex-1 text-start wrap-break-word text-current;
115
124
 
116
125
  &[data-placeholder="true"] {
117
126
  @apply text-field-placeholder;
@@ -138,7 +147,7 @@
138
147
  /* Similar to popover content styles */
139
148
  .select__popover {
140
149
  @apply min-w-(--trigger-width) origin-(--trigger-anchor-point) scroll-py-1 scrollbar overflow-y-auto overscroll-contain bg-overlay p-0 text-sm;
141
- border-radius: min(32px, var(--radius-3xl));
150
+ border-radius: min(32px, var(--component-radius));
142
151
  box-shadow: var(--shadow-overlay);
143
152
 
144
153
  /* Focus state */
@@ -215,6 +224,34 @@
215
224
  }
216
225
  }
217
226
 
227
+ /* ==========================================================================
228
+ Size variants
229
+ ========================================================================== */
230
+
231
+ /* The trigger's own metrics, and the option rows in a popover that is portalled out of this tree -
232
+ * which is why the popover carries its own size class rather than being reached from the base. */
233
+ .select--sm .select__trigger {
234
+ @apply min-h-8 field-line-sm;
235
+ }
236
+
237
+ .select--lg .select__trigger {
238
+ @apply min-h-10 field-line-lg;
239
+ }
240
+
241
+ .select__popover--sm {
242
+ [data-slot="list-box-item"] {
243
+ @apply min-h-8 py-1;
244
+ }
245
+ }
246
+
247
+ .select__popover--lg {
248
+ @apply text-base;
249
+
250
+ [data-slot="list-box-item"] {
251
+ @apply min-h-10 py-2;
252
+ }
253
+ }
254
+
218
255
  /* Full width modifier */
219
256
  .select--full-width {
220
257
  @apply w-full;