-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: camertron <camertron@users.noreply.github.com> Co-authored-by: Jon Rohan <rohan@github.com>
- Loading branch information
1 parent
e62af5e
commit c12ae8c
Showing
9 changed files
with
300 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@primer/view-components': patch | ||
--- | ||
|
||
Add a standalone FormControl component |
Binary file added
BIN
+7.55 KB
...t/screenshots/snapshots.test.ts-snapshots/primer/alpha/form_control/default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+7.55 KB
...t/screenshots/snapshots.test.ts-snapshots/primer/alpha/form_control/focused.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<%= render(Primer::BaseComponent.new(tag: :div, **@system_arguments)) do %> | ||
<%= render(Primer::BaseComponent.new(tag: :label, **@label_arguments)) do %> | ||
<%= @label %> | ||
<% if required? %> | ||
<span aria-hidden="true">*</span> | ||
<% end %> | ||
<% end %> | ||
<% if @input_block %> | ||
<%= view_context.capture { @input_block.call(@input_arguments) } %> | ||
<% end %> | ||
<% if @validation_message %> | ||
<%= render(Primer::BaseComponent.new(tag: :div, **@validation_arguments)) do %> | ||
<%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %> | ||
<span><%= @validation_message %></span> | ||
<% end %> | ||
<% end %> | ||
<% if @init_caption || caption? %> | ||
<span class="FormControl-caption" id="<%= @caption_id %>"> | ||
<% if caption? %> | ||
<%= caption %> | ||
<% else %> | ||
<%= @init_caption %> | ||
<% end %> | ||
</span> | ||
<% end %> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# frozen_string_literal: true | ||
|
||
module Primer | ||
module Alpha | ||
# Wraps an input (or arbitrary content) with a label above and a caption and validation message beneath. | ||
# NOTE: This `FormControl` component is designed for wrapping inputs that aren't supported by the Primer | ||
# forms framework. | ||
class FormControl < Primer::Component | ||
# Describes the field and what sorts of input it expects. Displayed below the input. | ||
# Note that this slot takes precedence over the `caption:` argument in the constructor. | ||
renders_one :caption | ||
|
||
# @example Default | ||
# <%= render(Primer::Alpha::FormControl.new(label: "Best character")) do |component| %> | ||
# <% component.with_input do |input_arguments| %> | ||
# <%= render(Primer::Alpha::SegmentedControl.new("aria-label": "Best character", **input_arguments)) do |seg| %> | ||
# <% seg.with_item(label: "Han Solo") %> | ||
# <% seg.with_item(label: "Luke Skywalker") %> | ||
# <% seg.with_item(label: "Leia Organa") %> | ||
# <% end %> | ||
# <% end %> | ||
# <% end %> | ||
# | ||
# @param label [String] Label text displayed above the input. | ||
# @param caption [String] Describes the field and what sort of input it expects. Displayed below the input. Note that the `caption` slot is also available and takes precedence over this argument when provided. | ||
# @param validation_message [String] A string displayed in red between the caption and the input indicating the input's contents are invalid. | ||
# @param required [Boolean] Default `false`. When set to `true`, causes an asterisk (*) to appear next to the field's label indicating it is a required field. Note that this option explicitly does _not_ add a `required` HTML attribute. Doing so would enable native browser validations, which are inaccessible and inconsistent with the Primer design system. | ||
# @param visually_hide_label [Boolean] When set to `true`, hides the label. Although the label will be hidden visually, it will still be visible to screen readers. | ||
# @param full_width [Boolean] When set to `true`, the form control will take up all the horizontal space allowed by its container. | ||
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %> | ||
def initialize(label:, caption: nil, validation_message: nil, required: false, visually_hide_label: false, full_width: false, **system_arguments) | ||
@label = label | ||
@init_caption = caption | ||
@validation_message = validation_message | ||
@required = required | ||
@visually_hide_label = visually_hide_label | ||
@full_width = full_width | ||
@system_arguments = system_arguments | ||
|
||
@system_arguments[:classes] = class_names( | ||
@system_arguments[:classes], | ||
"FormControl", | ||
"FormControl--fullWidth" => full_width? | ||
) | ||
|
||
@label_arguments = { | ||
classes: class_names( | ||
"FormControl-label", | ||
visually_hide_label? ? "sr-only" : nil | ||
) | ||
} | ||
|
||
base_id = self.class.generate_id | ||
@validation_id = "validation-#{base_id}" | ||
@caption_id = "caption-#{base_id}" | ||
|
||
@validation_arguments = { | ||
classes: "FormControl-inlineValidation", | ||
id: @validation_id | ||
} | ||
end | ||
|
||
# @!parse | ||
# # The input content. Yields a set of <%= link_to_system_arguments_docs %> that should be added to the input. | ||
# # | ||
# renders_one(:input) | ||
|
||
def with_input(&block) | ||
@input_block = block | ||
end | ||
|
||
def required? | ||
@required | ||
end | ||
|
||
def visually_hide_label? | ||
@visually_hide_label | ||
end | ||
|
||
def full_width? | ||
@full_width | ||
end | ||
|
||
private | ||
|
||
def before_render | ||
# make sure to evaluate the component's content block so slots are defined | ||
content | ||
|
||
@input_arguments = { | ||
aria: {} | ||
} | ||
|
||
ids = [].tap do |memo| | ||
memo << @validation_id if @validation_message | ||
memo << @caption_id if @init_caption || caption? | ||
end | ||
|
||
return if ids.empty? | ||
|
||
@input_arguments[:aria][:describedby] = ids.join(" ") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# frozen_string_literal: true | ||
|
||
module Primer | ||
module Alpha | ||
# @label FormControl | ||
class FormControlPreview < ViewComponent::Preview | ||
# @label Playground | ||
# | ||
# @param label text | ||
# @param caption text | ||
# @param validation_message text | ||
# @param required toggle | ||
# @param visually_hide_label toggle | ||
# @param full_width toggle | ||
def playground( | ||
label: "Best character", | ||
caption: "May the force be with you", | ||
validation_message: "Something went wrong", | ||
required: false, | ||
visually_hide_label: false, | ||
full_width: false | ||
) | ||
render_with_template( | ||
locals: { | ||
system_arguments: { | ||
label: label, | ||
caption: caption, | ||
validation_message: validation_message, | ||
required: required, | ||
visually_hide_label: visually_hide_label, | ||
full_width: full_width | ||
} | ||
} | ||
) | ||
end | ||
|
||
# @label Default | ||
def default | ||
render_with_template( | ||
template: "primer/alpha/form_control_preview/playground", | ||
locals: { | ||
system_arguments: { | ||
label: "Best character" | ||
} | ||
} | ||
) | ||
end | ||
|
||
# @!group Options | ||
# | ||
# @label With caption | ||
def with_caption | ||
render_with_template( | ||
template: "primer/alpha/form_control_preview/playground", | ||
locals: { | ||
system_arguments: { | ||
label: "Best character", | ||
caption: "May the force be with you" | ||
} | ||
} | ||
) | ||
end | ||
|
||
# @label With validation message | ||
def with_validation_message | ||
render_with_template( | ||
template: "primer/alpha/form_control_preview/playground", | ||
locals: { | ||
system_arguments: { | ||
label: "Best character", | ||
validation_message: "Something went wrong" | ||
} | ||
} | ||
) | ||
end | ||
|
||
# @label Required | ||
def required | ||
render_with_template( | ||
template: "primer/alpha/form_control_preview/playground", | ||
locals: { | ||
system_arguments: { | ||
label: "Best character", | ||
required: true | ||
} | ||
} | ||
) | ||
end | ||
|
||
# @label With visually hidden label | ||
def with_visually_hidden_label | ||
render_with_template( | ||
template: "primer/alpha/form_control_preview/playground", | ||
locals: { | ||
system_arguments: { | ||
label: "Best character", | ||
visually_hide_label: true | ||
} | ||
} | ||
) | ||
end | ||
# | ||
# @!endgroup | ||
end | ||
end | ||
end |
9 changes: 9 additions & 0 deletions
9
previews/primer/alpha/form_control_preview/playground.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<%= render(Primer::Alpha::FormControl.new(**system_arguments)) do |component| %> | ||
<% component.with_input do |input_arguments| %> | ||
<%= render(Primer::Alpha::SegmentedControl.new("aria-label": "Best character", **input_arguments)) do |seg| %> | ||
<% seg.with_item(label: "Han Solo", selected: true) %> | ||
<% seg.with_item(label: "Luke Skywalker") %> | ||
<% seg.with_item(label: "Leia Organa") %> | ||
<% end %> | ||
<% end %> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# frozen_string_literal: true | ||
|
||
require "components/test_helper" | ||
|
||
module Primer | ||
module Alpha | ||
class FormControlTest < Minitest::Test | ||
include Primer::ComponentTestHelpers | ||
|
||
def test_basic_structure | ||
render_preview(:playground) | ||
|
||
assert_selector(".FormControl-label", text: "Best character") | ||
assert_selector("segmented-control") | ||
assert_selector(".FormControl-inlineValidation", text: "Something went wrong") do | ||
assert_selector(".octicon-alert-fill") | ||
end | ||
assert_selector(".FormControl-caption", text: "May the force be with you") | ||
end | ||
|
||
def test_described_by_ids | ||
render_preview(:playground) | ||
|
||
caption_id = page.find_css(".FormControl-caption")[0].attributes["id"].value | ||
validation_id = page.find_css(".FormControl-inlineValidation")[0].attributes["id"].value | ||
described_by_ids = page.find_css("segmented-control ul")[0].attributes["aria-describedby"].value.split | ||
|
||
assert_includes(described_by_ids, caption_id) | ||
assert_includes(described_by_ids, validation_id) | ||
end | ||
|
||
def test_required | ||
render_preview(:required) | ||
|
||
assert_selector(".FormControl-label", text: "Best character") do | ||
assert_selector("[aria-hidden=true]", text: "*") | ||
end | ||
end | ||
|
||
def test_visually_hidden_label | ||
render_preview(:with_visually_hidden_label) | ||
|
||
assert_selector(".FormControl-label.sr-only", text: "Best character") | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters