From e1761b3dc763bc2a461c0bd81a13e3c3b7e1172d Mon Sep 17 00:00:00 2001 From: Shelley Nason Date: Mon, 24 Aug 2026 17:58:17 -0400 Subject: [PATCH 1/6] Embedded forms should not have h1 headings --- app/helpers/application_helper.rb | 26 +++ app/views/admin/forms/example.html.erb | 170 ++++++++++++------ .../forms}/_archived_form.html.erb | 5 +- app/views/components/forms/_custom.html.erb | 4 +- .../components/forms/_custom_layout.html.erb | 7 +- app/views/components/forms/_flash.html.erb | 9 +- .../components/forms/_logo_and_title.html.erb | 35 ++-- .../components/forms/edit/_builder.html.erb | 2 +- .../_custom_text_display.html.erb | 4 +- app/views/components/widget/_fba.js.erb | 6 +- app/views/components/widget/_modal.html.erb | 3 +- .../components/widget/_no_modal.html.erb | 9 +- app/views/components/widget/_widget.css.erb | 20 ++- app/views/submissions/_form.html.erb | 4 +- app/views/submissions/new.html.erb | 2 +- .../forms/_custom_layout.html.erb_spec.rb | 2 +- 16 files changed, 208 insertions(+), 100 deletions(-) rename app/views/{submissions => components/forms}/_archived_form.html.erb (65%) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ba820b3b2..bd18ea93e 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -248,5 +248,31 @@ def boolean_to_text(value) value ? 'Yes' : 'No' end + # Heading levels per render context and semantic role. The embedded widget is + # injected into host pages that already own the top-level

, so its title + # is demoted to

(and alerts to

) to preserve valid heading order. + # Hosted forms own the page, so the title is the

. + HEADING_LEVELS = { + hosted: { title: 'h1', alert: 'h2' }, + embedded: { title: 'h2', alert: 'h3' }, + }.freeze + + # Render context is passed explicitly as a `render_context` local down each + # partial chain (:hosted from components/forms/_custom_layout and + # submissions/new, :embedded from components/widget/_no_modal). It defaults to + # :embedded so the widget still renders correctly when invoked from a bare + # model/helper call with no local set. + def form_render_context(render_context = nil) + render_context || :embedded + end + + def title_heading_level(render_context = nil) + HEADING_LEVELS.fetch(form_render_context(render_context)).fetch(:title) + end + + def alert_heading_level(render_context = nil) + HEADING_LEVELS.fetch(form_render_context(render_context)).fetch(:alert) + end + delegate :fiscal_year_and_quarter, to: :FiscalYear end diff --git a/app/views/admin/forms/example.html.erb b/app/views/admin/forms/example.html.erb index 663bdaffd..40f38bbca 100644 --- a/app/views/admin/forms/example.html.erb +++ b/app/views/admin/forms/example.html.erb @@ -9,16 +9,98 @@ @@ -28,65 +110,41 @@ <% if @form.delivery_method == "inline" %> -
-
-
-
+
+
+ Example page +

Header

+
+
+ Inline form +
Touchpoint will be rendered here.
-
-
+
+
-
<% elsif @form.delivery_method == "custom-button-modal" %> -
-
-
-
- - This is a custom button - -
+ -
<% else %> -
-
-
-
-
- - Example page - -

-
header -

-
-
+
+
+ Example page +

Header

-
-
-
-
-
-
- main content -
-
+
+
+ main content
-
-
-
-
-
-
-
-
-
-
-
+ +
+
<% end %> diff --git a/app/views/submissions/_archived_form.html.erb b/app/views/components/forms/_archived_form.html.erb similarity index 65% rename from app/views/submissions/_archived_form.html.erb rename to app/views/components/forms/_archived_form.html.erb index 043d9aaea..2d28e8c74 100644 --- a/app/views/submissions/_archived_form.html.erb +++ b/app/views/components/forms/_archived_form.html.erb @@ -1,9 +1,10 @@ +<%# locals: (form:, render_context:) %>
-

+ <%= content_tag alert_heading_level(render_context), class: "usa-alert__heading" do %> This form is not currently accepting feedback -

+ <% end %>

The form, <%= form.title %>, diff --git a/app/views/components/forms/_custom.html.erb b/app/views/components/forms/_custom.html.erb index 7f580c3a2..c3661343c 100644 --- a/app/views/components/forms/_custom.html.erb +++ b/app/views/components/forms/_custom.html.erb @@ -1,3 +1,5 @@ +<%# locals: (form:, render_context:) %> + <% multi_section_question_number = 0 %>

<%= render 'components/forms/question_types/date_select', form: form, question: question, question_number: multi_section_question_number %> <% elsif question.question_type == "custom_text_display" %> - <%= render 'components/forms/question_types/custom_text_display', form: form, question: question, question_number: multi_section_question_number %> + <%= render 'components/forms/question_types/custom_text_display', question: question, render_context: render_context %> <% end %>
<% else %> diff --git a/app/views/components/forms/_custom_layout.html.erb b/app/views/components/forms/_custom_layout.html.erb index 2c4b3c76c..7f43021ec 100644 --- a/app/views/components/forms/_custom_layout.html.erb +++ b/app/views/components/forms/_custom_layout.html.erb @@ -1,7 +1,8 @@ +<%# locals: (form:, render_context:) %>
- <%= render "components/forms/logo_and_title", form: form %> + <%= render "components/forms/logo_and_title", form: form, render_context: render_context %> <%- if form.instructions.present? %>
<%= sanitize(form.instructions) %> @@ -14,8 +15,8 @@

<% end %> - <%= render 'components/forms/flash', form: form %> - <%= render partial: "components/forms/custom", locals: { form: form, questions: form.questions } %> + <%= render 'components/forms/flash', form: form, render_context: render_context %> + <%= render partial: "components/forms/custom", locals: { form: form, render_context: render_context } %>
diff --git a/app/views/components/forms/_flash.html.erb b/app/views/components/forms/_flash.html.erb index 9f8d7b36e..bf9a30a5c 100644 --- a/app/views/components/forms/_flash.html.erb +++ b/app/views/components/forms/_flash.html.erb @@ -1,8 +1,9 @@ +<%# locals: (form:, render_context:) %>