primer_view_components 0.0.51 → 0.0.55

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +159 -0
  3. data/app/components/primer/alpha/tab_nav.html.erb +11 -0
  4. data/app/components/primer/alpha/tab_nav.rb +130 -0
  5. data/app/components/primer/{tab_nav_component.html.erb → alpha/tab_panels.html.erb} +3 -8
  6. data/app/components/primer/alpha/tab_panels.rb +82 -0
  7. data/app/components/primer/alpha/underline_nav.html.erb +15 -0
  8. data/app/components/primer/alpha/underline_nav.rb +137 -0
  9. data/app/components/primer/{underline_nav_component.html.erb → alpha/underline_panels.html.erb} +3 -8
  10. data/app/components/primer/alpha/underline_panels.rb +86 -0
  11. data/app/components/primer/base_component.rb +1 -1
  12. data/app/components/primer/beta/avatar_stack.rb +9 -9
  13. data/app/components/primer/{breadcrumb_component.html.erb → beta/breadcrumbs.html.erb} +2 -1
  14. data/app/components/primer/beta/breadcrumbs.rb +61 -0
  15. data/app/components/primer/beta/truncate.html.erb +5 -0
  16. data/app/components/primer/beta/truncate.rb +110 -0
  17. data/app/components/primer/border_box_component.rb +27 -1
  18. data/app/components/primer/clipboard_copy.rb +1 -1
  19. data/app/components/primer/dropdown.rb +7 -7
  20. data/app/components/primer/icon_button.rb +1 -1
  21. data/app/components/primer/navigation/tab_component.rb +8 -6
  22. data/app/components/primer/octicon_component.rb +6 -1
  23. data/app/components/primer/progress_bar_component.rb +0 -3
  24. data/app/components/primer/tab_container_component.rb +1 -1
  25. data/app/lib/primer/class_name_helper.rb +14 -13
  26. data/app/lib/primer/fetch_or_fallback_helper.rb +2 -0
  27. data/app/lib/primer/octicon/cache.rb +10 -2
  28. data/app/lib/primer/tab_nav_helper.rb +35 -0
  29. data/app/lib/primer/tabbed_component_helper.rb +5 -5
  30. data/app/lib/primer/underline_nav_helper.rb +44 -0
  31. data/app/lib/primer/view_helper.rb +1 -0
  32. data/lib/primer/classify/cache.rb +0 -6
  33. data/lib/primer/classify/flex.rb +1 -1
  34. data/lib/primer/classify/functional_colors.rb +1 -1
  35. data/lib/primer/classify/utilities.rb +17 -2
  36. data/lib/primer/classify/utilities.yml +35 -0
  37. data/lib/primer/classify/validation.rb +18 -0
  38. data/lib/primer/classify.rb +4 -13
  39. data/lib/primer/view_components/constants.rb +1 -1
  40. data/lib/primer/view_components/linters/argument_mappers/base.rb +34 -8
  41. data/lib/primer/view_components/linters/argument_mappers/button.rb +5 -6
  42. data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +4 -3
  43. data/lib/primer/view_components/linters/argument_mappers/close_button.rb +43 -0
  44. data/lib/primer/view_components/linters/argument_mappers/flash.rb +32 -0
  45. data/lib/primer/view_components/linters/argument_mappers/helpers/erb_block.rb +48 -5
  46. data/lib/primer/view_components/linters/argument_mappers/label.rb +3 -4
  47. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +5 -7
  48. data/lib/primer/view_components/linters/autocorrectable.rb +6 -4
  49. data/lib/primer/view_components/linters/{helpers.rb → base_linter.rb} +69 -29
  50. data/lib/primer/view_components/linters/button_component_migration_counter.rb +4 -3
  51. data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +3 -4
  52. data/lib/primer/view_components/linters/close_button_component_migration_counter.rb +110 -3
  53. data/lib/primer/view_components/linters/flash_component_migration_counter.rb +18 -3
  54. data/lib/primer/view_components/linters/label_component_migration_counter.rb +2 -3
  55. data/lib/primer/view_components/version.rb +1 -1
  56. data/lib/rubocop/config/default.yml +5 -0
  57. data/lib/rubocop/cop/primer/base_cop.rb +28 -0
  58. data/lib/rubocop/cop/primer/deprecated_arguments.rb +263 -0
  59. data/lib/rubocop/cop/primer/no_tag_memoize.rb +1 -0
  60. data/lib/rubocop/cop/primer/primer_octicon.rb +178 -0
  61. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +4 -32
  62. data/lib/rubocop/cop/primer.rb +1 -2
  63. data/lib/tasks/coverage.rake +4 -0
  64. data/lib/tasks/docs.rake +10 -8
  65. data/lib/tasks/utilities.rake +7 -3
  66. data/lib/yard/docs_helper.rb +6 -3
  67. data/static/arguments.yml +82 -64
  68. data/static/classes.yml +10 -0
  69. data/static/constants.json +44 -30
  70. data/static/statuses.json +10 -6
  71. metadata +57 -18
  72. data/app/components/primer/auto_complete/auto_component.d.ts +0 -1
  73. data/app/components/primer/auto_complete/auto_component.js +0 -1
  74. data/app/components/primer/breadcrumb_component.rb +0 -57
  75. data/app/components/primer/tab_nav_component.rb +0 -151
  76. data/app/components/primer/underline_nav_component.rb +0 -187
  77. data/lib/primer/classify/functional_text_colors.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e619cd65db4a67059cc81f1d9f7d57a9c3b6c9cf9dadf9cfb2cd4c37fdcedc2
4
- data.tar.gz: 18eaf89147d7a3e415520b09f117bf4b748fbb9a06e166df12ccc3a930506007
3
+ metadata.gz: 24d9b6954280f4366b91f69fe7d29af41b8ce480b015a6d2f281c9e6c3bd4637
4
+ data.tar.gz: cae48c352697db57fd18b2712850cdc5a47da809449dcbd1f32398a777135cda
5
5
  SHA512:
6
- metadata.gz: 821f1b4b53b823049bbc8e1a740b1f21d36ada796e69c59471c9f9a28183b5d94a61958544ef3c3e6386424b595e72627abcab2cd05d61de10104ea40941e201
7
- data.tar.gz: 58d0e5f7961736bee805ed3d99d5432bb4dfa16df8170abe89b1f24f2857cf80a17a578fb762b0f6f1e5b307fe96a9803e960cce6a1a2901282908e678295f79
6
+ metadata.gz: e334ce2c9e71f8b54f0a22d094a333ce1df7216a601885732c2a1f669e03d67f4b0e2d9799c39600edc33e9ef972949a02de1a8adc4081c702b14d4bfe6bacbc
7
+ data.tar.gz: 4640a31794a5e6df77bcf1a707758bb970d80a33afbcd42a812efd3ce3c9f032b7789de55f3ab0d74d7d8657c1d06f3965f926437cf609455f3db4b2c4a2bc6f
data/CHANGELOG.md CHANGED
@@ -30,6 +30,159 @@ The category for changes related to documentation, testing and tooling. Also, fo
30
30
 
31
31
  ## main
32
32
 
33
+ ## 0.0.55
34
+
35
+ ### Breaking changes
36
+
37
+ * `Primer::Breadcrumbs` requires `href`s for all items and no longer accepts the `selected` argument.
38
+
39
+ *Joel Hawksley*
40
+
41
+ * Split `TabNav` into `TabNav` and `TabPanels`.
42
+
43
+ *Kate Higa*
44
+
45
+ ### New
46
+
47
+ * Use the allocation_stats gem to count object allocations in our benchmarks.
48
+ * Improve performance of Octicon cache key construction.
49
+
50
+ *Cameron Dutro*
51
+
52
+ * Update `@primer/css` to `17.7.0` which includes a new argument for `word_break`
53
+
54
+ *Jon Rohan*
55
+
56
+ ### Misc
57
+
58
+ * Clean up extra constants in `UnderlineNav`.
59
+
60
+ *Kate Higa*
61
+
62
+ * Refactor some of the rubocop valid_node? logic into BaseCop class.
63
+
64
+ *Jon Rohan*
65
+
66
+ ## 0.0.54
67
+
68
+ ### Breaking changes
69
+
70
+ * Rename `BreadcrumbComponent` to `Beta::Breadcrumbs`.
71
+
72
+ *Joel Hawksley*
73
+
74
+ * Split `UnderlineNavComponent` into `Alpha::UnderlineNav` and `Alpha::UnderlinePanels`.
75
+
76
+ *Kate Higa*
77
+
78
+ ## 0.0.53
79
+
80
+ ### New
81
+
82
+ * Add autocorrection to `FlashComponent` linter when the context is basic text.
83
+
84
+ *Manuel Puyol*
85
+
86
+ ### Updates
87
+
88
+ * Linters won't mark offenses when the ignore count is correct unless explicitly configured to do so.
89
+
90
+ *Manuel Puyol*
91
+
92
+ * Deprecating background and border color presentational arguments
93
+
94
+ *Jon Rohan*
95
+
96
+ * Map the `for` argument when autofixing `ClipboardCopy` migrations.
97
+
98
+ *Kristján Oddsson*
99
+
100
+ * Add autocorrection for `CloseButton` linter.
101
+
102
+ *Manuel Puyol*
103
+
104
+ * Moving text color variables to Utilities class
105
+
106
+ *Jon Rohan*
107
+
108
+ ### Bug fixes
109
+
110
+ * Linters won't convert HTML special elements.
111
+
112
+ *Manuel Puyol*
113
+
114
+ ### Misc
115
+
116
+ * Only run CHANGELOG CI on pull requests.
117
+
118
+ *Manuel Puyol*
119
+
120
+ * Run CI actions on pushes to main.
121
+
122
+ *Cameron Dutro*
123
+
124
+ * Get to 100% code coverage.
125
+
126
+ *Cameron Dutro*
127
+
128
+ ## 0.0.52
129
+
130
+ ### New
131
+
132
+ * Adding `Primer::Beta::Truncate` component to reflect changes in primer/css component [Truncate](https://primer.style/css/components/truncate).
133
+
134
+ *Jon Rohan*
135
+
136
+ * Add cop to look for deprecated system arguments and suggest replacements.
137
+
138
+ *Jon Rohan*
139
+
140
+ * Add cop to use `primer_octicon` in favor of `octicon`.
141
+
142
+ *Manuel Puyol*
143
+
144
+ * Fix release script so it doesn't loop continuously.
145
+
146
+ *Cameron Dutro*
147
+
148
+ ### Updates
149
+
150
+ * Promote `ClipboardCopy` to beta.
151
+
152
+ *Manuel Puyol*
153
+
154
+ * PrimerOcticon linter supports `aria-` and `data-` attributes.
155
+
156
+ *Manuel Puyol*
157
+
158
+ * Linters can:
159
+ * convert values with ERB interpolations.
160
+ * autocorrect cases with custom classes.
161
+
162
+ *Manuel Puyol*
163
+
164
+ * Add a `scheme` option to `BorderBoxComponent` rows.
165
+
166
+ *Cameron Dutro*
167
+
168
+ * Upgrade rubocop and support Ruby 3.0.
169
+
170
+ *Cameron Dutro*
171
+
172
+ * Linters will not autocorrect cases where a required argument is missing.
173
+
174
+ *Manuel Puyol*
175
+
176
+ ### Misc
177
+
178
+ * Update benchmarks to run in every supported Ruby version.
179
+
180
+ *Manuel Puyol*
181
+
182
+ * Add a linter generator.
183
+
184
+ *Manuel Puyol*
185
+
33
186
  ## 0.0.51
34
187
 
35
188
  ### Breaking changes
@@ -46,6 +199,12 @@ The category for changes related to documentation, testing and tooling. Also, fo
46
199
 
47
200
  ## 0.0.50
48
201
 
202
+ ### Updates
203
+
204
+ * Fix incorrect slots syntax in docs.
205
+
206
+ *Joel Hawksley*, *Blake Williams*
207
+
49
208
  ### New
50
209
 
51
210
  * Add linter suggestions for `CloseButton` component.
@@ -0,0 +1,11 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <%= extra if @align == :left %>
3
+
4
+ <%= render Primer::BaseComponent.new(**@body_arguments) do %>
5
+ <% tabs.each do |tab| %>
6
+ <%= tab %>
7
+ <% end %>
8
+ <% end %>
9
+
10
+ <%= extra if @align == :right %>
11
+ <% end %>
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ # Use `TabNav` to style navigation with a tab-based selected state, typically used for navigation placed at the top of the page.
6
+ # For panel navigation, use <%= link_to_component(Primer::Alpha::TabPanels) %> instead.
7
+ #
8
+ # @accessibility
9
+ # - By default, `TabNav` renders links within a `<nav>` element. `<nav>` has an
10
+ # implicit landmark role of `navigation` which should be reserved for main links.
11
+ # For all other set of links, set tag to `:div`.
12
+ # - See <%= link_to_component(Primer::Navigation::TabComponent) %> for additional
13
+ # accessibility considerations.
14
+ class TabNav < Primer::Component
15
+ include Primer::TabbedComponentHelper
16
+ include Primer::TabNavHelper
17
+
18
+ status :alpha
19
+
20
+ BODY_TAG_DEFAULT = :ul
21
+
22
+ TAG_DEFAULT = :nav
23
+ TAG_OPTIONS = [TAG_DEFAULT, :div].freeze
24
+
25
+ # Tabs to be rendered. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
26
+ #
27
+ # @param selected [Boolean] Whether the tab is selected.
28
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
+ renders_many :tabs, lambda { |selected: false, **system_arguments|
30
+ system_arguments[:classes] = tab_nav_tab_classes(system_arguments[:classes])
31
+ Primer::Navigation::TabComponent.new(
32
+ list: true,
33
+ selected: selected,
34
+ **system_arguments
35
+ )
36
+ }
37
+
38
+ # Renders extra content to the `TabNav`. This will be rendered after the tabs.
39
+ #
40
+ # @param align [Symbol] <%= one_of(Primer::Alpha::TabNav::EXTRA_ALIGN_OPTIONS) %>
41
+ renders_one :extra, lambda { |align: EXTRA_ALIGN_DEFAULT, &block|
42
+ @align = fetch_or_fallback(EXTRA_ALIGN_OPTIONS, align, EXTRA_ALIGN_DEFAULT)
43
+
44
+ view_context.capture { block&.call }
45
+ }
46
+
47
+ # @example Default with `<nav>`
48
+ # @description
49
+ # `<nav>` is a landmark and should be reserved for main navigation links. See <%= link_to_accessibility %>.
50
+ # @code
51
+ # <%= render(Primer::Alpha::TabNav.new(label: "Default")) do |c| %>
52
+ # <% c.tab(selected: true, href: "#") { "Tab 1" } %>
53
+ # <% c.tab(href: "#") { "Tab 2" } %>
54
+ # <% c.tab(href: "#") { "Tab 3" } %>
55
+ # <% end %>
56
+ #
57
+ # @example Default with `<div>`
58
+ # <%= render(Primer::Alpha::TabNav.new(label: "Default")) do |c| %>
59
+ # <% c.tab(selected: true, href: "#") { "Tab 1" } %>
60
+ # <% c.tab(href: "#") { "Tab 2" } %>
61
+ # <% c.tab(href: "#") { "Tab 3" } %>
62
+ # <% end %>
63
+ #
64
+ # @example With icons and counters
65
+ # <%= render(Primer::Alpha::TabNav.new(label: "With icons and counters")) do |component| %>
66
+ # <% component.tab(href: "#", selected: true) do |t| %>
67
+ # <% t.icon(icon: :star) %>
68
+ # <% t.text { "Item 1" } %>
69
+ # <% end %>
70
+ # <% component.tab(href: "#") do |t| %>
71
+ # <% t.icon(icon: :star) %>
72
+ # <% t.text { "Item 2" } %>
73
+ # <% t.counter(count: 10) %>
74
+ # <% end %>
75
+ # <% component.tab(href: "#") do |t| %>
76
+ # <% t.text { "Item 3" } %>
77
+ # <% t.counter(count: 10) %>
78
+ # <% end %>
79
+ # <% end %>
80
+ #
81
+ # @example With extra content
82
+ # <%= render(Primer::Alpha::TabNav.new(label: "With extra content")) do |c| %>
83
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
84
+ # <% c.tab(href: "#") { "Tab 2" } %>
85
+ # <% c.tab(href: "#") { "Tab 3" } %>
86
+ # <% c.extra do %>
87
+ # <%= render(Primer::ButtonComponent.new(float: :right)) { "Button" } %>
88
+ # <% end %>
89
+ # <% end %>
90
+ #
91
+ # @example Adding extra content after the tabs
92
+ # <%= render(Primer::Alpha::TabNav.new(label: "Adding extra content after the tabs", display: :flex, body_arguments: { flex: 1 })) do |c| %>
93
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
94
+ # <% c.tab(href: "#") { "Tab 2" } %>
95
+ # <% c.tab(href: "#") { "Tab 3" } %>
96
+ # <% c.extra(align: :right) do %>
97
+ # <div>
98
+ # <%= render(Primer::ButtonComponent.new) { "Button" } %>
99
+ # </div>
100
+ # <% end %>
101
+ # <% end %>
102
+ #
103
+ # @example Customizing the body
104
+ # <%= render(Primer::Alpha::TabNav.new(label: "Default", body_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
105
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
106
+ # <% c.tab(href: "#") { "Tab 2" } %>
107
+ # <% c.tab(href: "#") { "Tab 3" } %>
108
+ # <% end %>
109
+ #
110
+ # @param tag [Symbol] <%= one_of(Primer::Alpha::TabNav::TAG_OPTIONS) %>
111
+ # @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the links, and distinguish it from similar elements.
112
+ # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
113
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
114
+ def initialize(label:, tag: TAG_DEFAULT, body_arguments: {}, **system_arguments)
115
+ @align = EXTRA_ALIGN_DEFAULT
116
+ @system_arguments = system_arguments
117
+ @body_arguments = body_arguments
118
+
119
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
120
+ @system_arguments[:classes] = tab_nav_classes(system_arguments[:classes])
121
+
122
+ @body_arguments = body_arguments
123
+ @body_arguments[:tag] = BODY_TAG_DEFAULT
124
+ @body_arguments[:classes] = tab_nav_body_classes(system_arguments[:classes])
125
+
126
+ aria_label_for_page_nav(label)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,19 +1,14 @@
1
- <%= wrapper(**@wrapper_arguments) do %>
1
+ <%= tab_container_wrapper(with_panel: true, **@wrapper_arguments) do %>
2
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
3
  <%= extra if @align == :left %>
4
-
5
4
  <%= render Primer::BaseComponent.new(**@body_arguments) do %>
6
5
  <% tabs.each do |tab| %>
7
6
  <%= tab %>
8
7
  <% end %>
9
8
  <% end %>
10
-
11
9
  <%= extra if @align == :right %>
12
10
  <% end %>
13
-
14
- <% if @with_panel %>
15
- <% tabs.each do |tab| %>
16
- <%= tab.panel %>
17
- <% end %>
11
+ <% tabs.each do |tab| %>
12
+ <%= tab.panel %>
18
13
  <% end %>
19
14
  <% end %>
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ # Use `TabPanels` for tabs with panel navigation.
6
+ class TabPanels < Primer::Component
7
+ include Primer::TabbedComponentHelper
8
+ include Primer::TabNavHelper
9
+
10
+ status :alpha
11
+
12
+ BODY_TAG_DEFAULT = :ul
13
+
14
+ TAG_DEFAULT = :nav
15
+ TAG_OPTIONS = [TAG_DEFAULT, :div].freeze
16
+
17
+ # Tabs to be rendered. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
18
+ #
19
+ # @param id [String] Unique ID of tab.
20
+ # @param selected [Boolean] Whether the tab is selected.
21
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
22
+ renders_many :tabs, lambda { |id:, selected: false, **system_arguments|
23
+ system_arguments[:id] = id
24
+ system_arguments[:classes] = tab_nav_tab_classes(system_arguments[:classes])
25
+
26
+ Primer::Navigation::TabComponent.new(
27
+ selected: selected,
28
+ with_panel: true,
29
+ list: true,
30
+ panel_id: "panel-#{id}",
31
+ **system_arguments
32
+ )
33
+ }
34
+
35
+ # Renders extra content to the `TabPanels`. This will be rendered after the tabs.
36
+ #
37
+ # @param align [Symbol] <%= one_of(Primer::Alpha::TabNav::EXTRA_ALIGN_OPTIONS) %>
38
+ renders_one :extra, lambda { |align: EXTRA_ALIGN_DEFAULT, &block|
39
+ @align = fetch_or_fallback(EXTRA_ALIGN_OPTIONS, align, EXTRA_ALIGN_DEFAULT)
40
+
41
+ view_context.capture { block&.call }
42
+ }
43
+
44
+ # @example Default
45
+ # <%= render(Primer::Alpha::TabPanels.new(label: "With panels")) do |component| %>
46
+ # <% component.tab(id: "tab-1", selected: true) do |t| %>
47
+ # <% t.text { "Tab 1" } %>
48
+ # <% t.panel do %>
49
+ # Panel 1
50
+ # <% end %>
51
+ # <% end %>
52
+ # <% component.tab(id: "tab-2") do |t| %>
53
+ # <% t.text { "Tab 2" } %>
54
+ # <% t.panel do %>
55
+ # Panel 2
56
+ # <% end %>
57
+ # <% end %>
58
+ # <% end %>
59
+ #
60
+ # @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the tabs.
61
+ # @param align [Symbol] <%= one_of(Primer::TabNavHelper::EXTRA_ALIGN_OPTIONS) %> - Defaults to <%= Primer::TabNavHelper::EXTRA_ALIGN_DEFAULT %>
62
+ # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
63
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper.
64
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
65
+ def initialize(label:, body_arguments: {}, wrapper_arguments: {}, **system_arguments)
66
+ @align = EXTRA_ALIGN_DEFAULT
67
+ @wrapper_arguments = wrapper_arguments
68
+
69
+ @system_arguments = system_arguments
70
+ @system_arguments[:tag] = :div
71
+ @system_arguments[:classes] = tab_nav_classes(@system_arguments[:classes])
72
+
73
+ @body_arguments = body_arguments
74
+ @body_arguments[:tag] = :ul
75
+ @body_arguments[:classes] = tab_nav_body_classes(@body_arguments[:classes])
76
+
77
+ @body_arguments[:role] = :tablist
78
+ @body_arguments[:"aria-label"] = label
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,15 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <% if @align == :right %>
3
+ <%= actions %>
4
+ <% end %>
5
+
6
+ <%= render body do %>
7
+ <% tabs.each do |tab| %>
8
+ <%= tab %>
9
+ <% end %>
10
+ <% end %>
11
+
12
+ <% if @align == :left %>
13
+ <%= actions %>
14
+ <% end %>
15
+ <% end %>