@ropav/styles 0.4.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 (138) hide show
  1. package/README.md +10 -5
  2. package/dist/components/accordion.css +5 -5
  3. package/dist/components/alert-dialog.css +1 -1
  4. package/dist/components/alert.css +1 -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 +31 -3
  9. package/dist/components/button-group.css +6 -6
  10. package/dist/components/button.css +7 -11
  11. package/dist/components/calendar-year-picker.css +1 -1
  12. package/dist/components/card.css +1 -1
  13. package/dist/components/color-input-group/color-input-group.styles.d.ts +27 -0
  14. package/dist/components/color-input-group/color-input-group.styles.d.ts.map +1 -1
  15. package/dist/components/color-input-group/color-input-group.styles.js +6 -0
  16. package/dist/components/color-input-group.css +21 -1
  17. package/dist/components/combo-box/combo-box.styles.d.ts +27 -0
  18. package/dist/components/combo-box/combo-box.styles.d.ts.map +1 -1
  19. package/dist/components/combo-box/combo-box.styles.js +17 -7
  20. package/dist/components/combo-box.css +21 -1
  21. package/dist/components/date-input-group/date-input-group.styles.d.ts +27 -0
  22. package/dist/components/date-input-group/date-input-group.styles.d.ts.map +1 -1
  23. package/dist/components/date-input-group/date-input-group.styles.js +6 -0
  24. package/dist/components/date-input-group.css +21 -1
  25. package/dist/components/dropdown.css +1 -1
  26. package/dist/components/index.css +4 -0
  27. package/dist/components/index.d.ts +4 -0
  28. package/dist/components/index.d.ts.map +1 -1
  29. package/dist/components/input/input.styles.d.ts +15 -0
  30. package/dist/components/input/input.styles.d.ts.map +1 -1
  31. package/dist/components/input/input.styles.js +6 -0
  32. package/dist/components/input-group/input-group.styles.d.ts +27 -0
  33. package/dist/components/input-group/input-group.styles.d.ts.map +1 -1
  34. package/dist/components/input-group/input-group.styles.js +6 -0
  35. package/dist/components/input-group.css +23 -1
  36. package/dist/components/input.css +13 -1
  37. package/dist/components/list-box/list-box.styles.d.ts +15 -0
  38. package/dist/components/list-box/list-box.styles.d.ts.map +1 -1
  39. package/dist/components/list-box/list-box.styles.js +15 -5
  40. package/dist/components/list-box-item.css +4 -2
  41. package/dist/components/list-box.css +19 -0
  42. package/dist/components/menu/menu.styles.d.ts +19 -1
  43. package/dist/components/menu/menu.styles.d.ts.map +1 -1
  44. package/dist/components/menu/menu.styles.js +9 -1
  45. package/dist/components/menu.css +19 -0
  46. package/dist/components/modal.css +1 -1
  47. package/dist/components/number-field/number-field.styles.d.ts +27 -0
  48. package/dist/components/number-field/number-field.styles.d.ts.map +1 -1
  49. package/dist/components/number-field/number-field.styles.js +6 -0
  50. package/dist/components/number-field.css +60 -1
  51. package/dist/components/pagination.css +6 -6
  52. package/dist/components/popover.css +15 -1
  53. package/dist/components/search-field/search-field.styles.d.ts +27 -0
  54. package/dist/components/search-field/search-field.styles.d.ts.map +1 -1
  55. package/dist/components/search-field/search-field.styles.js +6 -0
  56. package/dist/components/search-field.css +25 -1
  57. package/dist/components/segmented-control/index.d.ts +2 -0
  58. package/dist/components/segmented-control/index.d.ts.map +1 -0
  59. package/dist/components/segmented-control/index.js +2 -0
  60. package/dist/components/segmented-control/segmented-control.styles.d.ts +73 -0
  61. package/dist/components/segmented-control/segmented-control.styles.d.ts.map +1 -0
  62. package/dist/components/segmented-control/segmented-control.styles.js +27 -0
  63. package/dist/components/segmented-control.css +193 -0
  64. package/dist/components/select/select.styles.d.ts +33 -0
  65. package/dist/components/select/select.styles.d.ts.map +1 -1
  66. package/dist/components/select/select.styles.js +12 -0
  67. package/dist/components/select.css +31 -3
  68. package/dist/components/sidebar/index.d.ts +2 -0
  69. package/dist/components/sidebar/index.d.ts.map +1 -0
  70. package/dist/components/sidebar/index.js +2 -0
  71. package/dist/components/sidebar/sidebar.styles.d.ts +190 -0
  72. package/dist/components/sidebar/sidebar.styles.d.ts.map +1 -0
  73. package/dist/components/sidebar/sidebar.styles.js +52 -0
  74. package/dist/components/sidebar.css +510 -0
  75. package/dist/components/splitter/index.d.ts +2 -0
  76. package/dist/components/splitter/index.d.ts.map +1 -0
  77. package/dist/components/splitter/index.js +2 -0
  78. package/dist/components/splitter/splitter.styles.d.ts +61 -0
  79. package/dist/components/splitter/splitter.styles.d.ts.map +1 -0
  80. package/dist/components/splitter/splitter.styles.js +26 -0
  81. package/dist/components/splitter.css +241 -0
  82. package/dist/components/table.css +3 -3
  83. package/dist/components/tabs.css +2 -2
  84. package/dist/components/textarea/textarea.styles.d.ts +15 -0
  85. package/dist/components/textarea/textarea.styles.d.ts.map +1 -1
  86. package/dist/components/textarea/textarea.styles.js +6 -0
  87. package/dist/components/textarea.css +13 -1
  88. package/dist/components/toast.css +1 -1
  89. package/dist/components/toggle-button-group.css +7 -7
  90. package/dist/components/toggle-button.css +7 -11
  91. package/dist/components/toolbar.css +1 -1
  92. package/dist/components/tooltip.css +15 -2
  93. package/dist/components/virtualizer/index.d.ts +2 -0
  94. package/dist/components/virtualizer/index.d.ts.map +1 -0
  95. package/dist/components/virtualizer/index.js +2 -0
  96. package/dist/components/virtualizer/virtualizer.styles.d.ts +44 -0
  97. package/dist/components/virtualizer/virtualizer.styles.d.ts.map +1 -0
  98. package/dist/components/virtualizer/virtualizer.styles.js +15 -0
  99. package/dist/components/virtualizer.css +64 -0
  100. package/dist/index.js +5 -1
  101. package/dist/ropav.min.css +2 -2
  102. package/dist/themes/airbnb.css +5 -0
  103. package/dist/themes/all.css +1 -0
  104. package/dist/themes/coinbase.css +5 -0
  105. package/dist/themes/default.css +16 -4
  106. package/dist/themes/discord.css +5 -0
  107. package/dist/themes/hero.css +262 -0
  108. package/dist/themes/lavender.css +5 -0
  109. package/dist/themes/mint.css +5 -0
  110. package/dist/themes/netflix.css +5 -0
  111. package/dist/themes/rabbit.css +5 -0
  112. package/dist/themes/shared/theme.css +19 -2
  113. package/dist/themes/sky.css +5 -0
  114. package/dist/themes/spotify.css +5 -0
  115. package/dist/themes/uber.css +5 -0
  116. package/dist/utilities/index.css +27 -0
  117. package/package.json +1 -1
  118. package/src/components/autocomplete/autocomplete.styles.ts +12 -0
  119. package/src/components/color-input-group/color-input-group.styles.ts +10 -0
  120. package/src/components/combo-box/combo-box.styles.ts +12 -0
  121. package/src/components/date-input-group/date-input-group.styles.ts +10 -0
  122. package/src/components/index.ts +4 -0
  123. package/src/components/input/input.styles.ts +6 -0
  124. package/src/components/input-group/input-group.styles.ts +10 -0
  125. package/src/components/list-box/list-box.styles.ts +6 -0
  126. package/src/components/menu/menu.styles.ts +10 -0
  127. package/src/components/number-field/number-field.styles.ts +10 -0
  128. package/src/components/search-field/search-field.styles.ts +10 -0
  129. package/src/components/segmented-control/index.ts +1 -0
  130. package/src/components/segmented-control/segmented-control.styles.ts +37 -0
  131. package/src/components/select/select.styles.ts +12 -0
  132. package/src/components/sidebar/index.ts +1 -0
  133. package/src/components/sidebar/sidebar.styles.ts +94 -0
  134. package/src/components/splitter/index.ts +1 -0
  135. package/src/components/splitter/splitter.styles.ts +44 -0
  136. package/src/components/textarea/textarea.styles.ts +6 -0
  137. package/src/components/virtualizer/index.ts +1 -0
  138. package/src/components/virtualizer/virtualizer.styles.ts +15 -0
@@ -0,0 +1,241 @@
1
+ /* Splitter styles */
2
+
3
+ /*
4
+ * Orientation is a modifier class rather than a `[data-orientation]` descendant selector, and
5
+ * that is not a style preference. A splitter nests — a vertical group inside a panel of a
6
+ * horizontal one is the ordinary case — so `.splitter[data-orientation="horizontal"]
7
+ * .splitter__handle` would reach the inner group's handle as well as its own and lay it out on
8
+ * the wrong axis. Every rule below therefore sits on the part it styles.
9
+ *
10
+ * The modifier also buys the Storybook forced-colors sweep, which collects `[class*='--']` and a
11
+ * fixed state list that does not include `data-dragging`. Without one the two parts that paint
12
+ * anything — the handle and its grip — would never be audited.
13
+ */
14
+
15
+ .splitter {
16
+ @apply isolate flex h-full w-full;
17
+ }
18
+
19
+ .splitter--horizontal {
20
+ @apply flex-row;
21
+ }
22
+
23
+ .splitter--vertical {
24
+ @apply flex-col;
25
+ }
26
+
27
+ /* A flex item's automatic minimum is its content, so without `min-w-0`/`min-h-0` a panel holding
28
+ * a long word or a wide table cannot be dragged narrower than that content and the drag silently
29
+ * stops responding partway along the track.
30
+ *
31
+ * `flex-1` is the unmanaged fallback only. The component writes the whole `flex` shorthand inline;
32
+ * an inline `flex-basis` alone would leave this `flex-grow: 1` in place and the panel would grow
33
+ * straight back past the size it was given. */
34
+ .splitter__panel {
35
+ @apply relative min-h-0 min-w-0 flex-1 overflow-hidden;
36
+ }
37
+
38
+ /* The flex item is the gutter and paints nothing itself. The line you see is `::after`, absolutely
39
+ * positioned, which is what lets it thicken on hover without the gutter changing width and
40
+ * reflowing both panels by a pixel. `.slider__thumb::after` carries its knob the same way. */
41
+ .splitter__handle {
42
+ /* The gutter is the line, with nothing either side of it. Dead space inside the gutter shows up
43
+ * as a gap wherever a nested group's divider meets this one — the panel between them clips its own
44
+ * contents, so the inner line cannot reach across to close it. `1px` rather than a spacing step,
45
+ * the same hairline `separator.css` writes as `h-px`/`w-px`, and both the flex item and `::after`
46
+ * are measured from it so a retuned token cannot let the gap back in. */
47
+ --splitter-gutter: 1px;
48
+ /* The whole grab area, gutter included — a hairline is not a target anyone can hit, so the target
49
+ * part overhangs it and every hit test lands there. Held as the total rather than as the overhang
50
+ * because the total is the number that means something, and it is off the spacing grid for the
51
+ * same reason: what is being sized is a target, not a step.
52
+ *
53
+ * Under the 24px WCAG 2.5.8 asks for, resting on that rule's spacing exception instead — what
54
+ * flanks a divider is a panel, not another target, so no two targets' circles can meet here. The
55
+ * overhang is also panel edge that stops taking clicks, and a scrollbar sits exactly there, which
56
+ * is why this is kept tight rather than widened to the letter of the rule. */
57
+ --splitter-target: 15px;
58
+ /* The pill's short axis and its long one. It is positioned rather than laid out, so it straddles a
59
+ * gutter narrower than itself without the panels giving up a pixel. */
60
+ --splitter-grip-thickness: calc(var(--spacing) * 1);
61
+ --splitter-grip-length: calc(var(--spacing) * 6);
62
+ /* How long the pointer has to stay before the divider lights up. A grab area many times the width
63
+ * of the line is one a pointer crosses on its way somewhere else, and a divider that flares at
64
+ * every crossing reads as a twitch rather than an invitation. Waiting means only an approach that
65
+ * settles counts. */
66
+ --splitter-highlight-delay: 500ms;
67
+
68
+ @apply relative z-10 flex shrink-0 grow-0 items-center justify-center self-stretch;
69
+ @apply bg-transparent outline-none select-none no-highlight;
70
+
71
+ /* The gesture is ours; the browser must not also pan or scroll from a drag on this. */
72
+ @apply touch-none;
73
+
74
+ &::after {
75
+ @apply pointer-events-none absolute rounded-sm bg-separator content-[''];
76
+
77
+ /* Flattened to `Canvas` the divider stops existing rather than weakening — the whole part
78
+ * *is* its background, which is why `separator.css` restates its colour the same way. */
79
+ @media (forced-colors: active) {
80
+ background-color: CanvasText;
81
+ }
82
+
83
+ /**
84
+ * Transitions
85
+ * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
86
+ */
87
+ transition:
88
+ background-color 150ms var(--ease-out),
89
+ inline-size 150ms var(--ease-out),
90
+ block-size 150ms var(--ease-out);
91
+ @apply motion-reduce:transition-none;
92
+ }
93
+
94
+ &:hover::after,
95
+ &[data-hovered="true"]::after,
96
+ &[data-dragging="true"]::after {
97
+ @apply bg-accent;
98
+
99
+ /* `bg-separator` and `bg-accent` both flatten to `Canvas`, so without this the resting and
100
+ * active states are byte-identical under the mode and grabbing the handle shows nothing. */
101
+ @media (forced-colors: active) {
102
+ background-color: Highlight;
103
+ }
104
+ }
105
+
106
+ /* The grip answers to the same states as the line, and is reached as a direct child so a nested
107
+ * group's own grip is left alone. */
108
+ &:hover > .splitter__handle-grip,
109
+ &[data-hovered="true"] > .splitter__handle-grip,
110
+ &[data-dragging="true"] > .splitter__handle-grip {
111
+ @apply bg-accent;
112
+
113
+ @media (forced-colors: active) {
114
+ background-color: Highlight;
115
+ }
116
+ }
117
+
118
+ /* Delayed on the way in and immediate on the way out: the delay lives here rather than in the
119
+ * base rule, so leaving drops the highlight at once and a pointer that only passes through never
120
+ * starts the transition at all. It covers the thickening too — both are the same flare. */
121
+ &:hover::after,
122
+ &[data-hovered="true"]::after,
123
+ &:hover > .splitter__handle-grip,
124
+ &[data-hovered="true"] > .splitter__handle-grip {
125
+ transition-delay: var(--splitter-highlight-delay);
126
+ }
127
+
128
+ /* Once a drag is under way the intent is not in question, so it skips the wait. Last, because a
129
+ * drag usually starts from a hover and has to win. */
130
+ &[data-dragging="true"]::after,
131
+ &[data-dragging="true"] > .splitter__handle-grip {
132
+ transition-delay: 0ms;
133
+ }
134
+
135
+ &:focus-visible,
136
+ &[data-focus-visible="true"] {
137
+ @apply status-focused;
138
+ }
139
+
140
+ &[data-disabled="true"] {
141
+ @apply status-disabled;
142
+
143
+ /* `status-disabled` reaches `color` and `border-color`, and neither the line nor the grip is
144
+ * either of those. */
145
+ &::after,
146
+ & > .splitter__handle-grip {
147
+ @media (forced-colors: active) {
148
+ background-color: GrayText;
149
+ }
150
+ }
151
+ }
152
+ }
153
+
154
+ /* The invisible hit area — named for the target size it exists to reach, and kept apart from the
155
+ * grip because that one is the part you can see. A negative `inset` rather than a transparent
156
+ * border: forced colors turns a transparent *border-color* opaque — the trap `slider.css` documents
157
+ * at both ends of its track — and a bordered target would render as two solid blocks flanking every
158
+ * divider. `inset` has no such behaviour, so this needs no forced-colors rule of its own. */
159
+ .splitter__handle-target {
160
+ @apply absolute inset-0 bg-transparent;
161
+ }
162
+
163
+ /* The visible grab affordance, and only that — the gesture belongs to the handle, the hit area to
164
+ * the target. No insets: an absolutely positioned child of a flex container takes its static
165
+ * position from the container's own alignment, which is the same `items-center justify-center` that
166
+ * centres the line above. `drawer.css` carries its handle bar as a child element the same way.
167
+ *
168
+ * Sized from custom properties rather than utilities so a theme can retune the pill without
169
+ * restating both axes in both orientations. */
170
+ .splitter__handle-grip {
171
+ @apply pointer-events-none absolute rounded-full bg-separator;
172
+
173
+ /* The whole part *is* its background, so the mode flattening it onto the page removes the grip
174
+ * rather than weakening it — the same reason the line restates its colour. */
175
+ @media (forced-colors: active) {
176
+ background-color: CanvasText;
177
+ }
178
+
179
+ /**
180
+ * Transitions
181
+ * CRITICAL: motion-reduce must be AFTER transition for correct override specificity
182
+ */
183
+ transition: background-color 150ms var(--ease-out);
184
+ @apply motion-reduce:transition-none;
185
+ }
186
+
187
+ .splitter__handle-grip--horizontal {
188
+ inline-size: var(--splitter-grip-thickness);
189
+ block-size: var(--splitter-grip-length);
190
+ }
191
+
192
+ .splitter__handle-grip--vertical {
193
+ inline-size: var(--splitter-grip-length);
194
+ block-size: var(--splitter-grip-thickness);
195
+ }
196
+
197
+ /* A horizontal group puts its panels side by side, so the divider is a vertical line. */
198
+ .splitter__handle--horizontal {
199
+ @apply cursor-col-resize;
200
+
201
+ inline-size: var(--splitter-gutter);
202
+
203
+ &::after {
204
+ @apply inset-y-0;
205
+
206
+ inline-size: var(--splitter-gutter);
207
+ }
208
+
209
+ &:hover::after,
210
+ &[data-hovered="true"]::after,
211
+ &[data-dragging="true"]::after {
212
+ inline-size: calc(var(--splitter-gutter) * 2);
213
+ }
214
+
215
+ & > .splitter__handle-target {
216
+ inset-inline: calc((var(--splitter-target) - var(--splitter-gutter)) / -2);
217
+ }
218
+ }
219
+
220
+ /* A vertical group stacks its panels, so the divider is a horizontal line. */
221
+ .splitter__handle--vertical {
222
+ @apply cursor-row-resize;
223
+
224
+ block-size: var(--splitter-gutter);
225
+
226
+ &::after {
227
+ @apply inset-x-0;
228
+
229
+ block-size: var(--splitter-gutter);
230
+ }
231
+
232
+ &:hover::after,
233
+ &[data-hovered="true"]::after,
234
+ &[data-dragging="true"]::after {
235
+ block-size: calc(var(--splitter-gutter) * 2);
236
+ }
237
+
238
+ & > .splitter__handle-target {
239
+ inset-block: calc((var(--splitter-target) - var(--splitter-gutter)) / -2);
240
+ }
241
+ }
@@ -205,9 +205,9 @@
205
205
  border-end-end-radius: min(32px, var(--radius-2xl));
206
206
  }
207
207
 
208
- /* Virtualized: elements are divs, not tr/td. VirtualizerItem wrappers
209
- break :first-child/:last-child on rows and cells, so round the body
210
- itself and clip overflow instead. */
208
+ /* Virtualized: elements are divs, not tr/td, and only a window of the rows
209
+ is in the DOM, so :first-child/:last-child name the window's edges rather
210
+ than the table's. Round the body itself and clip overflow instead. */
211
211
  &:not(tbody) {
212
212
  @apply relative h-full overflow-clip;
213
213
  border-radius: min(32px, var(--radius-2xl));
@@ -121,7 +121,7 @@
121
121
 
122
122
  /* Individual tab */
123
123
  .tabs__tab {
124
- @apply relative flex h-8 w-full items-center justify-center rounded-3xl px-4 text-center text-sm font-medium text-muted outline-none no-highlight;
124
+ @apply relative flex h-8 w-full items-center justify-center rounded-component px-4 text-center text-sm font-medium text-muted outline-none no-highlight;
125
125
 
126
126
  z-index: 1;
127
127
  cursor: var(--cursor-interactive);
@@ -221,7 +221,7 @@
221
221
 
222
222
  /* Tab indicator - React Aria's SelectionIndicator */
223
223
  .tabs__indicator {
224
- @apply absolute start-0 top-0 size-full rounded-3xl bg-segment shadow-surface;
224
+ @apply absolute start-0 top-0 size-full rounded-component bg-segment shadow-surface;
225
225
 
226
226
  z-index: -1;
227
227
 
@@ -4,6 +4,11 @@ export declare const textAreaVariants: import("tailwind-variants").TVReturnType<
4
4
  false: "";
5
5
  true: "textarea--full-width";
6
6
  };
7
+ size: {
8
+ lg: "textarea--lg";
9
+ md: "";
10
+ sm: "textarea--sm";
11
+ };
7
12
  variant: {
8
13
  primary: "textarea--primary";
9
14
  secondary: "textarea--secondary";
@@ -13,6 +18,11 @@ export declare const textAreaVariants: import("tailwind-variants").TVReturnType<
13
18
  false: "";
14
19
  true: "textarea--full-width";
15
20
  };
21
+ size: {
22
+ lg: "textarea--lg";
23
+ md: "";
24
+ sm: "textarea--sm";
25
+ };
16
26
  variant: {
17
27
  primary: "textarea--primary";
18
28
  secondary: "textarea--secondary";
@@ -22,6 +32,11 @@ export declare const textAreaVariants: import("tailwind-variants").TVReturnType<
22
32
  false: "";
23
33
  true: "textarea--full-width";
24
34
  };
35
+ size: {
36
+ lg: "textarea--lg";
37
+ md: "";
38
+ sm: "textarea--sm";
39
+ };
25
40
  variant: {
26
41
  primary: "textarea--primary";
27
42
  secondary: "textarea--secondary";
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.styles.d.ts","sourceRoot":"","sources":["../../../src/components/textarea/textarea.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgB3B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"textarea.styles.d.ts","sourceRoot":"","sources":["../../../src/components/textarea/textarea.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsB3B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
@@ -4,6 +4,7 @@ const textAreaVariants = tv({
4
4
  base: "textarea",
5
5
  defaultVariants: {
6
6
  fullWidth: false,
7
+ size: "md",
7
8
  variant: "primary"
8
9
  },
9
10
  variants: {
@@ -11,6 +12,11 @@ const textAreaVariants = tv({
11
12
  false: "",
12
13
  true: "textarea--full-width"
13
14
  },
15
+ size: {
16
+ lg: "textarea--lg",
17
+ md: "",
18
+ sm: "textarea--sm"
19
+ },
14
20
  variant: {
15
21
  primary: "textarea--primary",
16
22
  secondary: "textarea--secondary"
@@ -1,6 +1,6 @@
1
1
  /* use textarea instead of text-area to avoid conflict with Tailwind `text-` prefix */
2
2
  .textarea {
3
- @apply rounded-field border bg-field px-3 py-2 text-base text-field-foreground shadow-field outline-none placeholder:text-field-placeholder sm:text-sm;
3
+ @apply rounded-field border bg-field px-3 field-line-md text-field-foreground shadow-field outline-none placeholder:text-field-placeholder;
4
4
 
5
5
  min-height: 38px;
6
6
 
@@ -102,3 +102,15 @@
102
102
  .textarea--full-width {
103
103
  @apply w-full;
104
104
  }
105
+
106
+ /* ==========================================================================
107
+ Size variants
108
+ ========================================================================== */
109
+
110
+ .textarea--sm {
111
+ @apply field-line-sm;
112
+ }
113
+
114
+ .textarea--lg {
115
+ @apply field-line-lg;
116
+ }
@@ -47,7 +47,7 @@
47
47
  inset-inline-end: 0;
48
48
 
49
49
  @apply pointer-events-auto flex flex-row items-start justify-start gap-1.5 bg-surface px-4 py-3 shadow-overlay;
50
- border-radius: min(32px, var(--radius-3xl));
50
+ border-radius: min(32px, var(--component-radius));
51
51
  }
52
52
 
53
53
  .toast--bottom,
@@ -38,32 +38,32 @@
38
38
 
39
39
  /* Apply border radius to first button (start edge) */
40
40
  .toggle-button-group--horizontal .toggle-button:first-child {
41
- @apply rounded-s-3xl;
41
+ @apply rounded-s-component;
42
42
  }
43
43
 
44
44
  /* Apply border radius to last button (end edge) */
45
45
  .toggle-button-group--horizontal .toggle-button:last-child {
46
- @apply rounded-e-3xl;
46
+ @apply rounded-e-component;
47
47
  }
48
48
 
49
49
  /* If only one button, apply both rounded edges */
50
50
  .toggle-button-group--horizontal .toggle-button:first-child:last-child {
51
- @apply rounded-3xl;
51
+ @apply rounded-component;
52
52
  }
53
53
 
54
54
  /* Apply border radius to first button (top edge) in vertical */
55
55
  .toggle-button-group--vertical .toggle-button:first-child {
56
- @apply rounded-t-3xl;
56
+ @apply rounded-t-component;
57
57
  }
58
58
 
59
59
  /* Apply border radius to last button (bottom edge) in vertical */
60
60
  .toggle-button-group--vertical .toggle-button:last-child {
61
- @apply rounded-b-3xl;
61
+ @apply rounded-b-component;
62
62
  }
63
63
 
64
64
  /* If only one button in vertical, apply all rounded edges */
65
65
  .toggle-button-group--vertical .toggle-button:first-child:last-child {
66
- @apply rounded-3xl;
66
+ @apply rounded-component;
67
67
  }
68
68
 
69
69
  /* Remove scale transform on active/pressed state for buttons in group */
@@ -127,7 +127,7 @@
127
127
 
128
128
  /* Restore border radius in detached mode */
129
129
  .toggle-button-group--detached .toggle-button {
130
- @apply rounded-3xl;
130
+ @apply rounded-component;
131
131
  }
132
132
 
133
133
  /* Hide separators in detached mode */
@@ -4,7 +4,7 @@
4
4
 
5
5
  /* Base styles */
6
6
  .toggle-button {
7
- @apply relative isolate inline-flex h-10 w-fit origin-center items-center justify-center gap-2 rounded-3xl px-4 text-sm font-medium whitespace-nowrap outline-none select-none no-highlight md:h-9;
7
+ @apply relative isolate inline-flex h-9 w-fit origin-center items-center justify-center gap-2 rounded-component px-4 text-sm font-medium whitespace-nowrap outline-none select-none no-highlight;
8
8
 
9
9
  /**
10
10
  * Transitions
@@ -91,7 +91,7 @@
91
91
 
92
92
  /* SVG icon styling */
93
93
  & svg {
94
- @apply pointer-events-none -mx-0.5 my-0.5 size-5 shrink-0 self-center sm:my-1 sm:size-4;
94
+ @apply pointer-events-none -mx-0.5 my-1 size-4 shrink-0 self-center;
95
95
  }
96
96
  }
97
97
 
@@ -100,11 +100,7 @@
100
100
  ========================================================================== */
101
101
 
102
102
  .toggle-button--sm {
103
- @apply h-9 px-3 md:h-8;
104
-
105
- & svg {
106
- @apply size-4;
107
- }
103
+ @apply h-8 px-3;
108
104
 
109
105
  &:active,
110
106
  &[data-pressed="true"] {
@@ -117,7 +113,7 @@
117
113
  }
118
114
 
119
115
  .toggle-button--lg {
120
- @apply h-11 text-base md:h-10;
116
+ @apply h-10 text-base;
121
117
 
122
118
  &:active,
123
119
  &[data-pressed="true"] {
@@ -147,13 +143,13 @@
147
143
  ========================================================================== */
148
144
 
149
145
  .toggle-button--icon-only {
150
- @apply w-10 p-0 md:w-9;
146
+ @apply w-9 p-0;
151
147
  }
152
148
 
153
149
  .toggle-button--icon-only.toggle-button--sm {
154
- @apply w-9 md:w-8;
150
+ @apply w-8;
155
151
  }
156
152
 
157
153
  .toggle-button--icon-only.toggle-button--lg {
158
- @apply w-11 md:w-10;
154
+ @apply w-10;
159
155
  }
@@ -28,7 +28,7 @@
28
28
 
29
29
  /* Attached variant */
30
30
  .toolbar--attached {
31
- @apply rounded-3xl bg-surface p-1 shadow-overlay;
31
+ @apply rounded-component bg-surface p-1 shadow-overlay;
32
32
 
33
33
  /* Forced Colors Mode flattens the fill onto the page and strips the shadow, so the container
34
34
  * stops having any shape and its contents sit loose on the page. */
@@ -3,7 +3,7 @@
3
3
  /* Base tooltip styles */
4
4
  .tooltip {
5
5
  @apply max-w-xs origin-(--trigger-anchor-point) bg-overlay p-2 text-xs break-all;
6
- border-radius: min(32px, var(--radius-xl));
6
+ border-radius: min(32px, var(--component-radius));
7
7
  box-shadow: var(--shadow-overlay);
8
8
 
9
9
  /* Entering animations */
@@ -40,10 +40,23 @@
40
40
 
41
41
  /* Arrow styling */
42
42
  & [data-slot="overlay-arrow"] {
43
- @apply stroke-border/40;
44
43
  fill: var(--overlay);
45
44
  }
46
45
 
46
+ /**
47
+ * With an arrow, the edge treatment moves off the body and onto the pair.
48
+ *
49
+ * The arrow is a second shape filled with the body's own colour, overlapping it so no seam can
50
+ * open between them — which leaves nothing for a per-shape edge to be right about: a shadow or
51
+ * hairline painted on the body alone stops at the join, and one painted on the arrow crosses
52
+ * it. `--overlay-edge` is a filter, and a filter sees the two shapes as one image, so whatever
53
+ * edge it draws follows their combined silhouette.
54
+ */
55
+ &:has([data-slot="tooltip-arrow"]) {
56
+ box-shadow: none;
57
+ filter: var(--overlay-edge, none);
58
+ }
59
+
47
60
  /* Arrow rotation based on placement */
48
61
  &[data-placement="bottom"] [data-slot="overlay-arrow"] {
49
62
  rotate: 180deg;
@@ -0,0 +1,2 @@
1
+ export * from "./virtualizer.styles";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/virtualizer/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { virtualizerVariants } from "./virtualizer.styles.js";
2
+ export { virtualizerVariants };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The parts a windowed collection draws for itself, whichever collection it is.
3
+ *
4
+ * Only the scrollbar so far: a table and a listbox hide the native one and draw this in its place,
5
+ * so a dragged thumb moves the rows and the scroll offset together.
6
+ */
7
+ export declare const virtualizerVariants: import("tailwind-variants").TVReturnType<{
8
+ [key: string]: {
9
+ [key: string]: {
10
+ scrollbar?: import("tailwind-variants").ClassValue;
11
+ scrollbarThumb?: import("tailwind-variants").ClassValue;
12
+ scrollbarTrack?: import("tailwind-variants").ClassValue;
13
+ } | import("tailwind-variants").ClassValue;
14
+ };
15
+ } | {
16
+ [x: string]: {
17
+ [x: string]: {
18
+ scrollbar?: import("tailwind-variants").ClassValue;
19
+ scrollbarThumb?: import("tailwind-variants").ClassValue;
20
+ scrollbarTrack?: import("tailwind-variants").ClassValue;
21
+ } | import("tailwind-variants").ClassValue;
22
+ };
23
+ } | {}, {
24
+ scrollbar: string;
25
+ scrollbarThumb: string;
26
+ scrollbarTrack: string;
27
+ }, undefined, {
28
+ [key: string]: {
29
+ [key: string]: {
30
+ scrollbar?: import("tailwind-variants").ClassValue;
31
+ scrollbarThumb?: import("tailwind-variants").ClassValue;
32
+ scrollbarTrack?: import("tailwind-variants").ClassValue;
33
+ } | import("tailwind-variants").ClassValue;
34
+ };
35
+ } | {}, {
36
+ scrollbar: string;
37
+ scrollbarThumb: string;
38
+ scrollbarTrack: string;
39
+ }, import("tailwind-variants").TVReturnTypeLike<unknown, {
40
+ scrollbar: string;
41
+ scrollbarThumb: string;
42
+ scrollbarTrack: string;
43
+ }>>;
44
+ //# sourceMappingURL=virtualizer.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualizer.styles.d.ts","sourceRoot":"","sources":["../../../src/components/virtualizer/virtualizer.styles.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAM9B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { tv } from "tailwind-variants";
2
+ //#region src/components/virtualizer/virtualizer.styles.ts
3
+ /**
4
+ * The parts a windowed collection draws for itself, whichever collection it is.
5
+ *
6
+ * Only the scrollbar so far: a table and a listbox hide the native one and draw this in its place,
7
+ * so a dragged thumb moves the rows and the scroll offset together.
8
+ */
9
+ const virtualizerVariants = tv({ slots: {
10
+ scrollbar: "virtualizer__scrollbar",
11
+ scrollbarThumb: "virtualizer__scrollbar-thumb",
12
+ scrollbarTrack: "virtualizer__scrollbar-track"
13
+ } });
14
+ //#endregion
15
+ export { virtualizerVariants };
@@ -0,0 +1,64 @@
1
+ /* ==========================================================================
2
+ Virtualizer — the parts a windowed collection draws for itself.
3
+ ========================================================================== */
4
+
5
+ /* --------------------------------------------------------------------------
6
+ Scrollbar — drawn by a windowed collection in place of the native one it
7
+ hides, so a dragged thumb moves the rows and the scroll offset together.
8
+ The component sizes and places each track; this only paints them and holds
9
+ the box they hang from.
10
+ -------------------------------------------------------------------------- */
11
+
12
+ /* A box of no height stuck to the top and inline start of the viewport, so a track placed at its
13
+ * edges sits at the viewport's edges however far the content has been scrolled along either axis.
14
+ * The component gives it the viewport's width. */
15
+ .virtualizer__scrollbar {
16
+ @apply sticky start-0 top-0 z-2 h-0;
17
+ }
18
+
19
+ .virtualizer__scrollbar-track {
20
+ @apply absolute touch-none select-none;
21
+ background-color: var(--scrollbar-track);
22
+
23
+ /* The content wrapper drops pointers mid-scroll so a fast scroll does not hover every row it
24
+ * passes. The track is what is being dragged, so it keeps taking them. */
25
+ pointer-events: auto;
26
+
27
+ &[data-orientation="vertical"] {
28
+ @apply end-0 top-0;
29
+ }
30
+
31
+ &[data-orientation="horizontal"] {
32
+ @apply start-0;
33
+ }
34
+ }
35
+
36
+ .virtualizer__scrollbar-thumb {
37
+ @apply absolute rounded-full;
38
+ background-color: var(--scrollbar-thumb);
39
+
40
+ &[data-orientation="vertical"] {
41
+ inset-inline: 2px;
42
+ }
43
+
44
+ &[data-orientation="horizontal"] {
45
+ inset-block: 2px;
46
+ }
47
+
48
+ @media (hover: hover) {
49
+ &:hover,
50
+ &[data-hovered="true"] {
51
+ background-color: color-mix(in oklch, var(--foreground) 25%, transparent);
52
+ }
53
+ }
54
+
55
+ &[data-pressed="true"] {
56
+ background-color: color-mix(in oklch, var(--foreground) 35%, transparent);
57
+ }
58
+
59
+ /* Forced Colors Mode replaces the translucent fill with the canvas, and the thumb vanishes. */
60
+ @media (forced-colors: active) {
61
+ forced-color-adjust: none;
62
+ background-color: ButtonText;
63
+ }
64
+ }