class Primer::Alpha::FormControl


‘aria-describedby` manually on the input element.
input being wrapped is not generated by a Rails form helper, care must be taken to set
and validation message elements, and can be passed directly to Rails’ form helper methods. If the
example above, ‘input_arguments[:describedby]` contains the HTML IDs for both the caption
`aria-describedby` attribute in the hash it yields to the block passed to `#with_input`. In the
validation message elements. The component attempts to mitigate this by including the correct
Similarly, `FormControl` cannot automatically connect the `<input>` element to the caption and
as part of the `label_arguments` passed to the `FormControl` constructor.
Note that the name of the field, `:bar`, is passed to both the Rails `#text_field` method and
“`
<% end %>
<% end %>
<% end %>
<%= f.text_field(:bar, **input_arguments) %>
<% component.with_input do |input_arguments| %>
<%= render(Primer::Alpha::FormControl.new(label_arguments: { for: “bar” })) do |component| %>
<%= form_with(url: “/path/somewhere”) do |f| %>
“`erb
attribute, eg:
Users of the `FormControl` component will need to manually connect the label using the `for:`
use Primer’s pre-made form components like ‘TextField`, etc, ideally via the Primer forms framework.
the input and its associated label. For this and other reasons, consumers are highly encouraged to
Because `FormControl` does not manage the actual `<input>` element, it cannot semantically connect
@accessibility
forms framework.
NOTE: This `FormControl` component is designed for wrapping inputs that aren’t supported by the Primer
Wraps an input (or arbitrary content) with a label above and a caption and validation message beneath.

def before_render

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
  @input_arguments[:aria][:required] = "true" if required?
  return if ids.empty?
  @input_arguments[:aria][:describedby] = ids.join(" ")
end

def full_width?

@returns Boolean
Whether or not the form control should take up all the horizontal space allowed by its container.
def full_width?
  @full_width
end

def initialize(label:, caption: nil, validation_message: nil, required: false, visually_hide_label: false, full_width: false, label_arguments: {}, **system_arguments)

Parameters:
  • system_arguments (Hash) -- <%= link_to_system_arguments_docs %>
  • label_arguments (Hash) -- HTML attributes to attach to the `
  • full_width (Boolean) -- When set to `true`, the form control will take up all the horizontal space allowed by its container.
  • 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.
  • 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.
  • validation_message (String) -- A string displayed in red between the caption and the input indicating the input's contents are invalid.
  • 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.
  • label (String) -- Label text displayed above the input.
def initialize(label:, caption: nil, validation_message: nil, required: false, visually_hide_label: false, full_width: false, label_arguments: {}, **system_arguments)
  @label = label
  @init_caption = caption
  @validation_message = validation_message
  @required = required
  @visually_hide_label = visually_hide_label
  @full_width = full_width
  @label_arguments = label_arguments
  @system_arguments = system_arguments
  @system_arguments[:classes] = class_names(
    @system_arguments[:classes],
    "FormControl",
    "FormControl--fullWidth" => full_width?
  )
  @label_arguments[:classes] = class_names(
    @label_arguments.delete(:classes),
    "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

def required?

@returns Boolean
Whether or not this input is marked as required.
def required?
  @required
end

def visually_hide_label?

@returns Boolean
Whether or not to hide the label visually. The label will still be visible to screen readers.
def visually_hide_label?
  @visually_hide_label
end

def with_input(&block)

def with_input(&block)
  @input_block = block
end