Skip to content

Commit 2e91b10

Browse files
authored
Display forms embedded inline within guides; remove "forms" link from main nav (#556)
1 parent d06e0fc commit 2e91b10

21 files changed

Lines changed: 244 additions & 142 deletions

File tree

.cursor/settings.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/components/Header.astro

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ const { pathname } = Astro.url;
66
77
const navLinks = [
88
{ href: siteInfo.urls.guides, label: "Guides" },
9-
{ href: siteInfo.urls.forms, label: "Forms" },
109
{ href: siteInfo.urls.blog, label: "Blog" },
1110
{ href: siteInfo.urls.donate, label: "Donate" },
1211
];

src/components/forms/DeleteFormDataModal/DeleteFormDataModal.css

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
flex-direction: column;
44
gap: var(--space-m);
55
align-items: flex-start;
6-
padding: var(--space-l);
7-
border: 1px solid var(--border-color);
8-
border-radius: var(--radius-m);
6+
padding-block-end: var(--space-l);
7+
border-block-end: 1px solid var(--border-color);
98
}
109

1110
.delete-form-data-modal {

src/components/forms/FormCompleteStep/FormCompleteStep.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
flex-direction: column;
44
gap: var(--space-2xl);
55
align-items: flex-start;
6-
padding-block: var(--space-xl) var(--space-2xl);
6+
padding-block-start: var(--space-xl);
77
}
88

99
.form-complete-step-header {

src/components/forms/FormCompleteStep/FormCompleteStep.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,27 @@ export interface FormCompleteStepProps {
1212
slug: FormSlug;
1313
title: string;
1414
onRedownload: (e: React.SubmitEvent<HTMLFormElement>) => void | Promise<void>;
15+
inline?: boolean;
16+
headingLevel?: 1 | 2 | 3;
1517
}
1618

1719
export function FormCompleteStep({
1820
slug,
1921
title,
2022
onRedownload,
23+
inline = false,
24+
headingLevel = 1,
2125
}: FormCompleteStepProps) {
2226
const [isDownloading, setIsDownloading] = useState(false);
2327

2428
useEffect(() => {
29+
if (inline) return;
2530
const previous = document.body.dataset.color;
2631
document.body.dataset.color = "green";
2732
return () => {
2833
document.body.dataset.color = previous ?? "";
2934
};
30-
}, []);
35+
}, [inline]);
3136

3237
const handleSubmit = async (e: React.SubmitEvent<HTMLFormElement>) => {
3338
e.preventDefault();
@@ -49,7 +54,7 @@ export function FormCompleteStep({
4954
return (
5055
<section className="form-complete-step">
5156
<header className="form-complete-step-header">
52-
<Heading level={1} className="form-complete-step-heading">
57+
<Heading level={headingLevel} className="form-complete-step-heading">
5358
Form complete!
5459
</Heading>
5560
<p className="form-complete-step-description">

src/components/forms/FormContainer/FormContainer.css

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,56 @@
33
flex-direction: column;
44
gap: var(--space-m);
55
width: 100%;
6-
min-height: 100dvh;
7-
padding-block-end: var(--space-m);
6+
7+
&:not([data-inline]) {
8+
min-height: 100dvh;
9+
padding-block-end: var(--space-m);
10+
}
811
}
912

1013
.form-container-content {
1114
width: 100%;
12-
padding-block-end: var(--space-xl);
15+
16+
.form-container:not([data-inline]) & {
17+
padding-block-end: var(--space-xl);
18+
}
19+
20+
.form-container[data-inline] & {
21+
padding-inline: var(--space-xl);
22+
}
23+
}
24+
25+
.form-container[data-inline] {
26+
.form-title-step {
27+
padding-block: 0;
28+
}
29+
30+
.form-navigation {
31+
padding: var(--space-m);
32+
padding-inline-end: var(--space-l);
33+
}
34+
35+
.form-title-step-heading {
36+
padding-block-start: var(--space-xl);
37+
font-size: var(--step-3);
38+
}
39+
40+
.form-title-step-description {
41+
font-size: var(--step-1);
42+
}
43+
44+
.form-complete-step {
45+
padding-block: 0;
46+
}
47+
48+
.form-complete-step-heading {
49+
padding-block-start: var(--space-xl);
50+
font-size: var(--step-3);
51+
}
52+
53+
.form-complete-step-description {
54+
font-size: var(--step-1);
55+
}
1356
}
1457

1558
.form-container-loading {

src/components/forms/FormContainer/FormContainer.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ export interface FormContainerProps {
3939

4040
/** The costs associated with this form. */
4141
costs?: Costs | null;
42+
43+
/** Render inline within a page rather than as a full-page experience. */
44+
inline?: boolean;
4245
}
4346

4447
export function FormContainer({
@@ -49,6 +52,7 @@ export function FormContainer({
4952
updatedAt,
5053
pdfs,
5154
costs,
55+
inline = false,
5256
}: FormContainerProps) {
5357
const config = getFormConfig(slug);
5458

@@ -77,8 +81,16 @@ export function FormContainer({
7781
const [submitError, setSubmitError] = useState<string | null>(null);
7882

7983
const scrollToFormTop = useCallback(() => {
80-
containerRef.current?.scrollIntoView({ block: "start" });
81-
}, []);
84+
const el = containerRef.current;
85+
if (!el) return;
86+
if (inline) {
87+
if (el.getBoundingClientRect().top < 0) {
88+
el.scrollIntoView({ block: "start" });
89+
}
90+
return;
91+
}
92+
el.scrollIntoView({ block: "start" });
93+
}, [inline]);
8294

8395
const focusStepContent = useCallback(() => {
8496
requestAnimationFrame(() => {
@@ -162,6 +174,7 @@ export function FormContainer({
162174
updatedAt={updatedAt ?? ""}
163175
totalSteps={totalSteps}
164176
onStart={onStart}
177+
headingLevel={inline ? 2 : 1}
165178
>
166179
{banner && (
167180
<Banner icon={RiMegaphoneLine}>
@@ -185,6 +198,8 @@ export function FormContainer({
185198
title={title}
186199
slug={config.slug}
187200
onRedownload={onSubmit}
201+
inline={inline}
202+
headingLevel={inline ? 2 : 1}
188203
/>
189204
);
190205
default:
@@ -203,6 +218,7 @@ export function FormContainer({
203218
totalSteps,
204219
onStart,
205220
onSubmit,
221+
inline,
206222
]);
207223

208224
const showNavigation = !["title", "complete"].includes(phase);
@@ -225,6 +241,7 @@ export function FormContainer({
225241
return (
226242
<section
227243
className="form-container form-container-loading"
244+
data-inline={inline || undefined}
228245
ref={containerRef}
229246
>
230247
<ProgressCircle isIndeterminate aria-label="Loading form" size={40} />
@@ -235,7 +252,11 @@ export function FormContainer({
235252
return (
236253
<FormProvider {...form}>
237254
<FormStepContext.Provider value={stepContextValue}>
238-
<section className="form-container" ref={containerRef}>
255+
<section
256+
className="form-container"
257+
data-inline={inline || undefined}
258+
ref={containerRef}
259+
>
239260
{showNavigation && <FormNavigation />}
240261
<div className="form-container-content">{currentStepComponent}</div>
241262
</section>

src/components/forms/FormFeedback/FormFeedback.css

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
gap: var(--space-l);
55
align-items: stretch;
66
width: 100%;
7-
padding: var(--space-l);
8-
border: 1px solid var(--border-color);
9-
border-radius: var(--radius-m);
7+
padding-block-end: var(--space-l);
8+
border-block-end: 1px solid var(--border-color);
109
}
1110

1211
.form-feedback-success {

src/components/forms/FormTitleStep/FormTitleStep.css

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,6 @@
66
padding-block: var(--space-xl) var(--space-2xl);
77
}
88

9-
.form-title-step-back-link {
10-
display: flex;
11-
gap: var(--space-2xs);
12-
align-items: center;
13-
padding-inline-end: var(--space-2xs);
14-
margin-block-end: var(--space-s);
15-
margin-inline-start: calc(-1 * var(--space-2xs));
16-
font-size: var(--step-0);
17-
color: var(--text-color);
18-
text-decoration: none;
19-
20-
@media (hover: hover) {
21-
&:hover {
22-
text-decoration: underline;
23-
}
24-
}
25-
}
26-
279
.form-title-step-header {
2810
display: flex;
2911
flex-direction: column;
@@ -39,10 +21,6 @@
3921
color: var(--text-color);
4022
letter-spacing: var(--letter-spacing-condensed);
4123
text-wrap: balance;
42-
43-
@media (width < 700px) {
44-
font-size: var(--step-5);
45-
}
4624
}
4725

4826
.form-title-step-description {
@@ -82,6 +60,19 @@
8260
grid-area: title;
8361
}
8462

63+
.form-info-description {
64+
grid-area: description;
65+
font-size: var(--step--1);
66+
font-weight: var(--weight-medium);
67+
text-wrap: pretty;
68+
}
69+
70+
.form-info-pdf-list {
71+
padding-inline-start: var(--space-m);
72+
margin: 0;
73+
list-style-type: disc;
74+
}
75+
8576
.form-title-step-footer {
8677
display: flex;
8778
flex-direction: column;
@@ -96,22 +87,9 @@
9687
}
9788
}
9889

99-
.form-info-description {
100-
grid-area: description;
101-
font-size: var(--step--1);
102-
font-weight: var(--weight-medium);
103-
text-wrap: pretty;
104-
}
105-
106-
.form-info-pdf-list {
107-
padding-inline-start: var(--space-m);
108-
margin: 0;
109-
list-style-type: disc;
110-
}
111-
11290
.form-title-step-date-updated {
11391
width: 100%;
114-
padding-block: var(--space-s);
92+
padding-block-start: var(--space-s);
11593
font-size: var(--step--1);
11694
text-wrap: pretty;
11795
border-top: 1px solid var(--border-color);

src/components/forms/FormTitleStep/FormTitleStep.tsx

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {
22
type RemixiconComponentType,
3-
RiArrowLeftLine,
43
RiArrowRightLine,
54
RiFileCheckLine,
65
RiShieldKeyholeLine,
@@ -9,13 +8,13 @@ import {
98
import { useEffect, useState } from "react";
109
import { type IBrowser, type IDevice, UAParser } from "ua-parser-js";
1110
import type { FormPdfMetadata } from "../../../forms/getFormPdfMetadata";
11+
import { formatBrowser } from "../../../utils/formatBrowser";
12+
import { formatDevice } from "../../../utils/formatDevice";
1213
import { formatTimeEstimate } from "../../../utils/formatTimeEstimate";
1314
import { smartquotes } from "../../../utils/smartquotes";
1415
import { Button } from "../../common/Button";
15-
import "./FormTitleStep.css";
16-
import { formatBrowser } from "../../../utils/formatBrowser";
17-
import { formatDevice } from "../../../utils/formatDevice";
1816
import { Heading } from "../../common/Content/Content";
17+
import "./FormTitleStep.css";
1918

2019
const formatter = new Intl.DateTimeFormat("en-US", {
2120
dateStyle: "long",
@@ -49,40 +48,14 @@ function FormInfoItem({ icon: Icon, children }: FormInfoItemProps) {
4948
}
5049

5150
export interface FormTitleStepProps {
52-
/**
53-
* The title of the form.
54-
*/
5551
title: string;
56-
57-
/**
58-
* The description of the form.
59-
*/
6052
description?: string | null;
61-
62-
/**
63-
* Child content.
64-
*/
6553
children?: React.ReactNode;
66-
67-
/**
68-
* Handler for when the user clicks the start button.
69-
*/
7054
onStart: () => void;
71-
72-
/**
73-
* The PDF metadata for forms that will be generated.
74-
*/
7555
pdfs: FormPdfMetadata[];
76-
77-
/**
78-
* The total number of steps in the form.
79-
*/
8056
totalSteps: number;
81-
82-
/**
83-
* The date the form was last updated.
84-
*/
8557
updatedAt: string;
58+
headingLevel?: 1 | 2 | 3;
8659
}
8760

8861
export function FormTitleStep({
@@ -93,6 +66,7 @@ export function FormTitleStep({
9366
pdfs,
9467
totalSteps,
9568
updatedAt,
69+
headingLevel = 1,
9670
}: FormTitleStepProps) {
9771
const [device, setDevice] = useState<IDevice | null>(null);
9872
const [browser, setBrowser] = useState<IBrowser | null>(null);
@@ -108,10 +82,7 @@ export function FormTitleStep({
10882
return (
10983
<section className="form-title-step">
11084
<header className="form-title-step-header">
111-
<a href="/forms" className="form-title-step-back-link">
112-
<RiArrowLeftLine /> All forms
113-
</a>
114-
<Heading level={1} className="form-title-step-heading">
85+
<Heading level={headingLevel} className="form-title-step-heading">
11586
{smartquotes(title)}
11687
</Heading>
11788
{description && (

0 commit comments

Comments
 (0)