Skip to content

Commit

Permalink
Add nested forms for check boxes (#1498)
Browse files Browse the repository at this point in the history
  • Loading branch information
neall authored Oct 17, 2022
1 parent be0197e commit b3668d3
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-mice-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/view-components': patch
---

Add option for nested forms for check boxes
39 changes: 39 additions & 0 deletions app/forms/check_box_with_nested_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

# :nodoc:
class CustomCitiesForm < ApplicationForm
form do |custom_cities_form|
custom_cities_form.text_field(
name: :custom_cities,
label: "Custom cities",
description: "A space-separated list of cities"
)
end
end

# :nodoc:
class CheckBoxWithNestedForm < ApplicationForm
form do |check_form|
check_form.check_box_group(name: :city_categories) do |check_group|
check_group.check_box(
value: "capital",
label: "Capital",
description: "The capital city"
)
check_group.check_box(
value: "populous",
label: "Most-populous",
description: "The five most-populous cities"
)
check_group.check_box(
value: "custom",
label: "Custom",
description: "A custom list of cities"
) do |custom_check_box|
custom_check_box.nested_form do |builder|
CustomCitiesForm.new(builder)
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/primer/forms/check_box.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@
<%= render(Caption.new(input: @input)) %>
</span>
</div>
<% if @input.nested_form_block %>
<%= content_tag(:div, nested_form_arguments) do %>
<%= render(@input.nested_form_block.call(builder)) %>
<% end %>
<% end %>
13 changes: 13 additions & 0 deletions lib/primer/forms/check_box.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ def initialize(input:)
@input.label_arguments[:value] = checked_value
end

def nested_form_arguments
return @nested_form_arguments if defined?(@nested_form_arguments)

@nested_form_arguments = { **@input.nested_form_arguments }
@nested_form_arguments[:class] = class_names(
@nested_form_arguments[:class],
@nested_form_arguments.delete(:classes),
"ml-4"
)

@nested_form_arguments
end

private

def checked_value
Expand Down
4 changes: 2 additions & 2 deletions lib/primer/forms/dsl/check_box_group_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def type
:check_box_group
end

def check_box(**system_arguments)
def check_box(**system_arguments, &block)
args = {
name: @name,
**system_arguments,
Expand All @@ -40,7 +40,7 @@ def check_box(**system_arguments)
scheme: scheme
}

@check_boxes << CheckBoxInput.new(**args)
@check_boxes << CheckBoxInput.new(**args, &block)
end

private
Expand Down
9 changes: 8 additions & 1 deletion lib/primer/forms/dsl/check_box_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class CheckBoxInput < Input
DEFAULT_SCHEME = :boolean
SCHEMES = [DEFAULT_SCHEME, :array].freeze

attr_reader :name, :label, :value, :unchecked_value, :scheme
attr_reader :name, :label, :value, :unchecked_value, :scheme, :nested_form_block, :nested_form_arguments

def initialize(name:, label:, value: nil, unchecked_value: nil, scheme: DEFAULT_SCHEME, **system_arguments)
raise ArgumentError, "Check box scheme must be one of #{SCHEMES.join(', ')}" unless SCHEMES.include?(scheme)
Expand All @@ -22,12 +22,19 @@ def initialize(name:, label:, value: nil, unchecked_value: nil, scheme: DEFAULT_
@scheme = scheme

super(**system_arguments)

yield(self) if block_given?
end

def to_component
CheckBox.new(input: self)
end

def nested_form(**system_arguments, &block)
@nested_form_arguments = system_arguments
@nested_form_block = block
end

def type
:check_box
end
Expand Down
2 changes: 2 additions & 0 deletions previews/primer/forms/forms_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def select_list_form; end

def radio_button_with_nested_form; end

def check_box_with_nested_form; end

def caption_template_form; end

def after_content_form; end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= primer_form_with(url: "/foo") do |f| %>
<%= render(CheckBoxWithNestedForm.new(f)) %>
<% end %>
6 changes: 6 additions & 0 deletions test/primer/forms/forms_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ def test_composed_form
assert_selector ".FormControl-input[name='[last_name][last_name]']"
end

def test_check_box_includes_nested_form
render_preview :check_box_with_nested_form

assert_selector ".FormControl-checkbox-wrap + .ml-4 .FormControl input[name=custom_cities]"
end

def test_renders_separator
render_preview :multi_text_field_form

Expand Down

0 comments on commit b3668d3

Please sign in to comment.