maquina-components 0.1.2 → 0.3.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +399 -137
  3. data/app/assets/images/maquina.svg +1 -0
  4. data/app/assets/stylesheets/alert.css +143 -0
  5. data/app/assets/stylesheets/badge.css +145 -0
  6. data/app/assets/stylesheets/breadcrumbs.css +163 -0
  7. data/app/assets/stylesheets/card.css +128 -0
  8. data/app/assets/stylesheets/combobox.css +218 -0
  9. data/app/assets/stylesheets/dropdown_menu.css +248 -0
  10. data/app/assets/stylesheets/empty.css +133 -0
  11. data/app/assets/stylesheets/form.css +617 -0
  12. data/app/assets/stylesheets/header.css +61 -0
  13. data/app/assets/stylesheets/maquina_components.css +143 -64
  14. data/app/assets/stylesheets/pagination.css +154 -0
  15. data/app/assets/stylesheets/sidebar.css +477 -0
  16. data/app/assets/stylesheets/table.css +205 -0
  17. data/app/assets/stylesheets/toast.css +433 -0
  18. data/app/assets/stylesheets/toggle_group.css +151 -0
  19. data/app/assets/tailwind/maquina_components_engine/engine.css +18 -0
  20. data/app/helpers/maquina_components/breadcrumbs_helper.rb +118 -0
  21. data/app/helpers/maquina_components/combobox_helper.rb +300 -0
  22. data/app/helpers/maquina_components/dropdown_menu_helper.rb +249 -0
  23. data/app/helpers/maquina_components/empty_helper.rb +102 -0
  24. data/app/helpers/{components → maquina_components}/icons_helper.rb +40 -3
  25. data/app/helpers/maquina_components/pagination_helper.rb +153 -0
  26. data/app/helpers/maquina_components/sidebar_helper.rb +63 -0
  27. data/app/helpers/maquina_components/table_helper.rb +144 -0
  28. data/app/helpers/maquina_components/toast_helper.rb +115 -0
  29. data/app/helpers/maquina_components/toggle_group_helper.rb +172 -0
  30. data/app/javascript/controllers/breadcrumb_controller.js +71 -0
  31. data/app/javascript/controllers/combobox_controller.js +325 -0
  32. data/app/javascript/controllers/dropdown_menu_controller.js +203 -0
  33. data/app/javascript/controllers/menu_button_controller.js +59 -0
  34. data/app/javascript/controllers/sidebar_controller.js +316 -0
  35. data/app/javascript/controllers/sidebar_trigger_controller.js +32 -0
  36. data/app/javascript/controllers/toast_controller.js +115 -0
  37. data/app/javascript/controllers/toaster_controller.js +226 -0
  38. data/app/javascript/controllers/toggle_group_controller.js +178 -0
  39. data/app/views/components/_alert.html.erb +11 -10
  40. data/app/views/components/_badge.html.erb +10 -0
  41. data/app/views/components/_breadcrumbs.html.erb +16 -0
  42. data/app/views/components/_card.html.erb +4 -8
  43. data/app/views/components/_combobox.html.erb +13 -0
  44. data/app/views/components/_dropdown.html.erb +25 -0
  45. data/app/views/components/_dropdown_menu.html.erb +9 -0
  46. data/app/views/components/_empty.html.erb +10 -0
  47. data/app/views/components/_header.html.erb +8 -0
  48. data/app/views/components/_menu_button.html.erb +44 -0
  49. data/app/views/components/_pagination.html.erb +12 -33
  50. data/app/views/components/_separator.html.erb +11 -0
  51. data/app/views/components/_sidebar.html.erb +30 -20
  52. data/app/views/components/_simple_table.html.erb +49 -0
  53. data/app/views/components/_table.html.erb +21 -0
  54. data/app/views/components/_toast.html.erb +53 -0
  55. data/app/views/components/_toaster.html.erb +17 -0
  56. data/app/views/components/_toggle_group.html.erb +24 -0
  57. data/app/views/components/alert/_description.html.erb +6 -0
  58. data/app/views/components/alert/_title.html.erb +6 -0
  59. data/app/views/components/breadcrumbs/_ellipsis.html.erb +9 -0
  60. data/app/views/components/breadcrumbs/_item.html.erb +8 -0
  61. data/app/views/components/breadcrumbs/_link.html.erb +8 -0
  62. data/app/views/components/breadcrumbs/_list.html.erb +8 -0
  63. data/app/views/components/breadcrumbs/_page.html.erb +8 -0
  64. data/app/views/components/breadcrumbs/_separator.html.erb +17 -0
  65. data/app/views/components/card/_action.html.erb +6 -0
  66. data/app/views/components/card/_content.html.erb +9 -0
  67. data/app/views/components/card/_description.html.erb +6 -0
  68. data/app/views/components/card/_footer.html.erb +17 -0
  69. data/app/views/components/card/_header.html.erb +9 -0
  70. data/app/views/components/card/_title.html.erb +9 -0
  71. data/app/views/components/combobox/_content.html.erb +17 -0
  72. data/app/views/components/combobox/_empty.html.erb +9 -0
  73. data/app/views/components/combobox/_group.html.erb +8 -0
  74. data/app/views/components/combobox/_input.html.erb +18 -0
  75. data/app/views/components/combobox/_label.html.erb +8 -0
  76. data/app/views/components/combobox/_list.html.erb +8 -0
  77. data/app/views/components/combobox/_option.html.erb +24 -0
  78. data/app/views/components/combobox/_separator.html.erb +6 -0
  79. data/app/views/components/combobox/_trigger.html.erb +22 -0
  80. data/app/views/components/dropdown_menu/_content.html.erb +20 -0
  81. data/app/views/components/dropdown_menu/_group.html.erb +12 -0
  82. data/app/views/components/dropdown_menu/_item.html.erb +29 -0
  83. data/app/views/components/dropdown_menu/_label.html.erb +13 -0
  84. data/app/views/components/dropdown_menu/_separator.html.erb +11 -0
  85. data/app/views/components/dropdown_menu/_shortcut.html.erb +12 -0
  86. data/app/views/components/dropdown_menu/_trigger.html.erb +24 -0
  87. data/app/views/components/empty/_content.html.erb +8 -0
  88. data/app/views/components/empty/_description.html.erb +12 -0
  89. data/app/views/components/empty/_header.html.erb +8 -0
  90. data/app/views/components/empty/_media.html.erb +13 -0
  91. data/app/views/components/empty/_title.html.erb +12 -0
  92. data/app/views/components/pagination/_content.html.erb +8 -0
  93. data/app/views/components/pagination/_ellipsis.html.erb +28 -0
  94. data/app/views/components/pagination/_item.html.erb +8 -0
  95. data/app/views/components/pagination/_link.html.erb +23 -0
  96. data/app/views/components/pagination/_next.html.erb +57 -0
  97. data/app/views/components/pagination/_previous.html.erb +57 -0
  98. data/app/views/components/sidebar/_content.html.erb +8 -0
  99. data/app/views/components/sidebar/_footer.html.erb +8 -0
  100. data/app/views/components/sidebar/_group.html.erb +12 -0
  101. data/app/views/components/sidebar/_header.html.erb +8 -0
  102. data/app/views/components/sidebar/_inset.html.erb +8 -0
  103. data/app/views/components/sidebar/_menu.html.erb +8 -0
  104. data/app/views/components/sidebar/_menu_button.html.erb +14 -0
  105. data/app/views/components/sidebar/_menu_item.html.erb +7 -0
  106. data/app/views/components/sidebar/_menu_link.html.erb +32 -0
  107. data/app/views/components/sidebar/_provider.html.erb +16 -0
  108. data/app/views/components/sidebar/_trigger.html.erb +12 -0
  109. data/app/views/components/stats/_stats_card.html.erb +100 -0
  110. data/app/views/components/stats/_stats_grid.html.erb +38 -0
  111. data/app/views/components/table/_body.html.erb +5 -0
  112. data/app/views/components/table/_caption.html.erb +5 -0
  113. data/app/views/components/table/_cell.html.erb +5 -0
  114. data/app/views/components/table/_footer.html.erb +5 -0
  115. data/app/views/components/table/_head.html.erb +8 -0
  116. data/app/views/components/table/_header.html.erb +8 -0
  117. data/app/views/components/table/_row.html.erb +8 -0
  118. data/app/views/components/toast/_action.html.erb +14 -0
  119. data/app/views/components/toast/_description.html.erb +8 -0
  120. data/app/views/components/toast/_title.html.erb +8 -0
  121. data/app/views/components/toggle_group/_item.html.erb +19 -0
  122. data/config/importmap.rb +1 -0
  123. data/lib/generators/maquina_components/install/USAGE +39 -0
  124. data/lib/generators/maquina_components/install/install_generator.rb +123 -0
  125. data/lib/generators/maquina_components/install/templates/maquina_components_helper.rb.tt +68 -0
  126. data/lib/generators/maquina_components/install/templates/theme.css.tt +179 -0
  127. data/lib/maquina_components/engine.rb +10 -0
  128. data/lib/maquina_components/version.rb +1 -1
  129. metadata +138 -12
  130. data/app/helpers/components/pagination_helper.rb +0 -15
  131. data/app/views/components/_card_content.html.erb +0 -5
  132. data/app/views/components/_card_header.html.erb +0 -8
  133. data/app/views/components/_sidebar_content.html.erb +0 -8
  134. data/app/views/components/_sidebar_group.html.erb +0 -42
  135. data/app/views/components/_sidebar_header.html.erb +0 -3
@@ -0,0 +1,433 @@
1
+ /* ===== Toast Component Styles ===== */
2
+ /*
3
+ * Toast notification system for displaying temporary messages.
4
+ * Uses data attributes for styling to maintain consistency.
5
+ * Fully compatible with dark mode via CSS variables.
6
+ *
7
+ * Structure:
8
+ * - toaster (fixed container, manages stack)
9
+ * - toast (individual notification)
10
+ * - icon (variant icon)
11
+ * - content (title + description)
12
+ * - action (optional button)
13
+ * - close (dismiss button)
14
+ */
15
+
16
+ /* ===== Toaster Container ===== */
17
+ [data-component="toaster"] {
18
+ position: fixed;
19
+ z-index: 100;
20
+ display: flex;
21
+ flex-direction: column;
22
+ pointer-events: none;
23
+ @apply gap-3 p-4;
24
+ max-height: 100vh;
25
+ overflow: hidden;
26
+ }
27
+
28
+ /* Position variants */
29
+ [data-component="toaster"][data-position="top-left"] {
30
+ top: 0;
31
+ left: 0;
32
+ align-items: flex-start;
33
+ }
34
+
35
+ [data-component="toaster"][data-position="top-center"] {
36
+ top: 0;
37
+ left: 50%;
38
+ transform: translateX(-50%);
39
+ align-items: center;
40
+ }
41
+
42
+ [data-component="toaster"][data-position="top-right"] {
43
+ top: 0;
44
+ right: 0;
45
+ align-items: flex-end;
46
+ }
47
+
48
+ [data-component="toaster"][data-position="bottom-left"] {
49
+ bottom: 0;
50
+ left: 0;
51
+ align-items: flex-start;
52
+ flex-direction: column-reverse;
53
+ }
54
+
55
+ [data-component="toaster"][data-position="bottom-center"] {
56
+ bottom: 0;
57
+ left: 50%;
58
+ transform: translateX(-50%);
59
+ align-items: center;
60
+ flex-direction: column-reverse;
61
+ }
62
+
63
+ [data-component="toaster"][data-position="bottom-right"] {
64
+ bottom: 0;
65
+ right: 0;
66
+ align-items: flex-end;
67
+ flex-direction: column-reverse;
68
+ }
69
+
70
+ /* ===== Toast Base Styles ===== */
71
+ [data-component="toast"] {
72
+ position: relative;
73
+ display: flex;
74
+ align-items: flex-start;
75
+ pointer-events: auto;
76
+ background-color: var(--popover, var(--background));
77
+ color: var(--popover-foreground, var(--foreground));
78
+ border-color: var(--border);
79
+ @apply w-full max-w-sm gap-3 rounded-lg border p-4 pr-10 shadow-lg;
80
+ }
81
+
82
+ /* ===== Icon ===== */
83
+ [data-toast-part="icon"] {
84
+ @apply shrink-0;
85
+ color: var(--foreground);
86
+ }
87
+
88
+ [data-toast-part="icon"] svg {
89
+ @apply size-5;
90
+ }
91
+
92
+ /* ===== Content ===== */
93
+ [data-toast-part="content"] {
94
+ @apply flex-1 min-w-0;
95
+ }
96
+
97
+ /* ===== Title ===== */
98
+ [data-toast-part="title"] {
99
+ @apply text-sm font-semibold;
100
+ color: var(--foreground);
101
+ }
102
+
103
+ /* Title followed by description */
104
+ [data-toast-part="title"]:has(+ [data-toast-part="description"]) {
105
+ @apply mb-1;
106
+ }
107
+
108
+ /* ===== Description ===== */
109
+ [data-toast-part="description"] {
110
+ @apply text-sm;
111
+ color: var(--muted-foreground);
112
+ }
113
+
114
+ /* ===== Close Button ===== */
115
+ [data-toast-part="close"] {
116
+ position: absolute;
117
+ top: 0.5rem;
118
+ right: 0.5rem;
119
+ display: flex;
120
+ align-items: center;
121
+ justify-content: center;
122
+ border: none;
123
+ background: transparent;
124
+ cursor: pointer;
125
+ opacity: 0.5;
126
+ color: var(--foreground);
127
+ @apply size-6 rounded-sm transition-opacity;
128
+ }
129
+
130
+ [data-toast-part="close"]:hover {
131
+ opacity: 1;
132
+ }
133
+
134
+ [data-toast-part="close"]:focus-visible {
135
+ opacity: 1;
136
+ outline: 2px solid var(--ring);
137
+ outline-offset: 2px;
138
+ }
139
+
140
+ [data-toast-part="close"] svg {
141
+ @apply size-4;
142
+ }
143
+
144
+ /* ===== Action Button ===== */
145
+ [data-toast-part="action"] {
146
+ display: inline-flex;
147
+ align-items: center;
148
+ justify-content: center;
149
+ border: 1px solid var(--border);
150
+ background-color: transparent;
151
+ color: var(--foreground);
152
+ cursor: pointer;
153
+ text-decoration: none;
154
+ @apply mt-2 h-8 rounded-md px-3 text-xs font-medium transition-colors;
155
+ }
156
+
157
+ [data-toast-part="action"]:hover {
158
+ background-color: var(--accent);
159
+ color: var(--accent-foreground);
160
+ }
161
+
162
+ [data-toast-part="action"]:focus-visible {
163
+ outline: 2px solid var(--ring);
164
+ outline-offset: 2px;
165
+ }
166
+
167
+ /* ===== Variant: Default ===== */
168
+ [data-component="toast"][data-variant="default"] {
169
+ background-color: var(--popover, var(--background));
170
+ color: var(--popover-foreground, var(--foreground));
171
+ border-color: var(--border);
172
+ }
173
+
174
+ /* ===== Variant: Success ===== */
175
+ [data-component="toast"][data-variant="success"] {
176
+ background-color: var(--success);
177
+ color: var(--success-foreground);
178
+ border-color: var(--success);
179
+ }
180
+
181
+ [data-component="toast"][data-variant="success"] [data-toast-part="icon"],
182
+ [data-component="toast"][data-variant="success"] [data-toast-part="title"],
183
+ [data-component="toast"][data-variant="success"] [data-toast-part="close"] {
184
+ color: var(--success-foreground);
185
+ }
186
+
187
+ [data-component="toast"][data-variant="success"] [data-toast-part="description"] {
188
+ color: var(--success-foreground);
189
+ opacity: 0.9;
190
+ }
191
+
192
+ [data-component="toast"][data-variant="success"] [data-toast-part="action"] {
193
+ border-color: var(--success-foreground);
194
+ color: var(--success-foreground);
195
+ }
196
+
197
+ [data-component="toast"][data-variant="success"] [data-toast-part="action"]:hover {
198
+ background-color: var(--success-foreground);
199
+ color: var(--success);
200
+ }
201
+
202
+ /* ===== Variant: Info ===== */
203
+ [data-component="toast"][data-variant="info"] {
204
+ background-color: var(--info, var(--primary));
205
+ color: var(--info-foreground, var(--primary-foreground));
206
+ border-color: var(--info, var(--primary));
207
+ }
208
+
209
+ [data-component="toast"][data-variant="info"] [data-toast-part="icon"],
210
+ [data-component="toast"][data-variant="info"] [data-toast-part="title"],
211
+ [data-component="toast"][data-variant="info"] [data-toast-part="close"] {
212
+ color: var(--info-foreground, var(--primary-foreground));
213
+ }
214
+
215
+ [data-component="toast"][data-variant="info"] [data-toast-part="description"] {
216
+ color: var(--info-foreground, var(--primary-foreground));
217
+ opacity: 0.9;
218
+ }
219
+
220
+ [data-component="toast"][data-variant="info"] [data-toast-part="action"] {
221
+ border-color: var(--info-foreground, var(--primary-foreground));
222
+ color: var(--info-foreground, var(--primary-foreground));
223
+ }
224
+
225
+ [data-component="toast"][data-variant="info"] [data-toast-part="action"]:hover {
226
+ background-color: var(--info-foreground, var(--primary-foreground));
227
+ color: var(--info, var(--primary));
228
+ }
229
+
230
+ /* ===== Variant: Warning ===== */
231
+ [data-component="toast"][data-variant="warning"] {
232
+ background-color: var(--warning);
233
+ color: var(--warning-foreground);
234
+ border-color: var(--warning);
235
+ }
236
+
237
+ [data-component="toast"][data-variant="warning"] [data-toast-part="icon"],
238
+ [data-component="toast"][data-variant="warning"] [data-toast-part="title"],
239
+ [data-component="toast"][data-variant="warning"] [data-toast-part="close"] {
240
+ color: var(--warning-foreground);
241
+ }
242
+
243
+ [data-component="toast"][data-variant="warning"] [data-toast-part="description"] {
244
+ color: var(--warning-foreground);
245
+ opacity: 0.9;
246
+ }
247
+
248
+ [data-component="toast"][data-variant="warning"] [data-toast-part="action"] {
249
+ border-color: var(--warning-foreground);
250
+ color: var(--warning-foreground);
251
+ }
252
+
253
+ [data-component="toast"][data-variant="warning"] [data-toast-part="action"]:hover {
254
+ background-color: var(--warning-foreground);
255
+ color: var(--warning);
256
+ }
257
+
258
+ /* ===== Variant: Error ===== */
259
+ [data-component="toast"][data-variant="error"] {
260
+ background-color: var(--destructive);
261
+ color: var(--destructive-foreground);
262
+ border-color: var(--destructive);
263
+ }
264
+
265
+ [data-component="toast"][data-variant="error"] [data-toast-part="icon"],
266
+ [data-component="toast"][data-variant="error"] [data-toast-part="title"],
267
+ [data-component="toast"][data-variant="error"] [data-toast-part="close"] {
268
+ color: var(--destructive-foreground);
269
+ }
270
+
271
+ [data-component="toast"][data-variant="error"] [data-toast-part="description"] {
272
+ color: var(--destructive-foreground);
273
+ opacity: 0.9;
274
+ }
275
+
276
+ [data-component="toast"][data-variant="error"] [data-toast-part="action"] {
277
+ border-color: var(--destructive-foreground);
278
+ color: var(--destructive-foreground);
279
+ }
280
+
281
+ [data-component="toast"][data-variant="error"] [data-toast-part="action"]:hover {
282
+ background-color: var(--destructive-foreground);
283
+ color: var(--destructive);
284
+ }
285
+
286
+ /* ===== Animation States ===== */
287
+
288
+ /* Enter from right (for right-aligned positions) */
289
+ [data-component="toast"][data-state="entering"] {
290
+ animation: toast-enter-right 200ms ease-out;
291
+ }
292
+
293
+ /* Enter from left (for left-aligned positions) */
294
+ [data-component="toaster"][data-position="top-left"] [data-component="toast"][data-state="entering"],
295
+ [data-component="toaster"][data-position="bottom-left"] [data-component="toast"][data-state="entering"] {
296
+ animation: toast-enter-left 200ms ease-out;
297
+ }
298
+
299
+ /* Enter from top (for center-aligned positions) */
300
+ [data-component="toaster"][data-position="top-center"] [data-component="toast"][data-state="entering"] {
301
+ animation: toast-enter-top 200ms ease-out;
302
+ }
303
+
304
+ /* Enter from bottom (for bottom-center) */
305
+ [data-component="toaster"][data-position="bottom-center"] [data-component="toast"][data-state="entering"] {
306
+ animation: toast-enter-bottom 200ms ease-out;
307
+ }
308
+
309
+ /* Visible state */
310
+ [data-component="toast"][data-state="visible"] {
311
+ opacity: 1;
312
+ transform: translateX(0) translateY(0);
313
+ }
314
+
315
+ /* Exit animations */
316
+ [data-component="toast"][data-state="exiting"] {
317
+ animation: toast-exit-right 150ms ease-in forwards;
318
+ }
319
+
320
+ [data-component="toaster"][data-position="top-left"] [data-component="toast"][data-state="exiting"],
321
+ [data-component="toaster"][data-position="bottom-left"] [data-component="toast"][data-state="exiting"] {
322
+ animation: toast-exit-left 150ms ease-in forwards;
323
+ }
324
+
325
+ [data-component="toaster"][data-position="top-center"] [data-component="toast"][data-state="exiting"] {
326
+ animation: toast-exit-top 150ms ease-in forwards;
327
+ }
328
+
329
+ [data-component="toaster"][data-position="bottom-center"] [data-component="toast"][data-state="exiting"] {
330
+ animation: toast-exit-bottom 150ms ease-in forwards;
331
+ }
332
+
333
+ /* Keyframes */
334
+ @keyframes toast-enter-right {
335
+ from {
336
+ opacity: 0;
337
+ transform: translateX(100%);
338
+ }
339
+ to {
340
+ opacity: 1;
341
+ transform: translateX(0);
342
+ }
343
+ }
344
+
345
+ @keyframes toast-enter-left {
346
+ from {
347
+ opacity: 0;
348
+ transform: translateX(-100%);
349
+ }
350
+ to {
351
+ opacity: 1;
352
+ transform: translateX(0);
353
+ }
354
+ }
355
+
356
+ @keyframes toast-enter-top {
357
+ from {
358
+ opacity: 0;
359
+ transform: translateY(-100%);
360
+ }
361
+ to {
362
+ opacity: 1;
363
+ transform: translateY(0);
364
+ }
365
+ }
366
+
367
+ @keyframes toast-enter-bottom {
368
+ from {
369
+ opacity: 0;
370
+ transform: translateY(100%);
371
+ }
372
+ to {
373
+ opacity: 1;
374
+ transform: translateY(0);
375
+ }
376
+ }
377
+
378
+ @keyframes toast-exit-right {
379
+ from {
380
+ opacity: 1;
381
+ transform: translateX(0);
382
+ }
383
+ to {
384
+ opacity: 0;
385
+ transform: translateX(100%);
386
+ }
387
+ }
388
+
389
+ @keyframes toast-exit-left {
390
+ from {
391
+ opacity: 1;
392
+ transform: translateX(0);
393
+ }
394
+ to {
395
+ opacity: 0;
396
+ transform: translateX(-100%);
397
+ }
398
+ }
399
+
400
+ @keyframes toast-exit-top {
401
+ from {
402
+ opacity: 1;
403
+ transform: translateY(0);
404
+ }
405
+ to {
406
+ opacity: 0;
407
+ transform: translateY(-100%);
408
+ }
409
+ }
410
+
411
+ @keyframes toast-exit-bottom {
412
+ from {
413
+ opacity: 1;
414
+ transform: translateY(0);
415
+ }
416
+ to {
417
+ opacity: 0;
418
+ transform: translateY(100%);
419
+ }
420
+ }
421
+
422
+ /* ===== Hover Pause Indicator ===== */
423
+ [data-component="toast"]:hover {
424
+ /* Slight scale to indicate interaction */
425
+ box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
426
+ }
427
+
428
+ /* ===== Dark Mode ===== */
429
+ /*
430
+ * Dark mode is handled automatically through CSS variables.
431
+ * The theme variables change based on the .dark class on html/body.
432
+ * No additional dark mode styles needed here.
433
+ */
@@ -0,0 +1,151 @@
1
+ /* ===== Toggle Group Component Styles ===== */
2
+ /*
3
+ * A group of two-state buttons that can be toggled on or off.
4
+ * Uses data attributes for styling to avoid inline utility classes.
5
+ * Fully compatible with dark mode via CSS variables.
6
+ *
7
+ * Structure:
8
+ * - toggle-group (root container)
9
+ * - item (toggle button)
10
+ */
11
+
12
+ /* ===== Root Container ===== */
13
+ [data-component="toggle-group"] {
14
+ display: inline-flex;
15
+ align-items: center;
16
+ @apply gap-1 rounded-md;
17
+ }
18
+
19
+ /* Group disabled state */
20
+ [data-component="toggle-group"][aria-disabled="true"] {
21
+ @apply opacity-50 pointer-events-none;
22
+ }
23
+
24
+ /* ===== Toggle Item Base ===== */
25
+ [data-toggle-group-part="item"] {
26
+ display: inline-flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ @apply gap-2 rounded-md text-sm font-medium;
30
+ @apply transition-colors duration-150;
31
+
32
+ /* Default size */
33
+ @apply h-9 px-3;
34
+
35
+ /* Remove default button styles */
36
+ border: none;
37
+ cursor: pointer;
38
+
39
+ /* Default variant colors */
40
+ background-color: transparent;
41
+ color: var(--muted-foreground);
42
+ }
43
+
44
+ /* ===== Size Variants ===== */
45
+
46
+ /* Small */
47
+ [data-component="toggle-group"][data-size="sm"] [data-toggle-group-part="item"] {
48
+ @apply h-8 px-2.5 text-xs;
49
+ }
50
+
51
+ /* Large */
52
+ [data-component="toggle-group"][data-size="lg"] [data-toggle-group-part="item"] {
53
+ @apply h-10 px-4;
54
+ }
55
+
56
+ /* ===== Visual Variants ===== */
57
+
58
+ /* Default variant */
59
+ [data-component="toggle-group"][data-variant="default"] [data-toggle-group-part="item"] {
60
+ background-color: transparent;
61
+ }
62
+
63
+ [data-component="toggle-group"][data-variant="default"] [data-toggle-group-part="item"]:hover:not(:disabled) {
64
+ background-color: var(--muted);
65
+ color: var(--muted-foreground);
66
+ }
67
+
68
+ [data-component="toggle-group"][data-variant="default"] [data-toggle-group-part="item"][data-state="on"] {
69
+ background-color: var(--accent);
70
+ color: var(--accent-foreground);
71
+ }
72
+
73
+ /* Outline variant */
74
+ [data-component="toggle-group"][data-variant="outline"] {
75
+ background-color: transparent;
76
+ border: 1px solid var(--border);
77
+ @apply gap-0;
78
+ }
79
+
80
+ [data-component="toggle-group"][data-variant="outline"] [data-toggle-group-part="item"] {
81
+ @apply rounded-none;
82
+ border-right: 1px solid var(--border);
83
+ }
84
+
85
+ [data-component="toggle-group"][data-variant="outline"] [data-toggle-group-part="item"]:first-child {
86
+ @apply rounded-l-md;
87
+ }
88
+
89
+ [data-component="toggle-group"][data-variant="outline"] [data-toggle-group-part="item"]:last-child {
90
+ @apply rounded-r-md;
91
+ border-right: none;
92
+ }
93
+
94
+ [data-component="toggle-group"][data-variant="outline"] [data-toggle-group-part="item"]:hover:not(:disabled) {
95
+ background-color: var(--muted);
96
+ color: var(--muted-foreground);
97
+ }
98
+
99
+ [data-component="toggle-group"][data-variant="outline"] [data-toggle-group-part="item"][data-state="on"] {
100
+ background-color: var(--accent);
101
+ color: var(--accent-foreground);
102
+ }
103
+
104
+ /* ===== Interactive States ===== */
105
+
106
+ /* Hover */
107
+ [data-toggle-group-part="item"]:hover:not(:disabled) {
108
+ background-color: var(--muted);
109
+ color: var(--muted-foreground);
110
+ }
111
+
112
+ /* Pressed (on) state */
113
+ [data-toggle-group-part="item"][data-state="on"] {
114
+ background-color: var(--accent);
115
+ color: var(--accent-foreground);
116
+ }
117
+
118
+ /* Focus visible */
119
+ [data-toggle-group-part="item"]:focus-visible {
120
+ @apply outline-none;
121
+ box-shadow: 0 0 0 2px var(--background),
122
+ 0 0 0 4px var(--ring);
123
+ z-index: 1;
124
+ position: relative;
125
+ }
126
+
127
+ /* Disabled */
128
+ [data-toggle-group-part="item"]:disabled {
129
+ @apply opacity-50 cursor-not-allowed pointer-events-none;
130
+ }
131
+
132
+ /* ===== Icon Support ===== */
133
+ [data-toggle-group-part="item"] svg {
134
+ @apply size-4 shrink-0 pointer-events-none;
135
+ }
136
+
137
+ /* Icon-only size adjustments */
138
+ [data-component="toggle-group"][data-size="sm"] [data-toggle-group-part="item"] svg {
139
+ @apply size-3.5;
140
+ }
141
+
142
+ [data-component="toggle-group"][data-size="lg"] [data-toggle-group-part="item"] svg {
143
+ @apply size-5;
144
+ }
145
+
146
+ /* ===== Dark Mode ===== */
147
+ /*
148
+ * Dark mode is handled automatically through CSS variables.
149
+ * The theme variables change based on the .dark class on html/body.
150
+ * No additional dark mode styles needed here.
151
+ */
@@ -0,0 +1,18 @@
1
+ @source "../../../views/";
2
+
3
+ @layer components {
4
+ @import "../../stylesheets/alert.css";
5
+ @import "../../stylesheets/badge.css";
6
+ @import "../../stylesheets/breadcrumbs.css";
7
+ @import "../../stylesheets/card.css";
8
+ @import "../../stylesheets/combobox.css";
9
+ @import "../../stylesheets/dropdown_menu.css";
10
+ @import "../../stylesheets/empty.css";
11
+ @import "../../stylesheets/form.css";
12
+ @import "../../stylesheets/header.css";
13
+ @import "../../stylesheets/pagination.css";
14
+ @import "../../stylesheets/sidebar.css";
15
+ @import "../../stylesheets/table.css";
16
+ @import "../../stylesheets/toast.css";
17
+ @import "../../stylesheets/toggle_group.css";
18
+ }