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
|
@@ -1,207 +1,224 @@
|
|
|
1
1
|
/* ===== Breadcrumbs Component Styles ===== */
|
|
2
2
|
/* Comprehensive CSS using data-attribute selectors */
|
|
3
3
|
/* Uses @apply for theme-customizable properties */
|
|
4
|
+
/*
|
|
5
|
+
* Cascade order in this file (full contract documented in form.css):
|
|
6
|
+
* 1. base [data-component="breadcrumbs"], [data-breadcrumb-part="…"]
|
|
7
|
+
* 2. sizes :where([data-component="breadcrumbs"][data-size="sm"]) …
|
|
8
|
+
* 3. variants :where([data-component="breadcrumbs"][data-separator="…"]) …
|
|
9
|
+
* 4. states […]:where(:hover, :focus-visible, [data-state="open"], .hidden)
|
|
10
|
+
* 5. dark — none; dark-mode differences are tokens (see tokens.css)
|
|
11
|
+
* Every rule is flattened to 0,1,0 with :where() and lives in
|
|
12
|
+
* @layer components, so a caller's utility class wins and source order is
|
|
13
|
+
* the only tie-breaker. (Rules whose target is a bare element or a
|
|
14
|
+
* pseudo-element read 0,1,1 — an element selector cannot be zeroed away.)
|
|
15
|
+
*
|
|
16
|
+
* Imported LAST, after dropdown_menu.css: the overflow popover below has to
|
|
17
|
+
* beat dropdown_menu.css's `position: absolute`, and since every rule is now a
|
|
18
|
+
* flat 0,1,0 that is decided by import order alone (it used to lean on a
|
|
19
|
+
* doubled attribute selector). See engine.css.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
@layer components {
|
|
23
|
+
/* ===== Breadcrumbs Container (nav) ===== */
|
|
24
|
+
[data-component="breadcrumbs"] {
|
|
25
|
+
/* Container has no default styles - allows flexible placement */
|
|
26
|
+
}
|
|
4
27
|
|
|
5
|
-
/* ===== Breadcrumbs
|
|
6
|
-
[data-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@apply text-sm break-words;
|
|
14
|
-
list-style: none;
|
|
15
|
-
padding: 0;
|
|
16
|
-
margin: 0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/* Compact variant */
|
|
20
|
-
[data-component="breadcrumbs"][data-size="sm"] [data-breadcrumb-part="list"] {
|
|
21
|
-
@apply gap-1 text-xs;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/* ===== Breadcrumb Item ===== */
|
|
25
|
-
[data-breadcrumb-part="item"] {
|
|
26
|
-
@apply inline-flex items-center;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* Hidden state for responsive collapsing */
|
|
30
|
-
[data-breadcrumb-part="item"].hidden {
|
|
31
|
-
@apply hidden;
|
|
32
|
-
}
|
|
28
|
+
/* ===== Breadcrumbs List ===== */
|
|
29
|
+
[data-breadcrumb-part="list"] {
|
|
30
|
+
@apply flex flex-wrap items-center gap-1.5;
|
|
31
|
+
@apply text-sm break-words;
|
|
32
|
+
list-style: none;
|
|
33
|
+
padding: 0;
|
|
34
|
+
margin: 0;
|
|
35
|
+
}
|
|
33
36
|
|
|
34
|
-
/*
|
|
35
|
-
[data-breadcrumb-part="
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@apply underline-offset-4;
|
|
39
|
-
@apply transition-colors;
|
|
40
|
-
color: var(--muted-foreground);
|
|
41
|
-
}
|
|
37
|
+
/* Compact variant */
|
|
38
|
+
:where([data-component="breadcrumbs"][data-size="sm"]) [data-breadcrumb-part="list"] {
|
|
39
|
+
@apply gap-1 text-xs;
|
|
40
|
+
}
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
42
|
+
/* ===== Breadcrumb Item ===== */
|
|
43
|
+
[data-breadcrumb-part="item"] {
|
|
44
|
+
@apply inline-flex items-center;
|
|
45
|
+
}
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
47
|
+
/* Hidden state for responsive collapsing */
|
|
48
|
+
[data-breadcrumb-part="item"]:where(.hidden) {
|
|
49
|
+
@apply hidden;
|
|
50
|
+
}
|
|
52
51
|
|
|
53
|
-
/* Link
|
|
54
|
-
[data-breadcrumb-part="link"]
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
/* ===== Breadcrumb Link ===== */
|
|
53
|
+
[data-breadcrumb-part="link"] {
|
|
54
|
+
@apply inline-flex items-center;
|
|
55
|
+
@apply text-sm;
|
|
56
|
+
font-weight: var(--label-weight, 500);
|
|
57
|
+
@apply underline-offset-4;
|
|
58
|
+
@apply transition-colors;
|
|
59
|
+
color: var(--muted-foreground);
|
|
60
|
+
}
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
/* Link with icon */
|
|
63
|
+
[data-breadcrumb-part="link"] svg {
|
|
64
|
+
@apply size-3.5 shrink-0;
|
|
65
|
+
}
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@apply text-sm font-medium;
|
|
66
|
-
color: var(--foreground);
|
|
67
|
-
}
|
|
67
|
+
[data-breadcrumb-part="link"] svg:where(:first-child) {
|
|
68
|
+
@apply mr-1.5;
|
|
69
|
+
}
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
71
|
+
[data-breadcrumb-part="link"]:where(:hover) {
|
|
72
|
+
color: var(--foreground);
|
|
73
|
+
@apply underline;
|
|
74
|
+
}
|
|
73
75
|
|
|
74
|
-
[data-breadcrumb-part="
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
[data-breadcrumb-part="link"]:where(:focus-visible) {
|
|
77
|
+
@apply outline-none underline;
|
|
78
|
+
color: var(--foreground);
|
|
79
|
+
}
|
|
77
80
|
|
|
78
|
-
/* ===== Breadcrumb
|
|
79
|
-
[data-breadcrumb-part="
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
/* ===== Breadcrumb Page (current) ===== */
|
|
82
|
+
[data-breadcrumb-part="page"] {
|
|
83
|
+
@apply inline-flex items-center;
|
|
84
|
+
@apply text-sm;
|
|
85
|
+
font-weight: var(--label-weight, 500);
|
|
86
|
+
color: var(--foreground);
|
|
87
|
+
}
|
|
83
88
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
/* Page with icon */
|
|
90
|
+
[data-breadcrumb-part="page"] svg {
|
|
91
|
+
@apply size-3.5 shrink-0;
|
|
92
|
+
}
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
94
|
+
[data-breadcrumb-part="page"] svg:where(:first-child) {
|
|
95
|
+
@apply mr-1.5;
|
|
96
|
+
}
|
|
92
97
|
|
|
93
|
-
/* ===== Breadcrumb
|
|
94
|
-
[data-breadcrumb-part="
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
98
|
+
/* ===== Breadcrumb Separator ===== */
|
|
99
|
+
[data-breadcrumb-part="separator"] {
|
|
100
|
+
@apply inline-flex items-center;
|
|
101
|
+
color: var(--muted-foreground);
|
|
102
|
+
}
|
|
99
103
|
|
|
100
|
-
[data-breadcrumb-part="
|
|
101
|
-
|
|
102
|
-
}
|
|
104
|
+
[data-breadcrumb-part="separator"] svg {
|
|
105
|
+
@apply size-3.5 shrink-0;
|
|
106
|
+
}
|
|
103
107
|
|
|
104
|
-
/*
|
|
105
|
-
[data-breadcrumb-part="
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
108
|
+
/* Hidden state for responsive collapsing */
|
|
109
|
+
[data-breadcrumb-part="separator"]:where(.hidden) {
|
|
110
|
+
@apply hidden;
|
|
111
|
+
}
|
|
109
112
|
|
|
110
|
-
/* =====
|
|
111
|
-
/* Visual styling comes from dropdown_menu.css via data-dropdown-menu-part.
|
|
112
|
-
Anchor positioning places the popover in modern browsers;
|
|
113
|
-
breadcrumb_controller falls back to measured coordinates elsewhere.
|
|
114
|
-
The doubled attribute selector outranks dropdown_menu.css's
|
|
115
|
-
position: absolute regardless of import order. */
|
|
116
|
-
@supports (anchor-name: --a) and (position-area: block-end) {
|
|
113
|
+
/* ===== Breadcrumb Ellipsis ===== */
|
|
117
114
|
[data-breadcrumb-part="ellipsis"] {
|
|
118
|
-
|
|
115
|
+
@apply inline-flex size-9 items-center justify-center;
|
|
116
|
+
color: var(--muted-foreground);
|
|
117
|
+
cursor: pointer;
|
|
119
118
|
}
|
|
120
119
|
|
|
121
|
-
[data-breadcrumb-part="
|
|
122
|
-
|
|
123
|
-
position-anchor: --maquina-breadcrumbs;
|
|
124
|
-
position-area: block-end span-inline-end;
|
|
125
|
-
margin-block-start: 4px;
|
|
126
|
-
position-try-fallbacks: flip-block;
|
|
120
|
+
[data-breadcrumb-part="ellipsis"] svg {
|
|
121
|
+
@apply size-4 shrink-0;
|
|
127
122
|
}
|
|
128
|
-
}
|
|
129
123
|
|
|
130
|
-
/*
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
124
|
+
/* Ellipsis as dropdown trigger */
|
|
125
|
+
[data-breadcrumb-part="ellipsis"]:where([data-state="open"], :hover) {
|
|
126
|
+
color: var(--foreground);
|
|
127
|
+
}
|
|
135
128
|
|
|
136
|
-
/*
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
/* ===== Overflow Dropdown (top-layer popover) ===== */
|
|
130
|
+
/* Visual styling comes from dropdown_menu.css via data-dropdown-menu-part.
|
|
131
|
+
Anchor positioning places the popover in modern browsers;
|
|
132
|
+
breadcrumb_controller falls back to measured coordinates elsewhere. */
|
|
133
|
+
@supports (anchor-name: --a) and (position-area: block-end) {
|
|
134
|
+
[data-breadcrumb-part="ellipsis"] {
|
|
135
|
+
anchor-name: --maquina-breadcrumbs;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
[data-breadcrumb-part="dropdown"]:where([data-dropdown-menu-part="content"]) {
|
|
139
|
+
position: fixed;
|
|
140
|
+
position-anchor: --maquina-breadcrumbs;
|
|
141
|
+
position-area: block-end span-inline-end;
|
|
142
|
+
margin-block-start: 4px;
|
|
143
|
+
position-try-fallbacks: flip-block;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
141
146
|
|
|
142
|
-
/*
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
+
/* ===== Responsive Behavior ===== */
|
|
148
|
+
/* Force nowrap when responsive controller is active so scrollWidth detects overflow */
|
|
149
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-part="list"] {
|
|
150
|
+
@apply flex-nowrap overflow-hidden;
|
|
151
|
+
}
|
|
147
152
|
|
|
148
|
-
|
|
149
|
-
[data-controller="breadcrumb"] [data-breadcrumb-part="item"]
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
+
/* Items must not shrink or wrap text, otherwise flex compresses them and scrollWidth never exceeds clientWidth */
|
|
154
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-part="item"],
|
|
155
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-part="separator"] {
|
|
156
|
+
@apply shrink-0 whitespace-nowrap;
|
|
157
|
+
}
|
|
153
158
|
|
|
154
|
-
/*
|
|
155
|
-
[data-controller="breadcrumb"] [data-breadcrumb-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
+
/* Allow the last item (current page) to truncate gracefully instead of hard-clipping */
|
|
160
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-part="item"]:where(:last-child) {
|
|
161
|
+
@apply shrink min-w-0 overflow-hidden;
|
|
162
|
+
text-overflow: ellipsis;
|
|
163
|
+
}
|
|
159
164
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
165
|
+
:where([data-controller="breadcrumb"] [data-breadcrumb-part="item"]:last-child) :is([data-breadcrumb-part="page"], [data-breadcrumb-part="link"]) {
|
|
166
|
+
@apply overflow-hidden;
|
|
167
|
+
text-overflow: ellipsis;
|
|
168
|
+
}
|
|
164
169
|
|
|
165
|
-
/*
|
|
166
|
-
|
|
167
|
-
[data-breadcrumb-
|
|
168
|
-
@apply
|
|
170
|
+
/* Items hidden by Stimulus controller */
|
|
171
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-target="item"]:where(.hidden),
|
|
172
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-target="ellipsisSeparator"]:where(.hidden) {
|
|
173
|
+
@apply hidden;
|
|
169
174
|
}
|
|
170
175
|
|
|
171
|
-
/*
|
|
172
|
-
[data-
|
|
173
|
-
@apply
|
|
176
|
+
/* Ellipsis shown by Stimulus controller */
|
|
177
|
+
:where([data-controller="breadcrumb"]) [data-breadcrumb-target="ellipsis"]:where(:not(.hidden)) {
|
|
178
|
+
@apply inline-flex;
|
|
174
179
|
}
|
|
175
|
-
}
|
|
176
180
|
|
|
177
|
-
/* =====
|
|
181
|
+
/* ===== Mobile Adjustments ===== */
|
|
182
|
+
@media (max-width: 640px) {
|
|
183
|
+
[data-breadcrumb-part="list"] {
|
|
184
|
+
@apply gap-1;
|
|
185
|
+
}
|
|
178
186
|
|
|
179
|
-
/*
|
|
180
|
-
[data-component="breadcrumbs"][data-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
187
|
+
/* Hide middle items on very small screens by default */
|
|
188
|
+
:where([data-component="breadcrumbs"][data-auto-collapse]) [data-breadcrumb-part="item"]:where(:not(:first-child):not(:last-child)) {
|
|
189
|
+
@apply hidden sm:inline-flex;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
184
192
|
|
|
185
|
-
|
|
186
|
-
@apply hidden;
|
|
187
|
-
}
|
|
193
|
+
/* ===== Separator Variants ===== */
|
|
188
194
|
|
|
189
|
-
/*
|
|
190
|
-
[data-component="breadcrumbs"][data-separator="
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
195
|
+
/* Slash separator variant */
|
|
196
|
+
:where([data-component="breadcrumbs"][data-separator="slash"]) [data-breadcrumb-part="separator"]::before {
|
|
197
|
+
content: "/";
|
|
198
|
+
@apply px-1;
|
|
199
|
+
}
|
|
194
200
|
|
|
195
|
-
[data-component="breadcrumbs"][data-separator="
|
|
196
|
-
|
|
197
|
-
}
|
|
201
|
+
:where([data-component="breadcrumbs"][data-separator="slash"]) [data-breadcrumb-part="separator"] svg {
|
|
202
|
+
@apply hidden;
|
|
203
|
+
}
|
|
198
204
|
|
|
199
|
-
/*
|
|
200
|
-
[data-component="breadcrumbs"][data-separator="
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
205
|
+
/* Dot separator variant */
|
|
206
|
+
:where([data-component="breadcrumbs"][data-separator="dot"]) [data-breadcrumb-part="separator"]::before {
|
|
207
|
+
content: "•";
|
|
208
|
+
@apply px-1;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
:where([data-component="breadcrumbs"][data-separator="dot"]) [data-breadcrumb-part="separator"] svg {
|
|
212
|
+
@apply hidden;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Arrow separator variant */
|
|
216
|
+
:where([data-component="breadcrumbs"][data-separator="arrow"]) [data-breadcrumb-part="separator"]::before {
|
|
217
|
+
content: "→";
|
|
218
|
+
@apply px-1;
|
|
219
|
+
}
|
|
204
220
|
|
|
205
|
-
[data-component="breadcrumbs"][data-separator="arrow"] [data-breadcrumb-part="separator"] svg {
|
|
206
|
-
|
|
221
|
+
:where([data-component="breadcrumbs"][data-separator="arrow"]) [data-breadcrumb-part="separator"] svg {
|
|
222
|
+
@apply hidden;
|
|
223
|
+
}
|
|
207
224
|
}
|