maquina-components 0.7.3 → 0.7.4

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/drawer.css +8 -8
  3. data/app/assets/stylesheets/form.css +58 -4
  4. data/app/assets/stylesheets/separator.css +6 -1
  5. data/app/assets/tailwind/maquina_components_engine/tokens.css +1 -0
  6. data/app/helpers/maquina_components/calendar_helper.rb +32 -0
  7. data/app/helpers/maquina_components/drawer_helper.rb +3 -5
  8. data/app/helpers/maquina_components/dropdown_menu_helper.rb +22 -5
  9. data/app/helpers/maquina_components/empty_helper.rb +3 -3
  10. data/app/helpers/maquina_components/icons_helper.rb +9 -5
  11. data/app/helpers/maquina_components/pagination_helper.rb +27 -5
  12. data/app/javascript/controllers/calendar_controller.js +28 -25
  13. data/app/javascript/controllers/combobox_controller.js +17 -2
  14. data/app/javascript/controllers/date_picker_controller.js +57 -21
  15. data/app/javascript/controllers/drawer_controller.js +66 -44
  16. data/app/javascript/controllers/drawer_trigger_controller.js +13 -0
  17. data/app/javascript/controllers/sidebar_controller.js +84 -42
  18. data/app/javascript/controllers/sidebar_trigger_controller.js +13 -0
  19. data/app/javascript/controllers/toast_controller.js +2 -3
  20. data/app/javascript/controllers/toaster_controller.js +23 -1
  21. data/app/javascript/controllers/toggle_group_controller.js +17 -6
  22. data/app/views/components/_badge.html.erb +1 -1
  23. data/app/views/components/_breadcrumbs.html.erb +7 -7
  24. data/app/views/components/_calendar.html.erb +13 -28
  25. data/app/views/components/_combobox.html.erb +2 -0
  26. data/app/views/components/_date_picker.html.erb +19 -33
  27. data/app/views/components/_drawer.html.erb +1 -1
  28. data/app/views/components/_menu_button.html.erb +1 -1
  29. data/app/views/components/_sidebar.html.erb +1 -1
  30. data/app/views/components/breadcrumbs/_ellipsis.html.erb +1 -1
  31. data/app/views/components/breadcrumbs/_item.html.erb +1 -1
  32. data/app/views/components/breadcrumbs/_link.html.erb +1 -1
  33. data/app/views/components/breadcrumbs/_list.html.erb +1 -1
  34. data/app/views/components/breadcrumbs/_page.html.erb +1 -1
  35. data/app/views/components/breadcrumbs/_separator.html.erb +1 -2
  36. data/app/views/components/calendar/_week.html.erb +7 -4
  37. data/app/views/components/card/_content.html.erb +1 -1
  38. data/app/views/components/card/_footer.html.erb +3 -10
  39. data/app/views/components/card/_header.html.erb +1 -1
  40. data/app/views/components/card/_title.html.erb +1 -1
  41. data/app/views/components/combobox/_option.html.erb +2 -2
  42. data/app/views/components/drawer/_close.html.erb +11 -5
  43. data/app/views/components/drawer/_content.html.erb +1 -1
  44. data/app/views/components/drawer/_footer.html.erb +1 -1
  45. data/app/views/components/drawer/_header.html.erb +1 -1
  46. data/app/views/components/drawer/_provider.html.erb +1 -1
  47. data/app/views/components/drawer/_trigger.html.erb +4 -2
  48. data/app/views/components/pagination/_ellipsis.html.erb +5 -8
  49. data/app/views/components/pagination/_link.html.erb +1 -1
  50. data/app/views/components/pagination/_next.html.erb +6 -7
  51. data/app/views/components/pagination/_previous.html.erb +6 -7
  52. data/app/views/components/sidebar/_content.html.erb +1 -1
  53. data/app/views/components/sidebar/_footer.html.erb +1 -1
  54. data/app/views/components/sidebar/_group.html.erb +1 -1
  55. data/app/views/components/sidebar/_header.html.erb +1 -1
  56. data/app/views/components/sidebar/_inset.html.erb +1 -1
  57. data/app/views/components/sidebar/_menu.html.erb +1 -1
  58. data/app/views/components/sidebar/_menu_button.html.erb +1 -1
  59. data/app/views/components/sidebar/_menu_item.html.erb +1 -1
  60. data/app/views/components/sidebar/_menu_link.html.erb +3 -3
  61. data/app/views/components/sidebar/_provider.html.erb +1 -1
  62. data/app/views/components/sidebar/_trigger.html.erb +1 -1
  63. data/app/views/components/stats/_stats_card.html.erb +7 -6
  64. data/app/views/components/toast/_action.html.erb +2 -1
  65. data/lib/generators/maquina_components/install/templates/theme.css.tt +11 -0
  66. data/lib/maquina_components/version.rb +1 -1
  67. metadata +1 -1
@@ -32,13 +32,26 @@ export default class extends Controller {
32
32
  this.syncItemStates()
33
33
  }
34
34
 
35
+ /**
36
+ * A group rendered with disabled: true (aria-disabled="true") disables
37
+ * every item, including items rendered directly from partials and items
38
+ * added later, so they leave the tab order and ignore keyboard input.
39
+ */
40
+ itemTargetConnected(item) {
41
+ if (this.disabled) item.disabled = true
42
+ }
43
+
44
+ get disabled() {
45
+ return this.element.getAttribute("aria-disabled") === "true"
46
+ }
47
+
35
48
  /**
36
49
  * Toggle an item's state
37
50
  * @param {Event} event - Click event from toggle item
38
51
  */
39
52
  toggle(event) {
40
53
  const item = event.currentTarget
41
- if (item.disabled) return
54
+ if (item.disabled || this.disabled) return
42
55
 
43
56
  const value = item.dataset.value
44
57
  const isPressed = item.dataset.state === "on"
@@ -66,6 +79,8 @@ export default class extends Controller {
66
79
  * @param {KeyboardEvent} event
67
80
  */
68
81
  handleKeydown(event) {
82
+ if (this.disabled) return
83
+
69
84
  const item = event.currentTarget
70
85
  const items = this.itemTargets.filter(i => !i.disabled)
71
86
  const currentIndex = items.indexOf(item)
@@ -125,12 +140,8 @@ export default class extends Controller {
125
140
  : this.selectedValue
126
141
  }
127
142
 
143
+ // Emits a single bubbling `toggle-group:change` from the group element
128
144
  this.dispatch("change", { detail })
129
-
130
- this.element.dispatchEvent(new CustomEvent("toggle-group:change", {
131
- bubbles: true,
132
- detail
133
- }))
134
145
  }
135
146
 
136
147
  /**
@@ -11,6 +11,6 @@
11
11
  size: size
12
12
  ) %>
13
13
 
14
- <%= content_tag :span, class: css_classes, data: merged_data, **html_options do %>
14
+ <%= content_tag :span, class: css_classes.presence, data: merged_data, **html_options do %>
15
15
  <%= yield %>
16
16
  <% end %>
@@ -4,12 +4,12 @@
4
4
  component: :breadcrumbs
5
5
  )
6
6
 
7
- merged_data[:controller] = "breadcrumb" if responsive %>
7
+ merged_data[:controller] = "breadcrumb" if responsive
8
8
 
9
- <nav
10
- aria-label="Breadcrumb"
11
- class="<%= css_classes %>"
12
- <%= tag.attributes(data: merged_data, **html_options) %>
13
- >
9
+ # A caller's aria-label (either spelling) replaces the default one.
10
+ aria = (html_options.delete(:aria) || {}).symbolize_keys
11
+ aria[:label] = html_options.delete(:"aria-label") || aria[:label] || "Breadcrumb" %>
12
+
13
+ <%= content_tag :nav, class: css_classes.presence, data: merged_data, aria: aria, **html_options do %>
14
14
  <%= yield %>
15
- </nav>
15
+ <% end %>
@@ -1,30 +1,11 @@
1
1
  <%# locals: (selected: nil, selected_end: nil, month: nil, year: nil, mode: :single, min_date: nil, max_date: nil, disabled_dates: [], show_outside_days: true, week_starts_on: :sunday, cell_size: nil, input_name: nil, input_name_end: nil, css_classes: "", **html_options) %>
2
2
  <%
3
- # Parse selected dates
4
- selected_date = case selected
5
- when String then Date.parse(selected) rescue nil
6
- when Date, Time, DateTime then selected.to_date
7
- else nil
8
- end
9
-
10
- selected_end_date = case selected_end
11
- when String then Date.parse(selected_end) rescue nil
12
- when Date, Time, DateTime then selected_end.to_date
13
- else nil
14
- end
15
-
16
- # Parse min/max dates
17
- min_date_parsed = case min_date
18
- when String then Date.parse(min_date) rescue nil
19
- when Date, Time, DateTime then min_date.to_date
20
- else nil
21
- end
22
-
23
- max_date_parsed = case max_date
24
- when String then Date.parse(max_date) rescue nil
25
- when Date, Time, DateTime then max_date.to_date
26
- else nil
27
- end
3
+ # Dates may arrive as Date, Time or ISO strings
4
+ selected_date = calendar_to_date(selected)
5
+ selected_end_date = calendar_to_date(selected_end)
6
+ min_date_parsed = calendar_to_date(min_date)
7
+ max_date_parsed = calendar_to_date(max_date)
8
+ disabled_dates_parsed = Array(disabled_dates).filter_map { |date| calendar_to_date(date) }
28
9
 
29
10
  # Determine display month/year
30
11
  display_date = selected_date || Date.current
@@ -65,10 +46,14 @@
65
46
  "calendar-selected-end-value": selected_end_date&.iso8601,
66
47
  "calendar-min-date-value": min_date_parsed&.iso8601,
67
48
  "calendar-max-date-value": max_date_parsed&.iso8601,
68
- "calendar-week-starts-on-value": week_starts_on
49
+ "calendar-week-starts-on-value": week_starts_on,
50
+ "calendar-disabled-dates-value": disabled_dates_parsed.map(&:iso8601).presence,
51
+ "calendar-show-outside-days-value": show_outside_days
69
52
  )
70
53
 
71
- style_attr = cell_size ? "--cell-size: #{cell_size};" : nil
54
+ # cell_size and a caller's style: both write the style attribute, so join them
55
+ style_attr = [("--cell-size: #{cell_size};" if cell_size), html_options.delete(:style).presence]
56
+ .compact.join(" ").presence
72
57
  %>
73
58
 
74
59
  <%= content_tag :div,
@@ -115,7 +100,7 @@
115
100
  mode: mode,
116
101
  min_date: min_date_parsed,
117
102
  max_date: max_date_parsed,
118
- disabled_dates: disabled_dates,
103
+ disabled_dates: disabled_dates_parsed,
119
104
  show_outside_days: show_outside_days %>
120
105
  <% end %>
121
106
  </div>
@@ -10,5 +10,7 @@
10
10
  ) %>
11
11
 
12
12
  <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
13
+ <%# Submits the selection with the surrounding form; the controller keeps it in sync %>
14
+ <%= hidden_field_tag name, value, id: nil, data: {combobox_target: "hiddenInput"} if name.present? %>
13
15
  <%= yield combobox_id %>
14
16
  <% end %>
@@ -1,4 +1,4 @@
1
- <%# locals: (selected: nil, selected_end: nil, mode: :single, min_date: nil, max_date: nil, disabled_dates: [], show_outside_days: true, week_starts_on: :sunday, placeholder: nil, input_name: nil, input_name_end: nil, id: nil, disabled: false, required: false, css_classes: "", **html_options) %>
1
+ <%# locals: (selected: nil, selected_end: nil, mode: :single, min_date: nil, max_date: nil, disabled_dates: [], show_outside_days: true, week_starts_on: :sunday, placeholder: nil, input_name: nil, input_name_end: nil, id: nil, disabled: false, required: false, size: :default, full_width: false, css_classes: "", **html_options) %>
2
2
  <%
3
3
  # Deterministic ID for popover targeting: random ids break idiomorph
4
4
  # matching across Turbo morphs
@@ -6,46 +6,34 @@
6
6
  popover_id = "#{component_id}-popover"
7
7
 
8
8
  # Parse selected dates for display
9
- selected_date = case selected
10
- when String then Date.parse(selected) rescue nil
11
- when Date, Time, DateTime then selected.to_date
12
- else nil
13
- end
14
-
15
- selected_end_date = case selected_end
16
- when String then Date.parse(selected_end) rescue nil
17
- when Date, Time, DateTime then selected_end.to_date
18
- else nil
19
- end
9
+ selected_date = calendar_to_date(selected)
10
+ selected_end_date = calendar_to_date(selected_end)
20
11
 
21
- # Format display value
22
- display_value = if mode == :range && selected_date && selected_end_date
23
- "#{I18n.l(selected_date, format: :short)} - #{I18n.l(selected_end_date, format: :short)}"
24
- elsif mode == :range && selected_date
25
- "#{I18n.l(selected_date, format: :short)} - ..."
26
- elsif selected_date
27
- I18n.l(selected_date, format: :long)
12
+ # Same helpers the controller mirrors client-side, so connect() never
13
+ # rewrites the server-rendered text
14
+ display_value = if mode == :range
15
+ date_picker_format_range(selected_date, selected_end_date)
16
+ else
17
+ date_picker_format(selected_date)
28
18
  end
29
19
 
30
- default_placeholder = mode == :range ? "Select date range" : "Select date"
20
+ placeholder_text = placeholder.presence || (mode == :range ? "Select date range" : "Select date")
31
21
 
32
22
  merged_data = merge_component_data(html_options,
33
23
  controller: "date-picker",
34
24
  component: "date-picker",
25
+ size: size,
26
+ full_width: (full_width ? true : nil),
35
27
  "date-picker-mode-value": mode,
36
28
  "date-picker-selected-value": selected_date&.iso8601,
37
- "date-picker-selected-end-value": selected_end_date&.iso8601
29
+ "date-picker-selected-end-value": selected_end_date&.iso8601,
30
+ "date-picker-placeholder-value": placeholder_text,
31
+ "date-picker-placeholder-range-value": (placeholder_text if mode == :range),
32
+ "date-picker-locale-value": date_picker_locale_data
38
33
  )
39
34
  %>
40
35
 
41
- <div id="<%= component_id %>"
42
- class="<%= css_classes.presence %>"
43
- data-controller="date-picker"
44
- data-component="date-picker"
45
- data-date-picker-mode-value="<%= mode %>"
46
- data-date-picker-selected-value="<%= selected_date&.iso8601 %>"
47
- data-date-picker-selected-end-value="<%= selected_end_date&.iso8601 %>">
48
-
36
+ <%= content_tag :div, id: component_id, class: css_classes.presence, data: merged_data, **html_options do %>
49
37
  <%# Hidden inputs for form submission %>
50
38
  <% if input_name %>
51
39
  <input type="hidden"
@@ -70,9 +58,7 @@
70
58
  aria-haspopup="dialog"
71
59
  aria-expanded="false">
72
60
  <%= builtin_icon_for :calendar, class: "size-4" %>
73
- <span data-date-picker-target="display">
74
- <%= display_value || placeholder || default_placeholder %>
75
- </span>
61
+ <span data-date-picker-target="display"><%= display_value || placeholder_text %></span>
76
62
  <% unless display_value %>
77
63
  <span data-date-picker-part="placeholder-indicator"></span>
78
64
  <% end %>
@@ -100,4 +86,4 @@
100
86
  action: "calendar:change->date-picker#handleChange calendar:navigate->date-picker#handleNavigate"
101
87
  } %>
102
88
  </div>
103
- </div>
89
+ <% end %>
@@ -8,7 +8,7 @@
8
8
  ) %>
9
9
  <aside
10
10
  id="<%= stable_id %>"
11
- class="group peer drawer-loading <%= css_classes %>"
11
+ class="<%= class_names("group peer drawer-loading", css_classes) %>"
12
12
  <%= tag.attributes(data: merged_data, **html_options) %>
13
13
  >
14
14
  <%# Backdrop overlay %>
@@ -20,7 +20,7 @@
20
20
  <%= image_tag icon, alt: title.presence || "", class: icon_classes.presence %>
21
21
  <% elsif text_icon.present? %>
22
22
  <span data-menu-button-part="avatar">
23
- <span class="<%= icon_classes %>"><%= text_icon %></span>
23
+ <%= tag.span text_icon, class: icon_classes.presence %>
24
24
  </span>
25
25
  <% end %>
26
26
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  <aside
14
14
  id="<%= stable_id %>"
15
- class="group peer sidebar-loading <%= css_classes %>"
15
+ class="<%= class_names("group peer sidebar-loading", css_classes) %>"
16
16
  <%= tag.attributes(data: merged_data, **html_options) %>
17
17
  >
18
18
  <%# Sidebar gap (creates space for sidebar on desktop) %>
@@ -3,7 +3,7 @@
3
3
  breadcrumb_part: :ellipsis
4
4
  ) %>
5
5
 
6
- <%= content_tag :span, role: "presentation", class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :span, role: "presentation", class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= builtin_icon_for(:ellipsis) %>
8
8
  <span class="sr-only">More</span>
9
9
  <% end %>
@@ -3,6 +3,6 @@
3
3
  breadcrumb_part: :item
4
4
  ) %>
5
5
 
6
- <%= content_tag :li, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :li, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,6 +3,6 @@
3
3
  breadcrumb_part: :link
4
4
  ) %>
5
5
 
6
- <%= link_to href, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= link_to href, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,6 +3,6 @@
3
3
  breadcrumb_part: :list
4
4
  ) %>
5
5
 
6
- <%= content_tag :ol, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :ol, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,6 +3,6 @@
3
3
  breadcrumb_part: :page
4
4
  ) %>
5
5
 
6
- <%= content_tag :span, role: "link", aria: {current: "page", disabled: true}, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :span, role: "link", aria: {current: "page", disabled: true}, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -6,8 +6,7 @@
6
6
  <li
7
7
  role="presentation"
8
8
  aria-hidden="true"
9
- class="<%= css_classes %>"
10
- <%= tag.attributes(data: merged_data, **html_options) %>
9
+ <%= tag.attributes(class: css_classes.presence, data: merged_data, **html_options) %>
11
10
  >
12
11
  <% if icon == :custom %>
13
12
  <%= yield %>
@@ -3,8 +3,14 @@
3
3
 
4
4
  <%= content_tag :div, role: "row", class: css_classes.presence, data: merged_data, **html_options do %>
5
5
  <% days.each do |day| %>
6
+ <% is_outside = day.month != display_month %>
7
+ <%# A hidden outside day keeps its grid column, so the month's first day
8
+ still lands under the right weekday %>
9
+ <% if is_outside && !show_outside_days %>
10
+ <%= tag.span aria: {hidden: true}, data: {calendar_part: "outside-day"} %>
11
+ <% next %>
12
+ <% end %>
6
13
  <%
7
- is_outside = day.month != display_month
8
14
  is_today = day == Date.current
9
15
  is_selected = selected_date && day == selected_date
10
16
  is_range_end = selected_end_date && day == selected_end_date
@@ -24,9 +30,6 @@
24
30
  "selected"
25
31
  end
26
32
 
27
- # Skip rendering if outside day and not showing them
28
- next if is_outside && !show_outside_days
29
-
30
33
  day_data = {
31
34
  "calendar-part": "day",
32
35
  "calendar-target": "day",
@@ -1,7 +1,7 @@
1
1
  <%# locals: (spacing: :default, css_classes: "", **html_options) %>
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  card_part: :content,
4
- spacing: (spacing == :full ? :full : nil)
4
+ spacing: (spacing.to_sym == :full ? :full : nil)
5
5
  ).compact %>
6
6
 
7
7
  <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
@@ -1,15 +1,8 @@
1
1
  <%# locals: (align: :start, spacing: :default, css_classes: "", **html_options) %>
2
- <% align_value = case align.to_sym
3
- when :between then :between
4
- when :end then :end
5
- when :center then :center
6
- else nil
7
- end
8
-
9
- merged_data = merge_component_data(html_options,
2
+ <% merged_data = merge_component_data(html_options,
10
3
  card_part: :footer,
11
- align: align_value,
12
- spacing: (spacing == :full ? :full : nil)
4
+ align: align.to_sym.presence_in(%i[between end center]),
5
+ spacing: (spacing.to_sym == :full ? :full : nil)
13
6
  ).compact %>
14
7
 
15
8
  <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
@@ -1,7 +1,7 @@
1
1
  <%# locals: (layout: :column, css_classes: "", **html_options) %>
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  card_part: :header,
4
- layout: (layout == :row ? :row : nil)
4
+ layout: (layout.to_sym == :row ? :row : nil)
5
5
  ).compact %>
6
6
 
7
7
  <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
@@ -1,7 +1,7 @@
1
1
  <%# locals: (text: nil, content: nil, size: :default, css_classes: "", **html_options) %>
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  card_part: :title,
4
- size: (size == :sm ? :sm : nil)
4
+ size: (size.to_sym == :sm ? :sm : nil)
5
5
  ).compact %>
6
6
 
7
7
  <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
@@ -17,8 +17,8 @@
17
17
  class: css_classes.presence,
18
18
  data: merged_data,
19
19
  **html_options do %>
20
- <span data-combobox-part="check" class="<%= 'invisible' unless selected %>">
20
+ <%= tag.span data: {combobox_part: "check"}, class: ("invisible" unless selected) do %>
21
21
  <%= builtin_icon_for :check, class: "size-4" %>
22
- </span>
22
+ <% end %>
23
23
  <%= yield %>
24
24
  <% end %>
@@ -1,10 +1,16 @@
1
- <%# locals: (show_icon: true, css_classes: "", **html_options) %>
2
- <% merged_data = merge_component_data(html_options,
1
+ <%# locals: (show_icon: true, variant: nil, size: nil, css_classes: "", **html_options) %>
2
+ <%
3
+ # Without variant: it is the drawer's icon button (drawer.css). With one it
4
+ # renders as a regular data-component="button" in that variant and size.
5
+ button_data = variant ? {component: :button, variant: variant, size: size} : {}
6
+ merged_data = merge_component_data(html_options,
7
+ **button_data,
3
8
  drawer_part: :close,
4
9
  action: "click->drawer#close"
5
- ) %>
6
- <%= content_tag :button, type: :button, class: css_classes, data: merged_data, **html_options do %>
7
- <% if show_icon %>
10
+ )
11
+ %>
12
+ <%= content_tag :button, type: :button, class: css_classes.presence, data: merged_data, **html_options do %>
13
+ <% if show_icon %>
8
14
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
9
15
  <path d="M18 6 6 18"></path>
10
16
  <path d="m6 6 12 12"></path>
@@ -2,6 +2,6 @@
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  drawer_part: :content
4
4
  ) %>
5
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
5
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
6
6
  <%= yield %>
7
7
  <% end %>
@@ -2,6 +2,6 @@
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  drawer_part: :footer
4
4
  ) %>
5
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
5
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
6
6
  <%= yield %>
7
7
  <% end %>
@@ -2,7 +2,7 @@
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  drawer_part: :header
4
4
  ) %>
5
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
5
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
6
6
  <div data-drawer-part="header-content">
7
7
  <%= yield %>
8
8
  </div>
@@ -18,6 +18,6 @@
18
18
  action: "keydown.meta+#{keyboard_shortcut}@window->drawer#toggleWithKeyboard keydown.ctrl+#{keyboard_shortcut}@window->drawer#toggleWithKeyboard keydown.esc@window->drawer#closeOnEscape"
19
19
  )
20
20
  %>
21
- <%= content_tag :div, id: provider_id, class: css_classes, data: merged_data, **html_options do %>
21
+ <%= content_tag :div, id: provider_id, class: css_classes.presence, data: merged_data, **html_options do %>
22
22
  <%= yield %>
23
23
  <% end %>
@@ -23,9 +23,11 @@
23
23
  action: "click->drawer-trigger#triggerClick",
24
24
  drawer_trigger_drawer_outlet: drawer_selector
25
25
  )
26
- button_data = merged_data.merge(component: "button")
26
+ # The variant:/size: locals style the button. A caller's data: { variant: }
27
+ # (the pre-0.7.4 workaround) still wins so existing markup keeps its look.
28
+ button_data = {variant: variant, size: size}.merge(merged_data, component: "button")
27
29
  %>
28
- <%= content_tag :button, type: :button, class: css_classes, data: button_data, **html_options do %>
30
+ <%= content_tag :button, type: :button, class: css_classes.presence, data: button_data, **html_options do %>
29
31
  <%= icon_for(icon_name) if icon_name %>
30
32
  <%= yield %>
31
33
  <% end %>
@@ -1,12 +1,9 @@
1
1
  <%# locals: (css_classes: "", **html_options) %>
2
- <% sr_label = t("maquina_components.pagination.more_pages", default: "More pages") %>
2
+ <% sr_label = t("maquina_components.pagination.more_pages", default: "More pages")
3
+ merged_data = merge_component_data(html_options, "pagination-part": "ellipsis") %>
3
4
 
4
- <span
5
- class="<%= css_classes.presence %>"
6
- data-pagination-part="ellipsis"
7
- aria-hidden="true"
8
- <%= tag.attributes(html_options.except(:data)) %>
9
- >
5
+ <%# Only the glyph is hidden from assistive tech, so the label is announced. %>
6
+ <%= content_tag :span, class: css_classes.presence, data: merged_data, **html_options do %>
10
7
  <svg
11
8
  xmlns="http://www.w3.org/2000/svg"
12
9
  width="24"
@@ -25,4 +22,4 @@
25
22
  </svg>
26
23
 
27
24
  <span class="sr-only"><%= sr_label %></span>
28
- </span>
25
+ <% end %>
@@ -1,7 +1,7 @@
1
1
  <%# locals: (href:, active: false, disabled: false, css_classes: "", **html_options) %>
2
2
  <% merged_data = merge_component_data(html_options,
3
3
  "pagination-part": "link",
4
- active: active
4
+ active: (active ? true : nil)
5
5
  ) %>
6
6
 
7
7
  <% if disabled %>
@@ -4,12 +4,11 @@
4
4
  merged_data = merge_component_data(html_options, "pagination-part": "next") %>
5
5
 
6
6
  <% if is_disabled %>
7
- <span
8
- class="<%= css_classes.presence %>"
9
- data-pagination-part="next"
10
- aria-disabled="true"
11
- <%= tag.attributes(html_options.except(:data)) %>
12
- >
7
+ <%= content_tag :span,
8
+ class: css_classes.presence,
9
+ data: merged_data,
10
+ "aria-disabled": "true",
11
+ **html_options do %>
13
12
  <% if show_label %>
14
13
  <span><%= display_label %></span>
15
14
  <% end %>
@@ -28,7 +27,7 @@
28
27
  >
29
28
  <path d="m9 18 6-6-6-6" />
30
29
  </svg>
31
- </span>
30
+ <% end %>
32
31
  <% else %>
33
32
  <%= link_to href,
34
33
  class: css_classes.presence,
@@ -4,12 +4,11 @@
4
4
  merged_data = merge_component_data(html_options, "pagination-part": "previous") %>
5
5
 
6
6
  <% if is_disabled %>
7
- <span
8
- class="<%= css_classes.presence %>"
9
- data-pagination-part="previous"
10
- aria-disabled="true"
11
- <%= tag.attributes(html_options.except(:data)) %>
12
- >
7
+ <%= content_tag :span,
8
+ class: css_classes.presence,
9
+ data: merged_data,
10
+ "aria-disabled": "true",
11
+ **html_options do %>
13
12
  <svg
14
13
  xmlns="http://www.w3.org/2000/svg"
15
14
  width="24"
@@ -28,7 +27,7 @@
28
27
  <% if show_label %>
29
28
  <span><%= display_label %></span>
30
29
  <% end %>
31
- </span>
30
+ <% end %>
32
31
  <% else %>
33
32
  <%= link_to href,
34
33
  class: css_classes.presence,
@@ -3,6 +3,6 @@
3
3
  sidebar_part: :content
4
4
  ) %>
5
5
 
6
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,6 +3,6 @@
3
3
  sidebar_part: :footer
4
4
  ) %>
5
5
 
6
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,7 +3,7 @@
3
3
  sidebar_part: :group
4
4
  ) %>
5
5
 
6
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <% if title.present? %>
8
8
  <div data-sidebar-part="group-label"><%= title %></div>
9
9
  <% end %>
@@ -3,6 +3,6 @@
3
3
  sidebar_part: :header
4
4
  ) %>
5
5
 
6
- <%= content_tag :div, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :div, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,6 +3,6 @@
3
3
  sidebar_part: :inset
4
4
  ) %>
5
5
 
6
- <%= content_tag :main, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :main, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>
@@ -3,6 +3,6 @@
3
3
  sidebar_part: :menu
4
4
  ) %>
5
5
 
6
- <%= content_tag :ul, class: css_classes, data: merged_data, **html_options do %>
6
+ <%= content_tag :ul, class: css_classes.presence, data: merged_data, **html_options do %>
7
7
  <%= yield %>
8
8
  <% end %>