# Migration guide

> Upgrade ngwr from any earlier major.

Source: https://ngwr.dev/docs/migration

## Update

Commit first, then run one command from any major.

```bash
ng update ngwr
```

| Major | What ng update does |
| --- | --- |
| v15 | Rewrites paths, config calls, `-rgb` reads, renamed tokens and two values, lists files for the rest. |
| v14 | Rewrites six renames, lists files for the rest. |
| v13 | Lists files with a host `id` selector, rewrites nothing. |
| v12 | Rewrites the date import paths. |
| v10, v11 | Nothing. Colour changes only. |
| v9 | Rewrites `<wr-checkbox value>`. |
| v8 | Rewrites density and pagination sizes, lists removed components. |
| v7 | Rewrites tags, imports and `@use` paths. |

- Never target a 7.x, 8.x or 9.x release with `ng update`, `ng add` or `ng g ngwr:*`. Their schematics do not load.
- pnpm: on `ERR_PNPM_IGNORED_BUILDS`, allow the builds and run again.
- pnpm holds a new release back for a day, so `ng update` may find nothing yet.

## If an update failed

A failed or killed run skips its migration: update, commit, then run it by name.

```bash
ng update ngwr
git commit -am "chore: update ngwr"
ng update ngwr --migrate-only --name=migration-v14
```

| If | Migration |
| --- | --- |
| `ng update ngwr@7`, `@8` or `@9` failed with `exports is not defined in ES module scope` | `migration-v7`, `-v8`, `-v9`: each one that failed, oldest first |
| `ng update ngwr` hung on 14.5.0 or earlier | `migration-v14` |
| You are on 15.0.0-rc.0 or rc.1, which shipped without a codemod | `migration-v15`. The next `ng update ngwr` runs it too. |

## v14 to v15

Needs Angular 22 and Chrome 123, Firefox 120 or Safari 17.5. `ng update` runs `migration-v15`.

| ng update | What |
| --- | --- |
| Rewrites | Chart, bit, `ngwr/drag-drop` and `ngwr/icon/adapters/lucide` paths. Config calls into one `provideWr()`. `rgba(var(--…-rgb), a)` into `color-mix()`. Reads of the renamed tokens. `tone="dark"`, `tone="medium"`, `<wr-timeline-item color="medium">`. |
| Lists files | What needs your decision, by file and line: `@use 'ngwr'`, removed intents, `[data-theme]`, removed entry points and providers, the sortable list loop, validation copy. |
| Leaves alone | The behaviour and visual changes in the last two sections. |

- Most of what it lists fails silently. Work through the report rather than waiting for the build.
- Each table below says what the codemod does with each row.

## v14 to v15: providers

One `provideWr()` call from `ngwr`, one feature per setting, with the same options.

```diff
- provideWrDensity({ defaultDensity: 'sm' }),
- provideWrToastConfig({ duration: 6000 }),
+ provideWr(
+   withDensity({ defaultDensity: 'sm' }),
+   withToast({ duration: 6000 }),
+ ),
```

| Before | After | Codemod |
| --- | --- | --- |
| `provideWrDensity(o)` | `withDensity(o)` from `ngwr/density` | Rewrites |
| `provideWrToastConfig(o)` | `withToast(o)` from `ngwr/toast` | Rewrites |
| `provideWrStorage(o)` | `withStorage(o)` from `ngwr/storage` | Rewrites |
| `provideWrMeta(o)` | `withMeta(o)` from `ngwr/meta` | Rewrites |
| `provideWrTheme(o)` | `withTheme(o)` from `ngwr/theme` | Rewrites |
| `provideWrDateAdapter(o)` | `withDates(o)` from `ngwr/date`. Delete a call with no options. | Rewrites |
| `provideWrOverlay()` | Delete. Isolated overlays are the default. | Lists files |
| `WrDateAdapterOptions`, `ProvideWrStorageOptions` | `WrDatesOptions`, `WrStorageOptions` | Rewrites |

- Put `withDensity()`, `withToast()` and `withTheme()` in the app providers. A lazy route never reads them.
- `provideWrIcons()`, the i18n providers and `provideWrLoadingBarRouter()` are unchanged.
- The codemod moves a call only when it is a plain entry of a `providers` array. It lists one kept in a variable, a spread or a ternary, a second call of one kind in the same array, and a `provideWrTheme()` that passes `attribute`.

## v14 to v15: imports and styles

Symbols keep their names; only import, `@use` and `/testing` paths move.

| Before | After | Codemod |
| --- | --- | --- |
| `ngwr/bar-chart`, `calendar-heatmap`, `donut-chart`, `gauge`, `line-chart`, `meter-group`, `sparkline` | `ngwr/charts/<name>` | Rewrites |
| `ngwr/aurora`, `blur-text`, `border-glow`, `circular-text`, `click-spark`, `confetti`, `decrypt-text`, `falling-text`, `fuzzy-text`, `glitch-text`, `gradient-text`, `marquee`, `rotating-text`, `shiny-text`, `splash-cursor`, `split-text`, `spotlight-card`, `star-border`, `tilt-card`, `typewriter`, `waves` | `ngwr/bits/<name>` | Rewrites |
| `ngwr/drag-drop` | `ngwr/sortable-list` | Rewrites |
| `ngwr/icon/adapters/lucide` | `ngwr/icon` | Rewrites |
| `@use 'ngwr'` | `@use 'ngwr/theme'` first, then one `@use` per entry point you render | Lists files |

- The umbrella also carried the density scale. With `withDensity()` or `[wrDensity]`, add `@use 'ngwr/density'`, or the setting does nothing.
- `ngwr/reset`, `ngwr/animations` and `ngwr/typography-utilities` load the theme now. Write them below a configured `@use 'ngwr/theme' with (…)`, or the build fails.

## v14 to v15: colour tokens

Neutral colours are role tokens now, such as `--wr-color-surface` and `--wr-border-base`.

| Before | After | Codemod |
| --- | --- | --- |
| `--wr-color-light`, `--wr-color-outline` | `--wr-border-base` | Rewrites reads |
| `--wr-color-dark` | `--wr-color-on-surface` | Rewrites reads |
| `--wr-color-muted-text`, `--wr-color-medium` | `--wr-color-on-surface-muted` | Rewrites reads |
| `--wr-color-border`, `--wr-color-border-subtle`, `--wr-color-border-strong` | `--wr-border-subtle`, or `--wr-border-base` for a firmer line | Rewrites reads, to the subtle one |
| `--wr-color-white-contrast` (dark theme only) | `--wr-color-on-surface` | Rewrites reads |
| Every `-rgb` token, e.g. `rgba(var(--wr-color-primary-rgb), 0.2)` | `color-mix(in srgb, var(--wr-color-primary) 20%, transparent)` | Rewrites, lists what it cannot read |
| `--wr-color-backdrop-rgb` | `color-mix(in srgb, var(--wr-color-backdrop) 45%, transparent)` | Rewrites |
| `--wr-calendar-accent-rgb` | `--wr-calendar-accent` | Rewrites |
| `--wr-color-picker-rgb` | `--wr-color-picker-color` | Rewrites |
| The `-rgb` of a renamed token, e.g. `rgba(var(--wr-color-dark-rgb), 0.5)` | `color-mix(in srgb, var(--wr-color-on-surface) 50%, transparent)` | Rewrites |
| `color="secondary"`, `--wr-color-secondary-*`, and the colour, shades and classes of `light`, `medium`, `dark` | No replacement. Pick another intent or your own colour. | Lists files |
| Those four keys in `$base-colors` | Delete them | Lists files |

- A `var()` at a removed token drops its whole declaration, with no error. The codemod rewrites the reads, and lists a declaration, since which role it should set is your call. That includes a `[style.--…]` binding, `setProperty()` and a style-object key.
- Without `strictTemplates`, a removed `color` value renders neutral, with no error.
- `--wr-border-strong` is new, and darker than any border v14 had.

## v14 to v15: dark mode

`[data-theme]` is gone: the theme follows the OS through `color-scheme` and `light-dark()`.

```diff
- .hero { background: #fff; }
- [data-theme='dark'] .hero { background: #0b1120; }
+ .hero { background: light-dark(#fff, #0b1120); }

- .panel {
-   color: #111;
-   @include theme.dark { color: #eee; }
- }
+ .panel { color: light-dark(#111, #eee); }

- <html data-theme="dark">
+ <html style="color-scheme: dark">
```

| Before | After | Codemod |
| --- | --- | --- |
| `theme.dark-selector()`, `$theme-attribute`, the `attribute` option of `provideWrTheme()` and `wrThemePrePaintScript()` | Delete | Lists files |
| Reading `data-theme` in code | `WrTheme.resolved()` | Lists files |
| `wrThemeTokens()`, `wrIntentTokens()`, `wrContrastFor()` | `$base-colors` or `theme.rebrand()`, at build time. See [Theming](https://ngwr.dev/guides/theming). | Lists files |
| `--wr-star-border-stop` | `background` on `.wr-star-border .wr-star-border__ray` | Lists files |

- A leftover `[data-theme]` selector compiles and matches nothing.
- To stay light, add `:root { color-scheme: light; }` after `@use 'ngwr/theme'`.
- Add `withTheme()` so a stored choice applies at boot; on a prerendered page also ship `wrThemePrePaintScript()`.
- `light-dark()` takes colours only.
- In canvas code, read a token with [`resolveCssColor()`](https://ngwr.dev/reference/utils/resolve-css-color), not `getPropertyValue()`.
- For the old dark `wr-border-glow`, set `--wr-border-glow-halo-blend: plus-lighter`, `--wr-border-glow-fill-blend: soft-light` and `--wr-border-glow-fill-scale: 1` on the dark section.
- `[wrTilt]`'s glare blends `normal` in both schemes, so your own `--wr-tilt-glare-color` paints at face value.

## v14 to v15: components

```diff
- import { WrSortableList } from 'ngwr/drag-drop';
+ import { WrSortableList, WrSortableItem } from 'ngwr/sortable-list';

  <wr-sortable-list [(items)]="rows">
-   <ng-template let-row let-i="index">
-     <div>{{ i + 1 }}. {{ row.label }}</div>
-   </ng-template>
+   @for (row of rows(); track row.id; let i = $index) {
+     <wr-sortable-item>{{ i + 1 }}. {{ row.label }}</wr-sortable-item>
+   }
  </wr-sortable-list>
```

| Before | After | Codemod |
| --- | --- | --- |
| `<wr-sortable-list>` with an `<ng-template>` | Your own `@for` with one `<wr-sortable-item>` per row. `trackBy` is gone. | Rewrites the path, lists the loop |
| `wrSquircle` from `ngwr/squircle` | `shape="squircle"` on `wr-btn`, `wr-avatar`, `wr-badge`; the `theme.smooth-br()` mixin elsewhere | Lists files |
| `<wr-action-sheet>` | `<wr-drawer position="bottom" rounded>` with your own rows | Lists files |
| `<wr-drawer showHandle>`, `.wr-drawer__handle`, `__grabber`, `.wr-drawer__panel--handle` | Delete. Swipe-to-dismiss is gone. | Lists files |
| `responsive` on `wr-select`, `[wrDropdown]`, `[wrPopover]`, `wr-command-palette`, `WrDialog.open()` | Delete. For a sheet on phones, open a `<wr-drawer position="bottom">`. | Lists files |
| `WrPopoverHarness.isSheet()`, `WrCommandPaletteHarness.isPresentedAsSheet()` | Delete | Lists files |
| `<wr-editor format>`, `WrEditorFormat` | Delete. The value is a `WrEditorJson` tree, or `null` when empty. | Lists files |
| `[wrTypography] tone="dark"`, `tone="medium"` | `tone="base"`, `tone="muted"` | Rewrites |
| `.wr-typography--tone-dark`, `--tone-medium` | `.wr-typography--tone-base`, `--tone-muted` | Rewrites |
| `<wr-timeline-item color="medium">`, `.wr-timeline-item--medium` | `color="neutral"`, `.wr-timeline-item--neutral` | Rewrites |
| `WrSidebarItem` `badge: 'new'`, `badge: '12'` | `badge: { text: 'New', tone: 'primary' }` for a word, `count: 12` for a number | Lists files |
| `WrSidebarGroup.children` holds `WrSidebarItem`s | A child can be a group: check `'children' in child` before reading `url`, `disabled` or `activeOptions` | No |
| `<wr-sidebar>` draws `folder` and `caret-forward` icons by default | No icons by default. Bind `defaultGroupIcon` and `defaultItemIcon` to keep them. | Lists files |
| `.wr-sidebar__entry`, `__item`, `__group-toggle`, `__item-title`, `--active` and `--disabled` on the first two | `.wr-sidebar__row`, `__title`, `.wr-sidebar__row--active`, `.wr-sidebar__row--disabled`; `.wr-sidebar__row--group` for `__group-toggle` | Lists files |
| `--wr-sidebar-padding` | Unchanged. It was the only sidebar hook v14 published; the others are new. | Nothing to do |

- A `<wr-sortable-list>` that still holds an `<ng-template>` renders nothing.
- Bare `wrSquircle`, `showHandle`, `responsive` and `format` attributes compile and do nothing. So do rules on `.wr-overlay-sheet`, `.wr-overlay-backdrop` and `.wr-command-palette--sheet`.
- `<wr-editor>` refuses an HTML or markdown string, and `''`: convert to `WrEditorJson`, or `null` for empty.

## v14 to v15: removed entry points

| Removed | Use instead | Codemod |
| --- | --- | --- |
| `ngwr/config`: `provideWrConfig()`, `WR_CONFIG`, `useConfigValue()` | Bind the input where you want another value | Lists files |
| `ngwr/media`: `WrMedia`, `provideWrMedia()`, `WR_BREAKPOINTS` | `BreakpointObserver` from `@angular/cdk/layout` | Lists files |
| `ngwr/markdown`, `@use 'ngwr/markdown'` and the `markdown.*` catalog keys | `<wr-editor readonly [toolbar]="false">` | Lists files |
| `ngwr/icon/adapters/feather` | `svgIcon()` from `ngwr/icon`, with Feather's own SVG files | Lists files |
| `provideWrResponsiveOverlays()`, `WR_RESPONSIVE_OVERLAYS`, `wrPresentAsSheet`, `@use 'ngwr/overlay'` | Delete | Lists files |
| `WrVisualViewport`, `--wr-keyboard-inset` | `window.visualViewport` | Lists files |

```diff
# Breakpoints
- protected readonly isMd = inject(WrMedia).matches('md');
+ protected readonly isMd = toSignal(
+   inject(BreakpointObserver).observe('(min-width: 768px)').pipe(map(s => s.matches)),
+   { initialValue: false },
+ );

# Feather
# needs "loader": { ".svg": "text" } and declare module '*.svg?raw'
- provideWrIcons(featherIcons({ plus: featherSource.plus }));
+ import plusSvg from 'feather-icons/dist/icons/plus.svg?raw';
+ provideWrIcons([svgIcon('plus', plusSvg)]);
```

- Deleting `provideWrConfig()` resets every control it set to `md` and the standard radius. Bind those inputs first.
- `WrMedia`'s `md` is `(min-width: 768px)`. The other widths are `$breakpoints` in `ngwr/breakpoints`.
- A Feather glyph no longer has the `wr-icon__svg` class. Style `.wr-icon svg`.
- A `var(--wr-keyboard-inset, 0px)` compiles and stays `0px`.

## v14 to v15: validation messages

ngwr ships no error text: `provideWrFormErrors()`, `WR_FORM_ERRORS`, `WR_FORM_ERROR_FALLBACKS` and the catalogs' `validation` keys are gone.

```diff
# On one rule
+ required(path.email, { message: 'Please fill this in.' });

# Or for every field, date picker included, in your own catalog
+ provideWrI18nStaticLoader({
+   en: {
+     validation: {
+       required: 'Please fill this in.',
+       minlength: 'Minimum length is {{requiredLength}}.',
+       dateFormat: 'Expected format: {{example}}',
+       minDate: 'Choose a later date.',
+       maxDate: 'Choose an earlier date.',
+       dateFilter: 'This date is not available.',
+     },
+   },
+ }),
```

- Without your text a field shows no message; only dev mode warns. `<wr-form-error key>` still works.
- The codemod lists `provideWrFormErrors()`. While no catalog has a `validation` namespace, it also lists every `<wr-form-field>` without a `<wr-form-error>`. While none has `validation.dateFormat`, it lists every date picker.

## v14 to v15: dates

The native adapter needs no provider and follows `LOCALE_ID`.

| Before | After | Codemod |
| --- | --- | --- |
| `ngwr/date/adapters/fns`, `ngwr/date/adapters/luxon` | The native adapter, or your own `WrDateAdapter<Date>` passed as `withDates({ adapter })` | Lists files |
| `date-fns`, `luxon` as optional peers | No longer peers. Keep them only if your own code uses them. | No |
| Your own `WrDateAdapter<Date>` subclass, undecorated | Add `@Service()`, or dev mode warns | Lists files |
| Your own adapter handles six named formats | Ten more `WrDateFormat` keys: the `12h`, `24h` and `Seconds` variants of `time` and `shortDateTime`, e.g. `time24hSeconds`. The date picker asks for them from `timeFormat` and `showSeconds`. | No |
| `ng add ngwr --dateAdapter=…` | `ng add ngwr` | No |
| `wrDate` with no provider, `shortDate`: `3/15/26` | `3/15/2026` | No |
| `wrDate` with no provider, `time`: `2:30 PM` | `02:30 PM` | No |
| `wrDate` with no provider, `'dd.MM.yyyy'`: falls back to `shortDate` | Honoured | No |

- Native format tokens are `yyyy yy MMMM MMM MM M dd d HH H hh h mm ss a`. Others, such as date-fns' `EEEE` or `PPP`, print as letters.
- Your own adapter: see [Configuration](https://ngwr.dev/docs/configuration).

## v14 to v15: behaviour

Nothing here fails to compile, and `migration-v15` neither rewrites nor lists these.

| Before | After | Codemod |
| --- | --- | --- |
| `aria-sort` on every sorted `wr-table` column | Only on the primary sort column. The others say `none` and show their rank as a number. Tests read `getSortIndicator()` and `getSortOrder()` from `ngwr/table/testing`. | No |
| Table row and group controls named by `aria-label` | `aria-labelledby`: an action word plus the row's first cell (the tree column in a tree) or the group's label, e.g. "Select row Ada". `selectRowLabel`, `expandRowLabel`, `toggleRowLabel`, `selectGroupLabel` and `toggleGroupLabel` set only the action word. | No |
| Tab moves from option to option in the `<wr-cascader>` panel | The arrows or a typed letter move, as in a tree, and Tab leaves the panel. `getTabIndex()` from `ngwr/cascader/testing` is `0` for one option only. | No |
| `WrWindowManager.open()` leaves focus where it was | Moves focus into the window and gives it back on close. Pass `autoFocus: false` for a window that opens in the background. | No |
| A drawer with `hasBackdrop` off is modal | Non-modal: no focus trap, no `aria-modal`, and the page keeps scrolling. | No |
| Chart numbers: English `5k`, the `lineChart.thousands` catalog key | `Intl` in `LOCALE_ID`. Line-chart ticks and bar-chart labels are compact from a thousand up (`5K`, a bar of `12500` reads `13K`) unless the full numbers are shorter; tooltips never are. Drop the key from your catalogs. For another format, pass `valueFormat`, which every chart takes. | No |
| `fill` on `.wr-line-chart__tick`, an SVG `<text>` | HTML beside the plot. Restyle it with `color` or the `--wr-line-chart-tick-*` hooks. | No |
| A `static` flex or grid parent of a `wrAffix` | `position: relative` while an affix is in it, through `.wr-affix__container`. Its absolute children anchor to it and its `z-index` applies. A position you give it wins. | No |

- A test that found a table control by its old shared name, or tabbed through a cascader, needs the change.
- A drawer that has to stay modal keeps its backdrop. If the dimming was what you turned off, hide it: `.wr-drawer-backdrop { background: none; backdrop-filter: none; }`.

## v14 to v15: looks different

No API change and nothing to search for. Check the pages.

- The gray scale moved from Tailwind's slate to its gray, so neutral surfaces, text and borders are less blue: `--wr-color-gray-500` from `#64748b` to `#6b7280`, `--wr-color-gray-900` from `#0f172a` to `#111827`.
- Paddings, gaps and margins snapped to the `--wr-space-*` scale, so many components moved by a pixel or two. `wr-alert`'s padding went from `0.625rem 0.875rem` to `0.75rem 1rem`.
- `<wr-btn outlined>` with no `color` is transparent with a hover tint. It used to look like a plain button.

## v13 to v14

`ng update` rewrites:

| Before | After |
| --- | --- |
| `<wr-alert closeable>` | `closable` |
| `<wr-table [totalItems]>` | `[total]` |
| `<wr-pagination [(currentPage)]>`, `(currentPageChange)` | `[(page)]`, `(pageChange)` |
| `WrPaginationHarness.with({ currentPage })` | `{ page }` |
| `[isDisabledWhenLoading]` | `[disabledWhenLoading]` |
| `chromeSize: 'compact' \| 'normal'`, `.wr-window--chrome-compact` | `'sm' \| 'md'`, `.wr-window--chrome-sm` |
| `[wrInput] wrSize` | `size` |

By hand (`ng update` lists the files for most):

| Before | After |
| --- | --- |
| `WrWindowHarness.getChromeSize()`: `'compact'` | `'sm'` |
| `<wr-loading-bar>` follows the router on its own | Add `provideWrLoadingBarRouter()` from `ngwr/loading-bar/router` |
| `<wr-tab routerLink>` | Add `wrTabsRouting` on `<wr-tabs>` and `WrTabsRouting` from `ngwr/tabs/router` |
| `pagination.of` key | `pagination.range`, `pagination.compact` |
| `<wr-pagination ofLabel>` | Delete |
| `WR_DATE_LOCALE`, `WrI18n` locales follow the browser | Follow `LOCALE_ID`. `DEFAULT_WR_I18N_CONFIG` drops `defaultLocale`, `availableLocales`. |
| Named date formats parse through `new Date()` | Parse through `Intl` and refuse what they cannot read. For the old leniency, pass a token `[format]`. |

```diff
providers: [
  provideRouter(routes),
+   provideWrLoadingBarRouter(),
]

- <wr-tabs>
+ <wr-tabs wrTabsRouting>

- pagination: { of: 'von' }
+ pagination: {
+   range: '{{from}}–{{to}} von {{total}}',
+   compact: '{{current}} / {{total}}',
+ }
```

- Without `provideWrLoadingBarRouter()` the bar stays at 0% on navigation, with no error.
- A catalog that still defines `pagination.of` shows that line in English.
- Date output changed too: `MMMM` declines beside a day, `a` prints the locale's marker, and the calendar is always Gregorian.

## v12 to v13

`[id]` on `<wr-checkbox>`, `<wr-radio>` and `<wr-switch>` lands on the inner `<input>`, not the host.

```diff
- wr-checkbox#agree { margin: 0; }
+ #agree { margin: 0; }                  /* the input */
+ wr-checkbox:has(#agree) { margin: 0; }  /* the whole row */
```

`<wr-checkbox-group>` and `<wr-radio-group>` keep their host `id`.

## v11 to v12

| Before | After | Codemod |
| --- | --- | --- |
| `ngwr/date-adapter` | `ngwr/date` | Rewrites |
| `ngwr/date-adapter-fns` | `ngwr/date/adapters/fns` (removed in v15) | Rewrites |
| `ngwr/date-adapter-luxon` | `ngwr/date/adapters/luxon` (removed in v15) | Rewrites |
| `readI18nText()` returns `string` | `Signal<string>`: read it as `label()` | No, the compiler finds each |

## v8 to v9

| Before | After | Codemod |
| --- | --- | --- |
| `<wr-checkbox value>` in a group | `checkboxValue` | Rewrites |
| Checkbox state | The `checked` model: `[(checked)]` or `[formField]` | No |
| `lucideIcons({ chevronDown })` registers `chevron-down` | Registers `chevronDown` | No |
| `WrColor` | Adds `info`. An exhaustive `switch` needs the case. | No |

- A static `value` left on `<wr-checkbox>` makes the whole group toggle together.
- A camelCase Lucide key stops rendering with no error. Quote the key: `'chevron-down': ChevronDown`.

## v7 to v8

| Before | After | Codemod |
| --- | --- | --- |
| Density `compact`, `default`, `comfortable` | `sm`, `md` (the default), `lg`; `touch` unchanged | Rewrites |
| `WrPaginationSize` `xs`, `xl` | `sm`, `lg` | Rewrites |
| `wrReveal` | Removed, no replacement | Lists files |
| `<wr-scramble-text>` | `<wr-decrypt-text>` | Lists files |

## v6 to v7

`ng update` rewrites the tags, imports and `@use` paths.

| Before | After |
| --- | --- |
| `wr-autocomplete`, `wr-chips-input` | `wr-select` with `mode` |
| `wr-time-picker`, `wr-date-time-picker` | `wr-date-picker` |
| `wr-tooltip` | `wr-popover` |
| `wr-tree-select` | `wr-tree` |
| `wr-bottom-sheet` | `wr-drawer` |
| `wr-image` | `wr-lightbox` |
| `ngwr/tag` | `ngwr/badge` |
| `wr-animated-text` | `wr-typewriter`, `wr-decrypt-text` or `wr-split-text`, per mode |

## See also

- [Configuration](https://ngwr.dev/docs/configuration) — Set app-wide options at bootstrap.
- [Theming](https://ngwr.dev/guides/theming) — Load the theme, switch light and dark, and rebrand the palette.
- [Colors](https://ngwr.dev/guides/tokens/colors) — The --wr-color-* tokens, and which one to use for fills, text and borders.
- [Installation](https://ngwr.dev/docs/installation) — Add ngwr to an Angular app.
