primer_view_components 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/app/components/primer/base_component.rb +5 -2
  4. data/app/components/primer/blankslate_component.rb +3 -2
  5. data/app/components/primer/border_box_component.rb +4 -0
  6. data/app/components/primer/box_component.rb +10 -0
  7. data/app/components/primer/breadcrumb_component.rb +2 -1
  8. data/app/components/primer/button_component.rb +1 -1
  9. data/app/components/primer/button_group_component.html.erb +5 -0
  10. data/app/components/primer/button_group_component.rb +34 -0
  11. data/app/components/primer/button_marketing_component.rb +73 -0
  12. data/app/components/primer/component.rb +13 -0
  13. data/app/components/primer/counter_component.rb +11 -8
  14. data/app/components/primer/details_component.rb +10 -6
  15. data/app/components/primer/dropdown_menu_component.rb +31 -3
  16. data/app/components/primer/flash_component.rb +1 -0
  17. data/app/components/primer/flex_component.rb +10 -9
  18. data/app/components/primer/flex_item_component.rb +2 -1
  19. data/app/components/primer/heading_component.rb +7 -0
  20. data/app/components/primer/label_component.rb +4 -4
  21. data/app/components/primer/octicon_component.rb +4 -3
  22. data/app/components/primer/popover_component.rb +2 -0
  23. data/app/components/primer/progress_bar_component.rb +2 -2
  24. data/app/components/primer/spinner_component.rb +1 -2
  25. data/app/components/primer/state_component.rb +3 -3
  26. data/app/components/primer/subhead_component.rb +3 -0
  27. data/app/components/primer/timeline_item_component.rb +3 -0
  28. data/app/components/primer/tooltip_component.rb +88 -0
  29. data/app/components/primer/truncate_component.rb +41 -0
  30. data/app/components/primer/underline_nav_component.rb +26 -1
  31. data/app/components/primer/view_components.rb +4 -0
  32. data/lib/primer/class_name_helper.rb +1 -0
  33. data/lib/primer/classify.rb +127 -108
  34. data/lib/primer/fetch_or_fallback_helper.rb +1 -0
  35. data/lib/primer/join_style_arguments_helper.rb +1 -0
  36. data/lib/primer/view_components.rb +1 -0
  37. data/lib/primer/view_components/engine.rb +1 -0
  38. data/lib/primer/view_components/version.rb +1 -1
  39. metadata +41 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70daa13e7909487e01c01f4759a88740922070c985ac9604df738614d48c57a1
4
- data.tar.gz: 257383c54d408d94c8aac723804a1db9b75dee88527f60ce101f70514259567c
3
+ metadata.gz: 3e5a191f5ef0c2e50f095bce5d68943ebdc38a28d0edd66334152e876045d9cd
4
+ data.tar.gz: 8a103a45a9fed84736298a7b75c45b5f2bff3e78817fd4b02100853dbdf9003e
5
5
  SHA512:
6
- metadata.gz: 65bef1719944f20523e8670d382474fa15a49cd03eab6a39578ad3901933668c3d2bcfdff9da7e46ba9fdac8587447b92984a6e4c67028732f9ba2f18dc9cf52
7
- data.tar.gz: b578660620dc448087463fd24361c652a8fd9ead88cd6693a658af94f497eb68361e3236cb43386da66f58666c72051d5728bb67b4be6c832ee815c54f59e4c8
6
+ metadata.gz: 467aa20851a1b48cb605984b87a76f0297e5eddd32cee077a8f3cc7a06639829bf6f4dbf79fa81c4aa18f3b6b9cf697867cc8b347a9547d408a7c2aefddd3886
7
+ data.tar.gz: 9ad2bd67f630a6e734d6b08da43cad5b94482d0ff93085e65f8e8a4ffcf36e150bc7e5ec3beaa542b54a7f9949ff6411da8c6a3db0df460c4e430b0471a03fda
data/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## main
4
4
 
5
+ ## 0.0.18
6
+
7
+ * Add `border_radius` system argument.
8
+
9
+ *Ash Guillaume*
10
+
11
+ * Add `animation` system argument.
12
+
13
+ *Manuel Puyol*
14
+
15
+ * Add `Truncate`, `ButtonGroup` and `ButtonMarketing` components.
16
+
17
+ *Manuel Puyol*
18
+
19
+ * Add `Tooltip` component.
20
+
21
+ *Simon Taranto*
22
+
5
23
  ## 0.0.17
6
24
 
7
25
  * Ensure all components support inline styles.
@@ -62,7 +62,7 @@ module Primer
62
62
  # @param bottom [Boolean] If `false`, sets `bottom: 0`.
63
63
  # @param left [Boolean] If `false`, sets `left: 0`.
64
64
  #
65
- # @param display [Symbol] <%= one_of([:block, :none, :inline, :inline_block, :table, :table_cell]) %>
65
+ # @param display [Symbol] <%= one_of([:none, :block, :flex, :inline, :inline_block, :table, :table_cell]) %>
66
66
  #
67
67
  # @param v [Symbol] Visibility. <%= one_of([:hidden, :visible]) %>
68
68
  #
@@ -86,6 +86,7 @@ module Primer
86
86
  # @param border_bottom [Integer] Set to `0` to remove the bottom border.
87
87
  # @param border_left [Integer] Set to `0` to remove the left border.
88
88
  # @param border_right [Integer] Set to `0` to remove the right border.
89
+ # @param border_radius [Integer] <%= one_of([0, 1, 2, 3]) %>
89
90
  #
90
91
  # @param font_size [String, Integer] <%= one_of(["00", 0, 1, 2, 3, 4, 5, 6]) %>
91
92
  # @param text_align [Symbol] Text alignment. <%= one_of([:left, :right, :center]) %>
@@ -102,6 +103,8 @@ module Primer
102
103
  #
103
104
  # @param word_break [Symbol] Whether to break words on line breaks. Can only be `:break_all`.
104
105
  #
106
+ # @param animation [Symbol] <%= one_of([:fade_in, :fade_out, :fade_up, :fade_down, :scale_in, :pulse, :grow_x, :grow]) %>
107
+ #
105
108
  # @param tag [Symbol] HTML tag name to be passed to `tag.send`.
106
109
  # @param classes [String] CSS class name value to be concatenated with generated Primer CSS classes.
107
110
  def initialize(tag:, classes: nil, **system_arguments)
@@ -113,7 +116,7 @@ module Primer
113
116
  end
114
117
 
115
118
  def call
116
- content_tag(@tag, content, **@content_tag_args.merge(@result))
119
+ content_tag(@tag, content, { **@content_tag_args.merge(@result) })
117
120
  end
118
121
 
119
122
  private
@@ -94,7 +94,7 @@ module Primer
94
94
  link_text: "",
95
95
  link_url: "",
96
96
 
97
- #variations
97
+ # variations
98
98
  narrow: false,
99
99
  large: false,
100
100
  spacious: false,
@@ -108,7 +108,7 @@ module Primer
108
108
  "blankslate",
109
109
  "blankslate-narrow": narrow,
110
110
  "blankslate-large": large,
111
- "blankslate-spacious": spacious,
111
+ "blankslate-spacious": spacious
112
112
  )
113
113
 
114
114
  @title_tag = title_tag
@@ -125,6 +125,7 @@ module Primer
125
125
  @link_url = link_url
126
126
  end
127
127
 
128
+ # :nodoc
128
129
  class Spinner < Primer::Slot
129
130
  # @param size [Symbol] <%= one_of(Primer::SpinnerComponent::SIZE_MAPPINGS) %>
130
131
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -34,6 +34,7 @@ module Primer
34
34
  rows.any? || header.present? || body.present? || footer.present?
35
35
  end
36
36
 
37
+ # :nodoc
37
38
  class Header < Primer::Slot
38
39
  attr_reader :system_arguments
39
40
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -47,6 +48,7 @@ module Primer
47
48
  end
48
49
  end
49
50
 
51
+ # :nodoc
50
52
  class Body < Primer::Slot
51
53
  attr_reader :system_arguments
52
54
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -60,6 +62,7 @@ module Primer
60
62
  end
61
63
  end
62
64
 
65
+ # :nodoc
63
66
  class Footer < Primer::Slot
64
67
  attr_reader :system_arguments
65
68
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -73,6 +76,7 @@ module Primer
73
76
  end
74
77
  end
75
78
 
79
+ # :nodoc
76
80
  class Row < Primer::Slot
77
81
  attr_reader :system_arguments
78
82
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -3,6 +3,12 @@
3
3
  module Primer
4
4
  # A basic wrapper component for most layout related needs.
5
5
  class BoxComponent < Primer::Component
6
+ # @example 20|Default
7
+ # <%= render(Primer::BoxComponent.new) { "Your content here" } %>
8
+ #
9
+ # @example 54|Color and padding
10
+ # <%= render(Primer::BoxComponent.new(bg: :gray, p: 3)) { "Hello world" } %>
11
+ #
6
12
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
7
13
  def initialize(**system_arguments)
8
14
  @system_arguments = system_arguments
@@ -12,5 +18,9 @@ module Primer
12
18
  def call
13
19
  render(Primer::BaseComponent.new(**@system_arguments)) { content }
14
20
  end
21
+
22
+ def self.status
23
+ Primer::Component::STATUSES[:stable]
24
+ end
15
25
  end
16
26
  end
@@ -33,7 +33,8 @@ module Primer
33
33
  # @param selected [Boolean] Whether or not the item is selected and not rendered as a link.
34
34
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
35
35
  def initialize(href: nil, selected: false, **system_arguments)
36
- @href, @system_arguments = href, system_arguments
36
+ @href = href
37
+ @system_arguments = system_arguments
37
38
 
38
39
  @href = nil if selected
39
40
  @system_arguments[:tag] = :li
@@ -16,7 +16,7 @@ module Primer
16
16
  VARIANT_MAPPINGS = {
17
17
  :small => "btn-sm",
18
18
  DEFAULT_VARIANT => "",
19
- :large => "btn-large",
19
+ :large => "btn-large"
20
20
  }.freeze
21
21
  VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
22
22
 
@@ -0,0 +1,5 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <% buttons.each do |button| %>
3
+ <%= button %>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use ButtonGroupComponent to render a series of buttons.
5
+ class ButtonGroupComponent < Primer::Component
6
+ include ViewComponent::SlotableV2
7
+
8
+ renders_many :buttons, ->(**kwargs) { Primer::ButtonComponent.new(group_item: true, **kwargs) }
9
+
10
+ # @example 50|Default
11
+ # <%= render(Primer::ButtonGroupComponent.new) do |component|
12
+ # component.button { "Default" }
13
+ # component.button(button_type: :primary) { "Primary" }
14
+ # component.button(button_type: :danger) { "Danger" }
15
+ # component.button(button_type: :outline) { "Outline" }
16
+ # component.button(classes: "my-class") { "Custom class" }
17
+ # end %>
18
+ #
19
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
20
+ def initialize(**system_arguments)
21
+ @system_arguments = system_arguments
22
+ @system_arguments[:tag] ||= :div
23
+
24
+ @system_arguments[:classes] = class_names(
25
+ "BtnGroup",
26
+ system_arguments[:classes]
27
+ )
28
+ end
29
+
30
+ def render?
31
+ buttons.any?
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
+ class ButtonMarketingComponent < Primer::Component
6
+ DEFAULT_BUTTON_TYPE = :default
7
+ BUTTON_TYPE_MAPPINGS = {
8
+ DEFAULT_BUTTON_TYPE => "",
9
+ :primary => "btn-primary-mktg",
10
+ :outline => "btn-outline-mktg",
11
+ :transparent => "btn-transparent"
12
+ }.freeze
13
+ BUTTON_TYPE_OPTIONS = BUTTON_TYPE_MAPPINGS.keys
14
+
15
+ DEFAULT_VARIANT = :default
16
+ VARIANT_MAPPINGS = {
17
+ DEFAULT_VARIANT => "",
18
+ :large => "btn-large-mktg"
19
+ }.freeze
20
+ VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
21
+
22
+ DEFAULT_TAG = :button
23
+ TAG_OPTIONS = [DEFAULT_TAG, :a].freeze
24
+
25
+ DEFAULT_TYPE = :button
26
+ TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
27
+
28
+ # @example 125|Button types
29
+ # <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
30
+ # <%= render(Primer::ButtonMarketingComponent.new(button_type: :primary, mr: 2)) { "Primary" } %>
31
+ # <%= render(Primer::ButtonMarketingComponent.new(button_type: :outline)) { "Outline" } %>
32
+ # <div class="bg-gray-dark">
33
+ # <%= render(Primer::ButtonMarketingComponent.new(button_type: :transparent)) { "Transparent" } %>
34
+ # </div>
35
+ #
36
+ # @example 75|Sizes
37
+ # <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
38
+ # <%= render(Primer::ButtonMarketingComponent.new(variant: :large)) { "Large" } %>
39
+ #
40
+ # @param button_type [Symbol] <%= one_of(Primer::ButtonMarketingComponent::BUTTON_TYPE_OPTIONS) %>
41
+ # @param variant [Symbol] <%= one_of(Primer::ButtonMarketingComponent::VARIANT_OPTIONS) %>
42
+ # @param tag [Symbol] <%= one_of(Primer::ButtonMarketingComponent::TAG_OPTIONS) %>
43
+ # @param type [Symbol] <%= one_of(Primer::ButtonMarketingComponent::TYPE_OPTIONS) %>
44
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
45
+ def initialize(
46
+ button_type: DEFAULT_BUTTON_TYPE,
47
+ variant: DEFAULT_VARIANT,
48
+ tag: DEFAULT_TAG,
49
+ type: DEFAULT_TYPE,
50
+ **system_arguments
51
+ )
52
+ @system_arguments = system_arguments
53
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
54
+
55
+ if @system_arguments[:tag] == :a
56
+ @system_arguments[:role] = :button
57
+ else
58
+ @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
59
+ end
60
+
61
+ @system_arguments[:classes] = class_names(
62
+ "btn-mktg",
63
+ BUTTON_TYPE_MAPPINGS[fetch_or_fallback(BUTTON_TYPE_OPTIONS, button_type, DEFAULT_BUTTON_TYPE)],
64
+ VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
65
+ system_arguments[:classes]
66
+ )
67
+ end
68
+
69
+ def call
70
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
71
+ end
72
+ end
73
+ end
@@ -7,5 +7,18 @@ module Primer
7
7
  include FetchOrFallbackHelper
8
8
  include OcticonsHelper
9
9
  include JoinStyleArgumentsHelper
10
+
11
+ # sourced from https://primer.style/doctocat/usage/front-matter#status
12
+ STATUSES = {
13
+ deprecated: :deprecated,
14
+ review: :review,
15
+ experimental: :experimental,
16
+ new: :new,
17
+ stable: :stable
18
+ }.freeze
19
+
20
+ def self.status
21
+ STATUSES[:experimental]
22
+ end
10
23
  end
11
24
  end
@@ -7,7 +7,7 @@ module Primer
7
7
  SCHEME_MAPPINGS = {
8
8
  DEFAULT_SCHEME => "Counter",
9
9
  :gray => "Counter Counter--gray",
10
- :light_gray => "Counter Counter--gray-light",
10
+ :light_gray => "Counter Counter--gray-light"
11
11
  }.freeze
12
12
 
13
13
  #
@@ -30,7 +30,12 @@ module Primer
30
30
  round: false,
31
31
  **system_arguments
32
32
  )
33
- @count, @limit, @hide_if_zero, @text, @round, @system_arguments = count, limit, hide_if_zero, text, round, system_arguments
33
+ @count = count
34
+ @limit = limit
35
+ @hide_if_zero = hide_if_zero
36
+ @text = text
37
+ @round = round
38
+ @system_arguments = system_arguments
34
39
 
35
40
  @has_limit = !@limit.nil?
36
41
  @system_arguments[:title] = title
@@ -39,9 +44,7 @@ module Primer
39
44
  @system_arguments[:classes],
40
45
  SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme, DEFAULT_SCHEME)]
41
46
  )
42
- if count == 0 && hide_if_zero
43
- @system_arguments[:hidden] = true
44
- end
47
+ @system_arguments[:hidden] = true if count == 0 && hide_if_zero # rubocop:disable Style/NumericPredicate
45
48
  end
46
49
 
47
50
  def call
@@ -60,7 +63,7 @@ module Primer
60
63
  else
61
64
  count = @count.to_i
62
65
  str = number_with_delimiter(@has_limit ? [count, @limit].min : count)
63
- str += "+" if (@has_limit && count > @limit)
66
+ str += "+" if @has_limit && count > @limit
64
67
  str
65
68
  end
66
69
  end
@@ -76,14 +79,14 @@ module Primer
76
79
  if @round
77
80
  count = @has_limit ? [@count.to_i, @limit].min : @count.to_i
78
81
  precision = count.between?(100_000, 999_999) ? 0 : 1
79
- units = {thousand: "k", million: "m", billion: "b"}
82
+ units = { thousand: "k", million: "m", billion: "b" }
80
83
  str = number_to_human(count, precision: precision, significant: false, units: units, format: "%n%u")
81
84
  else
82
85
  @count = @count.to_i
83
86
  str = number_with_delimiter(@has_limit ? [@count, @limit].min : @count)
84
87
  end
85
88
 
86
- str += "+" if (@has_limit && @count.to_i > @limit)
89
+ str += "+" if @has_limit && @count.to_i > @limit
87
90
  str
88
91
  end
89
92
  end
@@ -1,11 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- #
5
- # overlay - options are `none`, `default` and `dark`. Dictates the type of overlay to render with.
6
- # button - options are `default` and `reset`. default will make the target a default primer ``.btn`
7
- # reset will remove all styles from the <summary> element.
8
- #
4
+ # Use DetailsComponent to reveal content after clicking a button.
9
5
  class DetailsComponent < Primer::Component
10
6
  include ViewComponent::Slotable
11
7
 
@@ -13,12 +9,15 @@ module Primer
13
9
  OVERLAY_MAPPINGS = {
14
10
  NO_OVERLAY => "",
15
11
  :default => "details-overlay",
16
- :dark => "details-overlay details-overlay-dark",
12
+ :dark => "details-overlay details-overlay-dark"
17
13
  }.freeze
18
14
 
19
15
  with_slot :body, class_name: "Body"
20
16
  with_slot :summary, class_name: "Summary"
21
17
 
18
+ # @param overlay [Symbol] Dictates the type of overlay to render with. <%= one_of(Primer::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
19
+ # @param reset [Boolean] Defatuls to false. If set to true, it will remove the default caret and remove style from the summary element
20
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
22
21
  def initialize(overlay: NO_OVERLAY, reset: false, **system_arguments)
23
22
  @system_arguments = system_arguments
24
23
  @system_arguments[:tag] = :details
@@ -33,7 +32,10 @@ module Primer
33
32
  summary.present? && body.present?
34
33
  end
35
34
 
35
+ # Use the Summary slot as a trigger to reveal the content.
36
36
  class Summary < Primer::Slot
37
+ # @param button [Boolean] Whether to render the Summary as a button or not.
38
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
37
39
  def initialize(button: true, **system_arguments)
38
40
  @button = button
39
41
 
@@ -49,7 +51,9 @@ module Primer
49
51
  end
50
52
  end
51
53
 
54
+ # Use the Body slot as the main content to be shown when triggered by the Summary.
52
55
  class Body < Primer::Slot
56
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
53
57
  def initialize(**system_arguments)
54
58
  @system_arguments = system_arguments
55
59
  @system_arguments[:tag] ||= :div
@@ -1,18 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # DropdownMenus are lightweight context menus for housing navigation and actions.
5
+ # They're great for instances where you don't need the full power (and code)
6
+ # of the select menu.
4
7
  class DropdownMenuComponent < Primer::Component
5
8
  SCHEME_DEFAULT = :default
6
9
  SCHEME_MAPPINGS = {
7
10
  SCHEME_DEFAULT => "",
8
- :dark => "dropdown-menu-dark",
11
+ :dark => "dropdown-menu-dark"
9
12
  }.freeze
10
13
 
11
14
  DIRECTION_DEFAULT = :se
12
- DIRECTION_OPTIONS = [DIRECTION_DEFAULT, :sw, :w, :e, :ne, :s]
15
+ DIRECTION_OPTIONS = [DIRECTION_DEFAULT, :sw, :w, :e, :ne, :s].freeze
13
16
 
17
+ # @example 200|With a header
18
+ # <div style="margin-bottom: 150px">
19
+ # <%= render(Primer::DetailsComponent.new(overlay: :default, reset: true, position: :relative)) do |c| %>
20
+ # <% c.slot(:summary) do %>
21
+ # Dropdown
22
+ # <% end %>
23
+ #
24
+ # <% c.slot(:body) do %>
25
+ # <%= render(Primer::DropdownMenuComponent.new(header: "Options")) do %>
26
+ # <ul>
27
+ # <li><a class="dropdown-item" href="#url">Dropdown item</a></li>
28
+ # <li><a class="dropdown-item" href="#url">Dropdown item</a></li>
29
+ # <li><a class="dropdown-item" href="#url">Dropdown item</a></li>
30
+ # </ul>
31
+ # <% end %>
32
+ # <% end %>
33
+ # <% end %>
34
+ # </div>
35
+ #
36
+ # @param direction [Symbol] <%= one_of(Primer::DropdownMenuComponent::DIRECTION_OPTIONS) %>
37
+ # @param scheme [Symbol] Pass :dark for dark mode theming
38
+ # @param header [String] Optional string to display as the header
39
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
14
40
  def initialize(direction: DIRECTION_DEFAULT, scheme: SCHEME_DEFAULT, header: nil, **system_arguments)
15
- @header, @direction, @system_arguments = header, direction, system_arguments
41
+ @header = header
42
+ @direction = direction
43
+ @system_arguments = system_arguments
16
44
 
17
45
  @system_arguments[:tag] = "details-menu"
18
46
  @system_arguments[:role] = "menu"