maquina-components 0.5.0 → 0.5.1

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 (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/app/assets/stylesheets/breadcrumbs.css +21 -0
  4. data/app/assets/stylesheets/combobox.css +36 -1
  5. data/app/assets/stylesheets/drawer.css +15 -0
  6. data/app/assets/stylesheets/menu_button.css +155 -0
  7. data/app/assets/stylesheets/separator.css +20 -0
  8. data/app/assets/stylesheets/sidebar.css +12 -0
  9. data/app/assets/stylesheets/stats.css +101 -0
  10. data/app/assets/tailwind/maquina_components_engine/engine.css +3 -0
  11. data/app/helpers/maquina_components/combobox_helper.rb +2 -1
  12. data/app/helpers/maquina_components/components_helper.rb +33 -0
  13. data/app/helpers/maquina_components/icons_helper.rb +58 -0
  14. data/app/javascript/controllers/breadcrumb_controller.js +39 -30
  15. data/app/javascript/controllers/combobox_controller.js +9 -0
  16. data/app/javascript/controllers/drawer_controller.js +43 -9
  17. data/app/javascript/controllers/drawer_trigger_controller.js +33 -3
  18. data/app/javascript/controllers/menu_button_controller.js +107 -29
  19. data/app/javascript/controllers/sidebar_controller.js +6 -8
  20. data/app/javascript/controllers/sidebar_trigger_controller.js +33 -4
  21. data/app/javascript/controllers/toaster_controller.js +12 -0
  22. data/app/views/components/_alert.html.erb +3 -1
  23. data/app/views/components/_badge.html.erb +7 -1
  24. data/app/views/components/_breadcrumbs.html.erb +1 -1
  25. data/app/views/components/_calendar.html.erb +1 -1
  26. data/app/views/components/_card.html.erb +1 -1
  27. data/app/views/components/_combobox.html.erb +3 -2
  28. data/app/views/components/_date_picker.html.erb +4 -3
  29. data/app/views/components/_drawer.html.erb +8 -2
  30. data/app/views/components/_dropdown.html.erb +21 -24
  31. data/app/views/components/_dropdown_menu.html.erb +1 -1
  32. data/app/views/components/_empty.html.erb +1 -1
  33. data/app/views/components/_header.html.erb +1 -1
  34. data/app/views/components/_menu_button.html.erb +29 -34
  35. data/app/views/components/_pagination.html.erb +1 -1
  36. data/app/views/components/_separator.html.erb +9 -10
  37. data/app/views/components/_sidebar.html.erb +1 -1
  38. data/app/views/components/_simple_table.html.erb +3 -1
  39. data/app/views/components/_table.html.erb +1 -1
  40. data/app/views/components/_toast.html.erb +6 -1
  41. data/app/views/components/_toaster.html.erb +1 -1
  42. data/app/views/components/_toggle_group.html.erb +1 -1
  43. data/app/views/components/alert/_description.html.erb +1 -1
  44. data/app/views/components/alert/_title.html.erb +1 -1
  45. data/app/views/components/breadcrumbs/_ellipsis.html.erb +1 -1
  46. data/app/views/components/breadcrumbs/_item.html.erb +1 -1
  47. data/app/views/components/breadcrumbs/_link.html.erb +1 -1
  48. data/app/views/components/breadcrumbs/_list.html.erb +1 -1
  49. data/app/views/components/breadcrumbs/_page.html.erb +1 -1
  50. data/app/views/components/breadcrumbs/_separator.html.erb +1 -1
  51. data/app/views/components/calendar/_header.html.erb +1 -1
  52. data/app/views/components/calendar/_week.html.erb +1 -1
  53. data/app/views/components/card/_action.html.erb +1 -1
  54. data/app/views/components/card/_content.html.erb +1 -1
  55. data/app/views/components/card/_description.html.erb +1 -1
  56. data/app/views/components/card/_footer.html.erb +1 -1
  57. data/app/views/components/card/_header.html.erb +1 -1
  58. data/app/views/components/card/_title.html.erb +1 -1
  59. data/app/views/components/combobox/_content.html.erb +1 -1
  60. data/app/views/components/combobox/_empty.html.erb +3 -3
  61. data/app/views/components/combobox/_group.html.erb +1 -1
  62. data/app/views/components/combobox/_input.html.erb +1 -1
  63. data/app/views/components/combobox/_label.html.erb +1 -1
  64. data/app/views/components/combobox/_list.html.erb +1 -1
  65. data/app/views/components/combobox/_option.html.erb +1 -1
  66. data/app/views/components/combobox/_separator.html.erb +1 -1
  67. data/app/views/components/combobox/_trigger.html.erb +1 -1
  68. data/app/views/components/drawer/_close.html.erb +1 -1
  69. data/app/views/components/drawer/_content.html.erb +1 -1
  70. data/app/views/components/drawer/_footer.html.erb +1 -1
  71. data/app/views/components/drawer/_header.html.erb +2 -2
  72. data/app/views/components/drawer/_provider.html.erb +2 -2
  73. data/app/views/components/drawer/_trigger.html.erb +1 -1
  74. data/app/views/components/dropdown_menu/_content.html.erb +1 -1
  75. data/app/views/components/dropdown_menu/_group.html.erb +1 -1
  76. data/app/views/components/dropdown_menu/_item.html.erb +1 -1
  77. data/app/views/components/dropdown_menu/_label.html.erb +3 -7
  78. data/app/views/components/dropdown_menu/_separator.html.erb +1 -1
  79. data/app/views/components/dropdown_menu/_shortcut.html.erb +3 -7
  80. data/app/views/components/dropdown_menu/_trigger.html.erb +1 -1
  81. data/app/views/components/empty/_content.html.erb +1 -1
  82. data/app/views/components/empty/_description.html.erb +3 -7
  83. data/app/views/components/empty/_header.html.erb +1 -1
  84. data/app/views/components/empty/_media.html.erb +5 -3
  85. data/app/views/components/empty/_title.html.erb +3 -7
  86. data/app/views/components/pagination/_content.html.erb +1 -1
  87. data/app/views/components/pagination/_item.html.erb +1 -1
  88. data/app/views/components/pagination/_link.html.erb +1 -1
  89. data/app/views/components/pagination/_next.html.erb +1 -1
  90. data/app/views/components/pagination/_previous.html.erb +1 -1
  91. data/app/views/components/sidebar/_content.html.erb +1 -1
  92. data/app/views/components/sidebar/_footer.html.erb +1 -1
  93. data/app/views/components/sidebar/_group.html.erb +1 -1
  94. data/app/views/components/sidebar/_header.html.erb +1 -1
  95. data/app/views/components/sidebar/_inset.html.erb +1 -1
  96. data/app/views/components/sidebar/_menu.html.erb +1 -1
  97. data/app/views/components/sidebar/_menu_button.html.erb +1 -1
  98. data/app/views/components/sidebar/_menu_item.html.erb +1 -1
  99. data/app/views/components/sidebar/_menu_link.html.erb +4 -7
  100. data/app/views/components/sidebar/_provider.html.erb +1 -1
  101. data/app/views/components/sidebar/_trigger.html.erb +1 -1
  102. data/app/views/components/stats/_stats_card.html.erb +32 -92
  103. data/app/views/components/stats/_stats_grid.html.erb +18 -24
  104. data/app/views/components/table/_body.html.erb +1 -1
  105. data/app/views/components/table/_caption.html.erb +3 -3
  106. data/app/views/components/table/_cell.html.erb +3 -3
  107. data/app/views/components/table/_footer.html.erb +1 -1
  108. data/app/views/components/table/_head.html.erb +3 -3
  109. data/app/views/components/table/_header.html.erb +1 -1
  110. data/app/views/components/table/_row.html.erb +1 -1
  111. data/app/views/components/toast/_action.html.erb +1 -1
  112. data/app/views/components/toast/_description.html.erb +1 -1
  113. data/app/views/components/toast/_title.html.erb +1 -1
  114. data/app/views/components/toggle_group/_item.html.erb +1 -1
  115. data/lib/generators/maquina_components/install/templates/maquina_components_helper.rb.tt +1 -0
  116. data/lib/maquina-components.rb +5 -0
  117. data/lib/maquina_components/engine.rb +7 -3
  118. data/lib/maquina_components/version.rb +1 -1
  119. metadata +33 -2
  120. data/app/assets/stylesheets/maquina_components.css +0 -178
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "empty-part": "content"
4
4
  ) %>
5
5
 
@@ -1,12 +1,8 @@
1
- <%# locals: (text: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
1
+ <%# locals: (text: nil, content: nil, css_classes: "", **html_options) %>
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "empty-part": "description"
4
4
  ) %>
5
5
 
6
6
  <%= content_tag :p, class: css_classes.presence, data: merged_data, **html_options do %>
7
- <% if text.present? %>
8
- <%= text %>
9
- <% else %>
10
- <%= yield %>
11
- <% end %>
7
+ <%= text.presence || content || yield %>
12
8
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "empty-part": "header"
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
- <%# locals: (icon: nil, variant: :icon, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
1
+ <%# locals: (icon: nil, content: nil, variant: :icon, css_classes: "", **html_options) %>
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "empty-part": "media",
4
4
  variant: variant
5
5
  ) %>
@@ -7,7 +7,9 @@
7
7
  <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
8
8
  <% if icon.present? && respond_to?(:icon_for) %>
9
9
  <%= icon_for(icon) %>
10
- <% elsif block_given? %>
10
+ <% elsif content %>
11
+ <%= content %>
12
+ <% else %>
11
13
  <%= yield %>
12
14
  <% end %>
13
15
  <% end %>
@@ -1,12 +1,8 @@
1
- <%# locals: (text: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
1
+ <%# locals: (text: nil, content: nil, css_classes: "", **html_options) %>
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "empty-part": "title"
4
4
  ) %>
5
5
 
6
6
  <%= content_tag :h3, class: css_classes.presence, data: merged_data, **html_options do %>
7
- <% if text.present? %>
8
- <%= text %>
9
- <% else %>
10
- <%= yield %>
11
- <% end %>
7
+ <%= text.presence || content || yield %>
12
8
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "pagination-part": "content"
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "pagination-part": "item"
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (href:, active: false, disabled: false, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "pagination-part": "link",
4
4
  active: active
5
5
  ) %>
@@ -1,7 +1,7 @@
1
1
  <%# locals: (href: nil, label: nil, disabled: false, show_label: true, css_classes: "", **html_options) %>
2
2
  <% is_disabled = disabled || href.nil?
3
3
  display_label = label || t("maquina_components.pagination.next", default: "Next")
4
- merged_data = (html_options.delete(:data) || {}).merge("pagination-part": "next") %>
4
+ merged_data = merge_component_data(html_options, "pagination-part": "next") %>
5
5
 
6
6
  <% if is_disabled %>
7
7
  <span
@@ -1,7 +1,7 @@
1
1
  <%# locals: (href: nil, label: nil, disabled: false, show_label: true, css_classes: "", **html_options) %>
2
2
  <% is_disabled = disabled || href.nil?
3
3
  display_label = label || t("maquina_components.pagination.previous", default: "Previous")
4
- merged_data = (html_options.delete(:data) || {}).merge("pagination-part": "previous") %>
4
+ merged_data = merge_component_data(html_options, "pagination-part": "previous") %>
5
5
 
6
6
  <% if is_disabled %>
7
7
  <span
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :content
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :footer
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (title: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :group
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :header
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :inset
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :menu
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (title:, url:, icon_name: nil, size: :default, active: false, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: "menu-button",
4
4
  size: size,
5
5
  active: active
@@ -1,6 +1,6 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
2
  <% merged_data =
3
- (html_options.delete(:data) || {}).merge(sidebar_part: "menu-item") %>
3
+ merge_component_data(html_options, sidebar_part: "menu-item") %>
4
4
 
5
5
  <%= content_tag :li, class: "group/menu-item #{css_classes}", data: merged_data, **html_options do %>
6
6
  <%= yield %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (url: "#", active: false, title: nil, subtitle: nil, icon: nil, text_icon: nil, icon_classes: "", css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: "menu-link",
4
4
  active: active
5
5
  ) %>
@@ -16,16 +16,13 @@
16
16
  <% end %>
17
17
 
18
18
  <% if title.present? || subtitle.present? %>
19
- <div
20
- class="flex flex-col gap-0.5 leading-none"
21
- data-sidebar-hide-on-collapse
22
- >
19
+ <div data-sidebar-part="menu-link-text" data-sidebar-hide-on-collapse>
23
20
  <% if title.present? %>
24
- <span class="font-medium"><%= title %></span>
21
+ <span data-sidebar-part="menu-link-title"><%= title %></span>
25
22
  <% end %>
26
23
 
27
24
  <% if subtitle.present? %>
28
- <span class="text-xs text-sidebar-foreground/70"><%= subtitle %></span>
25
+ <span data-sidebar-part="menu-link-subtitle"><%= subtitle %></span>
29
26
  <% end %>
30
27
  </div>
31
28
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (id: nil, default_open: true, variant: :inset, css_classes: "", cookie_name: "sidebar_state", keyboard_shortcut: "b", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  component: :sidebar,
4
4
  variant: variant,
5
5
  controller: "sidebar",
@@ -1,5 +1,5 @@
1
1
  <%# locals: (icon_name: :left_panel, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  sidebar_part: :trigger,
4
4
  controller: "sidebar-trigger",
5
5
  action: "click->sidebar-trigger#triggerClick",
@@ -1,100 +1,40 @@
1
- <%# locals: (title:, value:, icon: nil, icon_class: "", subtitle: nil, value_class: "", container_class: "") -%>
1
+ <%# locals: (title:, value:, icon: nil, subtitle: nil, css_classes: "", icon_classes: "", value_classes: "", container_class: "", icon_class: "", value_class: "", **html_options) %>
2
+ <%
3
+ # container_class / icon_class / value_class are legacy aliases
4
+ css_classes = css_classes.presence || container_class
5
+ icon_classes = icon_classes.presence || icon_class
6
+ value_classes = value_classes.presence || value_class
2
7
 
3
- <div
4
- class="<%= class_names("bg-card p-4 rounded-lg shadow-sm border border-border", container_class) %>"
5
- >
6
- <div class="flex items-center justify-between">
7
- <div>
8
- <p class="text-sm text-muted-foreground"><%= title %></p>
9
- <p
10
- class="<%= class_names("text-2xl font-bold", value_class.presence || "text-foreground") %>"
11
- >
12
- <%= value %>
13
- </p>
8
+ # Legacy string icon names map to built-in icons; symbols pass straight
9
+ # through; anything else renders as custom icon markup.
10
+ legacy_icons = {
11
+ "message-square" => :message_square,
12
+ "arrow-up" => :arrow_up,
13
+ "arrow-down" => :arrow_down,
14
+ "check-circle" => :check_circle,
15
+ "lightning-bolt" => :lightning_bolt,
16
+ "exclamation-circle" => :circle_alert,
17
+ "clipboard-list" => :clipboard_list,
18
+ "chart-bar" => :chart_bar
19
+ }
20
+ icon_name = icon.is_a?(Symbol) ? icon : legacy_icons[icon.to_s]
21
+
22
+ merged_data = merge_component_data(html_options, component: "stats-card")
23
+ %>
24
+ <%= tag.div class: css_classes.presence, data: merged_data, **html_options do %>
25
+ <div data-stats-part="body">
26
+ <div data-stats-part="text">
27
+ <p data-stats-part="title"><%= title %></p>
28
+ <p data-stats-part="value" class="<%= value_classes.presence %>"><%= value %></p>
14
29
  <% if subtitle.present? %>
15
- <p class="text-xs text-muted-foreground mt-1"><%= subtitle %></p>
30
+ <p data-stats-part="subtitle"><%= subtitle %></p>
16
31
  <% end %>
17
32
  </div>
33
+
18
34
  <% if icon.present? %>
19
- <div class="<%= icon_class.presence || "text-muted-foreground" %>">
20
- <% case icon %>
21
- <% when "message-square" %>
22
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
23
- <path
24
- stroke-linecap="round"
25
- stroke-linejoin="round"
26
- stroke-width="2"
27
- d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
28
- />
29
- </svg>
30
- <% when "arrow-up" %>
31
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
32
- <path
33
- stroke-linecap="round"
34
- stroke-linejoin="round"
35
- stroke-width="2"
36
- d="M7 17L17 7M17 7H7M17 7V17"
37
- />
38
- </svg>
39
- <% when "arrow-down" %>
40
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
41
- <path
42
- stroke-linecap="round"
43
- stroke-linejoin="round"
44
- stroke-width="2"
45
- d="M17 7L7 17M7 17H17M7 17V7"
46
- />
47
- </svg>
48
- <% when "check-circle" %>
49
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
50
- <path
51
- stroke-linecap="round"
52
- stroke-linejoin="round"
53
- stroke-width="2"
54
- d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
55
- />
56
- </svg>
57
- <% when "lightning-bolt" %>
58
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
59
- <path
60
- stroke-linecap="round"
61
- stroke-linejoin="round"
62
- stroke-width="2"
63
- d="M13 10V3L4 14h7v7l9-11h-7z"
64
- />
65
- </svg>
66
- <% when "exclamation-circle" %>
67
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68
- <path
69
- stroke-linecap="round"
70
- stroke-linejoin="round"
71
- stroke-width="2"
72
- d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
73
- />
74
- </svg>
75
- <% when "clipboard-list" %>
76
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
77
- <path
78
- stroke-linecap="round"
79
- stroke-linejoin="round"
80
- stroke-width="2"
81
- d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
82
- />
83
- </svg>
84
- <% when "chart-bar" %>
85
- <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
86
- <path
87
- stroke-linecap="round"
88
- stroke-linejoin="round"
89
- stroke-width="2"
90
- d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
91
- />
92
- </svg>
93
- <% else %>
94
- <%# Allow custom SVG or icon HTML to be passed %>
95
- <%= icon %>
96
- <% end %>
35
+ <div data-stats-part="icon" class="<%= icon_classes.presence %>">
36
+ <%= icon_name ? builtin_icon_for(icon_name, class: "size-8") : icon %>
97
37
  </div>
98
38
  <% end %>
99
39
  </div>
100
- </div>
40
+ <% end %>
@@ -1,38 +1,32 @@
1
- <%# locals: (cards: [], columns: 3, container_class: "", action: nil, action_position: "end") -%>
1
+ <%# locals: (cards: [], columns: 3, action: nil, action_position: :end, css_classes: "", container_class: "", **html_options) %>
2
+ <%
3
+ # container_class is a legacy alias
4
+ css_classes = css_classes.presence || container_class
5
+ action_position = action_position.to_s
6
+ columns = columns.to_i.clamp(1, 6)
2
7
 
3
- <div
4
- class="<%= class_names("flex flex-col lg:flex-row lg:items-center gap-4": action.present?) %>"
5
- >
8
+ merged_data = merge_component_data(html_options,
9
+ component: "stats-grid",
10
+ columns: columns
11
+ )
12
+ merged_data[:"with-action"] = true if action.present?
13
+ %>
14
+ <%= tag.div class: css_classes.presence, data: merged_data, **html_options do %>
6
15
  <% if action.present? && action_position == "start" %>
7
- <div class="flex justify-center lg:justify-start">
16
+ <div data-stats-part="action" data-position="start">
8
17
  <%= action %>
9
18
  </div>
10
19
  <% end %>
11
20
 
12
- <div
13
- class="<%= class_names(
14
- "grid gap-4",
15
- "grid-cols-1",
16
- "sm:grid-cols-#{columns}",
17
- container_class,
18
- "flex-1": action.present?
19
- ) %>"
20
- >
21
+ <div data-stats-part="grid">
21
22
  <% cards.each do |card| %>
22
- <%= render "components/stats/stats_card",
23
- title: card[:title],
24
- value: card[:value],
25
- icon: card[:icon],
26
- icon_class: card[:icon_class] || "",
27
- subtitle: card[:subtitle],
28
- value_class: card[:value_class] || "",
29
- container_class: card[:container_class] || "" %>
23
+ <%= render "components/stats/stats_card", **card.symbolize_keys %>
30
24
  <% end %>
31
25
  </div>
32
26
 
33
27
  <% if action.present? && action_position == "end" %>
34
- <div class="flex justify-center lg:justify-end">
28
+ <div data-stats-part="action" data-position="end">
35
29
  <%= action %>
36
30
  </div>
37
31
  <% end %>
38
- </div>
32
+ <% end %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(table_part: :body) %>
2
+ <% merged_data = merge_component_data(html_options, table_part: :body) %>
3
3
  <%= content_tag :tbody, class: css_classes.presence, data: merged_data, **html_options do %>
4
4
  <%= yield %>
5
5
  <% end %>
@@ -1,5 +1,5 @@
1
- <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(table_part: :caption) %>
1
+ <%# locals: (text: nil, content: nil, css_classes: "", **html_options) %>
2
+ <% merged_data = merge_component_data(html_options, table_part: :caption) %>
3
3
  <%= content_tag :caption, class: css_classes.presence, data: merged_data, **html_options do %>
4
- <%= yield if block_given? %>
4
+ <%= text || content || yield %>
5
5
  <% end %>
@@ -1,5 +1,5 @@
1
- <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(table_part: :cell) %>
1
+ <%# locals: (text: nil, content: nil, css_classes: "", **html_options) %>
2
+ <% merged_data = merge_component_data(html_options, table_part: :cell) %>
3
3
  <%= content_tag :td, class: css_classes.presence, data: merged_data, **html_options do %>
4
- <%= yield if block_given? %>
4
+ <%= text || content || yield %>
5
5
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(table_part: :footer) %>
2
+ <% merged_data = merge_component_data(html_options, table_part: :footer) %>
3
3
  <%= content_tag :tfoot, class: css_classes.presence, data: merged_data, **html_options do %>
4
4
  <%= yield %>
5
5
  <% end %>
@@ -1,8 +1,8 @@
1
- <%# locals: (css_classes: "", scope: "col", **html_options) %>
1
+ <%# locals: (text: nil, content: nil, css_classes: "", scope: "col", **html_options) %>
2
2
  <%
3
- merged_data = (html_options.delete(:data) || {}).merge(table_part: :head)
3
+ merged_data = merge_component_data(html_options, table_part: :head)
4
4
  html_options[:scope] = scope if scope
5
5
  %>
6
6
  <%= content_tag :th, class: css_classes.presence, data: merged_data, **html_options do %>
7
- <%= yield if block_given? %>
7
+ <%= text || content || yield %>
8
8
  <% end %>
@@ -1,6 +1,6 @@
1
1
  <%# locals: (css_classes: "", sticky: false, **html_options) %>
2
2
  <%
3
- merged_data = (html_options.delete(:data) || {}).merge(table_part: :header)
3
+ merged_data = merge_component_data(html_options, table_part: :header)
4
4
  merged_data[:sticky] = "true" if sticky
5
5
  %>
6
6
  <%= content_tag :thead, class: css_classes.presence, data: merged_data, **html_options do %>
@@ -1,6 +1,6 @@
1
1
  <%# locals: (css_classes: "", selected: false, **html_options) %>
2
2
  <%
3
- merged_data = (html_options.delete(:data) || {}).merge(table_part: :row)
3
+ merged_data = merge_component_data(html_options, table_part: :row)
4
4
  merged_data[:state] = :selected if selected
5
5
  %>
6
6
  <%= content_tag :tr, class: css_classes.presence, data: merged_data, **html_options do %>
@@ -1,5 +1,5 @@
1
1
  <%# locals: (label:, href: nil, method: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  toast_part: "action"
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (text: nil, content: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  toast_part: "description"
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (text: nil, content: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  toast_part: "title"
4
4
  ) %>
5
5
 
@@ -1,5 +1,5 @@
1
1
  <%# locals: (value:, pressed: false, disabled: false, aria_label: nil, css_classes: "", **html_options) %>
2
- <% merged_data = (html_options.delete(:data) || {}).merge(
2
+ <% merged_data = merge_component_data(html_options,
3
3
  "toggle-group-part": "item",
4
4
  "toggle-group-target": "item",
5
5
  value: value,
@@ -12,6 +12,7 @@
12
12
  # Documentation: https://github.com/maquina-app/maquina_components
13
13
  #
14
14
  module MaquinaComponentsHelper
15
+ include MaquinaComponents::ComponentsHelper
15
16
  include MaquinaComponents::IconsHelper
16
17
  include MaquinaComponents::SidebarHelper
17
18
  include MaquinaComponents::ToastHelper
@@ -1,3 +1,8 @@
1
+ # Gemspec dependencies are not auto-required by Bundler in host apps,
2
+ # so load them here before the engine wires them up.
3
+ require "importmap-rails"
4
+ require "stimulus-rails"
5
+
1
6
  require "maquina_components/version"
2
7
  require "maquina_components/engine"
3
8
 
@@ -1,11 +1,15 @@
1
1
  module MaquinaComponents
2
2
  class Engine < ::Rails::Engine
3
3
  initializer "maquina-components.importmap", before: "importmap" do |app|
4
- app.config.importmap.paths << root.join("config/importmap.rb")
5
- app.config.importmap.cache_sweepers << root.join("app/javascript")
4
+ # Hosts bundling JS without importmap-rails (esbuild, vite, bun)
5
+ # have no config.importmap; skip so the engine doesn't break boot.
6
+ if app.config.respond_to?(:importmap)
7
+ app.config.importmap.paths << root.join("config/importmap.rb")
8
+ app.config.importmap.cache_sweepers << root.join("app/javascript")
9
+ end
6
10
  end
7
11
 
8
- initializer "maquin-components.assets" do |app|
12
+ initializer "maquina-components.assets" do |app|
9
13
  if app.config.respond_to?(:assets)
10
14
  app.config.assets.paths << Engine.root.join("app/javascript")
11
15
  end
@@ -1,3 +1,3 @@
1
1
  module MaquinaComponents
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maquina-components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Alberto Chávez
@@ -37,6 +37,34 @@ dependencies:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '4.2'
40
+ - !ruby/object:Gem::Dependency
41
+ name: importmap-rails
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '1.2'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '1.2'
54
+ - !ruby/object:Gem::Dependency
55
+ name: stimulus-rails
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '1.3'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '1.3'
40
68
  description: ERB, TailwindCSS, and StimulusJS UI components based on Shadcn/UI.
41
69
  email:
42
70
  - mario.chavez@gmail.com
@@ -60,9 +88,11 @@ files:
60
88
  - app/assets/stylesheets/empty.css
61
89
  - app/assets/stylesheets/form.css
62
90
  - app/assets/stylesheets/header.css
63
- - app/assets/stylesheets/maquina_components.css
91
+ - app/assets/stylesheets/menu_button.css
64
92
  - app/assets/stylesheets/pagination.css
93
+ - app/assets/stylesheets/separator.css
65
94
  - app/assets/stylesheets/sidebar.css
95
+ - app/assets/stylesheets/stats.css
66
96
  - app/assets/stylesheets/table.css
67
97
  - app/assets/stylesheets/toast.css
68
98
  - app/assets/stylesheets/toggle_group.css
@@ -70,6 +100,7 @@ files:
70
100
  - app/helpers/maquina_components/breadcrumbs_helper.rb
71
101
  - app/helpers/maquina_components/calendar_helper.rb
72
102
  - app/helpers/maquina_components/combobox_helper.rb
103
+ - app/helpers/maquina_components/components_helper.rb
73
104
  - app/helpers/maquina_components/drawer_helper.rb
74
105
  - app/helpers/maquina_components/dropdown_menu_helper.rb
75
106
  - app/helpers/maquina_components/empty_helper.rb