@auronui/styles 1.2.2 → 1.4.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 (98) hide show
  1. package/components/context-menu.css +44 -0
  2. package/components/editable.css +136 -0
  3. package/components/hover-card.css +68 -0
  4. package/components/index.css +9 -0
  5. package/components/input.css +53 -10
  6. package/components/menubar.css +80 -0
  7. package/components/month-range-picker.css +154 -0
  8. package/components/navigation-menu.css +144 -0
  9. package/components/time-picker.css +95 -0
  10. package/components/time-range-field.css +543 -0
  11. package/components/year-range-picker.css +155 -0
  12. package/dist/components/context-menu/context-menu.styles.d.ts +40 -0
  13. package/dist/components/context-menu/context-menu.styles.d.ts.map +1 -0
  14. package/dist/components/context-menu/context-menu.styles.js +11 -0
  15. package/dist/components/context-menu/context-menu.styles.js.map +1 -0
  16. package/dist/components/context-menu/index.d.ts +2 -0
  17. package/dist/components/context-menu/index.d.ts.map +1 -0
  18. package/dist/components/context-menu/index.js +2 -0
  19. package/dist/components/dropdown/dropdown.styles.d.ts +3 -3
  20. package/dist/components/editable/editable.styles.d.ts +85 -0
  21. package/dist/components/editable/editable.styles.d.ts.map +1 -0
  22. package/dist/components/editable/editable.styles.js +15 -0
  23. package/dist/components/editable/editable.styles.js.map +1 -0
  24. package/dist/components/editable/index.d.ts +2 -0
  25. package/dist/components/editable/index.d.ts.map +1 -0
  26. package/dist/components/editable/index.js +2 -0
  27. package/dist/components/hover-card/hover-card.styles.d.ts +34 -0
  28. package/dist/components/hover-card/hover-card.styles.d.ts.map +1 -0
  29. package/dist/components/hover-card/hover-card.styles.js +10 -0
  30. package/dist/components/hover-card/hover-card.styles.js.map +1 -0
  31. package/dist/components/hover-card/index.d.ts +2 -0
  32. package/dist/components/hover-card/index.d.ts.map +1 -0
  33. package/dist/components/hover-card/index.js +2 -0
  34. package/dist/components/index.d.ts +9 -0
  35. package/dist/components/index.d.ts.map +1 -1
  36. package/dist/components/menubar/index.d.ts +2 -0
  37. package/dist/components/menubar/index.d.ts.map +1 -0
  38. package/dist/components/menubar/index.js +2 -0
  39. package/dist/components/menubar/menubar.styles.d.ts +40 -0
  40. package/dist/components/menubar/menubar.styles.d.ts.map +1 -0
  41. package/dist/components/menubar/menubar.styles.js +11 -0
  42. package/dist/components/menubar/menubar.styles.js.map +1 -0
  43. package/dist/components/month-range-picker/index.d.ts +2 -0
  44. package/dist/components/month-range-picker/index.d.ts.map +1 -0
  45. package/dist/components/month-range-picker/index.js +2 -0
  46. package/dist/components/month-range-picker/month-range-picker.styles.d.ts +61 -0
  47. package/dist/components/month-range-picker/month-range-picker.styles.d.ts.map +1 -0
  48. package/dist/components/month-range-picker/month-range-picker.styles.js +21 -0
  49. package/dist/components/month-range-picker/month-range-picker.styles.js.map +1 -0
  50. package/dist/components/navigation-menu/index.d.ts +2 -0
  51. package/dist/components/navigation-menu/index.d.ts.map +1 -0
  52. package/dist/components/navigation-menu/index.js +2 -0
  53. package/dist/components/navigation-menu/navigation-menu.styles.d.ts +76 -0
  54. package/dist/components/navigation-menu/navigation-menu.styles.d.ts.map +1 -0
  55. package/dist/components/navigation-menu/navigation-menu.styles.js +17 -0
  56. package/dist/components/navigation-menu/navigation-menu.styles.js.map +1 -0
  57. package/dist/components/time-picker/index.d.ts +2 -0
  58. package/dist/components/time-picker/index.d.ts.map +1 -0
  59. package/dist/components/time-picker/index.js +2 -0
  60. package/dist/components/time-picker/time-picker.styles.d.ts +82 -0
  61. package/dist/components/time-picker/time-picker.styles.d.ts.map +1 -0
  62. package/dist/components/time-picker/time-picker.styles.js +35 -0
  63. package/dist/components/time-picker/time-picker.styles.js.map +1 -0
  64. package/dist/components/time-range-field/index.d.ts +2 -0
  65. package/dist/components/time-range-field/index.d.ts.map +1 -0
  66. package/dist/components/time-range-field/index.js +2 -0
  67. package/dist/components/time-range-field/time-range-field.styles.d.ts +310 -0
  68. package/dist/components/time-range-field/time-range-field.styles.d.ts.map +1 -0
  69. package/dist/components/time-range-field/time-range-field.styles.js +94 -0
  70. package/dist/components/time-range-field/time-range-field.styles.js.map +1 -0
  71. package/dist/components/year-range-picker/index.d.ts +2 -0
  72. package/dist/components/year-range-picker/index.d.ts.map +1 -0
  73. package/dist/components/year-range-picker/index.js +2 -0
  74. package/dist/components/year-range-picker/year-range-picker.styles.d.ts +61 -0
  75. package/dist/components/year-range-picker/year-range-picker.styles.d.ts.map +1 -0
  76. package/dist/components/year-range-picker/year-range-picker.styles.js +21 -0
  77. package/dist/components/year-range-picker/year-range-picker.styles.js.map +1 -0
  78. package/dist/index.js +10 -1
  79. package/package.json +33 -1
  80. package/src/components/context-menu/context-menu.styles.ts +13 -0
  81. package/src/components/context-menu/index.ts +1 -0
  82. package/src/components/editable/editable.styles.ts +24 -0
  83. package/src/components/editable/index.ts +1 -0
  84. package/src/components/hover-card/hover-card.styles.ts +12 -0
  85. package/src/components/hover-card/index.ts +1 -0
  86. package/src/components/index.ts +9 -0
  87. package/src/components/menubar/index.ts +1 -0
  88. package/src/components/menubar/menubar.styles.ts +13 -0
  89. package/src/components/month-range-picker/index.ts +1 -0
  90. package/src/components/month-range-picker/month-range-picker.styles.ts +30 -0
  91. package/src/components/navigation-menu/index.ts +1 -0
  92. package/src/components/navigation-menu/navigation-menu.styles.ts +19 -0
  93. package/src/components/time-picker/index.ts +1 -0
  94. package/src/components/time-picker/time-picker.styles.ts +35 -0
  95. package/src/components/time-range-field/index.ts +1 -0
  96. package/src/components/time-range-field/time-range-field.styles.ts +87 -0
  97. package/src/components/year-range-picker/index.ts +1 -0
  98. package/src/components/year-range-picker/year-range-picker.styles.ts +30 -0
@@ -0,0 +1,543 @@
1
+ /* ─── TimeRangeField ─────────────────────────────────────────────────────────
2
+ Mirrors date-range-field.css: same prop surface (variant/size/color/
3
+ labelPlacement/fullWidth/isInvalid/isDisabled/isReadonly), same
4
+ data-attribute contract, same floating-label up-state, same start/end
5
+ content slots. The only difference from DateRangeField is time-only
6
+ segments (no day/month/year), using Reka's `data-reka-time-field-segment`
7
+ attribute. Each pseudo-class is paired with its Reka UI data-attribute
8
+ counterpart.
9
+ */
10
+
11
+ .time-range-field {
12
+ @apply flex items-center gap-2 rounded-field border bg-field px-3 py-2 text-sm text-field-foreground shadow-field outline-none sm:text-xs;
13
+
14
+ height: 2.25rem;
15
+
16
+ border-width: var(--border-width-field);
17
+ border-color: var(--color-field-border);
18
+
19
+ transition:
20
+ background-color 300ms var(--ease-smooth),
21
+ border-color 300ms var(--ease-smooth),
22
+ box-shadow 300ms var(--ease-out);
23
+ @apply motion-reduce:transition-none;
24
+
25
+ @media (hover: hover) {
26
+ &:hover:not([data-focused="true"]),
27
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
28
+ @apply bg-field-hover;
29
+ border-color: var(--color-field-border-hover);
30
+ }
31
+ }
32
+
33
+ &.time-range-field--sm {
34
+ @apply gap-[0.40rem];
35
+ }
36
+
37
+ &.time-range-field--lg {
38
+ @apply gap-4;
39
+ }
40
+
41
+ &[data-focused="true"] {
42
+ @apply status-focused-field;
43
+ border-color: var(--color-field-border-focus);
44
+ background-color: var(--color-field-focus);
45
+ }
46
+
47
+ &[data-invalid="true"] {
48
+ @apply status-invalid-field;
49
+ background-color: var(--color-field-focus);
50
+ border-color: var(--color-field-border-invalid);
51
+ }
52
+
53
+ &[data-disabled="true"] {
54
+ @apply status-disabled;
55
+ }
56
+
57
+ &[data-readonly="true"] {
58
+ background-color: var(--color-default-100);
59
+ cursor: default;
60
+ }
61
+ }
62
+
63
+ /* ─── Variant modifiers ─────────────────────────────────────────────────── */
64
+
65
+ .time-range-field--flat {
66
+ @apply shadow-none bg-transparent;
67
+ border-color: transparent;
68
+
69
+ @media (hover: hover) {
70
+ &:hover:not([data-focused="true"]),
71
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
72
+ @apply bg-transparent;
73
+ }
74
+ }
75
+
76
+ &[data-focused="true"] {
77
+ @apply bg-transparent;
78
+ border-color: var(--color-field-border-focus);
79
+ }
80
+ }
81
+
82
+ .time-range-field--bordered {
83
+ @apply shadow-none;
84
+ background-color: transparent;
85
+ border-width: var(--border-width);
86
+ border-color: var(--border);
87
+
88
+ @media (hover: hover) {
89
+ &:hover:not([data-focused="true"]),
90
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
91
+ background-color: transparent;
92
+ border-color: color-mix(in oklab, var(--border) 80%, var(--foreground) 20%);
93
+ }
94
+ }
95
+
96
+ &[data-focused="true"] {
97
+ background-color: transparent;
98
+ border-color: var(--color-field-border-focus);
99
+ }
100
+ }
101
+
102
+ .time-range-field--faded {
103
+ @apply shadow-none;
104
+ background-color: var(--color-background-tertiary);
105
+ border-color: var(--color-border);
106
+
107
+ &[data-focused="true"] {
108
+ background-color: var(--color-background-tertiary);
109
+ border-color: var(--color-field-border-focus);
110
+ }
111
+ }
112
+
113
+ .time-range-field--underlined {
114
+ @apply rounded-none shadow-none bg-transparent !pl-0;
115
+ border-top: none;
116
+ border-left: none;
117
+ border-right: none;
118
+ border-bottom-width: var(--border-width);
119
+ border-bottom-color: var(--border);
120
+
121
+ @media (hover: hover) {
122
+ &:hover:not([data-focused="true"]),
123
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
124
+ background-color: transparent;
125
+ border-bottom-color: color-mix(in oklab, var(--border) 80%, var(--foreground) 20%);
126
+ }
127
+ }
128
+
129
+ &[data-focused="true"] {
130
+ @apply bg-transparent;
131
+ border-bottom-color: var(--color-field-border-focus);
132
+ --tw-ring-color: var(--focus);
133
+ box-shadow: 0 1.2px 0 0 var(--tw-ring-color, var(--color-field-border-focus));
134
+ }
135
+ }
136
+
137
+ .time-range-field--raised {
138
+ @apply shadow-md;
139
+ background-color: var(--snow);
140
+ border-color: transparent;
141
+
142
+ @media (hover: hover) {
143
+ &:hover:not([data-focused="true"]),
144
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
145
+ @apply shadow-lg;
146
+ background-color: var(--background);
147
+ border-color: transparent;
148
+ }
149
+ }
150
+
151
+ &[data-focused="true"] {
152
+ @apply shadow-lg;
153
+ background-color: var(--snow);
154
+ border-color: var(--color-field-border-focus);
155
+ }
156
+ }
157
+
158
+ /* ─── Size modifiers ─────────────────────────────────────────────────────── */
159
+
160
+ .time-range-field--sm {
161
+ @apply text-xs px-2 py-1;
162
+ height: 1.75rem;
163
+ }
164
+
165
+ .time-range-field--md {
166
+ /* No styles — md is the default size */
167
+ }
168
+
169
+ .time-range-field--lg {
170
+ @apply text-base px-4 py-2.5;
171
+ height: 2.75rem;
172
+ }
173
+
174
+ /* ─── Color modifiers ─────────────────────────────────────────────────────── */
175
+
176
+ .time-range-field--default {
177
+ --time-range-field-accent: var(--color-default-foreground);
178
+ accent-color: var(--time-range-field-accent);
179
+ }
180
+
181
+ .time-range-field--primary {
182
+ --time-range-field-accent: var(--color-primary);
183
+ accent-color: var(--time-range-field-accent);
184
+
185
+ &[data-focused="true"] {
186
+ border-color: var(--color-primary);
187
+ --tw-ring-color: var(--color-secondary);
188
+ }
189
+ }
190
+
191
+ .time-range-field--secondary {
192
+ --time-range-field-accent: var(--color-secondary);
193
+ accent-color: var(--time-range-field-accent);
194
+
195
+ &[data-focused="true"] {
196
+ border-color: var(--color-secondary);
197
+ --tw-ring-color: var(--color-secondary);
198
+ }
199
+ }
200
+
201
+ .time-range-field--success {
202
+ --time-range-field-accent: var(--color-success);
203
+ accent-color: var(--time-range-field-accent);
204
+
205
+ &[data-focused="true"] {
206
+ border-color: var(--color-success);
207
+ --tw-ring-color: var(--color-success);
208
+ }
209
+ }
210
+
211
+ .time-range-field--warning {
212
+ --time-range-field-accent: var(--color-warning);
213
+ accent-color: var(--time-range-field-accent);
214
+
215
+ &[data-focused="true"] {
216
+ border-color: var(--color-warning);
217
+ --tw-ring-color: var(--color-warning);
218
+ }
219
+ }
220
+
221
+ .time-range-field--danger {
222
+ --time-range-field-accent: var(--color-danger);
223
+ accent-color: var(--time-range-field-accent);
224
+
225
+ &[data-focused="true"] {
226
+ border-color: var(--color-danger);
227
+ --tw-ring-color: var(--color-danger);
228
+ }
229
+ }
230
+
231
+ /* ─── Underlined + color variant overrides ───────────────────────────────── */
232
+
233
+ .time-range-field--underlined.time-range-field--primary,
234
+ .time-range-field--underlined.time-range-field--secondary,
235
+ .time-range-field--underlined.time-range-field--success,
236
+ .time-range-field--underlined.time-range-field--warning,
237
+ .time-range-field--underlined.time-range-field--danger {
238
+ border-top: none;
239
+ border-left: none;
240
+ border-right: none;
241
+ border-bottom-width: var(--border-width);
242
+ }
243
+
244
+ /* ─── State modifiers ────────────────────────────────────────────────────── */
245
+
246
+ .time-range-field--invalid {
247
+ border-color: var(--color-danger) !important;
248
+ @apply status-invalid-field;
249
+ }
250
+
251
+ .time-range-field--disabled {
252
+ @apply status-disabled opacity-60 cursor-not-allowed;
253
+ }
254
+
255
+ .time-range-field--readonly {
256
+ background-color: var(--color-default-100);
257
+ cursor: default;
258
+ }
259
+
260
+ /* ─── Layout modifiers ───────────────────────────────────────────────────── */
261
+
262
+ .time-range-field--full-width {
263
+ @apply w-full;
264
+ }
265
+
266
+ /* ─── Segment list + segments + separator ───────────────────────────────── */
267
+
268
+ .time-range-field__segment-list {
269
+ @apply inline-flex items-center min-w-0 shrink-0;
270
+ @apply bg-transparent outline-none border-0 p-0 h-auto text-inherit;
271
+ gap: 0.05rem;
272
+ }
273
+
274
+ .time-range-field__segment-list[data-type="end"] {
275
+ flex: 1;
276
+ }
277
+
278
+ .time-range-field__separator {
279
+ @apply inline-flex items-center justify-center shrink-0 select-none px-1;
280
+ color: var(--color-field-placeholder);
281
+ }
282
+
283
+ .time-range-field__segment {
284
+ @apply inline-flex items-center justify-center rounded-sm px-0.5 outline-none;
285
+ color: var(--color-field-foreground);
286
+ font-variant-numeric: tabular-nums;
287
+ transition: background-color 300ms var(--ease-smooth), color 300ms var(--ease-smooth);
288
+ @apply motion-reduce:transition-none;
289
+
290
+ &[data-placeholder="true"] {
291
+ color: var(--color-field-placeholder);
292
+ }
293
+
294
+ &:focus,
295
+ &:focus-visible,
296
+ &[data-focused="true"] {
297
+ background-color: color-mix(in oklab, var(--time-range-field-accent, var(--color-focus)) 18%, transparent);
298
+ color: var(--color-foreground);
299
+ }
300
+
301
+ &[data-readonly="true"] {
302
+ cursor: default;
303
+ }
304
+
305
+ &[data-disabled="true"] {
306
+ @apply cursor-not-allowed opacity-60;
307
+ }
308
+ }
309
+
310
+ /* ─── Start / end content ────────────────────────────────────────────────── */
311
+
312
+ .time-range-field__start-content,
313
+ .time-range-field__end-content {
314
+ @apply inline-flex items-center justify-center shrink-0;
315
+ color: var(--color-field-placeholder);
316
+ }
317
+
318
+ .time-range-field__start-content svg,
319
+ .time-range-field__end-content svg {
320
+ @apply size-4;
321
+ }
322
+
323
+ /* ─── Label slot ─────────────────────────────────────────────────────────── */
324
+
325
+ .time-range-field__label {
326
+ @apply text-sm font-medium select-none;
327
+ color: var(--color-field-placeholder);
328
+ pointer-events: none;
329
+ transition:
330
+ transform 300ms var(--ease-smooth),
331
+ color 300ms var(--ease-smooth),
332
+ scale 300ms var(--ease-smooth);
333
+ @apply motion-reduce:transition-none;
334
+ }
335
+
336
+ /* ─── Floating label (inside the field) ──────────────────────────────────── */
337
+
338
+ .time-range-field--label-inside {
339
+ position: relative;
340
+ height: 3.5rem;
341
+ padding-top: 0;
342
+ padding-bottom: 0;
343
+ }
344
+
345
+ .time-range-field--label-inside.time-range-field--sm {
346
+ height: 2.5rem;
347
+ }
348
+
349
+ .time-range-field--label-inside.time-range-field--lg {
350
+ height: 4rem;
351
+ }
352
+
353
+ .time-range-field--label-inside .time-range-field__label {
354
+ position: absolute;
355
+ left: 0.75rem;
356
+ top: 50%;
357
+ transform: translateY(-50%);
358
+ transform-origin: left center;
359
+ font-size: var(--text-sm);
360
+ color: var(--color-field-placeholder);
361
+ }
362
+
363
+ .time-range-field--label-inside.time-range-field--underlined .time-range-field__label {
364
+ left: 0rem;
365
+ }
366
+
367
+ /* Push segment rows down so they don't sit under the floated label. */
368
+ .time-range-field--label-inside .time-range-field__segment-list,
369
+ .time-range-field--label-inside .time-range-field__separator {
370
+ padding-top: 1rem;
371
+ padding-bottom: 0;
372
+ }
373
+
374
+ /* Hide placeholder-segment tokens and the separator while the inside-floating
375
+ label is at rest. Only applies when hasLabel + labelPlacement === 'inside'. */
376
+ .time-range-field--label-inside:not([data-focused="true"]):not([data-filled="true"])
377
+ .time-range-field__segment,
378
+ .time-range-field--label-inside:not([data-focused="true"]):not([data-filled="true"])
379
+ .time-range-field__separator {
380
+ color: transparent;
381
+ }
382
+
383
+ .time-range-field--label-inside.time-range-field--default[data-focused="true"] .time-range-field__label {
384
+ color: var(--color-foreground);
385
+ }
386
+
387
+ /* Up-state: focused OR filled. */
388
+ .time-range-field--label-inside[data-focused="true"] .time-range-field__label,
389
+ .time-range-field--label-inside[data-filled="true"] .time-range-field__label {
390
+ transform: translateY(-110%) scale(0.85);
391
+ }
392
+
393
+ /* Start-content pushes the label's left anchor so it doesn't overlap the icon */
394
+ .time-range-field--label-inside:has(> .time-range-field__start-content) .time-range-field__label {
395
+ left: calc(0.75rem + 1rem + 0.5rem);
396
+ }
397
+ .time-range-field--label-inside.time-range-field--underlined:has(> .time-range-field__start-content) .time-range-field__label {
398
+ left: calc(1rem + 0.5rem);
399
+ }
400
+
401
+ /* Size-aware offsets for the inside variant */
402
+ .time-range-field--label-inside.time-range-field--sm .time-range-field__label {
403
+ font-size: var(--text-xs, 0.75rem);
404
+ left: 0.5rem;
405
+ }
406
+
407
+ .time-range-field--label-inside.time-range-field--sm:has(> .time-range-field__start-content) .time-range-field__label {
408
+ left: calc(0.5rem + 1rem + 0.4rem);
409
+ }
410
+
411
+ .time-range-field--label-inside.time-range-field--underlined.time-range-field--sm:has(> .time-range-field__start-content) .time-range-field__label {
412
+ left: calc(1rem + 0.4rem);
413
+ }
414
+
415
+ .time-range-field--label-inside.time-range-field--sm .time-range-field__segment-list,
416
+ .time-range-field--label-inside.time-range-field--sm .time-range-field__separator {
417
+ padding-top: 0.625rem;
418
+ }
419
+
420
+ .time-range-field--label-inside.time-range-field--sm[data-focused="true"] .time-range-field__label,
421
+ .time-range-field--label-inside.time-range-field--sm[data-filled="true"] .time-range-field__label {
422
+ transform: translateY(-100%) scale(0.8);
423
+ }
424
+
425
+ .time-range-field--label-inside.time-range-field--lg .time-range-field__label {
426
+ font-size: var(--text-base, 1rem);
427
+ left: 1rem;
428
+ }
429
+ .time-range-field--label-inside.time-range-field--lg:has(> .time-range-field__start-content) .time-range-field__label {
430
+ left: calc(1rem + 1rem + 1rem);
431
+ }
432
+ .time-range-field--label-inside.time-range-field--underlined.time-range-field--lg:has(> .time-range-field__start-content) .time-range-field__label {
433
+ left: calc(1rem + 1rem);
434
+ }
435
+
436
+ .time-range-field--label-inside.time-range-field--lg .time-range-field__segment-list,
437
+ .time-range-field--label-inside.time-range-field--lg .time-range-field__separator {
438
+ padding-top: 1.125rem;
439
+ }
440
+
441
+ /* Underlined + inside label: ensure the segment row has enough top padding */
442
+ .time-range-field--underlined.time-range-field--label-inside .time-range-field__segment-list,
443
+ .time-range-field--underlined.time-range-field--label-inside .time-range-field__separator {
444
+ padding-top: 1.125rem;
445
+ }
446
+
447
+ /* Underlined + sm/lg: label flush left */
448
+ .time-range-field--label-inside.time-range-field--underlined.time-range-field--sm .time-range-field__label,
449
+ .time-range-field--label-inside.time-range-field--underlined.time-range-field--lg .time-range-field__label {
450
+ left: 0rem;
451
+ }
452
+
453
+ /* Invalid state — label color flips to danger */
454
+ .time-range-field--label-inside.time-range-field--invalid .time-range-field__label {
455
+ color: var(--color-danger);
456
+ }
457
+
458
+ /* ─── Root wrapper (holds label + field + helper) ────────────────────────── */
459
+
460
+ .time-range-field-root {
461
+ display: flex;
462
+ flex-direction: column;
463
+ gap: 0.375rem;
464
+ }
465
+
466
+ .time-range-field-root--full-width {
467
+ @apply w-full;
468
+ }
469
+
470
+ .time-range-field-root--label-outside-left {
471
+ flex-direction: row;
472
+ align-items: flex-start;
473
+ gap: 0.75rem;
474
+ }
475
+
476
+ .time-range-field__main-wrapper {
477
+ display: flex;
478
+ flex-direction: column;
479
+ gap: 0.25rem;
480
+ flex: 1;
481
+ min-width: 0;
482
+ }
483
+
484
+ /* ─── Outside label ──────────────────────────────────────────────────────── */
485
+
486
+ .time-range-field-root--label-outside > .time-range-field__label,
487
+ .time-range-field-root--label-outside-left > .time-range-field__label {
488
+ position: static;
489
+ transform: none;
490
+ display: block;
491
+ pointer-events: auto;
492
+ font-size: var(--text-sm);
493
+ font-weight: 500;
494
+ color: var(--color-foreground);
495
+ }
496
+
497
+ .time-range-field-root--label-outside-left > .time-range-field__label {
498
+ padding-top: 0.5rem;
499
+ min-width: 5rem;
500
+ flex-shrink: 0;
501
+ }
502
+
503
+ .time-range-field-root--label-outside[data-invalid="true"] > .time-range-field__label,
504
+ .time-range-field-root--label-outside-left[data-invalid="true"] > .time-range-field__label {
505
+ color: var(--color-danger);
506
+ }
507
+
508
+ /* ─── Helper text (description / error message) ─────────────────────────── */
509
+
510
+ .time-range-field__helper-wrapper {
511
+ display: flex;
512
+ flex-direction: column;
513
+ gap: 0.125rem;
514
+ padding: 0 0.25rem;
515
+ }
516
+
517
+ .time-range-field__description {
518
+ @apply text-xs;
519
+ color: color-mix(in oklab, var(--color-foreground) 60%, transparent);
520
+ }
521
+
522
+ .time-range-field__error-message {
523
+ @apply text-xs;
524
+ color: var(--color-danger);
525
+ }
526
+
527
+ /* ─── Color up-state — floated label picks up the accent ────────────────── */
528
+
529
+ .time-range-field--label-inside.time-range-field--primary[data-focused="true"] .time-range-field__label {
530
+ color: var(--color-primary);
531
+ }
532
+ .time-range-field--label-inside.time-range-field--secondary[data-focused="true"] .time-range-field__label {
533
+ color: var(--color-secondary);
534
+ }
535
+ .time-range-field--label-inside.time-range-field--success[data-focused="true"] .time-range-field__label {
536
+ color: var(--color-success);
537
+ }
538
+ .time-range-field--label-inside.time-range-field--warning[data-focused="true"] .time-range-field__label {
539
+ color: var(--color-warning);
540
+ }
541
+ .time-range-field--label-inside.time-range-field--danger[data-focused="true"] .time-range-field__label {
542
+ color: var(--color-danger);
543
+ }
@@ -0,0 +1,155 @@
1
+ /* =============================================================================
2
+ * YearRangePicker Component Styles
3
+ *
4
+ * A single 3x4 year grid for contiguous year-range selection.
5
+ * Density, typography, and cell layout mirror `.calendar__year-cell`
6
+ * (Calendar's year drill-up view, also shared by CalendarYearPicker) so this
7
+ * looks visually consistent outside of range-specific track/cap styling,
8
+ * which is adapted from `.range-calendar__cell`'s day-range treatment
9
+ * (simplified: year cells are single self-contained elements, not a
10
+ * <td>-wrapped circle, so no `:has()` targeting or row-wraparound
11
+ * corner-smoothing is needed). The aspect-[7/6] grid-box ratio matches
12
+ * `.calendar__year-grid` (calendar.css), confirming this is this codebase's
13
+ * deliberate convention for 3x4 picker grids, not an inherited mistake.
14
+ * ============================================================================= */
15
+
16
+ .year-range-picker {
17
+ @apply w-64 max-w-full text-xs;
18
+
19
+ container-type: inline-size;
20
+ }
21
+
22
+ /* -----------------------------------------------------------------------------
23
+ * Header
24
+ * -------------------------------------------------------------------------- */
25
+ .year-range-picker__header {
26
+ @apply flex items-center justify-between px-0.5 pb-1;
27
+ }
28
+
29
+ .year-range-picker__heading {
30
+ @apply flex flex-1 items-center justify-center text-center text-xs font-medium;
31
+ }
32
+
33
+ .year-range-picker__nav-button {
34
+ @apply flex size-6 items-center justify-center rounded-full text-accent;
35
+
36
+ will-change: scale;
37
+ transition:
38
+ transform 300ms var(--ease-out),
39
+ background-color 300ms var(--ease-out),
40
+ box-shadow 300ms var(--ease-out),
41
+ opacity 300ms var(--ease-out);
42
+ @apply transform-gpu motion-reduce:transition-none;
43
+
44
+ cursor: var(--cursor-interactive);
45
+
46
+ @media (hover: hover) {
47
+ &:hover,
48
+ &[data-hovered="true"] {
49
+ @apply bg-default text-accent;
50
+ }
51
+ }
52
+
53
+ &:active,
54
+ &[data-pressed="true"] {
55
+ transform: scale(0.95);
56
+ }
57
+
58
+ &:focus-visible,
59
+ &[data-focus-visible="true"] {
60
+ @apply status-focused;
61
+ }
62
+
63
+ &:disabled,
64
+ &[data-disabled] {
65
+ @apply status-disabled;
66
+ }
67
+ }
68
+
69
+ .year-range-picker__nav-button-icon {
70
+ @apply size-3.5;
71
+ }
72
+
73
+ /* -----------------------------------------------------------------------------
74
+ * Grid
75
+ * -------------------------------------------------------------------------- */
76
+ .year-range-picker__grid {
77
+ display: grid;
78
+ grid-template-columns: repeat(3, 1fr);
79
+ grid-template-rows: repeat(4, 1fr);
80
+ border-collapse: collapse;
81
+ @apply aspect-[7/6] w-full;
82
+ }
83
+
84
+ .year-range-picker__grid-body {
85
+ display: contents;
86
+
87
+ & > tr {
88
+ display: contents;
89
+ place-items: center;
90
+
91
+ & > td {
92
+ display: flex;
93
+ align-items: center;
94
+ justify-content: center;
95
+ padding: 0.5rem;
96
+ }
97
+ }
98
+ }
99
+
100
+ .year-range-picker__grid-row {
101
+ display: contents;
102
+ }
103
+
104
+ /* -----------------------------------------------------------------------------
105
+ * Cell
106
+ * -------------------------------------------------------------------------- */
107
+ .year-range-picker__cell {
108
+ @apply relative m-0.5 flex size-auto items-center justify-center rounded-lg text-center text-xs font-medium outline-none no-highlight;
109
+ will-change: scale;
110
+ transition:
111
+ transform 300ms var(--ease-out),
112
+ box-shadow 300ms var(--ease-out),
113
+ background-color 300ms var(--ease-out);
114
+ @apply transform-gpu motion-reduce:transition-none;
115
+ cursor: var(--cursor-interactive);
116
+
117
+ @media (hover: hover) {
118
+ &:hover:not([data-selected]),
119
+ &[data-hovered="true"]:not([data-selected]) {
120
+ @apply bg-default;
121
+ }
122
+ }
123
+
124
+ &:active,
125
+ &[data-pressed="true"] {
126
+ transform: scale(0.95);
127
+ }
128
+
129
+ &:focus-visible,
130
+ &[data-focus-visible="true"] {
131
+ @apply status-focused;
132
+ }
133
+
134
+ /* Range track (middle segment) — any year within the range, including caps */
135
+ &[data-selected] {
136
+ @apply rounded-none bg-accent-soft;
137
+ }
138
+
139
+ /* Range caps (start/end) — solid accent fill, rounded */
140
+ &[data-selection-start],
141
+ &[data-selection-end] {
142
+ @apply rounded-lg bg-accent text-accent-foreground;
143
+ }
144
+
145
+ &:disabled,
146
+ &[data-disabled] {
147
+ @apply status-disabled;
148
+
149
+ text-decoration: line-through;
150
+ }
151
+
152
+ &[data-unavailable] {
153
+ @apply status-disabled;
154
+ }
155
+ }