# React

Feitio’s components for React: the same HTML as Astro, with the behaviors wired by themselves.

## Install

The `@feitio/react` package brings the components; the CSS, the icons and the illustrations come from `@feitio/core`.

```shell
npm install @feitio/core @feitio/react
```

Load the CSS once, at the top of the app. The fonts come along, in `fonts.css`, without asking any other site for anything; if you already serve the fonts your own way, skip that file.

```jsx
import '@feitio/core/css/fonts.css';
import '@feitio/core/css/feitio.css';
```

## Use

Each component has the name and the props of the Astro component, with React’s names (`className`, `htmlFor`). What is a named slot in Astro (`logo`, `footer`, `do`, `dont`) is a prop here.

```jsx
import { Button, Field, Inline, Stack, TextInput } from '@feitio/react';

<Stack gap={5}>
  <Field label="Reminder name" for="nome" hint="Shows in the notification">
    <TextInput id="nome" describedBy="nome-hint" />
  </Field>
  <Inline gap={2}>
    <Button variant="primary" type="submit">Save reminder</Button>
    <Button>Cancel</Button>
  </Inline>
</Stack>
```

## Behaviors

The ones with a behavior wire it themselves when they mount: Menu, Notice, Dialog, Switch, SegmentedControl, TimeInput, FilterField, ScrollFade, BackToTop and AppShell. There is nothing to call.

-   **Uncontrolled controls.** `value`, `checked` and `on` say how they start; `onChange` tells what changed.
-   **A notice from code:** `useNotices()` gives back `show` and `close`, for the element the Notice’s `ref` points to.
-   **The StatusOverlay follows the state:** change `state` and `label`, and it shows loading, done or failed.
-   **The Dialog opens** from any button with `data-open-dialog` set to its id.

```jsx
import { useRef } from 'react';
import { Button, Notice, useNotices } from '@feitio/react';

const saved = useRef(null);
const { show } = useNotices();

<Notice ref={saved} status="ok" title="Saved" timeout={5000} hidden />
<Button onClick={() => show(saved.current)}>Save</Button>
```

## Icons

Without a word, the icons read the sprite at `/feitio/icons/sprite.svg`: copy `@feitio/core/icons/sprite.svg` there. If it lives somewhere else, say so once, around the app:

```jsx
import { FeitioProvider } from '@feitio/react';

<FeitioProvider sprite="/assets/sprite.svg">
  <App />
</FeitioProvider>
```

## The same HTML

Each component’s HTML is written only once, in Astro. React repeats that HTML, and a test holds it to it: every case is rendered in both and compared attribute by attribute. Then a real browser uses React’s behaviors, with the mouse and the keyboard, and checks that the page hydrates without a difference.
