Skip to content

Files

73 lines (51 loc) · 5.3 KB

adding_new_components.md

File metadata and controls

73 lines (51 loc) · 5.3 KB

Adding New Components

Checklist

Every new react-uswds component needs the following:

  • A Github issue with the requirements clearly listed. Requirements include a rough sketch of the expected props and any state the component will handle.
  • A component file (.tsx) inside a matching folder - e.g. component/GovBanner/GovBanner.tsx.
  • An export from the package entry point - e.g. index.ts must have the line export { GovBanner } from './components/GovBanner/GovBanner'
  • Unit tests (test.tsx file) for logic relating to props and events handlers.
  • Storybook stories (stories.tsx file) illustrating the use of the component. The goal is parity with the USWDS design system examples. Use the component story format.

Navigating documentation

We can extrapolate the requirements for react-uswds components by referencing several sources. Relevant documentation includes:

Pay special attention to:

  • Mobile. There are often mobile and desktop styles - see <Header /> and <FooterExtendedNavList /> for two different approaches to implementing mobile styles.
  • User Interaction. Consider interactions such click, focus, hover. Some of this will be naturally handled by applying the proper uswds CSS classes, other behaviors will need custom implementation. See <Accordion /> for examples of both cases,
  • Accessibility. Double check behavior of keyboard-only interactions. Some user interaction requires multiple event handlers (e.g. for non interactive elements that use onClick, a keyboard listener (such as onKeyDown or onKeyPress is also needed)). We have added the jsx-a11y plugin to help with accessibility requirements.

Guiding Patterns For Writing Flexible Components in react-uswds

Props

  • Require props that are fundamental to the element (such as id and name for a form input), even if they aren't necessarily "required" HTML attributes. Make all other props optional.
  • Extend the standard HTML attributes as props for the primary element in the component. For example, a form can have its own props and also extend the HTMLFormElement
  interface FormProps {
    children: React.ReactNode,
    big: boolean
  }
  
  export const Form = (
    props: FormProps & JSX.IntrinsicElements['form']
  ): React.ReactElement =>
  • Avoid conflicting boolean props. When props are mutually exclusive you likely need to use an enum prop instead. See <Button />.

State

  • Group state declarations and hooks at the top of the component function. Make it easy to see how state is being used in the component.
  • When using useState, prefer functional updates. Object spread syntax is useful here.
  • Keep components as flexible as possible. This means leaving business logic/implementation details out of the component (use props instead of internal state). Anytime you find yourself using component state heavily, ask yourself if its something that should actually be tracked by the consumer instead.

Children

  • Whenever main content is not required and is not highly structured or ordered, passing children may be the way to go.

Using "Subcomponents"

  • The react-uswds components will not always map one-to-one to uswds design system components. By creating subcomponents, we break down larger component into smaller concerns and benefit from React's ability to compose components together.
  • We have a pattern of grouping subcomponents together in a folder. We don't write stories for most subcomponents, unless they seem like a piece of UI that could be reused alone. Examples of subcomponents - Header, Footer, Card
  • Indicators that a subcomponent may be needed:
    • It's getting hard to pass conditional props (such as styles) to different levels of the HTML tree from the top level.
    • A smaller piece of UI is being used that is generalizable enough to be used and exported on its own.
    • The uswds component is complex - an organism in the language of atomic design.

Common Components in react-uswds

  • Components that apply uswds styles to a standard HTMLElement - Button, Table
  • Components that encapsulate user interaction flows - Accordion, Modal
  • Components for a common gov tech use case - Search, SocialLinks
  • Components that render children - Card, Header, Footer
  • Components related to forms, especially form inputs - DateInput, TextInput Checkbox, Label