-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1422 from NYPL/RENO-3681/newslettersignup-component
RENO-3681: NewsletterSignup Component
- Loading branch information
Showing
12 changed files
with
4,190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
import { ArgTypes, Canvas, Description, Meta, Source } from "@storybook/blocks"; | ||
|
||
import * as NewsletterSignupStories from "./NewsletterSignup.stories"; | ||
import Link from "../Link/Link"; | ||
import ComponentChangelogTable from "../../utils/ComponentChangelogTable"; | ||
import { changelogData } from "./newsletterSignupChangelogData"; | ||
|
||
<Meta of={NewsletterSignupStories} /> | ||
|
||
# NewsletterSignup | ||
|
||
| Component Version | DS Version | | ||
| ----------------- | ------------ | | ||
| Added | `Prerelease` | | ||
| Latest | `Prerelease` | | ||
|
||
## Table of Contents | ||
|
||
- {<Link href="#overview" target="_self">Overview</Link>} | ||
- {<Link href="#component-props" target="_self">Component Props</Link>} | ||
- {<Link href="#accessibility" target="_self">Accessibility</Link>} | ||
- {<Link href="#changelog" target="_self">Changelog</Link>} | ||
|
||
## Overview | ||
|
||
<Description of={NewsletterSignupStories} /> | ||
|
||
## Component Props | ||
|
||
<Canvas of={NewsletterSignupStories.WithControls} /> | ||
|
||
<ArgTypes of={NewsletterSignupStories.WithControls} /> | ||
|
||
## Accessibility | ||
|
||
The `NewsletterSignup` component is a complex component built from various Reservoir | ||
DS and Chakra components. | ||
|
||
The `title` prop of the `NewsletterSignup` component expects a `HTML Element` or a `React Component`. By default it renderes a `h2` tag but it is | ||
the responsibility of the consuming app to pass the heading tag (`h*`) that aligns with the page structure and ensures accessibility. | ||
|
||
Within the `NewsletterSignup` component, the DS `form` component wraps around two DS `FormField` components. | ||
Those`FormField` components hold a DS `TextInput` component of `type="email"` and a DS `Button` component of `type="submit"` respectively. | ||
Each of these components has their own accessibility features documented in their respective Storybook pages. | ||
|
||
When the form is submitted, focus is set to the confirmation message or the | ||
error message if an error occurs. | ||
|
||
Resources: | ||
|
||
- [W3C WAI Headings](https://www.w3.org/WAI/tutorials/page-structure/headings/) | ||
- [DS Form Accessibility](../?path=/docs/components-form-elements-form--docs#accessibility) | ||
- [DS Button Accessibility](../?path=/docs/components-form-elements-button--docs#accessibility) | ||
- [DS TextInput Accessibility](../?path=/docs/components-form-elements-textinput--docs#accessibility) | ||
|
||
## JSX Elements passed to descriptionText Prop | ||
|
||
Alternatively to a `descriptionText` of type `string`, a HTML Element or React component can be passed. When passing a JSX Element, the consuming app is responsible | ||
to assure its accessibility. | ||
|
||
_NOTE: This is applicable for all component props accepting HTML/JSX elements._ | ||
|
||
<Canvas of={NewsletterSignupStories.DescriptionUsingJSXElements} /> | ||
|
||
## Form Submission Data | ||
|
||
Submitted form data can be retrieved when the `NewsletterSignup` component is | ||
submitted through the required `onSubmit` prop. This prop expects a function and | ||
it will be called when the form is submitted. Similar to other DS form-components | ||
that have function props, the data from the component will be returned in the | ||
function's argument. In this case, it will be a single object. | ||
|
||
The submitted form data will be passed as an object that the parent component | ||
can use. The returned object will always contain the "email" field. | ||
|
||
Below is an example callback function named `onSubmit` that is passed to the | ||
`NewsletterSignup` component's `onSubmit` prop and how the view is controlled | ||
in the data submission process. The form data will be returned through | ||
the function's argument as an object, called `values` in the example below. | ||
|
||
<Source | ||
code={` | ||
const [view, setView] = React.useState("form"); | ||
const onSubmit = async (values) => { | ||
e.preventDefault(); | ||
setView("submitting"); | ||
const endpoint = "..."; | ||
//Form the request for sending data to the server. | ||
const options = { | ||
method: "POST", | ||
headers: {Content-Type: "application/json"}, | ||
body: JSON.stringify(values), | ||
}; | ||
//Send the form and await response. | ||
try { | ||
const response = await fetch(endpoint, options); | ||
const result = await response.json(); | ||
setView("confirmation"); | ||
} catch (error) { | ||
setView("error"); | ||
} | ||
}; | ||
//.... | ||
<NewsletterSignup onChange={onChange} onSubmit={onSubmit} view={view} /> | ||
`} | ||
language="jsx" | ||
/> | ||
|
||
## Interactive Example with onChange and onSubmit | ||
|
||
_NOTE: open the browser console to see the values logged in the example below._ | ||
|
||
The input value typed into the `TextInput` of the `NewsletterSignup` component can be accessed by the | ||
functions passed to the `onChange` and `onSubmit` prop. | ||
|
||
Both the `onChange` and `onSubmit` callback functions can retrieved the submitted value as `event.target.email.value` | ||
through the `event` object passed as the single argument. | ||
|
||
The following example logs the `event.target.email.value` to the console on each `onChange` call and upon | ||
clicking the Submit button which triggers the `onSubmit` function and simulate a submission. | ||
The component will transition through a `"submitting"` view to an alternating `"confirmation"`, `"error"` or "invalid Email" view. | ||
|
||
<Source | ||
code={` | ||
function NewsletterSignupOnSubmitExampleComponent() { | ||
const [view, setView] = React.useState("form"); | ||
const [inputVal, setInputVal] = React.useState(""); | ||
const handleChange = (event) => { | ||
console.log(\`onChange Email Input value: \${event.target.value}\`); | ||
setInputVal(event.target.value); | ||
}; | ||
const handleSubmit = (event) => { | ||
event.preventDefault(); | ||
console.log(\`onSubmit Email Input value: \${event.target.email.value}\`); | ||
}; | ||
return ( | ||
<NewsletterSignup | ||
id="interactive" | ||
view={view} | ||
isInvalidEmail={counter === 3} | ||
valueEmail={inputVal} | ||
onChange={handleChange} | ||
onSubmit={handleSubmit} | ||
confirmationHeading="Thank you for signing up!" | ||
confirmationText="You can update your email subscription preferences at any time using the links at the bottom of the email." | ||
/> | ||
); | ||
} `} | ||
language="jsx" | ||
/> | ||
|
||
<Canvas of={NewsletterSignupStories.NewsletterSignupOnSubmitExample} /> | ||
|
||
## Component States | ||
|
||
<Canvas of={NewsletterSignupStories.ComponentStates} /> | ||
|
||
## Changelog | ||
|
||
<ComponentChangelogTable changelogData={changelogData} /> |
Oops, something went wrong.
d0be2e0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
nypl-design-system – ./
nypl-design-system-git-development-nypl.vercel.app
nypl-design-system.vercel.app
nypl-design-system-nypl.vercel.app