Skip to content

Commit

Permalink
Merge pull request #1422 from NYPL/RENO-3681/newslettersignup-component
Browse files Browse the repository at this point in the history
RENO-3681: NewsletterSignup Component
  • Loading branch information
bigfishdesign13 authored Oct 12, 2023
2 parents 2571864 + 77c31d7 commit d0be2e0
Show file tree
Hide file tree
Showing 12 changed files with 4,190 additions and 0 deletions.
163 changes: 163 additions & 0 deletions src/components/NewsletterSignup/NewsletterSignup.mdx
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} />
Loading

1 comment on commit d0be2e0

@vercel
Copy link

@vercel vercel bot commented on d0be2e0 Oct 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.