primer_view_components 0.0.35 → 0.0.40

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +178 -22
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/components/primer/{auto_complete_component.rb → auto_complete.rb} +12 -12
  6. data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_complete.d.ts} +0 -0
  7. data/app/components/primer/{auto_complete_component.html.erb → auto_complete/auto_complete.html.erb} +0 -0
  8. data/app/components/primer/{auto_complete_component.js → auto_complete/auto_complete.js} +0 -0
  9. data/app/components/primer/{auto_complete_component.ts → auto_complete/auto_complete.ts} +0 -0
  10. data/app/components/primer/auto_complete/auto_component.d.ts +1 -0
  11. data/app/components/primer/auto_complete/auto_component.js +1 -0
  12. data/app/components/primer/auto_complete/item.rb +42 -0
  13. data/app/components/primer/avatar_component.rb +22 -3
  14. data/app/components/primer/avatar_stack_component.rb +6 -3
  15. data/app/components/primer/base_button.rb +47 -0
  16. data/app/components/primer/base_component.rb +9 -8
  17. data/app/components/primer/blankslate_component.rb +5 -2
  18. data/app/components/primer/border_box_component.rb +1 -1
  19. data/app/components/primer/box_component.rb +1 -1
  20. data/app/components/primer/breadcrumb_component.rb +1 -1
  21. data/app/components/primer/button_component.html.erb +9 -0
  22. data/app/components/primer/button_component.rb +58 -21
  23. data/app/components/primer/{button_group_component.html.erb → button_group.html.erb} +0 -0
  24. data/app/components/primer/button_group.rb +61 -0
  25. data/app/components/primer/button_marketing_component.rb +4 -9
  26. data/app/components/primer/clipboard_copy.html.erb +8 -0
  27. data/app/components/primer/clipboard_copy.rb +26 -0
  28. data/app/components/primer/clipboard_copy_component.d.ts +1 -0
  29. data/app/components/primer/clipboard_copy_component.js +23 -0
  30. data/app/components/primer/clipboard_copy_component.ts +26 -0
  31. data/app/components/primer/close_button.rb +39 -0
  32. data/app/components/primer/component.rb +21 -2
  33. data/app/components/primer/counter_component.rb +6 -1
  34. data/app/components/primer/details_component.rb +1 -1
  35. data/app/components/primer/dropdown/menu_component.rb +1 -1
  36. data/app/components/primer/dropdown_component.rb +1 -1
  37. data/app/components/primer/flash_component.rb +1 -1
  38. data/app/components/primer/flex_component.rb +28 -1
  39. data/app/components/primer/flex_item_component.rb +20 -1
  40. data/app/components/primer/heading_component.rb +25 -4
  41. data/app/components/primer/hidden_text_expander.rb +41 -0
  42. data/app/components/primer/icon_button.rb +65 -0
  43. data/app/components/primer/image_crop.d.ts +1 -0
  44. data/app/components/primer/image_crop.html.erb +12 -0
  45. data/app/components/primer/image_crop.js +1 -0
  46. data/app/components/primer/image_crop.rb +36 -0
  47. data/app/components/primer/image_crop.ts +1 -0
  48. data/app/components/primer/label_component.rb +1 -1
  49. data/app/components/primer/layout_component.rb +1 -1
  50. data/app/components/primer/link_component.rb +1 -1
  51. data/app/components/primer/{markdown_component.rb → markdown.rb} +6 -5
  52. data/app/components/primer/menu_component.rb +1 -1
  53. data/app/components/primer/octicon_component.html.erb +7 -0
  54. data/app/components/primer/octicon_component.rb +46 -14
  55. data/app/components/primer/octicon_symbols_component.html.erb +3 -0
  56. data/app/components/primer/octicon_symbols_component.rb +61 -0
  57. data/app/components/primer/popover_component.rb +1 -1
  58. data/app/components/primer/primer.d.ts +3 -1
  59. data/app/components/primer/primer.js +3 -1
  60. data/app/components/primer/primer.ts +3 -1
  61. data/app/components/primer/progress_bar_component.rb +1 -1
  62. data/app/components/primer/spinner_component.rb +3 -3
  63. data/app/components/primer/state_component.rb +2 -2
  64. data/app/components/primer/subhead_component.rb +34 -4
  65. data/app/components/primer/tab_container_component.rb +1 -1
  66. data/app/components/primer/tab_nav_component.rb +1 -1
  67. data/app/components/primer/text_component.rb +6 -3
  68. data/app/components/primer/time_ago_component.rb +1 -1
  69. data/app/components/primer/timeline_item_component.rb +1 -1
  70. data/app/components/primer/tooltip_component.rb +1 -1
  71. data/app/components/primer/{truncate_component.rb → truncate.rb} +8 -6
  72. data/app/components/primer/underline_nav_component.rb +1 -1
  73. data/app/lib/primer/classify.rb +9 -34
  74. data/app/lib/primer/classify/cache.rb +20 -15
  75. data/app/lib/primer/classify/flex.rb +111 -0
  76. data/app/lib/primer/classify/functional_border_colors.rb +1 -2
  77. data/app/lib/primer/fetch_or_fallback_helper.rb +2 -2
  78. data/app/lib/primer/octicon/cache.rb +42 -0
  79. data/lib/primer/view_components.rb +1 -1
  80. data/lib/primer/view_components/version.rb +1 -1
  81. data/lib/tasks/coverage.rake +14 -0
  82. data/lib/tasks/docs.rake +312 -0
  83. data/lib/tasks/statuses.rake +12 -0
  84. data/lib/yard/docs_helper.rb +57 -0
  85. data/static/statuses.json +52 -1
  86. metadata +53 -15
  87. data/app/assets/javascripts/primer_view_components.js.map.orig +0 -5
  88. data/app/assets/javascripts/primer_view_components.js.orig +0 -6
  89. data/app/components/primer/auto_complete_item_component.rb +0 -40
  90. data/app/components/primer/button_group_component.rb +0 -35
@@ -1,9 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Avatars are images used to represent users and organizations on GitHub.
5
- # Use the default round avatar for users, and the `square` argument
4
+ # `Avatar` can be used to represent users and organizations on GitHub.
5
+ #
6
+ # - Use the default round avatar for users, and the `square` argument
6
7
  # for organizations or any other non-human avatars.
8
+ # - By default, `Avatar` will render a static `<img>`. To have `Avatar` function as a link, set the `href` which will wrap the `<img>` in a `<a>`.
9
+ # - Set `size` to update the height and width of the `Avatar` in pixels.
10
+ # - To stack multiple avatars together, use <%= link_to_component(Primer::AvatarStackComponent) %>.
11
+ #
12
+ # @accessibility
13
+ # Images should have text alternatives that describe the information or function represented.
14
+ # If the avatar functions as a link, provide alt text that helps convey the function. For instance,
15
+ # if `Avatar` is a link to a user profile, the alt attribute should be `@kittenuser profile`
16
+ # rather than `@kittenuser`.
17
+ # [Learn more about best image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/)
7
18
  class AvatarComponent < Primer::Component
8
19
  status :beta
9
20
 
@@ -16,7 +27,15 @@ module Primer
16
27
  # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", square: true)) %>
17
28
  #
18
29
  # @example Link
19
- # <%= render(Primer::AvatarComponent.new(href: "#", src: "http://placekitten.com/200/200", alt: "@kittenuser")) %>
30
+ # <%= render(Primer::AvatarComponent.new(href: "#", src: "http://placekitten.com/200/200", alt: "@kittenuser profile")) %>
31
+ #
32
+ # @example With size
33
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 16)) %>
34
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 20)) %>
35
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 24)) %>
36
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 28)) %>
37
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 32)) %>
38
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 36)) %>
20
39
  #
21
40
  # @param src [String] The source url of the avatar image.
22
41
  # @param alt [String] Passed through to alt on img tag.
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use AvatarStack to stack multiple avatars together.
4
+ # Use `AvatarStack` to stack multiple avatars together.
5
5
  class AvatarStackComponent < Primer::Component
6
6
  status :beta
7
7
 
8
8
  ALIGN_DEFAULT = :left
9
9
  ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
10
10
 
11
+ DEFAULT_TAG = :div
12
+ TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
11
13
  # Required list of stacked avatars.
12
14
  #
13
15
  # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::AvatarComponent) %>.
@@ -34,11 +36,12 @@ module Primer
34
36
  # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
35
37
  # <% end %>
36
38
  #
39
+ # @param tag [Symbol] <%= one_of(Primer::AvatarStackComponent::TAG_OPTIONS) %>
37
40
  # @param align [Symbol] <%= one_of(Primer::AvatarStackComponent::ALIGN_OPTIONS) %>
38
41
  # @param tooltipped [Boolean] Whether to add a tooltip to the stack or not.
39
42
  # @param body_arguments [Hash] Parameters to add to the Body. If `tooltipped` is set, has the same arguments as <%= link_to_component(Primer::TooltipComponent) %>.
40
43
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
41
- def initialize(align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
44
+ def initialize(tag: DEFAULT_TAG, align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
42
45
  @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
43
46
  @system_arguments = system_arguments
44
47
  @tooltipped = tooltipped
@@ -50,7 +53,7 @@ module Primer
50
53
  @body_arguments[:classes]
51
54
  )
52
55
 
53
- @system_arguments[:tag] ||= :div
56
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
54
57
  @system_arguments[:classes] = class_names(
55
58
  "AvatarStack",
56
59
  system_arguments[:classes],
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use `BaseButton` to render an unstyled `<button>` tag that can be customized.
5
+ class BaseButton < Primer::Component
6
+ status :beta
7
+
8
+ DEFAULT_TAG = :button
9
+ TAG_OPTIONS = [DEFAULT_TAG, :a, :summary].freeze
10
+
11
+ DEFAULT_TYPE = :button
12
+ TYPE_OPTIONS = [DEFAULT_TYPE, :reset, :submit].freeze
13
+
14
+ # @example Block
15
+ # <%= render(Primer::BaseButton.new(block: :true)) { "Block" } %>
16
+ # <%= render(Primer::BaseButton.new(block: :true, scheme: :primary)) { "Primary block" } %>
17
+ #
18
+ # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
19
+ # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
20
+ # @param block [Boolean] Whether button is full-width with `display: block`.
21
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
22
+ def initialize(
23
+ tag: DEFAULT_TAG,
24
+ type: DEFAULT_TYPE,
25
+ block: false,
26
+ **system_arguments
27
+ )
28
+ @system_arguments = system_arguments
29
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
30
+
31
+ if @system_arguments[:tag] == :button
32
+ @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
33
+ else
34
+ @system_arguments[:role] = :button
35
+ end
36
+
37
+ @system_arguments[:classes] = class_names(
38
+ system_arguments[:classes],
39
+ "btn-block" => block
40
+ )
41
+ end
42
+
43
+ def call
44
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
45
+ end
46
+ end
47
+ end
@@ -69,13 +69,15 @@ module Primer
69
69
  #
70
70
  # | Name | Type | Description |
71
71
  # | :- | :- | :- |
72
- # | `align_items` | Symbol | <%= one_of([:flex_start, :flex_end, :center, :baseline, :stretch]) %> |
73
- # | `align_self` | Symbol | <%= one_of([:auto, :start, :end, :center, :baseline, :stretch]) %> |
72
+ # | `align_items` | Symbol | <%= one_of(Primer::Classify::Flex::ALIGN_ITEMS_VALUES) %> |
73
+ # | `align_self` | Symbol | <%= one_of(Primer::Classify::Flex::ALIGN_SELF_VALUES) %> |
74
+ # | `direction` | Symbol | <%= one_of(Primer::Classify::Flex::DIRECTION_VALUES) %> |
75
+ # | `flex` | Integer, Symbol | <%= one_of(Primer::Classify::Flex::FLEX_VALUES) %> |
74
76
  # | `flex_grow` | Integer | To enable, set to `0`. |
75
77
  # | `flex_shrink` | Integer | To enable, set to `0`. |
76
- # | `flex` | Integer, Symbol | <%= one_of([1, :auto]) %> |
77
- # | `justify_content` | Symbol | <%= one_of([:flex_start, :flex_end, :center, :space_between, :space_around]) %> |
78
- # | `width` | Symbol | <%= one_of([:fit, :fill]) %> |
78
+ # | `flex_wrap` | Symbol | <%= one_of(Primer::Classify::Flex::WRAP_MAPPINGS.keys) %> |
79
+ # | `justify_content` | Symbol | <%= one_of(Primer::Classify::Flex::JUSTIFY_CONTENT_VALUES) %> |
80
+ # | `width` | Symbol | <%= one_of([:fit]) %> |
79
81
  #
80
82
  # ## Grid
81
83
  #
@@ -87,8 +89,8 @@ module Primer
87
89
  #
88
90
  # | Name | Type | Description |
89
91
  # | :- | :- | :- |
90
- # | `display` | Symbol | <%= one_of([:none, :block, :flex, :inline, :inline_block, :table, :table_cell]) %> |
91
- # | `height` | Symbol | <%= one_of([:fit, :fill]) %> |
92
+ # | `display` | Symbol | <%= one_of([:none, :block, :flex, :inline, :inline_block, :inline_flex, :table, :table_cell]) %> |
93
+ # | `height` | Symbol | <%= one_of([:fit]) %> |
92
94
  # | `hide` | Symbol | Hide the element at a specific breakpoint. <%= one_of([:sm, :md, :lg, :xl]) %> |
93
95
  # | `v` | Symbol | Visibility. <%= one_of([:hidden, :visible]) %> |
94
96
  # | `vertical_align` | Symbol | <%= one_of([:baseline, :top, :middle, :bottom, :text_top, :text_bottom]) %> |
@@ -138,7 +140,6 @@ module Primer
138
140
  # | Name | Type | Description |
139
141
  # | :- | :- | :- |
140
142
  # | classes | String | CSS class name value to be concatenated with generated Primer CSS classes. |
141
- # | tag | Symbol | HTML tag name to be passed to `content_tag`. |
142
143
  # | test_selector | String | Adds `data-test-selector='given value'` in non-Production environments for testing purposes. |
143
144
  def initialize(tag:, classes: nil, **system_arguments)
144
145
  @tag = tag
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use Primer::BlankslateComponent when there is a lack of content within a page or section. Use as placeholder to tell users why something isn't there.
4
+ # Use `Blankslate` when there is a lack of content within a page or section. Use as placeholder to tell users why something isn't there.
5
+ # @accessibility
6
+ # `Blankslate` renders an `<h3>` element for the title by default. Update the heading level based on what is appropriate for your page hierarchy by setting `title_tag`.
7
+ # <%= link_to_heading_practices %>
5
8
  class BlankslateComponent < Primer::Component
6
9
  status :beta
7
10
 
@@ -108,7 +111,7 @@ module Primer
108
111
  **system_arguments
109
112
  )
110
113
  @system_arguments = system_arguments
111
- @system_arguments[:tag] ||= :div
114
+ @system_arguments[:tag] = :div
112
115
  @system_arguments[:classes] = class_names(
113
116
  @system_arguments[:classes],
114
117
  "blankslate",
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # BorderBox is a Box component with a border.
4
+ # `BorderBox` is a Box component with a border.
5
5
  class BorderBoxComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # A basic wrapper component for most layout related needs.
4
+ # `Box` is a basic wrapper component for most layout related needs.
5
5
  class BoxComponent < Primer::Component
6
6
  status :stable
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use breadcrumbs to display page hierarchy within a section of the site. All of the items in the breadcrumb "trail" are links except for the final item, which is a plain string indicating the current page.
4
+ # Use `Breadcrumb` to display page hierarchy within a section of the site. All of the items in the breadcrumb "trail" are links except for the final item, which is a plain string indicating the current page.
5
5
  class BreadcrumbComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -0,0 +1,9 @@
1
+ <%= render Primer::BaseButton.new(**@system_arguments) do %>
2
+ <%= icon %>
3
+ <%= content %>
4
+ <%= counter %>
5
+
6
+ <% if @caret %>
7
+ <%= primer_octicon("triangle-down") %>
8
+ <% end %>
9
+ <% end %>
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
4
+ # Use `Button` for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
5
  class ButtonComponent < Primer::Component
6
6
  status :beta
7
7
 
8
8
  DEFAULT_SCHEME = :default
9
+ LINK_SCHEME = :link
9
10
  SCHEME_MAPPINGS = {
10
11
  DEFAULT_SCHEME => "",
11
12
  :primary => "btn-primary",
12
13
  :danger => "btn-danger",
13
- :outline => "btn-outline"
14
+ :outline => "btn-outline",
15
+ :invisible => "btn-invisible",
16
+ LINK_SCHEME => "btn-link"
14
17
  }.freeze
15
18
  SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
16
19
 
@@ -22,56 +25,90 @@ module Primer
22
25
  }.freeze
23
26
  VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
24
27
 
25
- DEFAULT_TAG = :button
26
- TAG_OPTIONS = [DEFAULT_TAG, :a, :summary].freeze
28
+ # Icon to be rendered in the button.
29
+ #
30
+ # @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
31
+ renders_one :icon, Primer::OcticonComponent
27
32
 
28
- DEFAULT_TYPE = :button
29
- TYPE_OPTIONS = [DEFAULT_TYPE, :reset, :submit].freeze
33
+ # Counter to be rendered in the button.
34
+ #
35
+ # @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::CounterComponent) %>.
36
+ renders_one :counter, Primer::CounterComponent
30
37
 
31
38
  # @example Schemes
32
39
  # <%= render(Primer::ButtonComponent.new) { "Default" } %>
33
40
  # <%= render(Primer::ButtonComponent.new(scheme: :primary)) { "Primary" } %>
34
41
  # <%= render(Primer::ButtonComponent.new(scheme: :danger)) { "Danger" } %>
35
42
  # <%= render(Primer::ButtonComponent.new(scheme: :outline)) { "Outline" } %>
43
+ # <%= render(Primer::ButtonComponent.new(scheme: :invisible)) { "Invisible" } %>
44
+ # <%= render(Primer::ButtonComponent.new(scheme: :link)) { "Link" } %>
36
45
  #
37
46
  # @example Variants
38
47
  # <%= render(Primer::ButtonComponent.new(variant: :small)) { "Small" } %>
39
48
  # <%= render(Primer::ButtonComponent.new(variant: :medium)) { "Medium" } %>
40
49
  # <%= render(Primer::ButtonComponent.new(variant: :large)) { "Large" } %>
41
50
  #
51
+ # @example Block
52
+ # <%= render(Primer::ButtonComponent.new(block: :true)) { "Block" } %>
53
+ # <%= render(Primer::ButtonComponent.new(block: :true, scheme: :primary)) { "Primary block" } %>
54
+ #
55
+ # @example With icons
56
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
57
+ # <% c.icon(icon: :star) %>
58
+ # Button
59
+ # <% end %>
60
+ #
61
+ # @example With counter
62
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
63
+ # <% c.counter(count: 15) %>
64
+ # Button
65
+ # <% end %>
66
+ #
67
+ # @example With icons and counter
68
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
69
+ # <% c.icon(icon: :star) %>
70
+ # <% c.counter(count: 15) %>
71
+ # Button
72
+ # <% end %>
73
+ #
74
+ # @example With caret
75
+ # <%= render(Primer::ButtonComponent.new(caret: true)) do %>
76
+ # Button
77
+ # <% end %>
78
+ #
42
79
  # @param scheme [Symbol] <%= one_of(Primer::ButtonComponent::SCHEME_OPTIONS) %>
43
80
  # @param variant [Symbol] <%= one_of(Primer::ButtonComponent::VARIANT_OPTIONS) %>
44
- # @param tag [Symbol] <%= one_of(Primer::ButtonComponent::TAG_OPTIONS) %>
45
- # @param type [Symbol] <%= one_of(Primer::ButtonComponent::TYPE_OPTIONS) %>
81
+ # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
82
+ # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
46
83
  # @param group_item [Boolean] Whether button is part of a ButtonGroup.
84
+ # @param block [Boolean] Whether button is full-width with `display: block`.
85
+ # @param caret [Boolean] Whether or not to render a caret.
47
86
  def initialize(
48
87
  scheme: DEFAULT_SCHEME,
49
88
  variant: DEFAULT_VARIANT,
50
- tag: DEFAULT_TAG,
51
- type: DEFAULT_TYPE,
52
89
  group_item: false,
90
+ block: false,
91
+ caret: false,
53
92
  **system_arguments
54
93
  )
55
- @system_arguments = system_arguments
56
- @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
57
-
58
- if @system_arguments[:tag] == :a
59
- @system_arguments[:role] = :button
60
- else
61
- @system_arguments[:type] = type
62
- end
94
+ @scheme = scheme
95
+ @caret = caret
63
96
 
97
+ @system_arguments = system_arguments
64
98
  @system_arguments[:classes] = class_names(
65
- "btn",
66
99
  system_arguments[:classes],
67
100
  SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
68
101
  VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
102
+ "btn" => !link?,
103
+ "btn-block" => block,
69
104
  "BtnGroup-item" => group_item
70
105
  )
71
106
  end
72
107
 
73
- def call
74
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
108
+ private
109
+
110
+ def link?
111
+ @scheme == LINK_SCHEME
75
112
  end
76
113
  end
77
114
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use `ButtonGroup` to render a series of buttons.
5
+ class ButtonGroup < Primer::Component
6
+ status :beta
7
+
8
+ # Required list of buttons to be rendered.
9
+ #
10
+ # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::ButtonComponent) %> except for `variant` and `group_item`.
11
+ renders_many :buttons, lambda { |**kwargs|
12
+ kwargs[:group_item] = true
13
+ kwargs[:variant] = @variant
14
+
15
+ Primer::ButtonComponent.new(**kwargs)
16
+ }
17
+
18
+ # @example Default
19
+ #
20
+ # <%= render(Primer::ButtonGroup.new) do |component| %>
21
+ # <% component.button { "Default" } %>
22
+ # <% component.button(scheme: :primary) { "Primary" } %>
23
+ # <% component.button(scheme: :danger) { "Danger" } %>
24
+ # <% component.button(scheme: :outline) { "Outline" } %>
25
+ # <% component.button(classes: "my-class") { "Custom class" } %>
26
+ # <% end %>
27
+ #
28
+ # @example Variants
29
+ #
30
+ # <%= render(Primer::ButtonGroup.new(variant: :small)) do |component| %>
31
+ # <% component.button { "Default" } %>
32
+ # <% component.button(scheme: :primary) { "Primary" } %>
33
+ # <% component.button(scheme: :danger) { "Danger" } %>
34
+ # <% component.button(scheme: :outline) { "Outline" } %>
35
+ # <% end %>
36
+ #
37
+ # <%= render(Primer::ButtonGroup.new(variant: :large)) do |component| %>
38
+ # <% component.button { "Default" } %>
39
+ # <% component.button(scheme: :primary) { "Primary" } %>
40
+ # <% component.button(scheme: :danger) { "Danger" } %>
41
+ # <% component.button(scheme: :outline) { "Outline" } %>
42
+ # <% end %>
43
+ #
44
+ # @param variant [Symbol] <%= one_of(Primer::ButtonComponent::VARIANT_OPTIONS) %>
45
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
46
+ def initialize(variant: Primer::ButtonComponent::DEFAULT_VARIANT, **system_arguments)
47
+ @variant = variant
48
+ @system_arguments = system_arguments
49
+ @system_arguments[:tag] = :div
50
+
51
+ @system_arguments[:classes] = class_names(
52
+ "BtnGroup",
53
+ system_arguments[:classes]
54
+ )
55
+ end
56
+
57
+ def render?
58
+ buttons.any?
59
+ end
60
+ end
61
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
4
+ # Use `ButtonMarketing` for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
5
  class ButtonMarketingComponent < Primer::Component
6
6
  DEFAULT_SCHEME = :default
7
7
  SCHEME_MAPPINGS = {
@@ -50,14 +50,9 @@ module Primer
50
50
  **system_arguments
51
51
  )
52
52
  @system_arguments = system_arguments
53
+ @system_arguments[:block] = false
53
54
  @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
-
55
+ @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
61
56
  @system_arguments[:classes] = class_names(
62
57
  "btn-mktg",
63
58
  SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
@@ -67,7 +62,7 @@ module Primer
67
62
  end
68
63
 
69
64
  def call
70
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
65
+ render(Primer::BaseButton.new(**@system_arguments)) { content }
71
66
  end
72
67
  end
73
68
  end