maquina-components 0.5.1 → 0.6.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.
- checksums.yaml +4 -4
- data/README.md +76 -2
- data/app/assets/stylesheets/alert.css +169 -135
- data/app/assets/stylesheets/badge.css +143 -138
- data/app/assets/stylesheets/breadcrumbs.css +183 -166
- data/app/assets/stylesheets/calendar.css +219 -206
- data/app/assets/stylesheets/card.css +126 -120
- data/app/assets/stylesheets/combobox.css +208 -191
- data/app/assets/stylesheets/date_picker.css +144 -134
- data/app/assets/stylesheets/drawer.css +158 -125
- data/app/assets/stylesheets/dropdown_menu.css +203 -190
- data/app/assets/stylesheets/empty.css +125 -117
- data/app/assets/stylesheets/form.css +625 -525
- data/app/assets/stylesheets/header.css +63 -47
- data/app/assets/stylesheets/menu_button.css +121 -98
- data/app/assets/stylesheets/pagination.css +130 -125
- data/app/assets/stylesheets/separator.css +23 -11
- data/app/assets/stylesheets/sidebar.css +447 -401
- data/app/assets/stylesheets/stats.css +77 -67
- data/app/assets/stylesheets/table.css +184 -166
- data/app/assets/stylesheets/toast.css +287 -278
- data/app/assets/stylesheets/toggle_group.css +132 -139
- data/app/assets/tailwind/maquina_components_engine/engine.css +54 -15
- data/app/assets/tailwind/maquina_components_engine/tokens.css +101 -0
- data/app/helpers/maquina_components/combobox_helper.rb +32 -24
- data/app/helpers/maquina_components/components_helper.rb +30 -6
- data/app/helpers/maquina_components/dropdown_menu_helper.rb +12 -12
- data/app/helpers/maquina_components/icons_helper.rb +26 -2
- data/app/javascript/controllers/drawer_trigger_controller.js +24 -3
- data/app/views/components/_label.html.erb +14 -0
- data/app/views/components/_table.html.erb +2 -2
- data/app/views/components/calendar/_week.html.erb +4 -12
- data/app/views/components/drawer/_close.html.erb +1 -1
- data/app/views/components/drawer/_description.html.erb +6 -0
- data/app/views/components/drawer/_header.html.erb +1 -1
- data/app/views/components/drawer/_provider.html.erb +13 -4
- data/app/views/components/drawer/_section.html.erb +7 -0
- data/app/views/components/drawer/_separator.html.erb +11 -0
- data/app/views/components/drawer/_title.html.erb +6 -0
- data/app/views/components/drawer/_trigger.html.erb +24 -7
- data/app/views/components/sidebar/_group_action.html.erb +26 -0
- data/app/views/components/sidebar/_menu_action.html.erb +28 -0
- data/app/views/components/sidebar/_menu_badge.html.erb +10 -0
- data/app/views/components/sidebar/_menu_button.html.erb +3 -2
- data/app/views/components/sidebar/_menu_link.html.erb +3 -2
- data/app/views/components/sidebar/_separator.html.erb +12 -0
- data/lib/generators/maquina_components/install/install_generator.rb +36 -1
- data/lib/generators/maquina_components/install/templates/maquina_components_helper.rb.tt +5 -0
- data/lib/generators/maquina_components/install/templates/shape_state_tokens.css.tt +76 -0
- data/lib/generators/maquina_components/install/templates/theme.css.tt +10 -3
- data/lib/maquina-components.rb +29 -1
- data/lib/maquina_components/doctor.rb +280 -0
- data/lib/maquina_components/version.rb +1 -1
- data/lib/tasks/maquina_components_tasks.rake +16 -4
- metadata +14 -2
|
@@ -8,165 +8,175 @@
|
|
|
8
8
|
* - date-picker (root container)
|
|
9
9
|
* - trigger (button with popovertarget)
|
|
10
10
|
* - popover (native popover with calendar)
|
|
11
|
+
*
|
|
12
|
+
* Cascade order in this file (full contract documented in form.css):
|
|
13
|
+
* 1. base [data-component="date-picker"], [data-date-picker-part="…"]
|
|
14
|
+
* 2. sizes :where([data-size="sm"|"lg"]) [data-date-picker-part="trigger"]
|
|
15
|
+
* 3. variants :where([data-full-width]) …
|
|
16
|
+
* 4. states […]:where(:hover, :focus-visible, :disabled, [aria-expanded],
|
|
17
|
+
* :has(input:invalid))
|
|
18
|
+
* 5. dark — none; dark-mode differences are tokens (see tokens.css)
|
|
19
|
+
* Every rule is flattened to 0,1,0 with :where() and lives in
|
|
20
|
+
* @layer components, so a caller's utility class wins and source order is
|
|
21
|
+
* the only tie-breaker. (Rules whose target is a bare element read 0,1,1 — an
|
|
22
|
+
* element selector cannot be zeroed away.)
|
|
23
|
+
*
|
|
24
|
+
* This file must be imported after calendar.css: the "calendar inside popover"
|
|
25
|
+
* rule below strips the calendar's own border, and at a flat 0,1,0 only source
|
|
26
|
+
* order decides that. See engine.css.
|
|
11
27
|
*/
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
29
|
+
@layer components {
|
|
30
|
+
/* ===== Root Container ===== */
|
|
31
|
+
[data-component="date-picker"] {
|
|
32
|
+
position: relative;
|
|
33
|
+
display: inline-block;
|
|
34
|
+
}
|
|
18
35
|
|
|
19
|
-
/* ===== Trigger Button ===== */
|
|
20
|
-
[data-date-picker-part="trigger"] {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
/* ===== Trigger Button ===== */
|
|
37
|
+
[data-date-picker-part="trigger"] {
|
|
38
|
+
display: inline-flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: flex-start;
|
|
41
|
+
gap: 0.5rem;
|
|
42
|
+
width: 100%;
|
|
43
|
+
min-width: 200px;
|
|
44
|
+
@apply h-9 px-3 py-2 text-sm;
|
|
45
|
+
border-radius: var(--date-picker-radius, var(--control-radius, 0.375rem));
|
|
46
|
+
border: 1px solid var(--input);
|
|
47
|
+
background-color: var(--control-fill, var(--background));
|
|
48
|
+
color: var(--foreground);
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
text-align: left;
|
|
51
|
+
@apply transition-colors duration-150;
|
|
52
|
+
}
|
|
35
53
|
|
|
36
|
-
[data-date-picker-part="trigger"]
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
[data-date-picker-part="trigger"] svg {
|
|
55
|
+
@apply size-4 shrink-0;
|
|
56
|
+
color: var(--muted-foreground);
|
|
57
|
+
}
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
59
|
+
/* ===== Trigger Sizes ===== */
|
|
60
|
+
:where([data-component="date-picker"][data-size="sm"]) [data-date-picker-part="trigger"] {
|
|
61
|
+
@apply h-8 px-2 py-1 text-xs;
|
|
62
|
+
min-width: 160px;
|
|
63
|
+
}
|
|
46
64
|
|
|
47
|
-
[data-date-picker-part="trigger"]
|
|
48
|
-
|
|
49
|
-
}
|
|
65
|
+
:where([data-component="date-picker"][data-size="sm"]) [data-date-picker-part="trigger"] svg {
|
|
66
|
+
@apply size-3.5;
|
|
67
|
+
}
|
|
50
68
|
|
|
51
|
-
[data-date-picker-part="trigger"]
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
69
|
+
:where([data-component="date-picker"][data-size="lg"]) [data-date-picker-part="trigger"] {
|
|
70
|
+
@apply h-11 px-4 py-3 text-base;
|
|
71
|
+
min-width: 240px;
|
|
72
|
+
}
|
|
55
73
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
74
|
+
:where([data-component="date-picker"][data-size="lg"]) [data-date-picker-part="trigger"] svg {
|
|
75
|
+
@apply size-5;
|
|
76
|
+
}
|
|
60
77
|
|
|
61
|
-
/* =====
|
|
62
|
-
[data-date-picker
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
|
|
67
|
-
0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
68
|
-
|
|
69
|
-
/* Reset default popover styles */
|
|
70
|
-
margin: 0;
|
|
71
|
-
overflow: visible;
|
|
72
|
-
|
|
73
|
-
/* Position below trigger */
|
|
74
|
-
position-area: bottom span-right;
|
|
75
|
-
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
|
|
76
|
-
margin-top: 0.25rem;
|
|
77
|
-
|
|
78
|
-
/* Entry animation */
|
|
79
|
-
opacity: 1;
|
|
80
|
-
transform: translateY(0) scale(1);
|
|
81
|
-
transition: opacity 150ms ease-out,
|
|
82
|
-
transform 150ms ease-out;
|
|
83
|
-
}
|
|
78
|
+
/* ===== Full width variant ===== */
|
|
79
|
+
[data-component="date-picker"]:where([data-full-width]) {
|
|
80
|
+
display: block;
|
|
81
|
+
width: 100%;
|
|
82
|
+
}
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
transform: translateY(-0.5rem) scale(0.95);
|
|
89
|
-
}
|
|
84
|
+
:where([data-component="date-picker"][data-full-width]) [data-date-picker-part="trigger"] {
|
|
85
|
+
width: 100%;
|
|
86
|
+
}
|
|
90
87
|
|
|
91
|
-
/*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
/* ===== Trigger States ===== */
|
|
89
|
+
|
|
90
|
+
/* Placeholder state */
|
|
91
|
+
[data-date-picker-part="trigger"]:where(:has([data-date-picker-part="placeholder-indicator"])) {
|
|
92
|
+
color: var(--muted-foreground);
|
|
96
93
|
}
|
|
97
|
-
}
|
|
98
94
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
95
|
+
[data-date-picker-part="trigger"]:where(:hover:not(:disabled)) {
|
|
96
|
+
background-color: var(--accent-hover, var(--accent));
|
|
97
|
+
}
|
|
103
98
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
box-shadow: none;
|
|
108
|
-
}
|
|
99
|
+
[data-date-picker-part="trigger"]:where([aria-expanded="true"]) {
|
|
100
|
+
border-color: var(--ring);
|
|
101
|
+
}
|
|
109
102
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
103
|
+
[data-date-picker-part="trigger"]:where(:focus-visible) {
|
|
104
|
+
border-color: var(--ring);
|
|
105
|
+
outline: var(--focus-ring-width, 3px) var(--focus-ring-style, solid)
|
|
106
|
+
var(--focus-ring-color, var(--ring));
|
|
107
|
+
outline-offset: var(--focus-ring-offset, 0px);
|
|
108
|
+
}
|
|
114
109
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
min-width: 160px;
|
|
119
|
-
}
|
|
110
|
+
[data-date-picker-part="trigger"]:where(:disabled) {
|
|
111
|
+
@apply opacity-50 cursor-not-allowed;
|
|
112
|
+
}
|
|
120
113
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
114
|
+
/* Error state — the root :has() drives the trigger */
|
|
115
|
+
:where([data-component="date-picker"]:has(input:invalid), [data-component="date-picker"]:has(input[aria-invalid="true"])) [data-date-picker-part="trigger"] {
|
|
116
|
+
border-color: var(--destructive);
|
|
117
|
+
}
|
|
124
118
|
|
|
125
|
-
[data-component="date-picker"][data-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
119
|
+
:where([data-component="date-picker"]:has(input:invalid), [data-component="date-picker"]:has(input[aria-invalid="true"])) [data-date-picker-part="trigger"]:where(:focus-visible) {
|
|
120
|
+
--focus-ring-color: var(--destructive);
|
|
121
|
+
}
|
|
129
122
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
123
|
+
/* ===== Popover ===== */
|
|
124
|
+
[data-date-picker-part="popover"] {
|
|
125
|
+
@apply p-0 border;
|
|
126
|
+
border-radius: var(--date-picker-popover-radius, var(--surface-radius, 0.5rem));
|
|
127
|
+
/* A popover is above the page by definition, so it paints --popover */
|
|
128
|
+
background-color: var(--popover, var(--background));
|
|
129
|
+
border-color: var(--border);
|
|
130
|
+
box-shadow: var(--date-picker-popover-shadow, var(--elevation-overlay, var(--shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))));
|
|
131
|
+
|
|
132
|
+
/* Reset default popover styles */
|
|
133
|
+
margin: 0;
|
|
134
|
+
overflow: visible;
|
|
135
|
+
|
|
136
|
+
/* Position below trigger */
|
|
137
|
+
position-area: bottom span-right;
|
|
138
|
+
position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
|
|
139
|
+
margin-top: 0.25rem;
|
|
133
140
|
|
|
134
|
-
/*
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
141
|
+
/* Entry animation */
|
|
142
|
+
opacity: 1;
|
|
143
|
+
transform: translateY(0) scale(1);
|
|
144
|
+
transition: opacity 150ms ease-out,
|
|
145
|
+
transform 150ms ease-out;
|
|
146
|
+
}
|
|
139
147
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
148
|
+
/* Closed state - for exit animation */
|
|
149
|
+
[data-date-picker-part="popover"]:where(:not(:popover-open)) {
|
|
150
|
+
opacity: 0;
|
|
151
|
+
transform: translateY(-0.5rem) scale(0.95);
|
|
152
|
+
}
|
|
143
153
|
|
|
144
|
-
/*
|
|
145
|
-
|
|
146
|
-
[data-
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
/* Entry animation starting state */
|
|
155
|
+
@starting-style {
|
|
156
|
+
[data-date-picker-part="popover"]:where(:popover-open) {
|
|
157
|
+
opacity: 0;
|
|
158
|
+
transform: translateY(-0.5rem) scale(0.95);
|
|
159
|
+
}
|
|
149
160
|
}
|
|
150
161
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
162
|
+
/* Backdrop */
|
|
163
|
+
[data-date-picker-part="popover"]::backdrop {
|
|
164
|
+
background-color: transparent;
|
|
154
165
|
}
|
|
155
|
-
}
|
|
156
166
|
|
|
157
|
-
/* =====
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
top: 100%;
|
|
162
|
-
left: 0;
|
|
163
|
-
margin-top: 0.25rem;
|
|
167
|
+
/* ===== Calendar inside popover adjustments ===== */
|
|
168
|
+
:where([data-date-picker-part="popover"]) [data-component="calendar"] {
|
|
169
|
+
border: none;
|
|
170
|
+
box-shadow: var(--elevation-none, none);
|
|
164
171
|
}
|
|
165
|
-
}
|
|
166
172
|
|
|
167
|
-
/* =====
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
/* ===== Fallback for browsers without anchor positioning ===== */
|
|
174
|
+
@supports not (position-area: bottom) {
|
|
175
|
+
[data-date-picker-part="popover"] {
|
|
176
|
+
position: absolute;
|
|
177
|
+
top: 100%;
|
|
178
|
+
left: 0;
|
|
179
|
+
margin-top: 0.25rem;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -1,135 +1,168 @@
|
|
|
1
1
|
/* ===== Drawer Component Styles ===== */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
[data-component="drawer"]
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/* =====
|
|
20
|
-
[data-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
[data-drawer-part="
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/*
|
|
30
|
-
[data-drawer-part="
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
[data-drawer-part="
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
[data-drawer-part="
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
2
|
+
/*
|
|
3
|
+
* Cascade order in this file (full contract documented in form.css):
|
|
4
|
+
* 1. base [data-component="drawer"], [data-drawer-part="…"]
|
|
5
|
+
* 2. sizes — none
|
|
6
|
+
* 3. variants :where([data-drawer-part="root"][data-side="…"]) …
|
|
7
|
+
* 4. states […]:where(:hover, :focus-visible, [data-state="…"])
|
|
8
|
+
* 5. dark — none; dark-mode differences are tokens (see tokens.css)
|
|
9
|
+
* Every rule is flattened to 0,1,0 with :where() and lives in
|
|
10
|
+
* @layer components, so a caller's utility class wins and source order is
|
|
11
|
+
* the only tie-breaker. (Rules whose target is a bare element read 0,1,1 — an
|
|
12
|
+
* element selector cannot be zeroed away.)
|
|
13
|
+
*
|
|
14
|
+
* The one exception is the body scroll lock at the bottom of this file: see the
|
|
15
|
+
* comment there. It is intentionally NOT in the layer.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
@layer components {
|
|
19
|
+
/* ===== Provider (Wrapper) ===== */
|
|
20
|
+
[data-component="drawer"] {
|
|
21
|
+
@apply flex w-full;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* ===== Drawer Root ===== */
|
|
25
|
+
[data-drawer-part="root"] {
|
|
26
|
+
@apply block text-foreground;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Prevent transitions on initial load */
|
|
30
|
+
[data-drawer-part="root"]:where(.drawer-loading),
|
|
31
|
+
:where([data-drawer-part="root"].drawer-loading) * {
|
|
32
|
+
transition: none !important;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* ===== Drawer Backdrop (overlay) ===== */
|
|
36
|
+
[data-drawer-part="backdrop"] {
|
|
37
|
+
@apply fixed inset-0 z-40 hidden bg-black opacity-0;
|
|
38
|
+
transition: opacity 300ms;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[data-drawer-part="backdrop"]:where([data-state="visible"]) {
|
|
42
|
+
@apply block opacity-60;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ===== Drawer Panel (fixed positioned) ===== */
|
|
46
|
+
[data-drawer-part="panel"] {
|
|
47
|
+
@apply fixed inset-y-0 z-50 flex h-full w-80 flex-col;
|
|
48
|
+
@apply bg-background;
|
|
49
|
+
box-shadow: var(--drawer-shadow, var(--elevation-overlay, var(--shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1))));
|
|
50
|
+
transition: right 300ms ease-in-out, left 300ms ease-in-out;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:where([data-drawer-part="root"][data-side="left"]) [data-drawer-part="panel"] {
|
|
54
|
+
@apply left-0;
|
|
55
|
+
right: auto;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
:where([data-drawer-part="root"][data-side="right"]) [data-drawer-part="panel"] {
|
|
59
|
+
@apply right-0;
|
|
60
|
+
left: auto;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* Closed state - slide out */
|
|
64
|
+
:where([data-drawer-part="root"][data-side="left"][data-state="closed"]) [data-drawer-part="panel"] {
|
|
65
|
+
@apply -translate-x-full;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
:where([data-drawer-part="root"][data-side="right"][data-state="closed"]) [data-drawer-part="panel"] {
|
|
69
|
+
@apply translate-x-full;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ===== Drawer Inner Content Wrapper ===== */
|
|
73
|
+
[data-drawer-part="inner"] {
|
|
74
|
+
@apply flex h-full w-full flex-col;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* ===== Drawer Header ===== */
|
|
78
|
+
[data-drawer-part="header"] {
|
|
79
|
+
@apply flex shrink-0 items-center justify-between gap-2 border-b px-4 py-3;
|
|
80
|
+
border-color: var(--border);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
[data-drawer-part="header-content"] {
|
|
84
|
+
@apply flex-1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* ===== Drawer Content (scrollable area) ===== */
|
|
88
|
+
[data-drawer-part="content"] {
|
|
89
|
+
@apply flex min-h-0 flex-1 flex-col gap-2 overflow-auto p-4;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* ===== Drawer Footer ===== */
|
|
93
|
+
[data-drawer-part="footer"] {
|
|
94
|
+
@apply flex shrink-0 flex-col gap-2 border-t p-4;
|
|
95
|
+
border-color: var(--border);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ===== Drawer Trigger ===== */
|
|
99
|
+
[data-drawer-part="trigger"]:where(:hover) {
|
|
100
|
+
background-color: var(--accent-hover, var(--accent));
|
|
101
|
+
color: var(--accent-foreground);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* ===== Drawer Title ===== */
|
|
105
|
+
[data-drawer-part="title"] {
|
|
106
|
+
@apply text-lg font-semibold;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* ===== Drawer Description ===== */
|
|
110
|
+
[data-drawer-part="description"] {
|
|
111
|
+
@apply text-sm text-muted-foreground;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* ===== Drawer Close Button ===== */
|
|
115
|
+
[data-drawer-part="close"] {
|
|
116
|
+
@apply inline-flex items-center justify-center p-1;
|
|
117
|
+
@apply transition-colors;
|
|
118
|
+
border-radius: var(--drawer-close-radius, var(--control-radius, 0.375rem));
|
|
119
|
+
color: var(--foreground);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
[data-drawer-part="close"] svg {
|
|
123
|
+
@apply size-4;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
[data-drawer-part="close"]:where(:hover) {
|
|
127
|
+
background-color: var(--accent-hover, var(--accent));
|
|
128
|
+
color: var(--accent-foreground);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* outline, not a ring: the drawer panel clips box-shadow rings */
|
|
132
|
+
[data-drawer-part="close"]:where(:focus-visible) {
|
|
133
|
+
outline: var(--focus-ring-width, 3px) var(--focus-ring-style, solid)
|
|
134
|
+
var(--focus-ring-color, var(--ring));
|
|
135
|
+
outline-offset: var(--focus-ring-offset, 0px);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* ===== Drawer Section ===== */
|
|
139
|
+
[data-drawer-part="section"] {
|
|
140
|
+
@apply flex flex-col gap-2;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* ===== Drawer Separator ===== */
|
|
144
|
+
[data-drawer-part="separator"] {
|
|
145
|
+
@apply mx-4 my-2 w-auto;
|
|
146
|
+
background-color: var(--border);
|
|
147
|
+
}
|
|
58
148
|
}
|
|
59
149
|
|
|
60
150
|
/* ===== Body Scroll Lock ===== */
|
|
61
|
-
/*
|
|
62
|
-
|
|
63
|
-
|
|
151
|
+
/*
|
|
152
|
+
* Shared by drawer_controller and sidebar_controller: the controllers set
|
|
153
|
+
* the data attribute and the --maquina-scroll-lock-top offset on <body>;
|
|
154
|
+
* all styling lives here.
|
|
155
|
+
*
|
|
156
|
+
* PUBLIC CONTRACT — this is the only engine rule outside @layer components.
|
|
157
|
+
* It is not component appearance, it is a functional lock: if a host's own
|
|
158
|
+
* unlayered `body { position: … }` beat it, the page would scroll behind an
|
|
159
|
+
* open drawer and the restored scroll position would be wrong. Keeping it
|
|
160
|
+
* unlayered means it wins the way it did before 0.6.0. Nothing else in the
|
|
161
|
+
* engine claims that privilege.
|
|
162
|
+
*/
|
|
64
163
|
body[data-maquina-scroll-locked] {
|
|
65
164
|
position: fixed;
|
|
66
165
|
top: var(--maquina-scroll-lock-top, 0px);
|
|
67
166
|
width: 100%;
|
|
68
167
|
overflow: hidden;
|
|
69
168
|
}
|
|
70
|
-
|
|
71
|
-
/* ===== Drawer Header ===== */
|
|
72
|
-
[data-drawer-part="header"] {
|
|
73
|
-
@apply flex shrink-0 items-center justify-between gap-2 border-b px-4 py-3;
|
|
74
|
-
border-color: var(--border);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
[data-drawer-part="header-content"] {
|
|
78
|
-
@apply flex-1;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/* ===== Drawer Content (scrollable area) ===== */
|
|
82
|
-
[data-drawer-part="content"] {
|
|
83
|
-
@apply flex min-h-0 flex-1 flex-col gap-2 overflow-auto p-4;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/* ===== Drawer Footer ===== */
|
|
87
|
-
[data-drawer-part="footer"] {
|
|
88
|
-
@apply flex shrink-0 flex-col gap-2 border-t p-4;
|
|
89
|
-
border-color: var(--border);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/* ===== Drawer Trigger ===== */
|
|
93
|
-
|
|
94
|
-
[data-drawer-part="trigger"]:hover {
|
|
95
|
-
background-color: var(--accent);
|
|
96
|
-
color: var(--accent-foreground);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/* ===== Drawer Title ===== */
|
|
100
|
-
[data-drawer-part="title"] {
|
|
101
|
-
@apply text-lg font-semibold;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/* ===== Drawer Description ===== */
|
|
105
|
-
[data-drawer-part="description"] {
|
|
106
|
-
@apply text-sm text-muted-foreground;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/* ===== Drawer Close Button ===== */
|
|
110
|
-
[data-drawer-part="close"] {
|
|
111
|
-
@apply inline-flex items-center justify-center rounded-md p-1;
|
|
112
|
-
@apply outline-hidden ring-ring focus-visible:ring-2;
|
|
113
|
-
@apply transition-colors;
|
|
114
|
-
color: var(--foreground);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
[data-drawer-part="close"]:hover {
|
|
118
|
-
background-color: var(--accent);
|
|
119
|
-
color: var(--accent-foreground);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
[data-drawer-part="close"] svg {
|
|
123
|
-
@apply size-4;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/* ===== Drawer Section ===== */
|
|
127
|
-
[data-drawer-part="section"] {
|
|
128
|
-
@apply flex flex-col gap-2;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/* ===== Drawer Separator ===== */
|
|
132
|
-
[data-drawer-part="separator"] {
|
|
133
|
-
@apply mx-4 my-2 w-auto;
|
|
134
|
-
background-color: var(--border);
|
|
135
|
-
}
|