@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
@@ -1,14 +1,33 @@
1
1
  /* === Focus Ring === */
2
+ /*
3
+ * Every ring here is a `box-shadow` - that is what `ring-*` compiles to - and Forced Colors
4
+ * Mode strips `box-shadow` outright. Since `outline-none` has already given up the native
5
+ * outline, the two together leave no focus indicator at all, which is WCAG 2.4.7 across every
6
+ * component that focuses. Each utility therefore draws an outline back under
7
+ * `forced-colors: active`, in `Highlight`: system colours are exempt from the override, and
8
+ * `Highlight` is the one the platform reserves for the focused control.
9
+ */
2
10
  @utility focus-ring {
3
11
  @apply ring-2 ring-focus ring-offset-0 ring-offset-background outline-none;
4
12
  /* Overrides the ring offset from the theme variables */
5
13
  --tw-ring-offset-width: var(--ring-offset-width);
14
+
15
+ @media (forced-colors: active) {
16
+ outline: 2px solid Highlight;
17
+ outline-offset: 2px;
18
+ }
6
19
  }
7
20
 
8
21
  @utility focus-field-ring {
9
22
  @apply ring-2 ring-focus ring-offset-0 outline-none;
10
23
  /* No separation - ring sits directly against the element */
11
24
  --tw-ring-offset-width: 0px;
25
+
26
+ /* Offset stays at 0, matching the ring this stands in for */
27
+ @media (forced-colors: active) {
28
+ outline: 2px solid Highlight;
29
+ outline-offset: 0;
30
+ }
12
31
  }
13
32
 
14
33
  @utility invalid-field-ring {
@@ -25,6 +44,15 @@
25
44
  &[data-focus-within="true"] {
26
45
  @apply ring-2 ring-danger ring-offset-0;
27
46
  --tw-ring-offset-width: 0px;
47
+
48
+ /* The unfocused outline above survives forced colors, but the ring marking focus does
49
+ * not - widen and recolour the outline instead, or a focused invalid field is
50
+ * indistinguishable from an unfocused one. The danger colour is not the loss it looks
51
+ * like: forced colors overrides it either way, and the error message carries it. */
52
+ @media (forced-colors: active) {
53
+ outline-width: 2px;
54
+ outline-color: Highlight;
55
+ }
28
56
  }
29
57
  }
30
58
 
@@ -49,12 +77,54 @@
49
77
  opacity: var(--disabled-opacity);
50
78
  cursor: var(--cursor-disabled);
51
79
  pointer-events: none;
80
+
81
+ /* Forced colors leaves `opacity` alone, so the element still reads as dimmed without this.
82
+ * `GrayText` is the signal the platform actually uses for a disabled control, and it
83
+ * inherits, which is what carries it to the label and description inside. */
84
+ @media (forced-colors: active) {
85
+ color: GrayText;
86
+ border-color: GrayText;
87
+ }
52
88
  }
53
89
 
54
90
  @utility status-pending {
55
91
  @apply pointer-events-none;
56
92
  }
57
93
 
94
+ /* === Forced Colors (Windows High Contrast Mode) === */
95
+
96
+ /*
97
+ * Restates "selected" for Forced Colors Mode.
98
+ *
99
+ * The mode replaces every author colour with the user's palette, so a state carried only by
100
+ * `background-color` - a selected tag, calendar day, table row - collapses into its neighbours
101
+ * and the selection becomes invisible. `Highlight` / `HighlightText` is the pair the platform
102
+ * reserves for a selected control and is exempt from the override, so restating the state
103
+ * with it survives.
104
+ *
105
+ * Only for elements whose selected state is a background and nothing else. Where selection
106
+ * also shows as a glyph or a moved thumb, the component's own `forced-colors` block handles
107
+ * it, because those parts need colours of their own.
108
+ *
109
+ * Apply it as a statement of its own, never folded into another `@apply` list: Tailwind sorts
110
+ * the utilities in one list and hoists the nested at-rule above the plain declarations, where
111
+ * the very `background-color` this is meant to override then wins.
112
+ */
113
+ @utility forced-selected {
114
+ @media (forced-colors: active) {
115
+ /* Chromium paints a `Canvas`-coloured backplate behind the text of any element that has
116
+ * one, so that text over an image stays legible. It goes on top of the element's own
117
+ * background, which means a `Highlight` fill with `HighlightText` on it renders as a
118
+ * solid plate with invisible text - the label disappears completely. Opting the element
119
+ * out of adjustment is what suppresses the backplate; the colours below are system
120
+ * colours either way, so the user's palette is still what gets used. */
121
+ forced-color-adjust: none;
122
+ background-color: Highlight;
123
+ border-color: Highlight;
124
+ color: HighlightText;
125
+ }
126
+ }
127
+
58
128
  /* === Scrollbars (standards-only; apply per scroll slot in component CSS) === */
59
129
  @utility scrollbar {
60
130
  scrollbar-width: var(--scrollbar-width);
@@ -81,3 +151,30 @@
81
151
  scrollbar-gutter: auto;
82
152
  -ms-overflow-style: none;
83
153
  }
154
+
155
+ /* === Field metrics === */
156
+ /*
157
+ * One line of a field, at each size. The size scale is the control scale: 32px, 36px, 40px, the
158
+ * same three heights a button stands at, so a field and a button of the same size line up.
159
+ *
160
+ * The padding is what carries it rather than a height, because a field is content-driven - some
161
+ * shells grow (a group around a textarea, a multi-select trigger wrapping its chips) and a height
162
+ * would fight them. The shell states its own floor: `min-h-8` / `min-h-9` / `min-h-10` where it may
163
+ * grow, `h-8` / `h-9` / `h-10` where it may not.
164
+ *
165
+ * The padding also changes at `sm` where the type does. 16px type below that breakpoint is what
166
+ * stops mobile Safari zooming the page on focus, and 16px sets a 24px line where 14px sets a 20px
167
+ * one - so the padding gives back the 4px difference and the height comes out the same either way.
168
+ * `lg` keeps 16px throughout, as the large button does.
169
+ */
170
+ @utility field-line-sm {
171
+ @apply py-1 text-base sm:py-1.5 sm:text-sm;
172
+ }
173
+
174
+ @utility field-line-md {
175
+ @apply py-1.5 text-base sm:py-2 sm:text-sm;
176
+ }
177
+
178
+ @utility field-line-lg {
179
+ @apply py-2 text-base;
180
+ }
@@ -10,7 +10,7 @@
10
10
  * motion-safe:animate-spin - Full motion effects
11
11
  * dark:bg-gray-900 - Dark mode styles
12
12
  *
13
- * Priority: Explicit data attributes/classes → System preferences (fallback)
13
+ * Priority: Explicit data attributes → System preferences (fallback); `dark` is explicit-only
14
14
  * ================================================================================================
15
15
  */
16
16
 
@@ -79,10 +79,12 @@
79
79
 
80
80
  /* -------------------------------------------------------------------------------------------------
81
81
  * dark — Dark mode styles
82
- * Priority: .dark class / data-theme="dark" prefers-color-scheme: dark
82
+ * Explicit only: .dark class / data-theme="dark". No `prefers-color-scheme` fallback here — the
83
+ * token layer in `themes/` keys off these same selectors and has no media query of its own, so a
84
+ * fallback would flip the utilities while the colours stayed light. Apps read `matchMedia` and set
85
+ * the class themselves, which is also what a light/dark/system toggle needs.
83
86
  * ------------------------------------------------------------------------------------------------- */
84
87
  @custom-variant dark {
85
- /* Explicit: .dark class or data-theme="dark" on element or ancestor */
86
88
  &:is(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *) {
87
89
  @slot;
88
90
 
@@ -91,16 +93,4 @@
91
93
  @slot;
92
94
  }
93
95
  }
94
-
95
- /* Fallback: system prefers dark color scheme */
96
- @media (prefers-color-scheme: dark) {
97
- &:not(:is(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *)) & {
98
- @slot;
99
-
100
- &::before,
101
- &::after {
102
- @slot;
103
- }
104
- }
105
- }
106
96
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ropav/styles",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Ropav core styles - framework-agnostic CSS and Tailwind variants",
5
5
  "keywords": [
6
6
  "css",
@@ -50,8 +50,7 @@
50
50
  "./base": "./dist/base/base.css",
51
51
  "./base/*.css": "./dist/base/*.css",
52
52
  "./components/*.css": "./dist/components/*.css",
53
- "./themes/default": "./dist/themes/default/index.css",
54
- "./themes/*/*.css": "./dist/themes/*/*.css",
53
+ "./themes/*": "./dist/themes/*.css",
55
54
  "./themes/*.css": "./dist/themes/*.css",
56
55
  "./utilities": "./dist/utilities/index.css",
57
56
  "./variants": "./dist/variants/index.css",
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const autocompleteVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -24,6 +25,17 @@ export const autocompleteVariants = tv({
24
25
  trigger: "autocomplete__trigger--full-width",
25
26
  },
26
27
  },
28
+ size: {
29
+ lg: {
30
+ base: "autocomplete--lg",
31
+ popover: "autocomplete__popover--lg",
32
+ },
33
+ md: {},
34
+ sm: {
35
+ base: "autocomplete--sm",
36
+ popover: "autocomplete__popover--sm",
37
+ },
38
+ },
27
39
  variant: {
28
40
  primary: {
29
41
  base: "autocomplete--primary",
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const colorInputGroupVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -20,6 +21,15 @@ export const colorInputGroupVariants = tv({
20
21
  base: "color-input-group--full-width",
21
22
  },
22
23
  },
24
+ size: {
25
+ lg: {
26
+ base: "color-input-group--lg",
27
+ },
28
+ md: {},
29
+ sm: {
30
+ base: "color-input-group--sm",
31
+ },
32
+ },
23
33
  variant: {
24
34
  primary: {
25
35
  base: "color-input-group--primary",
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const comboBoxVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  },
9
10
  slots: {
10
11
  base: "combo-box",
@@ -21,6 +22,17 @@ export const comboBoxVariants = tv({
21
22
  inputGroup: "combo-box__input-group--full-width",
22
23
  },
23
24
  },
25
+ /* The field itself is the `Input` inside, which takes its own size class from the context the
26
+ * root provides. Only the popover is left, and it is teleported out of this tree. */
27
+ size: {
28
+ lg: {
29
+ popover: "combo-box__popover--lg",
30
+ },
31
+ md: {},
32
+ sm: {
33
+ popover: "combo-box__popover--sm",
34
+ },
35
+ },
24
36
  },
25
37
  });
26
38
 
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const dateInputGroupVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -22,6 +23,15 @@ export const dateInputGroupVariants = tv({
22
23
  base: "date-input-group--full-width",
23
24
  },
24
25
  },
26
+ size: {
27
+ lg: {
28
+ base: "date-input-group--lg",
29
+ },
30
+ md: {},
31
+ sm: {
32
+ base: "date-input-group--sm",
33
+ },
34
+ },
25
35
  variant: {
26
36
  primary: {
27
37
  base: "date-input-group--primary",
@@ -4,7 +4,9 @@ import { tv } from "tailwind-variants";
4
4
 
5
5
  export const dropdownVariants = tv({
6
6
  slots: {
7
- menu: "dropdown__menu",
7
+ // The block is shared with the standalone menu; `dropdown__menu` is only the hook that
8
+ // `dropdown.css` and callers target.
9
+ menu: "menu dropdown__menu",
8
10
  popover: "dropdown__popover",
9
11
  root: "dropdown",
10
12
  trigger: "dropdown__trigger",
@@ -61,11 +61,14 @@ export * from "./radio";
61
61
  export * from "./radio-group";
62
62
  export * from "./scroll-shadow";
63
63
  export * from "./search-field";
64
+ export * from "./segmented-control";
64
65
  export * from "./select";
65
66
  export * from "./separator";
67
+ export * from "./sidebar";
66
68
  export * from "./skeleton";
67
69
  export * from "./slider";
68
70
  export * from "./spinner";
71
+ export * from "./splitter";
69
72
  export * from "./surface";
70
73
  export * from "./switch";
71
74
  export * from "./switch-group";
@@ -82,3 +85,4 @@ export * from "./toggle-button";
82
85
  export * from "./toggle-button-group";
83
86
  export * from "./toolbar";
84
87
  export * from "./tooltip";
88
+ export * from "./virtualizer";
@@ -6,6 +6,7 @@ export const inputVariants = tv({
6
6
  base: "input",
7
7
  defaultVariants: {
8
8
  fullWidth: false,
9
+ size: "md",
9
10
  variant: "primary",
10
11
  },
11
12
  variants: {
@@ -13,6 +14,11 @@ export const inputVariants = tv({
13
14
  false: "",
14
15
  true: "input--full-width",
15
16
  },
17
+ size: {
18
+ lg: "input--lg",
19
+ md: "",
20
+ sm: "input--sm",
21
+ },
16
22
  variant: {
17
23
  primary: "input--primary",
18
24
  secondary: "input--secondary",
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const inputGroupVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -20,6 +21,15 @@ export const inputGroupVariants = tv({
20
21
  base: "input-group--full-width",
21
22
  },
22
23
  },
24
+ size: {
25
+ lg: {
26
+ base: "input-group--lg",
27
+ },
28
+ md: {},
29
+ sm: {
30
+ base: "input-group--sm",
31
+ },
32
+ },
23
33
  variant: {
24
34
  primary: {
25
35
  base: "input-group--primary",
@@ -5,9 +5,15 @@ import { tv } from "tailwind-variants";
5
5
  export const listboxVariants = tv({
6
6
  base: "list-box",
7
7
  defaultVariants: {
8
+ size: "md",
8
9
  variant: "default",
9
10
  },
10
11
  variants: {
12
+ size: {
13
+ lg: "list-box--lg",
14
+ md: "",
15
+ sm: "list-box--sm",
16
+ },
11
17
  variant: {
12
18
  danger: "list-box--danger",
13
19
  default: "list-box--default",
@@ -4,6 +4,16 @@ import { tv } from "tailwind-variants";
4
4
 
5
5
  export const menuVariants = tv({
6
6
  base: "menu",
7
+ defaultVariants: {
8
+ size: "md",
9
+ },
10
+ variants: {
11
+ size: {
12
+ lg: "menu--lg",
13
+ md: "",
14
+ sm: "menu--sm",
15
+ },
16
+ },
7
17
  });
8
18
 
9
19
  export type MenuVariants = VariantProps<typeof menuVariants>;
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const numberFieldVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -22,6 +23,15 @@ export const numberFieldVariants = tv({
22
23
  group: "number-field__group--full-width",
23
24
  },
24
25
  },
26
+ size: {
27
+ lg: {
28
+ base: "number-field--lg",
29
+ },
30
+ md: {},
31
+ sm: {
32
+ base: "number-field--sm",
33
+ },
34
+ },
25
35
  variant: {
26
36
  primary: {
27
37
  base: "number-field--primary",
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const searchFieldVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -22,6 +23,15 @@ export const searchFieldVariants = tv({
22
23
  group: "search-field__group--full-width",
23
24
  },
24
25
  },
26
+ size: {
27
+ lg: {
28
+ base: "search-field--lg",
29
+ },
30
+ md: {},
31
+ sm: {
32
+ base: "search-field--sm",
33
+ },
34
+ },
25
35
  variant: {
26
36
  primary: {
27
37
  base: "search-field--primary",
@@ -0,0 +1 @@
1
+ export * from "./segmented-control.styles";
@@ -0,0 +1,37 @@
1
+ import type { VariantProps } from "tailwind-variants";
2
+
3
+ import { tv } from "tailwind-variants";
4
+
5
+ export const segmentedControlVariants = tv({
6
+ defaultVariants: {
7
+ fullWidth: false,
8
+ size: "md",
9
+ },
10
+ slots: {
11
+ base: "segmented-control",
12
+ indicator: "segmented-control__indicator",
13
+ item: "segmented-control__item",
14
+ separator: "segmented-control__separator",
15
+ },
16
+ variants: {
17
+ fullWidth: {
18
+ false: {},
19
+ true: {
20
+ base: "segmented-control--full-width",
21
+ },
22
+ },
23
+ size: {
24
+ lg: {
25
+ base: "segmented-control--lg",
26
+ },
27
+ md: {
28
+ base: "segmented-control--md",
29
+ },
30
+ sm: {
31
+ base: "segmented-control--sm",
32
+ },
33
+ },
34
+ },
35
+ });
36
+
37
+ export type SegmentedControlVariants = VariantProps<typeof segmentedControlVariants>;
@@ -5,6 +5,7 @@ import { tv } from "tailwind-variants";
5
5
  export const selectVariants = tv({
6
6
  defaultVariants: {
7
7
  fullWidth: false,
8
+ size: "md",
8
9
  variant: "primary",
9
10
  },
10
11
  slots: {
@@ -22,6 +23,17 @@ export const selectVariants = tv({
22
23
  trigger: "select__trigger--full-width",
23
24
  },
24
25
  },
26
+ size: {
27
+ lg: {
28
+ base: "select--lg",
29
+ popover: "select__popover--lg",
30
+ },
31
+ md: {},
32
+ sm: {
33
+ base: "select--sm",
34
+ popover: "select__popover--sm",
35
+ },
36
+ },
25
37
  variant: {
26
38
  primary: {
27
39
  base: "select--primary",
@@ -0,0 +1 @@
1
+ export * from "./sidebar.styles";
@@ -0,0 +1,94 @@
1
+ import type { VariantProps } from "tailwind-variants";
2
+
3
+ import { tv } from "tailwind-variants";
4
+
5
+ /*
6
+ * Side and collapse mode are carried as modifier classes rather than left to `[data-side]` /
7
+ * `[data-collapsible]` selectors in the stylesheet, the same call `splitterVariants` makes: a
8
+ * selector descending from the shell would reach a second sidebar rendered inside the inset — a
9
+ * settings pane with a nav of its own — and lay its border down the outer one's edge.
10
+ *
11
+ * Only the slots with side- or mode-specific rules branch. `data-collapsed` is deliberately not a
12
+ * variant: it flips while you watch, which is what a state key is for, and a modifier saying so
13
+ * would have to be recomputed on every toggle.
14
+ */
15
+ export const sidebarVariants = tv({
16
+ defaultVariants: {
17
+ collapsible: "icon",
18
+ side: "left",
19
+ },
20
+ slots: {
21
+ base: "sidebar",
22
+ content: "sidebar__content",
23
+ footer: "sidebar__footer",
24
+ group: "sidebar__group",
25
+ groupLabel: "sidebar__group-label",
26
+ header: "sidebar__header",
27
+ inset: "sidebar__inset",
28
+ item: "sidebar__item",
29
+ itemIcon: "sidebar__item-icon",
30
+ itemIndicator: "sidebar__item-indicator",
31
+ itemLabel: "sidebar__item-label",
32
+ itemTooltip: "sidebar__item-tooltip",
33
+ itemTrailing: "sidebar__item-trailing",
34
+ panel: "sidebar__panel",
35
+ rail: "sidebar__rail",
36
+ railTarget: "sidebar__rail-target",
37
+ separator: "sidebar__separator",
38
+ subMenu: "sidebar__sub-menu",
39
+ trigger: "sidebar__trigger",
40
+ },
41
+ variants: {
42
+ collapsible: {
43
+ icon: {
44
+ panel: "sidebar__panel--icon",
45
+ },
46
+ none: {
47
+ panel: "sidebar__panel--none",
48
+ },
49
+ offcanvas: {
50
+ panel: "sidebar__panel--offcanvas",
51
+ },
52
+ },
53
+ // Whether the panel is rendering inside a drawer. Resolved by the panel at call time rather
54
+ // than by the root, because it is the one part that changes shape when the viewport narrows.
55
+ inDrawer: {
56
+ true: {
57
+ panel: "sidebar__panel--drawer",
58
+ },
59
+ },
60
+ // Whether this submenu folds. Resolved by the submenu at call time rather than by the root,
61
+ // because one sidebar holds items that fold and items that do not.
62
+ isCollapsible: {
63
+ true: {
64
+ subMenu: "sidebar__sub-menu--collapsible",
65
+ },
66
+ },
67
+ // Whether the rail resizes rather than only toggling. Not folded into `collapsible`, because
68
+ // the two are independent: a sidebar that cannot collapse at all can still be dragged wider.
69
+ isResizable: {
70
+ true: {
71
+ rail: "sidebar__rail--resizable",
72
+ },
73
+ },
74
+ // Whether the row is a child under another item. Resolved by the item at call time, from the
75
+ // submenu it finds itself inside rather than from a prop a caller has to remember on every row.
76
+ isSub: {
77
+ true: {
78
+ item: "sidebar__item--sub",
79
+ },
80
+ },
81
+ side: {
82
+ left: {
83
+ base: "sidebar--left",
84
+ panel: "sidebar__panel--left",
85
+ },
86
+ right: {
87
+ base: "sidebar--right",
88
+ panel: "sidebar__panel--right",
89
+ },
90
+ },
91
+ },
92
+ });
93
+
94
+ export type SidebarVariants = VariantProps<typeof sidebarVariants>;
@@ -0,0 +1 @@
1
+ export * from "./splitter.styles";
@@ -0,0 +1,44 @@
1
+ import type { VariantProps } from "tailwind-variants";
2
+
3
+ import { tv } from "tailwind-variants";
4
+
5
+ /*
6
+ * Orientation is carried as a modifier class rather than left to a `[data-orientation]` selector
7
+ * in the stylesheet: a splitter nests, and a descendant selector on the root would reach an inner
8
+ * group's handle as well as its own. Only `base`, `handle` and `handleGrip` branch, because only
9
+ * they have orientation-specific rules — a modifier on the others would be dead CSS.
10
+ *
11
+ * `handleGrip` branches here rather than being sized from its parent's modifier, and that buys two
12
+ * things at once: the root already resolves these slots against the orientation, so a handle needs
13
+ * no extra wiring to size its grip, and the grip carries a `--` class of its own — which is what
14
+ * puts it in front of the Storybook forced-colors sweep. `showGrip` is deliberately *not* a variant:
15
+ * the grip is only rendered when it is asked for, so a modifier saying so would be dead CSS.
16
+ */
17
+ export const splitterVariants = tv({
18
+ defaultVariants: {
19
+ orientation: "horizontal",
20
+ },
21
+ slots: {
22
+ base: "splitter",
23
+ handle: "splitter__handle",
24
+ handleGrip: "splitter__handle-grip",
25
+ handleTarget: "splitter__handle-target",
26
+ panel: "splitter__panel",
27
+ },
28
+ variants: {
29
+ orientation: {
30
+ horizontal: {
31
+ base: "splitter--horizontal",
32
+ handle: "splitter__handle--horizontal",
33
+ handleGrip: "splitter__handle-grip--horizontal",
34
+ },
35
+ vertical: {
36
+ base: "splitter--vertical",
37
+ handle: "splitter__handle--vertical",
38
+ handleGrip: "splitter__handle-grip--vertical",
39
+ },
40
+ },
41
+ },
42
+ });
43
+
44
+ export type SplitterVariants = VariantProps<typeof splitterVariants>;