alouette
Version:
A modern, customizable design system built on top of NativeWind v5 with configurable defaults
149 lines (120 loc) • 10.6 kB
Markdown
# alouette 23
Breaking changes of 23.0.0. Run the 22.x codemod first ([22.md](22.md)).
## To 23.0.0
The button material is reworked. The default is now `tonal`: a ground lighter
than the page, a pale tone of the accent in light mode, with the accent carried
by the label's ink (`text-on-tonal`). The old accent-filled `contained` button
becomes `filled`, and is flat (no shadow). The secondary action beside a
primary one is `accent="neutral" variant="soft"`: a neutral text button.
### Custom palette: regenerate it
If the app ships its own palette (`writeTheme` / `generateTheme` from
`alouette/theme-generator`), rerun its build script. The interactive tokens are
renamed (see [Color tokens](#color-tokens)), so a palette generated by 22.x has
no ground for any button. Apps on alouette's default palette have nothing to do.
### Variants
| Component | Before | After |
| ------------------------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------ |
| `Button`, `ActionButton`, `ExternalLinkButton`, `InternalLinkButton`, `AppHeaderSignIn`, `PressableBox` | `variant="contained"` | `variant="filled"` to keep the accent fill, or nothing for `tonal` |
| | `variant="ghost"` | `variant="soft"` |
| | no `variant` (contained) | no `variant` (now `tonal`) |
| | `variant="list"` | nothing (`tonal`) |
| `IconButton` | `variant="contained"` | `variant="filled"`, or nothing for `tonal` |
| | no `variant` (contained) | no `variant` (now `tonal`) |
| | `variant="list"` | nothing (`tonal`) |
| | `variant="outlined"` | `variant="soft"` |
| | `variant="ghost"` | `variant="soft"` |
| `PressableListItem` | `variant="list"` (default) | `variant="tonal"` (the default) |
| | `variant="contained"` | `variant="filled"` |
| | `variant="ghost"` | nothing (`tonal`) or `variant="outlined"` |
| `EditableItem` `variant`, `EditableSection` `editIconVariant` | any `IconButton` variant | the `IconButton` mapping above |
| `RadioCardGroup`, `CheckboxCardGroup` | `variant="contained"` | `variant="tonal"` (the default) |
`outlined` and `soft` are unchanged on `Button` and `PressableBox`, but a `soft`
`Button` is now a text button: its label is `text-accent` and underlined.
Do not map every `contained` to `filled`. `filled` is for the one action that
must dominate; everything else takes the `tonal` default. The secondary action
of a pair (Cancel, Dismiss, Discard) is `accent="neutral" variant="soft"`, not
`accent="neutral"` alone: a neutral `tonal` button keeps its ground and shadow,
so the pair reads as two equal choices, and on a white `bg-highlight` ground (a
`Modal` footer, the `AppHeader` bar) that ground is the same white and
dissolves.
```tsx
// A pair: the primary on the default, the secondary neutral and soft
<Button accent="neutral" variant="soft" text="Cancel" onPress={close} />
<Button text="Save" onPress={save} />
// The one action that must dominate: filled; the other stays neutral and soft
<Button accent="neutral" variant="soft" text="Dismiss" onPress={close} />
<Button variant="filled" text="Save and close" onPress={saveAndClose} />
```
alouette's own footers (`AlertDialog`, `useFormEditorModal`) and the header
"Sign up" now do this.
**An accented surface** (`<Box accent="…" className="surface">`, a
`GradientBackground`) needs a change too: an accented `tonal` ground is the
surface's own color in light mode and dissolves. Make a lone button there
`accent="neutral"`, and the accented action `variant="filled"` or
`variant="soft"`. On web, outside production, `PressableBox` logs
`[Alouette] A tonal pressable rests on its own ground` when this happens.
### Removed and renamed components
| Before | After |
| -------------------------------------------- | --------------------------------------------------------------------- |
| `CheckboxButtonGroup` + `CheckboxButton` | `CheckboxGroup` + `Checkbox`, or `CheckboxCardGroup` + `CheckboxCard` |
| `AppHeaderNav` / `AppHeaderNavProps` | `HeaderNav` / `HeaderNavProps` |
| `AppHeaderNavItem` / `AppHeaderNavItemProps` | `HeaderNavItem` / `HeaderNavItemProps` |
`HeaderNav` and `HeaderNavItem` take the same props as before; only the names
change.
### Deprecated components removed
The aliases deprecated in 22.x are gone. Migrate with the codemod before
upgrading (see
[22.md](22.md)
for the full mapping and its warnings):
```sh
npx alouette-codemod surface-and-stacks src
```
| Before | After |
| ---------------------------------------------------- | ------------------------------------------------------------------------ |
| `VStack` / `VStackProps` | `<View>` / `ViewProps` |
| `HStack` / `HStackProps` | `<View className="flex-row">` / `ViewProps` |
| `Stack` / `StackProps` | `<View className="flex-row flex-wrap">` / `ViewProps` |
| `Surface` / `SurfaceProps` | `<Box className="surface">` / `BoxProps` |
| `<EditableSurface>` / `EditableSurfaceProps` | `<EditableSection className="surface">` / `EditableSectionProps` |
| `<FormEditableSurface>` / `FormEditableSurfaceProps` | `<FormEditableSection className="surface">` / `FormEditableSectionProps` |
### Color tokens
Only relevant if the app writes these classes itself:
| Before | After |
| -------------------------------------------------------- | ----------------------------------------------------- |
| `*-interactive-contained-{pressable,hover,focus,active}` | `*-interactive-filled-{pressable,hover,focus,active}` |
| `*-interactive-contained-disabled` | `*-interactive-filled-disabled` |
| `*-interactive-list-{pressable,hover,focus,active}` | `*-interactive-tonal-{pressable,hover,focus,active}` |
| `text-on-list` | `text-on-tonal` |
New: `interactive-tonal-disabled`, and the shadow layer colors
(`shadow-highlight`, `dark-shadow`, `soft-shadow`, `shadow-lowered-dark`,
`shadow-lowered-highlight`, `bar-dark-shadow`, `bar-soft-shadow`), which
`shadow-s` / `-m` / `-l` / `-lowered` / `-bar` now read so that dark mode can
deepen them.
Some values change. In the neutral theme, the `filled` ground and `enabled` are
the sharp ink as a ground: near black in light mode, near white in dark mode,
where `text-on-accent` turns dark and `text-on-accent-muted` moves with it.
`enabled` moves one step on colored accents. Accented `emphasis` (dark mode),
`highlight-accent` (light mode), `disabled-sharp` and `disabled-muted` (dark
mode) move by one or two steps.
### Changed appearance
No code change is needed. Review these screens:
- `Avatar` is `bg-emphasis` + `text-on-emphasis` instead of `bg-enabled` +
`text-on-accent`. `<Avatar variant="enabled">` restores the old fill.
- `Badge` `solid` is `bg-emphasis` + `text-on-emphasis` instead of
`bg-highlight-accent` + `text-sharp`. `outlined` gains a `bg-highlight-accent`
ground. `solid` and `solid.enabled` gain a 1px border in their fill color, so
they are 2px larger, the size of `outlined`. `Badge` also accepts
`accent="neutral"`.
- `AlertDialog` (confirm variant): Cancel is neutral `soft` and confirm is
accented `tonal`. The new `primaryAction="cancel"` gives a neutral `filled`
Cancel and a `soft` confirm, for an irreversible action where backing out is
the expected answer.
- The close button of `Modal`, the dismiss of `Message` and the remove button of
`FormFieldArray` are `soft`.
- `EditableSection` with an `accent` defaults its edit button to `soft`.
- `Radio` and `Checkbox` rows take a `soft` fill on hover, focus and press.
- `Message` and `Bullet` set `text-base` on their text. `Bullet` centers its icon
on the first line.
- `StableAccentScope` with a `mode` and no `accent` now re-applies the inherited
accent in that mode. It used to keep the inherited theme as it was, ignoring
`mode`. `PortalAccentScope` takes the same `mode` prop.