@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,44 @@
1
+ /* ==========================================================================
2
+ ContextMenu
3
+
4
+ Right-click menu. Item/section-level styling (.menu, .menu-item,
5
+ .menu-section) is reused directly from the shared Dropdown/menu styles —
6
+ see menu.css, menu-item.css, menu-section.css. Only content positioning/
7
+ animation is specific to ContextMenu, adapted verbatim from
8
+ .dropdown__popover since floating-ui behavior is identical; the only
9
+ difference between Dropdown and ContextMenu is how each is triggered
10
+ (click vs. right-click), not how the resulting menu is positioned/styled.
11
+ ========================================================================== */
12
+
13
+ .context-menu {
14
+ @apply contents;
15
+ }
16
+
17
+ .context-menu__trigger {
18
+ @apply inline-block;
19
+ }
20
+
21
+ /* Positioning, sizing, and open/close animations — visuals come from card classes */
22
+ .context-menu__popover {
23
+ z-index: var(--z-popover);
24
+ @apply max-w-[48svw] origin-(--trigger-anchor-point) scroll-py-1 overflow-y-auto overscroll-contain md:min-w-55;
25
+ @apply will-change-[opacity,transform];
26
+
27
+ &:focus-visible:not(:focus),
28
+ &[data-focus-visible="true"] {
29
+ @apply outline-none;
30
+ }
31
+
32
+ &[data-state="open"] {
33
+ @apply animate-in duration-200 ease-smooth fade-in-0 zoom-in-95;
34
+
35
+ &[data-side="top"] { @apply slide-in-from-bottom-1; }
36
+ &[data-side="bottom"] { @apply slide-in-from-top-1; }
37
+ &[data-side="left"] { @apply slide-in-from-right-1; }
38
+ &[data-side="right"] { @apply slide-in-from-left-1; }
39
+ }
40
+
41
+ &[data-state="closed"] {
42
+ @apply animate-out duration-150 ease-smooth zoom-out-95 fade-out;
43
+ }
44
+ }
@@ -0,0 +1,136 @@
1
+ /* =============================================================================
2
+ * Editable Component Styles
3
+ *
4
+ * Click/double-click-to-edit inline text. Preview state visually matches
5
+ * Text's base treatment (readable text, no box). Edit state visually matches
6
+ * Input's field-box treatment (border-field, bg-field, focus ring), applied
7
+ * directly to the bare <input> element since Editable has no separate
8
+ * wrapper box the way Input does.
9
+ * ============================================================================= */
10
+
11
+ .editable {
12
+ @apply inline-flex items-center gap-1.5;
13
+ }
14
+
15
+ .editable__area {
16
+ @apply relative inline-flex items-center;
17
+ }
18
+
19
+ /* -----------------------------------------------------------------------------
20
+ * Preview (read-only text display)
21
+ * -------------------------------------------------------------------------- */
22
+ .editable__preview {
23
+ @apply inline-block rounded-md px-1 py-0.5 text-sm text-foreground outline-none;
24
+ cursor: var(--cursor-interactive);
25
+
26
+ transition:
27
+ background-color 300ms var(--ease-smooth),
28
+ box-shadow 300ms var(--ease-out);
29
+ @apply motion-reduce:transition-none;
30
+
31
+ @media (hover: hover) {
32
+ &:hover {
33
+ @apply bg-default;
34
+ }
35
+ }
36
+
37
+ &:focus-visible {
38
+ @apply status-focused;
39
+ }
40
+
41
+ &[data-empty] {
42
+ @apply text-muted;
43
+ }
44
+ }
45
+
46
+ /* -----------------------------------------------------------------------------
47
+ * Input (edit-mode field)
48
+ * -------------------------------------------------------------------------- */
49
+ .editable__input {
50
+ @apply rounded-field border bg-field px-2 py-0.5 text-sm text-field-foreground shadow-field outline-none;
51
+
52
+ border-width: var(--border-width-field);
53
+ border-color: var(--color-field-border);
54
+
55
+ transition:
56
+ background-color 300ms var(--ease-smooth),
57
+ border-color 300ms var(--ease-smooth),
58
+ box-shadow 300ms var(--ease-out);
59
+ @apply motion-reduce:transition-none;
60
+
61
+ &:focus {
62
+ @apply status-focused-field;
63
+ border-color: var(--color-field-border-focus);
64
+ background-color: var(--color-field-focus);
65
+ }
66
+
67
+ &[data-disabled] {
68
+ @apply status-disabled;
69
+ }
70
+
71
+ &[data-readonly] {
72
+ background-color: var(--color-default-100);
73
+ cursor: default;
74
+ }
75
+ }
76
+
77
+ /* -----------------------------------------------------------------------------
78
+ * Triggers (edit / submit / cancel)
79
+ * -------------------------------------------------------------------------- */
80
+ .editable__edit-trigger,
81
+ .editable__submit-trigger,
82
+ .editable__cancel-trigger {
83
+ @apply relative isolate inline-flex size-6 shrink-0 items-center justify-center rounded-full bg-default text-muted no-highlight;
84
+
85
+ cursor: var(--cursor-interactive);
86
+
87
+ transition:
88
+ transform 300ms var(--ease-out-quart),
89
+ color 300ms var(--ease-out),
90
+ background-color 300ms var(--ease-out),
91
+ box-shadow 300ms var(--ease-out);
92
+ @apply transform-gpu motion-reduce:transition-none;
93
+
94
+ @media (hover: hover) {
95
+ &:hover {
96
+ @apply bg-default-hover;
97
+ }
98
+ }
99
+
100
+ &:active {
101
+ transform: scale(0.93);
102
+ }
103
+
104
+ &:focus-visible {
105
+ @apply status-focused;
106
+ }
107
+
108
+ &:disabled,
109
+ &[data-disabled] {
110
+ @apply status-disabled;
111
+ }
112
+
113
+ & svg {
114
+ @apply pointer-events-none size-3.5 shrink-0;
115
+ }
116
+ }
117
+
118
+ .editable__submit-trigger {
119
+ @apply text-success;
120
+
121
+ @media (hover: hover) {
122
+ &:hover {
123
+ @apply bg-success/10;
124
+ }
125
+ }
126
+ }
127
+
128
+ .editable__cancel-trigger {
129
+ @apply text-danger;
130
+
131
+ @media (hover: hover) {
132
+ &:hover {
133
+ @apply bg-danger/10;
134
+ }
135
+ }
136
+ }
@@ -0,0 +1,68 @@
1
+ /* HoverCard component styles */
2
+
3
+ /* Base hover card styles */
4
+ .hover-card {
5
+ @apply origin-(--trigger-anchor-point) rounded-3xl bg-overlay p-0 text-sm;
6
+ z-index: var(--z-popover);
7
+ box-shadow: var(--shadow-overlay);
8
+
9
+ /* Entering animations */
10
+ &[data-state="open"] {
11
+ @apply animate-in duration-300 ease-smooth fade-in-0 zoom-in-90;
12
+
13
+ /* Placement-specific translations (Reka sets data-side, not data-placement) */
14
+ &[data-side="top"] {
15
+ @apply slide-in-from-bottom-1;
16
+ }
17
+
18
+ &[data-side="bottom"] {
19
+ @apply slide-in-from-top-1;
20
+ }
21
+
22
+ &[data-side="left"] {
23
+ @apply slide-in-from-right-1;
24
+ }
25
+
26
+ &[data-side="right"] {
27
+ @apply slide-in-from-left-1;
28
+ }
29
+ }
30
+
31
+ /* Exiting animations */
32
+ &[data-state="closed"] {
33
+ @apply animate-out duration-300 ease-smooth zoom-out-95 fade-out;
34
+ }
35
+
36
+ &,
37
+ & {
38
+ @apply will-change-[opacity,transform];
39
+ }
40
+
41
+ /* Arrow styling */
42
+ & [data-slot="hover-card-overlay-arrow"] {
43
+ fill: var(--overlay);
44
+ }
45
+
46
+ /* Arrow rotation based on placement (Reka sets data-side, not data-placement) */
47
+ &[data-side="bottom"] [data-slot="hover-card-overlay-arrow"] {
48
+ rotate: 180deg;
49
+ }
50
+
51
+ &[data-side="left"] [data-slot="hover-card-overlay-arrow"] {
52
+ rotate: -90deg;
53
+ }
54
+
55
+ &[data-side="right"] [data-slot="hover-card-overlay-arrow"] {
56
+ rotate: 90deg;
57
+ }
58
+ }
59
+
60
+ .hover-card__trigger {
61
+ @apply inline-block;
62
+ cursor: var(--cursor-interactive);
63
+
64
+ &:focus-visible:not(:focus),
65
+ &[data-focus-visible="true"] {
66
+ @apply status-focused;
67
+ }
68
+ }
@@ -28,6 +28,7 @@
28
28
  @import "./collapsible-group.css";
29
29
  @import "./collapsible.css";
30
30
  @import "./link.css";
31
+ @import "./navigation-menu.css";
31
32
  @import "./pagination.css";
32
33
  @import "./tabs.css";
33
34
 
@@ -43,6 +44,8 @@
43
44
  /* ------------------------------------------------------------------------------------------------
44
45
  * Collections
45
46
  * ------------------------------------------------------------------------------------------------ */
47
+ @import "./context-menu.css";
48
+ @import "./menubar.css";
46
49
  @import "./dropdown.css";
47
50
  @import "./list-box-item.css";
48
51
  @import "./list-box-section.css";
@@ -95,6 +98,7 @@
95
98
  * ------------------------------------------------------------------------------------------------ */
96
99
  @import "./checkbox-group.css";
97
100
  @import "./checkbox.css";
101
+ @import "./editable.css";
98
102
  @import "./fieldset.css";
99
103
  @import "./input-otp.css";
100
104
  @import "./input.css";
@@ -108,10 +112,14 @@
108
112
  * ------------------------------------------------------------------------------------------------ */
109
113
  @import "./calendar.css";
110
114
  @import "./range-calendar.css";
115
+ @import "./month-range-picker.css";
116
+ @import "./year-range-picker.css";
111
117
  @import "./calendar-year-picker.css";
112
118
  @import "./date-input.css";
113
119
  @import "./date-range-field.css";
114
120
  @import "./time-field.css";
121
+ @import "./time-picker.css";
122
+ @import "./time-range-field.css";
115
123
  @import "./date-picker.css";
116
124
  @import "./date-range-picker.css";
117
125
  @import "./date-time-picker.css";
@@ -134,6 +142,7 @@
134
142
  * ------------------------------------------------------------------------------------------------ */
135
143
  @import "./alert-dialog.css";
136
144
  @import "./drawer.css";
145
+ @import "./hover-card.css";
137
146
  @import "./modal.css";
138
147
  @import "./popover.css";
139
148
  @import "./tooltip.css";
@@ -18,8 +18,8 @@
18
18
  @apply motion-reduce:transition-none;
19
19
 
20
20
  @media (hover: hover) {
21
- &:has(> input:hover):not(:focus-within),
22
- &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
21
+ &:has(> input:hover):not(:focus-within):not(:has(> input:-webkit-autofill)),
22
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]):not(:has(> input:-webkit-autofill)) {
23
23
  @apply bg-field-hover;
24
24
  border-color: var(--color-field-border-hover);
25
25
  }
@@ -65,6 +65,29 @@
65
65
  background-color: var(--color-default-100);
66
66
  cursor: default;
67
67
  }
68
+
69
+ /*
70
+ * Autofilled state — browsers only ever apply :-webkit-autofill styling to
71
+ * the <input> itself, never to sibling elements like the clear/password
72
+ * toggle buttons (whose own background is transparent, see .input__clear-button
73
+ * / .input__password-toggle below). Mirroring the same tint here on the
74
+ * wrapper — using the same :has(> input:pseudo) idiom as every other state
75
+ * above — makes it spread across the entire bordered box, icons included,
76
+ * instead of stopping at the text portion.
77
+ */
78
+ &:has(> input:-webkit-autofill) {
79
+ /*
80
+ * srgb, not oklch: --color-field resolves to a fully achromatic white
81
+ * (oklch(100% 0 0)) in the default theme, and mixing a saturated
82
+ * chromatic color into a chroma-0 endpoint in a polar space like oklch
83
+ * is a known cross-browser gotcha — at low percentages the result's hue
84
+ * can drift unpredictably (observed rendering pink instead of blue)
85
+ * depending on how each engine handles "powerless hue" and gamut
86
+ * mapping. Plain per-channel srgb blending has no hue component to
87
+ * drift, so the result is a predictable pale blue everywhere.
88
+ */
89
+ background-color: color-mix(in srgb, #006fee 8%, var(--color-field, white));
90
+ }
68
91
  }
69
92
 
70
93
  /* ─── Variant modifiers ─────────────────────────────────────────────────────── */
@@ -75,8 +98,8 @@
75
98
  border-color: transparent;
76
99
 
77
100
  @media (hover: hover) {
78
- &:has(> input:hover):not(:focus-within),
79
- &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
101
+ &:has(> input:hover):not(:focus-within):not(:has(> input:-webkit-autofill)),
102
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]):not(:has(> input:-webkit-autofill)) {
80
103
  @apply bg-transparent;
81
104
  }
82
105
  }
@@ -96,8 +119,8 @@
96
119
  border-color: var(--border);
97
120
 
98
121
  @media (hover: hover) {
99
- &:has(> input:hover):not(:focus-within),
100
- &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
122
+ &:has(> input:hover):not(:focus-within):not(:has(> input:-webkit-autofill)),
123
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]):not(:has(> input:-webkit-autofill)) {
101
124
  background-color: transparent;
102
125
  border-color: color-mix(in oklab, var(--border) 80%, var(--foreground) 20%);
103
126
  }
@@ -133,8 +156,8 @@
133
156
  border-bottom-color: var(--border);
134
157
 
135
158
  @media (hover: hover) {
136
- &:has(> input:hover):not(:focus-within),
137
- &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
159
+ &:has(> input:hover):not(:focus-within):not(:has(> input:-webkit-autofill)),
160
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]):not(:has(> input:-webkit-autofill)) {
138
161
  background-color: transparent;
139
162
  border-bottom-color: color-mix(in oklab, var(--border) 80%, var(--foreground) 20%);
140
163
  }
@@ -156,8 +179,8 @@
156
179
  border-color: transparent;
157
180
 
158
181
  @media (hover: hover) {
159
- &:has(> input:hover):not(:focus-within),
160
- &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]) {
182
+ &:has(> input:hover):not(:focus-within):not(:has(> input:-webkit-autofill)),
183
+ &[data-hovered="true"]:not([data-focused="true"]):not([data-focus-visible="true"]):not(:has(> input:-webkit-autofill)) {
161
184
  @apply shadow-lg;
162
185
  background-color: var(--background);
163
186
  border-color: transparent;
@@ -316,6 +339,26 @@
316
339
  outline: none;
317
340
  box-shadow: none;
318
341
  }
342
+
343
+ /*
344
+ * Autofill indicator tint — light-blue accent, matching the .input
345
+ * wrapper's :has(> input:-webkit-autofill) rule above so the whole
346
+ * bordered box (icons included) shows one consistent color instead of
347
+ * stopping at the text portion. srgb, not oklch: --color-field resolves
348
+ * to a fully achromatic white in the default theme, and color-mix in a
349
+ * polar space like oklch with a chroma-0 endpoint is a known cross-browser
350
+ * gotcha — the resulting hue can drift unpredictably at low percentages
351
+ * (observed rendering pink instead of blue). Plain srgb blending has no
352
+ * hue component to drift.
353
+ */
354
+ &:-webkit-autofill,
355
+ &:-webkit-autofill:hover,
356
+ &:-webkit-autofill:focus {
357
+ -webkit-box-shadow: 0 0 0px 1000px color-mix(in srgb, #006fee 8%, var(--color-field, white)) inset;
358
+ box-shadow: 0 0 0px 1000px color-mix(in srgb, #006fee 8%, var(--color-field, white)) inset;
359
+ -webkit-text-fill-color: var(--color-field-foreground);
360
+ caret-color: var(--color-field-foreground);
361
+ }
319
362
  }
320
363
 
321
364
  /* Underlined: no horizontal padding on the input — underline spans edge-to-edge */
@@ -0,0 +1,80 @@
1
+ /* ==========================================================================
2
+ Menubar
3
+
4
+ App-style top menu bar (File/Edit/View...). Item/section-level styling
5
+ (.menu, .menu-item, .menu-section) is reused directly from the shared
6
+ Dropdown/ContextMenu styles — see menu.css, menu-item.css, menu-section.css.
7
+ `root` adapts Toolbar's horizontal bar layout; `popover` is adapted
8
+ verbatim from context-menu.css/dropdown.css (identical floating-ui
9
+ behavior — the only difference between these three components is how
10
+ each is triggered, not how the resulting menu is positioned/styled);
11
+ `trigger` is genuinely new since Menubar triggers render real, visible
12
+ buttons by default (unlike Dropdown/ContextMenu, whose Auron wrappers
13
+ apply no class to their own — typically asChild-wrapped — triggers).
14
+ ========================================================================== */
15
+
16
+ .menubar {
17
+ @apply flex w-fit items-center gap-1 rounded-lg bg-surface p-1;
18
+ }
19
+
20
+ /* -----------------------------------------------------------------------------
21
+ * Trigger
22
+ * -------------------------------------------------------------------------- */
23
+ .menubar__trigger {
24
+ @apply inline-flex h-8 items-center rounded-md px-3 text-sm font-medium text-foreground outline-none select-none;
25
+
26
+ cursor: var(--cursor-interactive);
27
+
28
+ transition:
29
+ background-color 300ms var(--ease-smooth),
30
+ color 300ms var(--ease-smooth);
31
+ @apply motion-reduce:transition-none;
32
+
33
+ @media (hover: hover) {
34
+ &:hover {
35
+ @apply bg-default;
36
+ }
37
+ }
38
+
39
+ &:focus-visible,
40
+ &[data-focus-visible="true"] {
41
+ @apply status-focused;
42
+ }
43
+
44
+ &[data-state="open"],
45
+ &[data-highlighted] {
46
+ @apply bg-default;
47
+ }
48
+
49
+ &:disabled,
50
+ &[data-disabled] {
51
+ @apply status-disabled;
52
+ }
53
+ }
54
+
55
+ /* -----------------------------------------------------------------------------
56
+ * Content positioning, sizing, and open/close animations
57
+ * -------------------------------------------------------------------------- */
58
+ .menubar__popover {
59
+ z-index: var(--z-popover);
60
+ @apply max-w-[48svw] origin-(--trigger-anchor-point) scroll-py-1 overflow-y-auto overscroll-contain md:min-w-55;
61
+ @apply will-change-[opacity,transform];
62
+
63
+ &:focus-visible:not(:focus),
64
+ &[data-focus-visible="true"] {
65
+ @apply outline-none;
66
+ }
67
+
68
+ &[data-state="open"] {
69
+ @apply animate-in duration-200 ease-smooth fade-in-0 zoom-in-95;
70
+
71
+ &[data-side="top"] { @apply slide-in-from-bottom-1; }
72
+ &[data-side="bottom"] { @apply slide-in-from-top-1; }
73
+ &[data-side="left"] { @apply slide-in-from-right-1; }
74
+ &[data-side="right"] { @apply slide-in-from-left-1; }
75
+ }
76
+
77
+ &[data-state="closed"] {
78
+ @apply animate-out duration-150 ease-smooth zoom-out-95 fade-out;
79
+ }
80
+ }
@@ -0,0 +1,154 @@
1
+ /* =============================================================================
2
+ * MonthRangePicker Component Styles
3
+ *
4
+ * A single 3x4 month grid for contiguous month-range selection.
5
+ * Density, typography, and cell layout mirror `.calendar__month-cell`
6
+ * (Calendar's month drill-up view) so this looks visually consistent with
7
+ * Calendar/MonthPicker outside of range-specific track/cap styling, which is
8
+ * adapted from `.range-calendar__cell`'s day-range treatment (simplified:
9
+ * month cells are single self-contained elements, not a <td>-wrapped circle,
10
+ * so no `:has()` targeting or row-wraparound corner-smoothing is needed —
11
+ * every row is always a full row of 3 months, unlike day grids which have
12
+ * partial weeks and "outside view" spillover).
13
+ * ============================================================================= */
14
+
15
+ .month-range-picker {
16
+ @apply w-64 max-w-full text-xs;
17
+
18
+ container-type: inline-size;
19
+ }
20
+
21
+ /* -----------------------------------------------------------------------------
22
+ * Header
23
+ * -------------------------------------------------------------------------- */
24
+ .month-range-picker__header {
25
+ @apply flex items-center justify-between px-0.5 pb-1;
26
+ }
27
+
28
+ .month-range-picker__heading {
29
+ @apply flex flex-1 items-center justify-center text-center text-xs font-medium;
30
+ }
31
+
32
+ .month-range-picker__nav-button {
33
+ @apply flex size-6 items-center justify-center rounded-full text-accent;
34
+
35
+ will-change: scale;
36
+ transition:
37
+ transform 300ms var(--ease-out),
38
+ background-color 300ms var(--ease-out),
39
+ box-shadow 300ms var(--ease-out),
40
+ opacity 300ms var(--ease-out);
41
+ @apply transform-gpu motion-reduce:transition-none;
42
+
43
+ cursor: var(--cursor-interactive);
44
+
45
+ @media (hover: hover) {
46
+ &:hover,
47
+ &[data-hovered="true"] {
48
+ @apply bg-default text-accent;
49
+ }
50
+ }
51
+
52
+ &:active,
53
+ &[data-pressed="true"] {
54
+ transform: scale(0.95);
55
+ }
56
+
57
+ &:focus-visible,
58
+ &[data-focus-visible="true"] {
59
+ @apply status-focused;
60
+ }
61
+
62
+ &:disabled,
63
+ &[data-disabled] {
64
+ @apply status-disabled;
65
+ }
66
+ }
67
+
68
+ .month-range-picker__nav-button-icon {
69
+ @apply size-3.5;
70
+ }
71
+
72
+ /* -----------------------------------------------------------------------------
73
+ * Grid
74
+ * -------------------------------------------------------------------------- */
75
+ .month-range-picker__grid {
76
+ display: grid;
77
+ grid-template-columns: repeat(3, 1fr);
78
+ grid-template-rows: repeat(4, 1fr);
79
+ border-collapse: collapse;
80
+ @apply aspect-[7/6] w-full;
81
+ }
82
+
83
+ .month-range-picker__grid-body {
84
+ display: contents;
85
+
86
+ & > tr {
87
+ display: contents;
88
+ place-items: center;
89
+
90
+ & > td {
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: center;
94
+ padding: 0.5rem;
95
+ }
96
+ }
97
+ }
98
+
99
+ .month-range-picker__grid-row {
100
+ display: contents;
101
+ }
102
+
103
+ /* -----------------------------------------------------------------------------
104
+ * Cell
105
+ * -------------------------------------------------------------------------- */
106
+ .month-range-picker__cell {
107
+ @apply relative m-0.5 flex size-auto items-center justify-center rounded-lg text-center text-xs font-medium outline-none no-highlight;
108
+ will-change: scale;
109
+ transition:
110
+ transform 300ms var(--ease-out),
111
+ box-shadow 300ms var(--ease-out),
112
+ background-color 300ms var(--ease-out);
113
+ @apply transform-gpu motion-reduce:transition-none;
114
+ cursor: var(--cursor-interactive);
115
+
116
+ @media (hover: hover) {
117
+ &:hover:not([data-selected]),
118
+ &[data-hovered="true"]:not([data-selected]) {
119
+ @apply bg-default;
120
+ }
121
+ }
122
+
123
+ &:active,
124
+ &[data-pressed="true"] {
125
+ transform: scale(0.95);
126
+ }
127
+
128
+ &:focus-visible,
129
+ &[data-focus-visible="true"] {
130
+ @apply status-focused;
131
+ }
132
+
133
+ /* Range track (middle segment) — any month within the range, including caps */
134
+ &[data-selected] {
135
+ @apply rounded-none bg-accent-soft;
136
+ }
137
+
138
+ /* Range caps (start/end) — solid accent fill, rounded */
139
+ &[data-selection-start],
140
+ &[data-selection-end] {
141
+ @apply rounded-lg bg-accent text-accent-foreground;
142
+ }
143
+
144
+ &:disabled,
145
+ &[data-disabled] {
146
+ @apply status-disabled;
147
+
148
+ text-decoration: line-through;
149
+ }
150
+
151
+ &[data-unavailable] {
152
+ @apply status-disabled;
153
+ }
154
+ }