Skip to content

Commit

Permalink
Merge pull request #185 from primer/btn-group-component
Browse files Browse the repository at this point in the history
ButtonGroup component
  • Loading branch information
manuelpuyol committed Feb 3, 2021
2 parents 0068f12 + 19d60d0 commit d464d1d
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -12,6 +12,7 @@
**/*.stories.json
**/node_modules/
*.log
*.orig
demo/public/packs/
demo/tmp/
demo/config/master.key
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Expand Up @@ -214,7 +214,7 @@ GEM
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
unicode-display_width (1.7.0)
view_component (2.24.0)
view_component (2.25.1)
activesupport (>= 5.0.0, < 7.0)
view_component_storybook (0.6.0)
view_component (>= 2.2)
Expand Down
1 change: 1 addition & 0 deletions Rakefile
Expand Up @@ -110,6 +110,7 @@ namespace :docs do
Primer::BoxComponent,
Primer::BreadcrumbComponent,
Primer::ButtonComponent,
Primer::ButtonGroupComponent,
Primer::CounterComponent,
Primer::DropdownMenuComponent,
Primer::FlashComponent,
Expand Down
5 changes: 5 additions & 0 deletions app/components/primer/button_group_component.html.erb
@@ -0,0 +1,5 @@
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
<% buttons.each do |button| %>
<%= button %>
<% end %>
<% end %>
34 changes: 34 additions & 0 deletions app/components/primer/button_group_component.rb
@@ -0,0 +1,34 @@
# frozen_string_literal: true

module Primer
# Use ButtonGroupComponent to render a series of buttons.
class ButtonGroupComponent < Primer::Component
include ViewComponent::SlotableV2

renders_many :buttons, ->(**kwargs) { Primer::ButtonComponent.new(group_item: true, **kwargs) }

# @example 50|Default
# <%= render(Primer::ButtonGroupComponent.new) do |component|
# component.button { "Default" }
# component.button(button_type: :primary) { "Primary" }
# component.button(button_type: :danger) { "Danger" }
# component.button(button_type: :outline) { "Outline" }
# component.button(classes: "my-class") { "Custom class" }
# end %>
#
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(**system_arguments)
@system_arguments = system_arguments
@system_arguments[:tag] ||= :div

@system_arguments[:classes] = class_names(
"BtnGroup",
system_arguments[:classes]
)
end

def render?
buttons.any?
end
end
end
1 change: 1 addition & 0 deletions app/components/primer/view_components.rb
Expand Up @@ -31,6 +31,7 @@
require_relative "box_component"
require_relative "breadcrumb_component"
require_relative "button_component"
require_relative "button_group_component"
require_relative "counter_component"
require_relative "details_component"
require_relative "dropdown_menu_component"
Expand Down
2 changes: 1 addition & 1 deletion demo/Gemfile.lock
Expand Up @@ -175,7 +175,7 @@ GEM
thor (1.1.0)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
view_component (2.18.0)
view_component (2.25.1)
activesupport (>= 5.0.0, < 7.0)
view_component_storybook (0.6.0)
view_component (>= 2.2)
Expand Down
31 changes: 31 additions & 0 deletions docs/content/components/buttongroup.md
@@ -0,0 +1,31 @@
---
title: ButtonGroup
status: Experimental
source: https://github.com/primer/view_components/tree/main/app/components/primer/button_group_component.rb
---

<!-- Warning: AUTO-GENERATED file, do not edit. Add code comments to your Ruby instead <3 -->

Use ButtonGroupComponent to render a series of buttons.

## Examples

### Default

<iframe style="width: 100%; border: 0px; height: 50px;" srcdoc="<html><head><link href='https://unpkg.com/@primer/css/dist/primer.css' rel='stylesheet'></head><body><div class='BtnGroup '> <button type='button' class='btn BtnGroup-item '>Default</button> <button type='button' class='btn BtnGroup-item btn-primary '>Primary</button> <button type='button' class='btn BtnGroup-item btn-danger '>Danger</button> <button type='button' class='btn BtnGroup-item btn-outline '>Outline</button> <button type='button' class='btn BtnGroup-item my-class '>Custom class</button></div></body></html>"></iframe>

```erb
<%= render(Primer::ButtonGroupComponent.new) do |component|
component.button { "Default" }
component.button(button_type: :primary) { "Primary" }
component.button(button_type: :danger) { "Danger" }
component.button(button_type: :outline) { "Outline" }
component.button(classes: "my-class") { "Custom class" }
end %>
```

## Arguments

| Name | Type | Default | Description |
| :- | :- | :- | :- |
| `system_arguments` | `Hash` | N/A | [System arguments](/system-arguments) |
2 changes: 2 additions & 0 deletions docs/src/@primer/gatsby-theme-doctocat/nav.yml
Expand Up @@ -20,6 +20,8 @@
url: /components/breadcrumb
- title: Button
url: /components/button
- title: ButtonGroup
url: /components/buttongroup
- title: Counter
url: /components/counter
- title: DropdownMenu
Expand Down
14 changes: 14 additions & 0 deletions stories/primer/button_group_component_stories.rb
@@ -0,0 +1,14 @@
# frozen_string_literal: true

class Primer::ButtonGroupComponentStories < ViewComponent::Storybook::Stories
layout "storybook_preview"

story(:button_group) do
content do |c|
c.button { "Button" }
c.button(button_type: :primary) { "Primary" }
c.button(button_type: :danger) { "Danger" }
c.button(button_type: :outline) { "Outline" }
end
end
end
45 changes: 45 additions & 0 deletions test/components/button_group_component_test.rb
@@ -0,0 +1,45 @@
# frozen_string_literal: true

require "test_helper"

class PrimerButtonGroupComponentTest < Minitest::Test
include Primer::ComponentTestHelpers

def test_does_not_render_without_buttons
render_inline(Primer::ButtonGroupComponent.new)

refute_selector("div.BtnGroup")
end

def test_renders_button_items
render_inline(Primer::ButtonGroupComponent.new) { |c| c.button { "Button" } }

assert_selector("div.BtnGroup") do
assert_selector("button.btn.BtnGroup-item", text: "Button")
end
end

def test_renders_button_with_props
render_inline(Primer::ButtonGroupComponent.new) do |c|
c.button { "Button" }
c.button(button_type: :primary) { "Primary" }
c.button(button_type: :danger) { "Danger" }
c.button(button_type: :outline) { "Outline" }
c.button(classes: "my-class") { "Custom class" }
end

assert_selector("div.BtnGroup") do
assert_selector("button.btn.BtnGroup-item", text: "Button")
assert_selector("button.btn.BtnGroup-item.btn-primary", text: "Primary")
assert_selector("button.btn.BtnGroup-item.btn-danger", text: "Danger")
assert_selector("button.btn.BtnGroup-item.btn-outline", text: "Outline")
assert_selector("button.btn.BtnGroup-item.my-class", text: "Custom class")
end
end

def test_does_not_render_content
render_inline(Primer::ButtonGroupComponent.new) { "content" }

refute_text("content")
end
end
1 change: 1 addition & 0 deletions test/components/component_test.rb
Expand Up @@ -14,6 +14,7 @@ class PrimerComponentTest < Minitest::Test
[Primer::BoxComponent, {}],
[Primer::BreadcrumbComponent, {}, proc { |component| component.slot(:item) { "Foo" } }],
[Primer::ButtonComponent, {}],
[Primer::ButtonGroupComponent, {}, proc { |component| component.button { "Button" } }],
[Primer::CounterComponent, { count: 1 }],
[Primer::DetailsComponent, {}, lambda do |component|
component.slot(:summary) { "Foo" }
Expand Down

1 comment on commit d464d1d

@vercel
Copy link

@vercel vercel bot commented on d464d1d Feb 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.