The Primer forms framework is a framework for declaratively defining forms using the Primer design system that are accessible by default.
Every input type (text fields, select lists, etc) is defined as an input, i.e. a class that inherits from Primer::Forms::Dsl::Input
. These inputs together form the framework's DSL, or Domain Specific Language. Inputs return component instances via their #to_component
methods. Components are classes that inherit from Primer::Forms::BaseComponent
. Together, inputs and components define the form.
Example: The TextFieldInput
.
Inputs are essentially the DSL layer. They produce components that can be rendered on the page. As such, they generally don't concern themselves with HTML, CSS, etc. Instead, they are supposed to be an abstraction that collects high-level configuration that can be used to construct a component. In practice, the distinction between an input and a component is somewhat blurry, and we are considering merging the two together to reduce complexity.
Example: The TextField
component
Although they are not strictly view components (i.e. they do not inherit from ViewComponent::Base
), components are designed to work in a very similar fashion. Templates (i.e. ERB files) are defined in separate files with the same file name as the corresponding component class. For example, the TextField
component class lives in text_field.rb and renders the text_field.html.erb class.
Text fields (for example) can be declared by calling the text_field
method, which is defined here. All this method does is create a new instance of TextFieldInput
and add it to the list of inputs. When rendered, the framework interates over this list of inputs, calls #to_component
on each input, and render
s the resulting component instance.
Adding an input requires these steps:
- Create a new input class in
Primer::Forms::Dsl
. - Create a new component class and associated template in the
Primer::Forms
namespace. Define the#to_component
method on the input class and return an instance of the component class. - Add a method to the
InputMethods
module that creates a new input instance and passes it to#add_input
. - Write previews and tests.