diff --git a/lookbook/docs/patterns/02-forms.md.erb b/lookbook/docs/patterns/02-forms.md.erb
index 6b5732f9b0cd..629e7afe0fc3 100644
--- a/lookbook/docs/patterns/02-forms.md.erb
+++ b/lookbook/docs/patterns/02-forms.md.erb
@@ -17,15 +17,15 @@ Additional elements like Banners might also be used.
## Grouping and hierarchy
-Form elements are related need to be grouped together. For this, use a form group.
+Form elements that are related need to be grouped together. For this, use a [form group](https://primer-lookbook.github.com/view-components/lookbook/pages/forms/groups_layouts).
-If a form is particularly long, split it into different form groups and use a `Subhead` at the start of each to give it a title. When using Subheads, we recommend implementing individual Save buttons for each section (using the Secondary style). If a section only contains `Toggle switch` elements, a separate Save button is not necessarily (since the Toggle sends its own server request on interaction).
+If a form is particularly long, split it into different form groups and use a [`Subhead`](https://primer-lookbook.github.com/view-components/lookbook/inspect/primer/beta/subhead/default) at the start of each to give it a title. When using Subheads, we recommend implementing individual Save buttons for each section (using the Secondary style). If a section only contains `Toggle switch` elements, a separate Save button is not necessarily (since the Toggle sends its own server request on interaction).
If a form does not use Subhead sections, then there should be a single 'Save' (using the Primary style) button at the end.
## Form width
-In Primer, form elements automatically take the width of the container. In certain cases (especially Settings pages), full-width input fields will look strange. In this case, form inputs will need to have a smaller width.
+In Primer, form elements automatically take the width of the container. In certain cases (especially Settings pages), full-width input fields will look strange. In this case, form inputs will need to have a smaller width. A good rule of thumb is to fit the size of the fields to the expected length of the user input. Date fields can for example be rather small, as they are limited in length. The name of an object on the other hand can be quite long, so the field is expected to be larger.
In OpenProject, each form element has its own container. It is thus possible to define the container width for each input. This width will define both the visual width of the field but also the max width of the caption field (where the line breaks).
@@ -38,6 +38,9 @@ The options are:
- :xlarge => max-width: min(640px, 100vw - 2rem)
- :xxlarge => max-width: min(960px, 100vw - 2rem)
+
+<%= embed Patterns::FormsPreview, :default, panels: %i[] %>
+
## Vertical spacing
By default, form elements do not have proper vertical spacing in Primer. We recommend a 16px (`stack/gap/normal`) vertical separate between individual elements. There is an [open issue in Primer's GitHub](https://github.com/primer/view_components/issues/3042) to fix this.
diff --git a/lookbook/previews/patterns/forms_preview.rb b/lookbook/previews/patterns/forms_preview.rb
new file mode 100644
index 000000000000..8529546f40c7
--- /dev/null
+++ b/lookbook/previews/patterns/forms_preview.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Patterns
+ # @hidden
+ class FormsPreview < ViewComponent::Preview
+ # @display min_height 500px
+ def default
+ render_with_template
+ end
+ end
+end
diff --git a/lookbook/previews/patterns/forms_preview/default.html.erb b/lookbook/previews/patterns/forms_preview/default.html.erb
new file mode 100644
index 000000000000..8ebbc3db5e9d
--- /dev/null
+++ b/lookbook/previews/patterns/forms_preview/default.html.erb
@@ -0,0 +1,60 @@
+<%
+ custom_width_form = Class.new(ApplicationForm) do
+ form do |f|
+ f.text_field(
+ name: :ultimate_answer,
+ label: "Auto",
+ caption: "Takes container width",
+ required: true,
+ input_width: :auto
+ )
+
+ f.text_field(
+ name: :ultimate_answer,
+ label: "Small",
+ required: true,
+ input_width: :small
+ )
+
+ f.text_field(
+ name: :lots_of_text,
+ label: "Medium",
+ required: true,
+ input_width: :medium
+ )
+
+ f.select_list(
+ name: "cities",
+ label: "Large",
+ caption: "All widths also work on Select fields",
+ include_blank: true,
+ required: true,
+ input_width: :large
+ ) do |city_list|
+ city_list.option(label: "Lopez Island", value: "lopez_island")
+ city_list.option(label: "Bellevue", value: "bellevue")
+ city_list.option(label: "Seattle", value: "seattle")
+ end
+
+
+ f.text_field(
+ name: :lots_of_text,
+ label: "XLarge",
+ required: true,
+ input_width: :xlarge
+ )
+
+
+ f.text_field(
+ name: :lots_of_text,
+ label: "XXLarge",
+ required: true,
+ input_width: :xxlarge
+ )
+ end
+ end
+%>
+
+<%= primer_form_with(url: "/foo") do |f| %>
+ <%= render(custom_width_form.new(f)) %>
+<% end %>