Skip to main content
Neighborhood Design System v5.1.0

React

Use the React package: client components, props, slots, events, refs and forms.

@fbin-web/neighborhood-react has a React component for every Neighborhood component. Each one renders the same custom element as the Web Component, so it looks and behaves the same, and the React version adds typed props and event props. Installation covers the packages; this page covers using them.

Client components

Neighborhood components run in the browser. In the Next.js App Router, use them from Client Components, in files that start with 'use client'. In a Vite app or the Pages Router, nothing extra is needed.

The components are still rendered on the server as their tags, with their slotted content, so put the text that should be in the first HTML in slots. Platform setup covers Next.js.

Props

Props use the property names from each component page, in camelCase: marginBottom, helpText, totalPages. They’re set as properties on the element, so they can take any value, including lists and objects:

<NbhdSelect
  name="finish"
  label="Finish"
  items={[
    { name: 'Chrome', value: 'chrome' },
    { name: 'Matte Black', value: 'matte-black' },
  ]}
/>

Leave a prop out rather than passing undefined. The components apply every prop they’re given, so placeholder={undefined} replaces the default placeholder with nothing. When a prop is optional, spread it only when it has a value:

<NbhdSelect
  label="Finish"
  items={finishes}
  {...(placeholder && { placeholder })}
/>

Slots

Fill a slot with the slot prop on the element that holds the content. Children with no slot go into the default slot.

<NbhdHeadlineContent surface="inverse">
  <NbhdText
    slot="title"
    tag="h2"
    variant="title">
    Built to last
  </NbhdText>
  <NbhdCta
    slot="cta"
    href="/warranty">
    See the warranty
  </NbhdCta>
</NbhdHeadlineContent>

Events

Each nbhd-* event has a prop that starts with onNbhd: nbhd-change is onNbhdChange, nbhd-page-changed is onNbhdPageChanged and nbhd-dialog-close is onNbhdDialogClose. The handler receives the event, with its details on event.detail. Each component page lists its events.

<NbhdPagination
  totalPages={12}
  currentPage={page}
  onNbhdPageChanged={(event) => setPage(event.detail.page)}
/>

Form fields also send a standard change event, so React 19 calls an onChange prop too. Prefer onNbhdChange: it’s typed, and its event.detail.value always holds the new value.

Form fields

Input, Textarea, Checkbox, Radio, Radio Group and Select report changes with onNbhdChange, and event.detail.value holds the new value.

Controlled: keep the value in state and pass it back with value.

const [email, setEmail] = useState('');

<NbhdInput
  name="email"
  type="email"
  label="Email"
  value={email}
  onNbhdChange={(event) => setEmail(event.detail.value)}
/>;

Uncontrolled: leave out value, and read every field when the form submits. The fields submit with a native <form> under their name, as described in Use components in forms.

function onSubmit(event) {
  event.preventDefault();
  const data = new FormData(event.currentTarget);
  subscribe(data.get('email'));
}

<form onSubmit={onSubmit}>
  <NbhdInput
    name="email"
    type="email"
    label="Email"
    required
  />
  <NbhdButton type="submit">Subscribe</NbhdButton>
</form>;

Refs and methods

A ref points to the element itself, so you can call its methods, such as checkValidity() on a field, slideTo() on a Carousel or show() and hide() on a Dialog:

const carousel = useRef(null);

<NbhdButton onClick={() => carousel.current.slideTo(0)}>Back to the first slide</NbhdButton>
<NbhdCarousel ref={carousel}>…</NbhdCarousel>

The methods are listed on each component page.

Dialogs and other open states

When a component can close itself, keep your state in step with its event. A Dialog closes on Escape and its close button, so set your state back in onNbhdDialogClose:

const [open, setOpen] = useState(false);

<NbhdButton onClick={() => setOpen(true)}>See details</NbhdButton>
<NbhdDialog
  label="Details"
  open={open}
  onNbhdDialogClose={() => setOpen(false)}>
  …
</NbhdDialog>

Without it, the dialog closes but open stays true, and the next click doesn’t open it again.

Types

Types are exported from the package root, next to the components: props (ButtonProps), content shapes (CardContent, SelectOptionContent), shared values (Surface) and event types (BreadcrumbClickEvent).

import type { SelectOptionContent, Surface } from '@fbin-web/neighborhood-react';

React 19

React 19 can set properties and listen for events on custom elements itself, so the plain tags work in JSX too: <nbhd-button variant="primary">. Prefer the React components anyway: they’re typed, and their event props are named for you.

Next steps

Esc
↑ ↓ to move↵ to open