@nxgt/material 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +447 -51
- package/dist/components.js +3 -2
- package/dist/{dist-BVcMAlfA.js → dist-CwhEp6Y-.js} +4 -4
- package/dist/dnd.js +2 -2
- package/dist/{hooks-BPv0i6YN.js → hooks-CHmfdtMs.js} +81 -47
- package/dist/hooks.js +3 -3
- package/dist/{i18n-1Eg35q8-.js → i18n-D4R3sSqT.js} +102 -0
- package/dist/i18n.js +1 -1
- package/dist/lib/components/index.d.ts +15 -0
- package/dist/lib/components/ui/anchor-heading.d.ts +9 -0
- package/dist/lib/components/ui/anchor-heading.stories.d.ts +13 -0
- package/dist/lib/components/ui/anchor-heading.utils.d.ts +2 -0
- package/dist/lib/components/ui/api-endpoint.d.ts +9 -0
- package/dist/lib/components/ui/api-endpoint.stories.d.ts +14 -0
- package/dist/lib/components/ui/api-operation.d.ts +13 -0
- package/dist/lib/components/ui/api-operation.stories.d.ts +13 -0
- package/dist/lib/components/ui/cards/cards.stories.d.ts +20 -0
- package/dist/lib/components/ui/cards/cards.stories.data.d.ts +8 -0
- package/dist/lib/components/ui/cards/index.d.ts +9 -0
- package/dist/lib/components/ui/cards/partials/crew-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/feature-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/media-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/overlay-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/pricing-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/profile-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/quote-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/partials/spotlight-card.d.ts +2 -0
- package/dist/lib/components/ui/cards/types.d.ts +56 -0
- package/dist/lib/components/ui/code/code-group.d.ts +13 -0
- package/dist/lib/components/ui/code/code-group.stories.d.ts +14 -0
- package/dist/lib/components/ui/code/index.d.ts +2 -0
- package/dist/lib/components/ui/copy-button/copy-button.d.ts +5 -3
- package/dist/lib/components/ui/doc/doc-api.stories.d.ts +13 -0
- package/dist/lib/components/ui/doc/doc-blocks.stories.d.ts +13 -0
- package/dist/lib/components/ui/doc/doc-context.d.ts +61 -0
- package/dist/lib/components/ui/doc/doc.d.ts +11 -0
- package/dist/lib/components/ui/doc/doc.keyboard.d.ts +20 -0
- package/dist/lib/components/ui/doc/doc.keyboard.test.d.ts +1 -0
- package/dist/lib/components/ui/doc/doc.slice.d.ts +97 -0
- package/dist/lib/components/ui/doc/doc.stories.d.ts +15 -0
- package/dist/lib/components/ui/doc/doc.stories.data.d.ts +7 -0
- package/dist/lib/components/ui/doc/doc.utils.d.ts +29 -0
- package/dist/lib/components/ui/doc/doc.utils.test.d.ts +1 -0
- package/dist/lib/components/ui/doc/index.d.ts +36 -0
- package/dist/lib/components/ui/doc/partials/doc-article.d.ts +6 -0
- package/dist/lib/components/ui/doc/partials/doc-child-cards.d.ts +4 -0
- package/dist/lib/components/ui/doc/partials/doc-copy-actions.d.ts +7 -0
- package/dist/lib/components/ui/doc/partials/doc-empty.d.ts +3 -0
- package/dist/lib/components/ui/doc/partials/doc-header.d.ts +18 -0
- package/dist/lib/components/ui/doc/partials/doc-link.d.ts +3 -0
- package/dist/lib/components/ui/doc/partials/doc-nav.d.ts +4 -0
- package/dist/lib/components/ui/doc/partials/doc-page.d.ts +6 -0
- package/dist/lib/components/ui/doc/partials/doc-pager.d.ts +4 -0
- package/dist/lib/components/ui/doc/partials/doc-progress.d.ts +3 -0
- package/dist/lib/components/ui/doc/partials/doc-search.d.ts +1 -0
- package/dist/lib/components/ui/doc/partials/doc-see-also.d.ts +4 -0
- package/dist/lib/components/ui/doc/partials/doc-sidebar.d.ts +4 -0
- package/dist/lib/components/ui/doc/partials/doc-skip-link.d.ts +2 -0
- package/dist/lib/components/ui/doc/partials/doc-toc.d.ts +6 -0
- package/dist/lib/components/ui/doc/partials/doc-topbar.d.ts +4 -0
- package/dist/lib/components/ui/doc/types.d.ts +46 -0
- package/dist/lib/components/ui/doc/use-doc.d.ts +43 -0
- package/dist/lib/components/ui/feedback/empty-state.stories.d.ts +1 -0
- package/dist/lib/components/ui/feedback/index.d.ts +1 -0
- package/dist/lib/components/ui/feedback/scroll-progress.d.ts +6 -0
- package/dist/lib/components/ui/feedback/scroll-progress.stories.d.ts +13 -0
- package/dist/lib/components/ui/figure.d.ts +7 -0
- package/dist/lib/components/ui/figure.stories.d.ts +13 -0
- package/dist/lib/components/ui/forms/index.d.ts +1 -0
- package/dist/lib/components/ui/hero.d.ts +10 -0
- package/dist/lib/components/ui/hero.stories.d.ts +13 -0
- package/dist/lib/components/ui/highlight-text.d.ts +6 -0
- package/dist/lib/components/ui/highlight-text.stories.d.ts +12 -0
- package/dist/lib/components/ui/list-tile.d.ts +2 -1
- package/dist/lib/components/ui/list-tile.stories.d.ts +1 -0
- package/dist/lib/components/ui/metrics/index.d.ts +6 -0
- package/dist/lib/components/ui/metrics/metrics.stories.d.ts +16 -0
- package/dist/lib/components/ui/metrics/metrics.stories.data.d.ts +5 -0
- package/dist/lib/components/ui/metrics/partials/breakdown-card.d.ts +2 -0
- package/dist/lib/components/ui/metrics/partials/goal-card.d.ts +2 -0
- package/dist/lib/components/ui/metrics/partials/rank-card.d.ts +2 -0
- package/dist/lib/components/ui/metrics/partials/sparkline.d.ts +5 -0
- package/dist/lib/components/ui/metrics/partials/trend-card.d.ts +2 -0
- package/dist/lib/components/ui/metrics/types.d.ts +35 -0
- package/dist/lib/components/ui/pager.d.ts +20 -0
- package/dist/lib/components/ui/pager.stories.d.ts +13 -0
- package/dist/lib/components/ui/param-table.d.ts +13 -0
- package/dist/lib/components/ui/param-table.stories.d.ts +13 -0
- package/dist/lib/components/ui/see-also.d.ts +17 -0
- package/dist/lib/components/ui/see-also.stories.d.ts +12 -0
- package/dist/lib/components/ui/skip-link.d.ts +3 -0
- package/dist/lib/components/ui/skip-link.stories.d.ts +12 -0
- package/dist/lib/components/ui/steps.d.ts +13 -0
- package/dist/lib/components/ui/steps.stories.d.ts +13 -0
- package/dist/lib/components/ui/tabs.d.ts +4 -1
- package/dist/lib/components/ui/tabs.stories.d.ts +1 -0
- package/dist/lib/components/ui/toc.d.ts +21 -0
- package/dist/lib/components/ui/toc.stories.d.ts +13 -0
- package/dist/lib/hooks/index.d.ts +1 -0
- package/dist/lib/hooks/use-heading-spy.d.ts +6 -0
- package/dist/lib/i18n/resources/en/index.d.ts +57 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +57 -0
- package/dist/lib/i18n/resources/fr/index.d.ts +57 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +57 -0
- package/dist/lib/i18n/resources/index.d.ts +114 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib/lib/string.utils.d.ts +9 -0
- package/dist/lib/lib/url.utils.d.ts +2 -0
- package/dist/{lib-CaKARQ-7.js → lib-Rq5clPUe.js} +620 -584
- package/dist/lib.js +3 -3
- package/dist/{main-B-cRR76_.js → main-D7WtUVbv.js} +35341 -33380
- package/dist/main.js +6 -6
- package/dist/material.css +1 -1
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Steve Tsala
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -3,14 +3,48 @@
|
|
|
3
3
|
React component library: primitives, form fields, layout shell, `DataTable`,
|
|
4
4
|
drag-and-drop, i18n, and `Icon`. Tailwind CSS v4 + Base UI.
|
|
5
5
|
|
|
6
|
+
## At a glance
|
|
7
|
+
|
|
8
|
+
- **155 catalogue entries in 12 categories** ([Components](#components)).
|
|
9
|
+
They cover primitives and overlays as well as data tables, filters, kanban,
|
|
10
|
+
calendars, charts, chat, documentation pages, rich-text and code editors,
|
|
11
|
+
PDF and media players.
|
|
12
|
+
- **Form fields ship in pairs.** Each one has a standalone component
|
|
13
|
+
(`TextField`) and a React Hook Form wrapper (`TextFormField`). Both are in
|
|
14
|
+
the same barrel.
|
|
15
|
+
- **Helpers** ([Helpers](#helpers)): `cn`, `clientOnly`, date, number,
|
|
16
|
+
storage and URL utilities, a Zod error map, and Redux Toolkit slice
|
|
17
|
+
factories in `/lib`. Theme, i18n-aware formatting and option hooks are in
|
|
18
|
+
`/hooks`.
|
|
19
|
+
- **i18n** ([i18n](#i18n)): an `I18nProvider` with ICU messages and shipped
|
|
20
|
+
`en` / `fr` strings. Your app merges in its own resources.
|
|
21
|
+
- **SSR-safe barrels** ([SSR](#ssr)): no browser globals at import, and
|
|
22
|
+
browser-only widgets are wrapped in `clientOnly`.
|
|
23
|
+
- **Vue sister**: `@nxgt/material-vue` uses the same names. The catalogue's
|
|
24
|
+
last column gives the Vue export for each entry.
|
|
25
|
+
|
|
26
|
+
## Contents
|
|
27
|
+
|
|
28
|
+
- [Install](#install)
|
|
29
|
+
- [Setup](#setup)
|
|
30
|
+
- [Subpaths](#subpaths)
|
|
31
|
+
- [Usage](#usage)
|
|
32
|
+
- [Components](#components)
|
|
33
|
+
- [Helpers](#helpers)
|
|
34
|
+
- [SSR](#ssr)
|
|
35
|
+
- [Traps](#traps)
|
|
36
|
+
- [Development](#development)
|
|
37
|
+
- [License](#license)
|
|
38
|
+
|
|
6
39
|
## Install
|
|
7
40
|
|
|
8
41
|
```bash
|
|
9
42
|
bun add @nxgt/material
|
|
10
43
|
```
|
|
11
44
|
|
|
12
|
-
|
|
13
|
-
copy,
|
|
45
|
+
It is public on npmjs, so no token is needed. **Required peers**: the app must
|
|
46
|
+
resolve the same copy of each, otherwise hooks throw and tokens come from two
|
|
47
|
+
builds.
|
|
14
48
|
|
|
15
49
|
```bash
|
|
16
50
|
bun add react react-dom react-hook-form react-redux @reduxjs/toolkit @tanstack/react-table react-use
|
|
@@ -19,10 +53,10 @@ bun add react react-dom react-hook-form react-redux @reduxjs/toolkit @tanstack/r
|
|
|
19
53
|
| Peer | Used by |
|
|
20
54
|
| --- | --- |
|
|
21
55
|
| `react`, `react-dom` `^19` | everything |
|
|
22
|
-
| `react-hook-form` | every `*FormField` |
|
|
23
|
-
| `react-redux`, `@reduxjs/toolkit` | `DataTable`, filter, gallery, kanban, player |
|
|
56
|
+
| `react-hook-form` `^7` | every `*FormField` |
|
|
57
|
+
| `react-redux` `^9`, `@reduxjs/toolkit` `^2` | `DataTable`, filter, gallery, kanban, player, slice helpers |
|
|
24
58
|
| `@tanstack/react-table` `^9` | `DataTable` |
|
|
25
|
-
| `react-use` |
|
|
59
|
+
| `react-use` `^17` | `useTheme`, `useIsMobile`, `ScrollProgress` (`useScroll` / `useWindowScroll`), `CopyButton` (`useCopyToClipboard`), other hooks |
|
|
26
60
|
|
|
27
61
|
The tarball is `dist/`, not `lib/`. There is no `postinstall` build.
|
|
28
62
|
|
|
@@ -39,17 +73,18 @@ In the app's root stylesheet, in this order:
|
|
|
39
73
|
```
|
|
40
74
|
|
|
41
75
|
`styles.css` is the **source** `@theme` layer (colours, `--radius`, `dark`,
|
|
42
|
-
fonts) so it runs through *your* Tailwind build. `@source` is
|
|
43
|
-
|
|
44
|
-
every utility used *inside* a component is
|
|
76
|
+
fonts), so it runs through *your* Tailwind build. The `@source` line is
|
|
77
|
+
required, and nothing warns you when it is missing. Tailwind v4 does not scan
|
|
78
|
+
`node_modules`, so without it every utility used *inside* a component is
|
|
79
|
+
missing and the UI renders unstyled.
|
|
45
80
|
|
|
46
|
-
Import it **explicitly**, nothing injects it
|
|
47
|
-
from a single CSS graph, and Tailwind CSS IntelliSense reads the
|
|
48
|
-
this entry file to autocomplete them in your components.
|
|
81
|
+
Import it **explicitly**, because nothing injects it. Tailwind v4 builds one
|
|
82
|
+
`@theme` from a single CSS graph, and Tailwind CSS IntelliSense reads the
|
|
83
|
+
tokens from this entry file to autocomplete them in your components.
|
|
49
84
|
|
|
50
85
|
In a Tailwind app, do not also import the compiled `style` condition on
|
|
51
|
-
`@nxgt/material` (`dist/material.css`). Take the tokens
|
|
52
|
-
the utilities. The compiled file is for apps without Tailwind.
|
|
86
|
+
`@nxgt/material` (`dist/material.css`). Take the tokens and let the app
|
|
87
|
+
generate the utilities. The compiled file is for apps without Tailwind.
|
|
53
88
|
|
|
54
89
|
### Icons
|
|
55
90
|
|
|
@@ -62,25 +97,26 @@ import { Icon } from '@nxgt/material/components';
|
|
|
62
97
|
// → /assets/icons/sprites/duotone.svg#atom
|
|
63
98
|
```
|
|
64
99
|
|
|
65
|
-
Serve Font Awesome Pro sheets from
|
|
66
|
-
This package does **not** ship them:
|
|
67
|
-
own products, not redistribution inside
|
|
68
|
-
`"!dist/assets"` so a local build cannot leak them
|
|
69
|
-
sheet renders
|
|
100
|
+
Serve the Font Awesome Pro sprite sheets from
|
|
101
|
+
`public/assets/icons/sprites/<style>.svg`. This package does **not** ship them:
|
|
102
|
+
the FA Pro licence covers use in your own products, not redistribution inside
|
|
103
|
+
a library. `files` includes `"!dist/assets"` so a local build cannot leak them
|
|
104
|
+
into a tarball. A missing sheet renders nothing, with no error and no fallback.
|
|
70
105
|
|
|
71
106
|
## Subpaths
|
|
72
107
|
|
|
73
108
|
| Specifier | What is in it |
|
|
74
109
|
| --- | --- |
|
|
75
|
-
| `@nxgt/material` |
|
|
76
|
-
| `@nxgt/material/components` | UI components and `*FormField` wrappers |
|
|
77
|
-
| `@nxgt/material/hooks` | `useTheme`, `useIsClient`, `
|
|
78
|
-
| `@nxgt/material/dnd` | `@dnd-kit` primitives |
|
|
79
|
-
| `@nxgt/material/i18n` | `I18nProvider`, `mergeResources`, `createTranslator` |
|
|
80
|
-
| `@nxgt/material/lib` | `cn`, `clientOnly`, date
|
|
81
|
-
| `@nxgt/material/models` |
|
|
82
|
-
| `@nxgt/material/types` | shared function types |
|
|
83
|
-
| `@nxgt/material/styles.css` | source Tailwind v4 tokens
|
|
110
|
+
| `@nxgt/material` | Everything below in one barrel, plus the compiled `style` condition (`dist/material.css`, for apps without Tailwind) |
|
|
111
|
+
| `@nxgt/material/components` | UI components and `*FormField` wrappers ([Components](#components)) |
|
|
112
|
+
| `@nxgt/material/hooks` | `useTheme`, `useIsClient`, `useIsMobile`, `useLocalizedDate`, … ([hooks](#nxgtmaterialhooks)) |
|
|
113
|
+
| `@nxgt/material/dnd` | `@dnd-kit` primitives ([dnd](#nxgtmaterialdnd)) |
|
|
114
|
+
| `@nxgt/material/i18n` | `I18nProvider`, `mergeResources`, `createTranslator` ([i18n](#nxgtmateriali18n)) |
|
|
115
|
+
| `@nxgt/material/lib` | `cn`, `clientOnly`, date, number and storage utilities, `useSliceReducer` ([lib](#nxgtmateriallib)) |
|
|
116
|
+
| `@nxgt/material/models` | `Status<T>` |
|
|
117
|
+
| `@nxgt/material/types` | shared function types (`PromiseOr`, `FunctionOr`, …) |
|
|
118
|
+
| `@nxgt/material/styles.css` | source Tailwind v4 tokens. **This** is the file the app imports |
|
|
119
|
+
|
|
84
120
|
## Usage
|
|
85
121
|
|
|
86
122
|
### Components
|
|
@@ -96,8 +132,9 @@ import { Button, Icon } from '@nxgt/material/components';
|
|
|
96
132
|
|
|
97
133
|
### Form fields
|
|
98
134
|
|
|
99
|
-
|
|
100
|
-
(`TextFormField`) in the same barrel.
|
|
135
|
+
Each field has a standalone component (`TextField`) and a React Hook Form
|
|
136
|
+
wrapper (`TextFormField`) in the same barrel. The wrappers take `control` and
|
|
137
|
+
`name`.
|
|
101
138
|
|
|
102
139
|
```tsx
|
|
103
140
|
import { TextFormField, Button } from '@nxgt/material/components';
|
|
@@ -113,9 +150,11 @@ const form = useForm({ defaultValues: { email: '' } });
|
|
|
113
150
|
|
|
114
151
|
### i18n
|
|
115
152
|
|
|
116
|
-
This package owns the **mechanism
|
|
117
|
-
|
|
118
|
-
|
|
153
|
+
This package owns the i18n **mechanism**, and the app owns the resource
|
|
154
|
+
**content**. This package's strings live under the `material` namespace.
|
|
155
|
+
`mergeResources` deep-merges your bundle over it per language, so you can
|
|
156
|
+
override one string (`material.command.title`) without losing the rest. Every
|
|
157
|
+
overridden key is reported with `console.warn` outside production.
|
|
119
158
|
|
|
120
159
|
```ts
|
|
121
160
|
import {
|
|
@@ -140,16 +179,20 @@ export const useTranslation = createTypedTranslation<LocaleKey>(translate);
|
|
|
140
179
|
</I18nProvider>
|
|
141
180
|
```
|
|
142
181
|
|
|
143
|
-
Language state lives only in `I18nProvider`.
|
|
144
|
-
|
|
145
|
-
MessageFormat
|
|
182
|
+
Language state lives only in `I18nProvider`. If the provider is not mounted,
|
|
183
|
+
the components in this package fall back to their English copy. Messages use
|
|
184
|
+
ICU MessageFormat, and a missing key is returned as-is.
|
|
185
|
+
|
|
186
|
+
To translate Zod messages as well, add
|
|
187
|
+
`z.config({ customError: zodLocaleError() })`, with `zodLocaleError` from
|
|
188
|
+
`@nxgt/material/lib`.
|
|
146
189
|
|
|
147
190
|
### App shell
|
|
148
191
|
|
|
149
|
-
`items` is a prop
|
|
150
|
-
already translated (`ReactNode`), not a key. `footer: true`
|
|
151
|
-
|
|
152
|
-
holds no session.
|
|
192
|
+
`items` is a prop: the shell does not build or filter the menu. Each `label`
|
|
193
|
+
is already translated (a `ReactNode`), not a key. Set `footer: true` to pin an
|
|
194
|
+
entry to the footer; being last in the list does not do it. `avatar` and
|
|
195
|
+
`headerActions` are props too, because the shell holds no session.
|
|
153
196
|
|
|
154
197
|
```tsx
|
|
155
198
|
import { ActivityLayout, ActivityContent } from '@nxgt/material/components';
|
|
@@ -164,24 +207,372 @@ const items = [
|
|
|
164
207
|
</ActivityLayout>
|
|
165
208
|
```
|
|
166
209
|
|
|
167
|
-
The active entry is the **longest** match across the whole menu
|
|
168
|
-
|
|
169
|
-
`handle.breadcrumb`
|
|
210
|
+
The active entry is the **longest** match across the whole menu. Matching is
|
|
211
|
+
segment-aware, so `/admin` does not cover `/administrators`. `AppBreadcrumb`
|
|
212
|
+
reads `handle.breadcrumb` from `useMatches()`, so it needs a data router
|
|
170
213
|
(`createMemoryRouter` + `RouterProvider`, not `MemoryRouter`).
|
|
171
214
|
|
|
215
|
+
## Components
|
|
216
|
+
|
|
217
|
+
Everything below is imported from `@nxgt/material/components`. In the
|
|
218
|
+
*Component* column, `·` separates a field from its React Hook Form wrapper.
|
|
219
|
+
The last column gives the matching export in `@nxgt/material-vue`, or `—` when
|
|
220
|
+
Vue has none. "(same parts)" means Vue exports the same sub-components.
|
|
221
|
+
|
|
222
|
+
### Primitives
|
|
223
|
+
|
|
224
|
+
| Component | What it does | @nxgt/material-vue |
|
|
225
|
+
| --- | --- | --- |
|
|
226
|
+
| `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` | Collapsible sections with a rotating chevron and animated content. | `Accordion` (same parts) |
|
|
227
|
+
| `Collapsible`, `CollapsibleTrigger`, `CollapsibleContent` | A single show / hide region and its trigger. | `Collapsible` (same parts) |
|
|
228
|
+
| `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter` | Card surface with header, action slot, content and footer. | `Card` (same parts) |
|
|
229
|
+
| `Typography` | Text in the Material type scale (headline, title, body, caption…). | `Typography` |
|
|
230
|
+
| `AnchorHeading` | Heading with a hover copy-link (always visible on the phone). | `AnchorHeading` |
|
|
231
|
+
| `Label` | Form label with an optional required asterisk. | `Label` |
|
|
232
|
+
| `HelperText` | Hint or error message under a field. | `HelperText` |
|
|
233
|
+
| `ExtendedLabel` | Section title with an animated accent underline and a trailing slot. | `ExtendedLabel` |
|
|
234
|
+
| `Input` | Styled native `<input>`. | `Input` |
|
|
235
|
+
| `Textarea` | Styled native `<textarea>`. | `Textarea` |
|
|
236
|
+
| `InputGroup`, `InputGroupAddon`, `InputGroupInput`, `InputGroupButton`, `InputGroupText`, `InputGroupTextarea` | Input with inline or block addons, buttons and text. | `InputGroup` (same parts) |
|
|
237
|
+
| `Icon` | Font Awesome sprite icon by name and style (duotone by default), labelled with `role="img"`. | `Icon` |
|
|
238
|
+
| `Kbd`, `KbdShortcut` | One keyboard key, or a key combination with platform glyphs. | `Kbd`, `KbdShortcut` |
|
|
239
|
+
| `Separator` | Horizontal or vertical divider. | `Separator` |
|
|
240
|
+
| `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption` | Styled semantic table inside a scrollable wrapper. | `Table` (same parts), `TableEmpty` |
|
|
241
|
+
| `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | Tabs whose triggers can take an icon. `variant="line"` is the quieter pill style. | `Tabs` (same parts) |
|
|
242
|
+
| `Toggle` | Pressable on / off button: default or outlined, three sizes. | `Toggle` |
|
|
243
|
+
| `ToggleGroup`, `ToggleGroupItem`, `ToggleGroupSeparator` | Single or multiple toggle group sharing variant and size. | `ToggleGroup`, `ToggleGroupItem` |
|
|
244
|
+
| `Activity` | React `<Activity>` switched by a boolean `visible`. | `Activity` |
|
|
245
|
+
|
|
246
|
+
### Buttons & actions
|
|
247
|
+
|
|
248
|
+
| Component | What it does | @nxgt/material-vue |
|
|
249
|
+
| --- | --- | --- |
|
|
250
|
+
| `Button` | Filled, tonal, outlined, ghost or link button in seven colours, with a loading state. | `Button` |
|
|
251
|
+
| `IconButton` | Icon-only button with an optional tooltip. | `IconButton` |
|
|
252
|
+
| `ButtonGroup` | Joins adjacent buttons into one control. | `ButtonGroup` |
|
|
253
|
+
| `SplitButton` | Main action plus a dropdown menu of secondary actions. | `SplitButton` |
|
|
254
|
+
| `ResponsiveButton` | Shows its label on desktop and collapses to icon-only on mobile. | `ResponsiveButton` |
|
|
255
|
+
| `LinkButton`, `IconLinkButton`, `ResponsiveLinkButton` | The button styles rendered as `react-router` links. | `LinkButton`, `IconLinkButton`, `ResponsiveLinkButton` |
|
|
256
|
+
| `CopyButton`, `CopyValue` | Copies a value to the clipboard and briefly shows a check mark. `CopyValue` displays the value next to the button. | `CopyButton` |
|
|
257
|
+
| `HighlightText` | Marks case-insensitive matches of a query inside a string (`splitMatch`). | `HighlightText` |
|
|
258
|
+
| `LoadMoreButton` | "Load more" button for cursor pagination; icon-only with a tooltip unless `expanded`. | `LoadMoreButton` |
|
|
259
|
+
| `ScrollToTop` | Floating button that appears past a scroll threshold. | `ScrollToTop` |
|
|
260
|
+
| `ActionCard` | Clickable card with icon, title, description and active indicator. | `ActionCard` |
|
|
261
|
+
| `ThemeToggle` | Light / dark / system switch that stores and applies the choice. | `ThemeToggle` |
|
|
262
|
+
| `LanguageSwitcher` | Globe button with a menu of the `I18nProvider` languages. | `LanguageSwitcher` |
|
|
263
|
+
|
|
264
|
+
### Form fields
|
|
265
|
+
|
|
266
|
+
| Component | What it does | @nxgt/material-vue |
|
|
267
|
+
| --- | --- | --- |
|
|
268
|
+
| `Field` · `FormField` | Renders the field matching a config `type` (text, select, date, upload, otp…). | `Field` |
|
|
269
|
+
| `TextField` · `TextFormField` | Labelled input with leading / trailing adornments and helper text. | `TextField`, `TextFormField` |
|
|
270
|
+
| `TextareaField` · `TextareaFormField` | Labelled textarea with row sizing and a `maxLength` counter. | `TextareaField`, `TextareaFormField` |
|
|
271
|
+
| `EmailField` · `EmailFormField` | Validates on blur; shows a `mailto:` button once the address is valid. | `EmailField`, `EmailFormField` |
|
|
272
|
+
| `PasswordField` · `PasswordFormField` | Show / hide toggle and an optional strength meter (`scorePassword`). | `PasswordField`, `PasswordFormField` |
|
|
273
|
+
| `NumberField` · `NumberFormField` | Emits `number \| null`, with min / max / step clamping, +/− buttons and a suffix. | `NumberField`, `NumberFormField` |
|
|
274
|
+
| `PercentField` · `PercentFormField` | `NumberField` with a `%` suffix. | `PercentField`, `PercentFormField` |
|
|
275
|
+
| `CurrencyField` · `CurrencyFormField` | Amount formatted to the locale on blur, with a currency suffix (EUR by default). | `CurrencyField`, `CurrencyFormField` |
|
|
276
|
+
| `PhoneField` · `PhoneFormField` | International number with a country picker; emits E.164. | `PhoneField`, `PhoneFormField` |
|
|
277
|
+
| `UrlField` · `UrlFormField` | Validates on blur; open-in-new-tab and copy buttons. | `UrlField`, `UrlFormField` |
|
|
278
|
+
| `SearchField` · `SearchFormField` | Search icon, clear button and spinner, with a debounced `onValueChange`. | `SearchField`, `SearchFormField` |
|
|
279
|
+
| `ColorField` · `ColorFormField` | Hex input with a colour picker in a popover. | `ColorField`, `ColorFormField` |
|
|
280
|
+
| `OtpField` · `OtpFormField` | One-time code input of configurable length. | `OtpField`, `OtpFormField`, `InputOTP` |
|
|
281
|
+
| `InputGroupField` · `InputGroupFormField` | Labelled `InputGroup` with addons and helper text. | `InputGroupField`, `InputGroupFormField` |
|
|
282
|
+
| `InlineEdit` · `InlineEditFormField` | Click-to-edit text with save and cancel. | `InlineEdit` |
|
|
283
|
+
| `CountryField` · `CountryFormField` | Single or multiple country picker with flags. | `CountryField`, `CountryFormField` |
|
|
284
|
+
| `TimezoneField` · `TimezoneFormField` | Searchable IANA timezone picker with localised labels. | `TimezoneField`, `TimezoneFormField` |
|
|
285
|
+
| `RatingField` · `RatingFormField` | Star rating with hover preview, click-to-clear and a read-only mode. | `RatingField`, `RatingFormField` |
|
|
286
|
+
| `Slider` · `SliderFormField` | Labelled single or range slider with an editable value and ticks. | `Slider`, `SliderField`, `SliderFormField` |
|
|
287
|
+
| `Switch` · `SwitchFormField` | Toggle switch, optionally in a labelled, bordered row. | `Switch`, `SwitchField`, `SwitchFormField` |
|
|
288
|
+
| `AttributesField`, `AttributesList`, `AttributeDialog`, `AttributeForm`, `AttributeValuesForm` · `AttributesFormField`, `AttributeValuesFormFieldSet`, `AttributeValueFormField` | Editor for typed custom attributes (string, number, date, select, rich text…). | `AttributesField`, `AttributesList`, `AttributeDialog`, `AttributeForm`, `AttributeValuesForm`, `AttributesFormField`, `AttributeValuesFormFieldSet`, `AttributeValueFormField` |
|
|
289
|
+
| `Contacts`, `ContactItem`, `ContactDialog` · `ContactsFormField` | Typed contact list (phone, email, URL…) with an add / edit dialog. | `Contacts`, `ContactItem`, `ContactDialog`, `ContactsFormField` |
|
|
290
|
+
| `PostalAddress`, `PostalAddressDialog` · `PostalAddressFormField` | Address card with an edit dialog. | `PostalAddress`, `PostalAddressDialog`, `PostalAddressFormField` |
|
|
291
|
+
| `OpeningHours`, `OpeningHoursDialog`, `OpeningHoursItem` · `OpeningHoursFormField` | Weekly opening hours with an add / edit dialog. | `OpeningHours`, `OpeningHoursDialog`, `OpeningHoursItem`, `OpeningHoursFormField` |
|
|
292
|
+
|
|
293
|
+
### Date & time
|
|
294
|
+
|
|
295
|
+
| Component | What it does | @nxgt/material-vue |
|
|
296
|
+
| --- | --- | --- |
|
|
297
|
+
| `Calendar`, `CalendarDayButton` | Day-picker calendar with a year view, a today shortcut and `disablePast` / `disableFuture`. | `Calendar` (Reka parts) |
|
|
298
|
+
| `DateField` · `DateFormField` | Labelled trigger that opens a calendar popover, with an optional time picker. | `DateField`, `DateFormField` |
|
|
299
|
+
| `DateRangeField` · `DateRangeFormField` | From / to range picked in a popover calendar. | `DateRangeField`, `DateRangeFormField` |
|
|
300
|
+
| `TimeField` · `TimeFormField` | Opens a `TimePicker` in a popover, or in a dialog on mobile. | `TimeField`, `TimeFormField` |
|
|
301
|
+
| `TimePicker` | Hour and minute inputs with AM / PM and auto-advancing focus. | `TimePicker` |
|
|
302
|
+
| `DurationField` · `DurationFormField` | Hours and minutes combined into a total in minutes. | `DurationField`, `DurationFormField` |
|
|
303
|
+
|
|
304
|
+
### Selection & choice
|
|
305
|
+
|
|
306
|
+
| Component | What it does | @nxgt/material-vue |
|
|
307
|
+
| --- | --- | --- |
|
|
308
|
+
| `Select`, `SelectTrigger`, `SelectValue`, `SelectContent`, `SelectItem`, `SelectGroup`, `SelectLabel`… | Select primitives with groups, labels and scroll buttons. | `Select` (same parts), `NativeSelect` |
|
|
309
|
+
| `SelectField` · `SelectFormField` | Labelled select built from `options`, with `renderOption`. | `SelectField`, `SelectFormField` |
|
|
310
|
+
| `Combobox`, `ComboboxInput`, `ComboboxContent`, `ComboboxList`, `ComboboxItem`, `ComboboxChips`… | Base UI combobox primitives: input, popup list, groups and chips. | — |
|
|
311
|
+
| `ComboboxField` · `ComboboxFormField` | Labelled, searchable single select over `{ value, label }` options. | `ComboboxField`, `ComboboxFormField` |
|
|
312
|
+
| `Autocomplete`, `AutocompleteChips` · `AutocompleteFormField` | Single or multiple (chips) autocomplete with free-solo values and a query callback. | `Autocomplete`, `AutocompleteFormField` |
|
|
313
|
+
| `Checkbox` · `CheckboxFormField` | Checkbox with label, helper text and an indeterminate state. | `Checkbox` |
|
|
314
|
+
| `CheckboxGroup` · `CheckboxGroupFormField` | Checkbox list built from `options`, valued as `string[]`. | `CheckboxGroup`, `CheckboxGroupFormField` |
|
|
315
|
+
| `RadioGroup`, `RadioGroupItem` · `RadioGroupFormField` | Labelled radio group built from `options`, horizontal or vertical. | `RadioGroupField`, `RadioGroup`, `RadioGroupFormField` |
|
|
316
|
+
| `CheckCardField` · `CheckCardFormField` | A yes / no choice shown as two selectable cards. | `CheckCardField`, `CheckCardFormField` |
|
|
317
|
+
| `SelectCardField` · `SelectCardFormField` | Single or multiple choice shown as `ActionCard`s. | `SelectCardField`, `SelectCardFormField` |
|
|
318
|
+
| `SelectChipField` · `SelectChipFormField` | Single or multiple choice shown as toggleable chips. | `SelectChipField`, `SelectChipFormField` |
|
|
319
|
+
| `TransferList` · `TransferListFormField` | Two-pane picker with search, drag-and-drop, reordering and a `max`. | `TransferList`, `TransferListFormField` |
|
|
320
|
+
| `SortableList` · `SortableListFormField` | Searchable list of strings you reorder by dragging or with the keyboard. | `SortableList`, `SortableListFormField` |
|
|
321
|
+
| `Switcher` | Dropdown for switching the active workspace or account, with an avatar. | `Switcher` |
|
|
322
|
+
|
|
323
|
+
### Data display
|
|
324
|
+
|
|
325
|
+
| Component | What it does | @nxgt/material-vue |
|
|
326
|
+
| --- | --- | --- |
|
|
327
|
+
| `Avatar`, `AvatarImage`, `AvatarFallback`, `AvatarBase` | Image with a fallback and an optional online / offline dot. | `Avatar`, `AvatarImage`, `AvatarFallback` |
|
|
328
|
+
| `AvatarGroup` | Overlapping avatars with a `+N` overflow. | `AvatarGroup` |
|
|
329
|
+
| `Badge` | Pill label: default, secondary, error, success, info, warning, outlined. | `Badge` |
|
|
330
|
+
| `CountBadge` | Count in the corner of its children, capped at `99+` and hidden at 0. | `CountBadge` |
|
|
331
|
+
| `Chip` | Pill with leading, avatar and trailing slots, an active state and a dismiss button. | `Chip` |
|
|
332
|
+
| `StatCard` | KPI tile with value, hint, icon, toned delta and a loading skeleton. | `StatCard` |
|
|
333
|
+
| `TrendCard`, `GoalCard`, `BreakdownCard`, `RankCard` | Dashboard tiles: trend + sparkline, goal vs target, share breakdown, ranked list. Container queries. | `TrendCard`, `GoalCard`, `BreakdownCard`, `RankCard` |
|
|
334
|
+
| `FeatureCard`, `MediaCard`, `PricingCard`, `ProfileCard`, `QuoteCard`, `OverlayCard`, `SpotlightCard`, `CrewCard` | Card presets: product, media, pricing, profile, quote, cinematic overlay, bento spotlight, crew with avatars. Container queries. | `FeatureCard`, `MediaCard`, `PricingCard`, `ProfileCard`, `QuoteCard`, `OverlayCard`, `SpotlightCard`, `CrewCard` |
|
|
335
|
+
| `StatusIndicator` | Coloured status dot with an optional pulse and label. | `StatusIndicator` |
|
|
336
|
+
| `SummaryData` | Label / value pairs as a grid or inline; hides empty values. | `SummaryData` |
|
|
337
|
+
| `Description` | Read-only label / value pair that renders nothing when empty. | `Description` |
|
|
338
|
+
| `EntityHeader` | Page header with icon, title, status, metadata and actions. | `EntityHeader` |
|
|
339
|
+
| `ListTile` | Row with leading / trailing slots, title and subtitle; becomes a link or button when interactive. `size="sm"` is the dense row. | `ListTile` |
|
|
340
|
+
| `AccordionCard` | Renders `items` (title, content) as a styled accordion. | `AccordionCard` |
|
|
341
|
+
| `Timeline`, `TimelineItem`, `RelativeTime` | Vertical event timeline with toned icons and relative times. | `Timeline`, `TimelineItem`, `RelativeTime` |
|
|
342
|
+
| `EventChip` | Calendar event pill with time, all-day and continuation edges. | `EventChip` |
|
|
343
|
+
| `CodeBlock`, `CodeDiff`, `JsonViewer`, `CodeGroup` | Highlighted code with line numbers and copy, a Monaco diff, a collapsible JSON tree, and tabbed samples (`Tabs variant="line"`). | `CodeBlock`, `CodeDiff`, `JsonViewer`, `CodeGroup` |
|
|
344
|
+
| `Figure` | Framed media with an optional caption. | `Figure` |
|
|
345
|
+
| `ApiEndpoint`, `ApiOperation` | HTTP method badge, path and copy; `ApiOperation` adds a param table and example `CodeGroup`. | `ApiEndpoint`, `ApiOperation` |
|
|
346
|
+
| `ParamTable` | Name / type / default / description table; stacked cards below `sm`. | `ParamTable` |
|
|
347
|
+
| `QRCode` | QR code on a padded tile, with an optional centred logo. | `QRCode` |
|
|
348
|
+
| `Barecode` | 1D barcode. | `Barecode` |
|
|
349
|
+
|
|
350
|
+
### Data table, filter & lists
|
|
351
|
+
|
|
352
|
+
| Component | What it does | @nxgt/material-vue |
|
|
353
|
+
| --- | --- | --- |
|
|
354
|
+
| `DataTable`, `DataTableColumnHeader`, `DataTablePagination`, `DataTableViewOptions` | TanStack Table v9 with sorting, filtering, selection, expandable rows, pagination or load-more, and column visibility. | `DataTable`, `DataTableColumnHeader`, `DataTablePagination`, `DataTableViewOptions` |
|
|
355
|
+
| `Filter`, `FilterProvider`, `FilterContent`, `FilterChips`, `FilterPresets` · `FilterFormField` | Schema-driven filters with chips, presets, validation, and URL or storage persistence. | `Filter`, `FilterProvider`, `FilterContent`, `FilterChips`, `FilterPresets`, `FilterFormField` |
|
|
356
|
+
| `FilterInline`, `FilterPopover`, `FilterDialog`, `FilterSheet`, `FilterDrawer` | The filter panel shown inline, or in a popover, dialog, sheet or drawer. | `FilterInline`, `FilterPopover`, `FilterDialog`, `FilterSheet`, `FilterDrawer` |
|
|
357
|
+
| `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink`, `PaginationBar`… | Pagination primitives. `PaginationBar` adds a sibling window with ellipses. | `Pagination` (parts), `PaginationFirst`, `PaginationLast` |
|
|
358
|
+
| `Tree`, `TreeItem`, `useTree` | Expandable tree with none, single or multiple selection and keyboard navigation. | `Tree`, `TreeItem`, `useTree` |
|
|
359
|
+
| `DndProvider`, `Draggable`, `Droppable`, `Sortable`, `DragHandle`… | Drag-and-drop primitives; see [dnd](#nxgtmaterialdnd). | `DndProvider`, `Draggable`, `Droppable`, `Sortable`, `DragHandle` |
|
|
360
|
+
|
|
361
|
+
### Navigation & layout
|
|
362
|
+
|
|
363
|
+
| Component | What it does | @nxgt/material-vue |
|
|
364
|
+
| --- | --- | --- |
|
|
365
|
+
| `ActivityLayout`, `ActivityContent`, `AppSidebar`, `AppHeader`, `AppBreadcrumb` | App shell: sidebar built from `items`, a header with a mobile sheet, route breadcrumbs and a titled page. See [App shell](#app-shell). | `ActivityLayout`, `ActivityContent`, `AppSidebar`, `AppHeader`, `AppBreadcrumb` |
|
|
366
|
+
| `Sidebar`, `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarMenuItem`, `SidebarMenuLabel` | Collapsible navigation sidebar with icons, tooltips and active items. | `Sidebar` (same parts) |
|
|
367
|
+
| `TopAppBar`, `BottomAppBar` | Top bar surface, and a bottom bar of icon actions with an active state. | `TopAppBar`, `BottomAppBar` |
|
|
368
|
+
| `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` | Breadcrumb primitives. | `Breadcrumb` (same parts) |
|
|
369
|
+
| `ListDetailsLayout`, `PaneLayout`, `ThreadLayout` | List / details that collapses to one view on mobile, a side pane that becomes a sheet, and a centred column. | `ListDetailsLayout`, `PaneLayout`, `ThreadLayout` |
|
|
370
|
+
| `ResponsiveGrid` | Container-query grid that grows from 1 to 5 columns. | `ResponsiveGrid` |
|
|
371
|
+
| `ResizableGroup`, `ResizablePanel`, `ResizableSeparator` | Resizable panels with an optional grip handle. | `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle` |
|
|
372
|
+
| `SkipLink` | Skip-to-content control, visible on focus. `DocSkipLink` composes it with `#doc-content`. | `SkipLink` |
|
|
373
|
+
| `Pager` | Previous / next cards for a sequence of pages. `DocPager` composes it. | `Pager` |
|
|
374
|
+
| `SeeAlso` | Related-link list with outbound icons. `DocSeeAlso` composes it. | `SeeAlso` |
|
|
375
|
+
| `Toc` | On-this-page outline with a per-item active bar. Rail from `xl`, collapsible panel below. `DocToc` composes it. | `Toc` |
|
|
376
|
+
| `Stepper`, `StepperIndicator` | Clickable horizontal or vertical steps with status and progress; compact on mobile. | `Stepper` |
|
|
377
|
+
| `Steps`, `StepsItem` | Numbered editorial steps that stay visible on every breakpoint. | `Steps`, `StepsItem` |
|
|
378
|
+
| `Hero` | Landing band with eyebrow, title, supporting copy and actions. | `Hero` |
|
|
379
|
+
| `Doc`, `DocPage`, `DocTopbar`, `DocSidebar`, `DocToc`, `DocPager`, `DocSearch`, `DocChildCards`, `DocSeeAlso`, `DocEmpty`, `DocProgress` | Documentation site shell: sidebar from `md`, TOC rail from `xl`. Reading bar, copy-page / markdown, child cards, see also, and a 404 slot. Storybook `UI/Doc/Api` composes an API page from `DocPage`, `AnchorHeading`, `ApiOperation`, `ParamTable` and `CodeGroup`. | `Doc`, `DocPage`, `DocTopbar`, `DocSidebar`, `DocToc`, `DocPager`, `DocSearch`, `DocChildCards`, `DocSeeAlso`, `DocEmpty`, `DocProgress` |
|
|
380
|
+
| `Background` | Full-viewport gradient with blurred colour blobs; centres its children. | `Background` |
|
|
381
|
+
| `NavigationRail` | Placeholder: renders an empty rail container and takes no props yet. | `NavigationRail` |
|
|
382
|
+
|
|
383
|
+
### Overlays & menus
|
|
384
|
+
|
|
385
|
+
| Component | What it does | @nxgt/material-vue |
|
|
386
|
+
| --- | --- | --- |
|
|
387
|
+
| `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogTitle`, `DialogDescription`, `DialogFooter`, `DialogClose`… | Modal dialog parts with an icon close button. | `Dialog` (same parts), `DialogScrollContent` |
|
|
388
|
+
| `Sheet`, `SheetTrigger`, `SheetContent`, `SheetHeader`, `SheetTitle`, `SheetFooter`… | Panel that slides in from any edge. | `Sheet` (same parts) |
|
|
389
|
+
| `Drawer`, `DrawerTrigger`, `DrawerContent`, `DrawerHeader`, `DrawerTitle`, `DrawerFooter`… | Swipeable bottom or side drawer (Vaul). | `Drawer` (same parts) |
|
|
390
|
+
| `Popover`, `PopoverTrigger`, `PopoverContent`, `PopoverAnchor` | Floating panel anchored to a trigger. | `Popover` (same parts) |
|
|
391
|
+
| `HoverCard`, `HoverCardTrigger`, `HoverCardContent` | Card shown on pointer hover. | `HoverCard` (same parts) |
|
|
392
|
+
| `Tooltip`, `TooltipProvider`, `TooltipTrigger`, `TooltipContent` | Tooltip. The `Tooltip` shorthand wraps its children and shows `content`. | `Tooltip` (same parts) |
|
|
393
|
+
| `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem`, `DropdownMenuSub`… | Menu with checkbox and radio items, submenus, shortcuts and an error item. | `DropdownMenu` (same parts) |
|
|
394
|
+
| `ContextMenu`, `ContextMenuTrigger`, `ContextMenuContent`, `ContextMenuItem`… | Right-click menu with the same kinds of items. | `ContextMenu` (same parts) |
|
|
395
|
+
| `Menubar`, `MenubarMenu`, `MenubarTrigger`, `MenubarContent`, `MenubarItem`… | Desktop-style menubar. | `Menubar` (same parts) |
|
|
396
|
+
| `Command`, `CommandDialog`, `CommandInput`, `CommandList`, `CommandItem`… | Command palette with filtering, groups and shortcuts. `CommandDialog` shows it in a modal. | `Command`, `CommandDialog` (same parts) |
|
|
397
|
+
|
|
398
|
+
### Feedback & status
|
|
399
|
+
|
|
400
|
+
| Component | What it does | @nxgt/material-vue |
|
|
401
|
+
| --- | --- | --- |
|
|
402
|
+
| `Alert` | Callout with icon, title and description in seven tones. | `Alert` |
|
|
403
|
+
| `Banner` | Dismissible info / success / warning / error banner with an action. | `Banner` |
|
|
404
|
+
| `AlertDialog`, `AlertDialogContent`, `AlertDialogAction`, `AlertDialogCancel`… | Parts for a blocking confirmation dialog. | `AlertDialog` (same parts) |
|
|
405
|
+
| `ConfirmDialog`, `ConfirmationDialog`, `CustomAlertDialog` | Confirm / cancel dialog with async loading. `ConfirmationDialog` adds a trigger and an optional Zod form. | `ConfirmDialog`, `ConfirmationDialog`, `CustomAlertDialog` |
|
|
406
|
+
| `CustomDialog` | Ready-made dialog with trigger, icon, title, body and footer. | `CustomDialog` |
|
|
407
|
+
| `EmptyState` | Icon in a tinted well, title, description and action; not-found, unauthorized, generic and empty presets. | `EmptyState` |
|
|
408
|
+
| `Progress`, `CircularProgress`, `ProgressField` | Linear bar, circular ring with a label, and a labelled progress field. | `Progress`, `CircularProgress`, `ProgressField` |
|
|
409
|
+
| `ScrollProgress` | Hairline that tracks window or a scrollable `target` (`react-use` `useWindowScroll` / `useScroll`). `DocProgress` composes it. | `ScrollProgress` |
|
|
410
|
+
| `Spinner` | Loading spinner in several styles and colours. | `Spinner` |
|
|
411
|
+
| `Toaster`, `toast`, `toasts`, `Toast` | Sonner toasts with icon and action. `toasts` provides `success` / `error` / `warning` / `info` / `loading` presets. | `Toaster`, `toast`, `toasts`, `Toast` |
|
|
412
|
+
| `Skeleton`, `SkeletonAvatar`, `SkeletonCard`, `SkeletonText`, `SkeletonTable` | Loading placeholder and ready-made shapes. | `Skeleton` (same parts) |
|
|
413
|
+
| `HydrateLoading` | Full-area spinner shown while hydrating. | `HydrateLoading` |
|
|
414
|
+
| `Notifications` | Notification centre as a bell popover with an unread count, or as an inline panel, with filters and read / dismiss. | `Notifications` |
|
|
415
|
+
|
|
416
|
+
### Media & files
|
|
417
|
+
|
|
418
|
+
| Component | What it does | @nxgt/material-vue |
|
|
419
|
+
| --- | --- | --- |
|
|
420
|
+
| `S3UploadField`, `NetworkUploadField` · `S3UploadFormField`, `NetworkUploadFormField` | Drag-and-drop uploader with progress, retry, previews and size / count limits. The S3 variant uploads through a presigned PUT. | `S3UploadField`, `NetworkUploadField`, `S3UploadFormField`, `NetworkUploadFormField` |
|
|
421
|
+
| `UploadField` · `UploadFormField` | Labelled file input showing the chosen file's name. | `UploadField`, `UploadFormField` |
|
|
422
|
+
| `FileList`, `FileListField`, `FileListS3Field` · `FileListFormField`, `FileListS3FormField` | File list with type icons, size, download and remove. The field variants upload with progress. | `FileList`, `FileListField`, `FileListS3Field`, `FileListFormField`, `FileListS3FormField` |
|
|
423
|
+
| `FilesFormField` | Free-solo autocomplete of file URLs, with image thumbnails. | — |
|
|
424
|
+
| `ImageField`, `ImageS3Field` · `ImageFormField`, `ImageS3FormField` | Single image upload with preview and progress. | `ImageField`, `ImageS3Field`, `ImageFormField`, `ImageS3FormField` |
|
|
425
|
+
| `ImageCropper`, `ImageCropperDialog` | Crop with zoom, rotation, aspect presets and a round shape; outputs a `File`. | `ImageCropper`, `ImageCropperDialog` |
|
|
426
|
+
| `Gallery`, `LightboxGallery`, `MiniGallery` | Image / video gallery (grid, masonry, justified, carousel…) with a lightbox and selection. | `Gallery`, `LightboxGallery`, `MiniGallery` |
|
|
427
|
+
| `Carousel`, `CarouselContent`, `CarouselItem`, `CarouselPrevious`, `CarouselNext` | Embla carousel with keyboard navigation. | `Carousel` (same parts) |
|
|
428
|
+
| `PdfReader`, `PdfViewer`, `PdfToolbar`, `PdfSidebar`, `PdfPageList`… | Browser-only PDF reader with zoom, rotation, search, thumbnails, outline and print. | `PdfReader`, `PdfViewer` (same parts) |
|
|
429
|
+
| `StxPlayer`, `StxPlayerProvider`, `StxPlayerMini`, `StxPlayerQueue`… | Video / audio player with a queue, captions, playback rate, PiP, and full or mini layouts. | `StxPlayer` (same parts) |
|
|
430
|
+
| `VideoPlayer` | Deprecated alias of `StxPlayer`. | `VideoPlayer` |
|
|
431
|
+
| `PrintHeader`, `PrintSection`, `PrintTable`, `PrintTotals`, `PrintCard`… | `@react-pdf/renderer` building blocks for printable PDF documents, with a shared `tw`. | `PrintHeader`, `PrintSection`, `PrintTable`, `PrintTotals`, `PrintCard` |
|
|
432
|
+
|
|
433
|
+
### Rich widgets
|
|
434
|
+
|
|
435
|
+
| Component | What it does | @nxgt/material-vue |
|
|
436
|
+
| --- | --- | --- |
|
|
437
|
+
| `ChatThread`, `ChatMessageList`, `ChatMessage`, `ChatComposer`, `ChatConversationItem`… | Chat kit: auto-scrolling list, streaming and tool messages, a composer with attachments, and markdown. | `ChatThread`, `ChatMessageList`, `ChatMessage`, `ChatComposer` (same parts) |
|
|
438
|
+
| `Kanban` | Board with columns, swimlanes, WIP limits, search, and drag-and-drop cards and columns. | `Kanban` |
|
|
439
|
+
| `EventCalendar` | Month / week / day / agenda calendar with drag, resize and slot creation. | `EventCalendar` |
|
|
440
|
+
| `AreaChart`, `BarChart`, `LineChart`, `PieChart`, `RadarChart`, `ScatterChart`, `FunnelChart`, `HeatmapChart` | Nivo charts themed from the CSS tokens, with loading and empty states (`ChartContainer`). | same names |
|
|
441
|
+
| `RichTextEditor` · `RichTextEditorFormField` | Tiptap editor with toolbar, bubble menu, slash commands, mentions, tables, emoji and images. | `RichTextEditor`, `RichTextEditorFormField` |
|
|
442
|
+
| `CodeEditor` · `CodeEditorFormField` | Monaco editor field with a label and a language switch. | `CodeEditor` |
|
|
443
|
+
| `Quiz`, `QuestionCard` | Multi-step quiz with choice, boolean and text questions, answer reveal and scoring. | `Quiz`, `QuestionCard` |
|
|
444
|
+
|
|
445
|
+
`@nxgt/material-vue` also has components with no React counterpart here:
|
|
446
|
+
`Camera`, `ScrollArea`, `NativeSelect` and the `InputOTP` primitives.
|
|
447
|
+
|
|
448
|
+
## Helpers
|
|
449
|
+
|
|
450
|
+
Everything below is also re-exported from the root `@nxgt/material` barrel.
|
|
451
|
+
The Vue sister, `@nxgt/material-vue`, uses the **same names** for the plain
|
|
452
|
+
functions; the differences are listed under each table.
|
|
453
|
+
|
|
454
|
+
### `@nxgt/material/lib`
|
|
455
|
+
|
|
456
|
+
| Export | What it does |
|
|
457
|
+
| --- | --- |
|
|
458
|
+
| `cn(...classes)` | `clsx` + `tailwind-merge`: joins conditional classes, last Tailwind utility wins. |
|
|
459
|
+
| `clientOnly(Component)` | Wraps a component so it renders nothing on the server and mounts only on the client. |
|
|
460
|
+
| `renderSlot(slot, context)` | Resolves a `ContentSlot` — a `ReactNode` or a `(context) => ReactNode`. |
|
|
461
|
+
| `DATE_UTILS` | `format(iso, 'PP', locale?)` (`'-'` when empty), `parseFromTimestring('HH:mm')`, `parseFromISOString`, `formatDateRangeFilter`. |
|
|
462
|
+
| `formatDateRangeFilter(range)` | Turns a day-picker range into `{ from, to }` ISO strings at start / end of day. |
|
|
463
|
+
| `formatNumber(value, { language?, ...Intl.NumberFormatOptions })` | `Intl.NumberFormat` with a language shortcut (`'en-US'` by default). |
|
|
464
|
+
| `ifEmptyString(value, fallback)`, `ifEmptyList(value, fallback)` | Returns the fallback when the string / array is null or empty. |
|
|
465
|
+
| `objectToFormData(obj)`, `formDataToObject(formData)` | Converts a flat object to `FormData` (skipping nullish values) and back. |
|
|
466
|
+
| `convertToFormData(files, fieldName = 'files')` | Appends one file or a list of files to a new `FormData`. |
|
|
467
|
+
| `uniqueArray(array)` | De-duplicates an array. |
|
|
468
|
+
| `findByKey(array, key, value)`, `findByKeyIn(array, key, values)` | Finds the first item / every item whose `key` matches. |
|
|
469
|
+
| `useFindByKey(items, key)`, `useFindById(items)` | Memoised `findByKey` / `findByKeyIn` bound to a list. |
|
|
470
|
+
| `pick(obj, keys)`, `omit(obj, keys)` | Typed pick / omit for one key or a list. |
|
|
471
|
+
| `cleanObject(obj, cleanNulls?)` | Drops `undefined` (and optionally `null`) properties. |
|
|
472
|
+
| `cast<T>(value)`, `castAsync<T>(promise)` | Type-only casts. |
|
|
473
|
+
| `delay(ms)` | Promise that resolves after `ms`. |
|
|
474
|
+
| `safeGetItem(key, default)`, `safeSetItem(key, value)`, `safeRemoveItem(key)` | JSON `localStorage` access that never throws (SSR, private mode). Grouped as `LOCALE_STORE_UTILS`. |
|
|
475
|
+
| `enumToKebabCase(value)`, `joinTruthyParts(parts, sep = ', ')`, `splitMatch(text, query)` | `SOME_ENUM` → `some-enum`; joins the truthy parts only; splits a string around case-insensitive matches. Grouped as `STRING_UTILS`. |
|
|
476
|
+
| `STYLES_UTILS.colorFromVariable(name, alpha?)` | `rgb(from var(--name) r g b / alpha)` for a theme token. |
|
|
477
|
+
| `searchParams(request)`, `searchParam(request, key)` | Reads the query string of a Fetch `Request` (loaders, actions). |
|
|
478
|
+
| `isExternalHref(href)` | True for `http(s):` and `mailto:` — new tab, not in-app. |
|
|
479
|
+
| `buildFieldOptions(values, { valueKey, label })` | Maps records to `{ value, label }` options by path or label function. |
|
|
480
|
+
| `zodLocaleError()` | Zod v4 `customError` that translates issues through `material.zod.*`: `z.config({ customError: zodLocaleError() })`. |
|
|
481
|
+
| `parsedType(data)` | Runtime type name used for Zod's `{received}` placeholder. |
|
|
482
|
+
|
|
483
|
+
**Redux Toolkit helpers** (same subpath) — the state pattern behind filter,
|
|
484
|
+
gallery, kanban and player:
|
|
485
|
+
|
|
486
|
+
| Export | What it does |
|
|
487
|
+
| --- | --- |
|
|
488
|
+
| `useSliceReducer(slice, initialState?)` | Runs an RTK slice as *local* component state via `useReducer`; returns `[state, boundActions]`. |
|
|
489
|
+
| `resolveSliceState(base, overrides?)` | Merges a slice's initial state with partial overrides. |
|
|
490
|
+
| `useSliceSelector(state, selector)` | Memoised selector over local slice state. |
|
|
491
|
+
| `useActions(actionCreators, deps?)` | Binds action creators to the store `dispatch` (`react-redux`). |
|
|
492
|
+
| `createStatusSlice({ name, … })` | Slice over a `Status<T>` with `reset`, `start`, `success(data)` and `error(message)`. |
|
|
493
|
+
| `createStatusesSlice({ name, initialState, … })` | Same for a record of named `Status` entries, addressed by path. |
|
|
494
|
+
| `createStepFormSlice({ name, initialState? })` | Multi-step form: `step`, `values`, `isDirty`, with `updateStep`, `updateFormValues`, `reset`. |
|
|
495
|
+
| `createSliceWithFilter({ name, initialState, … })` | Adds `updateFilter` and `resetFilter` for a `{ filter, sort }` state. |
|
|
496
|
+
| `createAsyncSlice` | `buildCreateSlice` with the `asyncThunk` creator enabled. |
|
|
497
|
+
|
|
498
|
+
Vue: the Redux helpers are Pinia store factories — `defineLocalStore`
|
|
499
|
+
(per-instance store, like `useSliceReducer`), `defineStatusStore`,
|
|
500
|
+
`defineStatusesStore`, `defineStepFormStore`, `defineFilterStore`,
|
|
501
|
+
`resolveStoreState`, plus `runStatus`. `createAsyncSlice`, `useActions` and
|
|
502
|
+
`useSliceSelector` have no Vue counterpart.
|
|
503
|
+
|
|
504
|
+
### `@nxgt/material/hooks`
|
|
505
|
+
|
|
506
|
+
| Export | What it does |
|
|
507
|
+
| --- | --- |
|
|
508
|
+
| `useTheme()` | `{ theme, preference, updateTheme }`: light / dark / system, stored in `localStorage`, applied as the `dark` class. |
|
|
509
|
+
| `resolveTheme(stored, prefersDark)`, `applyResolvedTheme(theme)` | The pure theme logic behind `useTheme`, usable in an inline boot script. |
|
|
510
|
+
| `useIsClient()` | `false` on the server and first render, `true` after mount — a hydration guard. |
|
|
511
|
+
| `useIsMobile()` | `true` below 768 px. |
|
|
512
|
+
| `useHeadingSpy(ids, onActive, options?)` | IntersectionObserver over heading ids; reports the topmost visible one. |
|
|
513
|
+
| `useLocalizedDate()` | `{ language, locale, format }`: `DATE_UTILS.format` bound to the `I18nProvider` language. |
|
|
514
|
+
| `useNumberFormatter()` | `{ formatNumber, formatCurrency }` bound to the `I18nProvider` language. |
|
|
515
|
+
| `useOptions(items, { value, label, filter?, expanded? })` | Memoised `{ value, label }` options for selects; `buildOptions` is the non-hook version. |
|
|
516
|
+
| `extractNode(connection)` | Unwraps a GraphQL `{ edges: [{ node }] }` connection into an array. |
|
|
517
|
+
| `useSearchParam(name)` | One query-string value from the router (`react-router`). |
|
|
518
|
+
| `useNavigationHandler(to, options?)`, `useNavigationHandlers(routes)` | Stable click handlers that navigate (`react-router`). |
|
|
519
|
+
| `useAllowedTransitions(status, transitions, configs)` | Status-machine actions (icon, colour, label, dialog copy) allowed from the current status. |
|
|
520
|
+
|
|
521
|
+
Vue: `@nxgt/material-vue/composables`, same names.
|
|
522
|
+
|
|
523
|
+
### `@nxgt/material/i18n`
|
|
524
|
+
|
|
525
|
+
| Export | What it does |
|
|
526
|
+
| --- | --- |
|
|
527
|
+
| `I18nProvider` | Holds the current language (props `defaultLanguage`, `initialLanguage` for SSR, `storageKey`, `supportedLanguages`, `onLanguageChange`). |
|
|
528
|
+
| `useI18nContext()`, `useOptionalI18nContext()` | Reads `{ language, setLanguage, … }`; the first throws outside the provider, the second returns `null`. |
|
|
529
|
+
| `mergeResources(base, app)` | Deep, per-language merge (`lodash.merge`) of the package bundle and yours; your leaf keys win, and each override is warned about outside production. |
|
|
530
|
+
| `resources` | The package's `en` / `fr` bundle, namespace `material`. |
|
|
531
|
+
| `createTranslator(resources, getLanguage?)` | ICU MessageFormat translator; a missing key comes back verbatim. |
|
|
532
|
+
| `createTypedTranslation(translate)` | Turns a translator into a typed `useTranslation()` hook. |
|
|
533
|
+
| `translate`, `useMaterialTranslation()` | Translator / hook bound to the package's own `material.*` keys. |
|
|
534
|
+
| `getLanguage()` | Language read from `localStorage`, else `FALLBACK_LANGUAGE`. |
|
|
535
|
+
| `LANGUAGE_KEY`, `FALLBACK_LANGUAGE`, `SUPPORTED_LANGUAGES` | Storage key (`'language'`), fallback and supported languages (`en`, `fr`). |
|
|
536
|
+
|
|
537
|
+
Types: `FlatObject`, `Path`, `Language`, `MaterialLocaleKey`, `Translate`,
|
|
538
|
+
`TranslationContext`, `ResourceBundle`. Vue adds `provideI18n()` for apps that
|
|
539
|
+
provide the context from `setup()` instead of the component.
|
|
540
|
+
|
|
541
|
+
### `@nxgt/material/models`, `/types`
|
|
542
|
+
|
|
543
|
+
| Export | What it does |
|
|
544
|
+
| --- | --- |
|
|
545
|
+
| `Status<T>` | `{ data?, status: 'idle' \| 'loading' \| 'success' \| 'error', error? }` — the shape the status slices manage. |
|
|
546
|
+
| `PromiseOr<T>`, `FunctionOr<T, R>`, `AsyncFunctionOr<T, R>` | A value or a promise; a value or a function computing it. |
|
|
547
|
+
| `Predicate<T>`, `AsyncPredicate<T>` | `(arg) => boolean` and its async form. |
|
|
548
|
+
|
|
549
|
+
### `@nxgt/material/dnd`
|
|
550
|
+
|
|
551
|
+
The drag-and-drop layer on `@dnd-kit`, also in `/components`:
|
|
552
|
+
|
|
553
|
+
| Export | What it does |
|
|
554
|
+
| --- | --- |
|
|
555
|
+
| `DndProvider`, `DndOverlay` | The `DndContext` (sensors, collision detection) and the floating drag preview. |
|
|
556
|
+
| `Draggable`, `Droppable`, `DraggableDroppable`, `DragHandle` | Primitives for free drag, drop zones, nested boards and handles. |
|
|
557
|
+
| `Sortable`, `SortableProvider` | A sortable item and its list context. |
|
|
558
|
+
| `useDndItem`, `useDndActiveId` | The item's drag state; the id being dragged. |
|
|
559
|
+
| `insertIds`, `arrayMove`, `composeRefs` | Pure list and ref helpers. |
|
|
560
|
+
| `closestCenter`, `pointerWithin`, `rectIntersection`, `verticalListSortingStrategy`, `horizontalListSortingStrategy`, `CSS` | Re-exported from `@dnd-kit`. |
|
|
561
|
+
|
|
172
562
|
## SSR
|
|
173
563
|
|
|
174
564
|
An SSR app that bundles this package (`ssr.noExternal: ['@nxgt/material']`)
|
|
175
|
-
|
|
176
|
-
renders the component.
|
|
565
|
+
runs every module the barrels reach when the server **boots**, whether or not
|
|
566
|
+
a page renders the component.
|
|
177
567
|
|
|
178
|
-
- **Nothing browser-only at module scope.** `pdfjs-dist` runs
|
|
179
|
-
at import.
|
|
180
|
-
`clientOnly` from `@nxgt/material/lib`. A `typeof window` guard around a
|
|
181
|
-
statement does nothing when the *import* is the side effect.
|
|
568
|
+
- **Nothing browser-only at module scope.** `pdfjs-dist` runs
|
|
569
|
+
`new DOMMatrix()` at import. Load it with `import()` and wrap the component
|
|
570
|
+
in `clientOnly` from `@nxgt/material/lib`. A `typeof window` guard around a
|
|
571
|
+
statement does nothing when the *import* itself is the side effect.
|
|
182
572
|
- **Never `<svg><title>`.** React 19 hoists `<title>` as document metadata:
|
|
183
|
-
server emits `<title></title
|
|
184
|
-
the
|
|
573
|
+
the server emits `<title></title>` while the client renders the text, and
|
|
574
|
+
the hydration mismatch makes React discard the whole tree. Use
|
|
575
|
+
`role="img"` + `aria-label` instead (`Icon` already does).
|
|
185
576
|
|
|
186
577
|
## Traps
|
|
187
578
|
|
|
@@ -189,7 +580,7 @@ renders the component.
|
|
|
189
580
|
| --- | --- | --- |
|
|
190
581
|
| Components render unstyled, no console error | Tailwind did not scan the package | `@source "../node_modules/@nxgt/material/"` |
|
|
191
582
|
| `<Icon>` is blank | sprite sheet not served | `public/assets/icons/sprites/<style>.svg` |
|
|
192
|
-
| Package strings
|
|
583
|
+
| Package strings change after adding i18n | your resources define keys under `material` | keep app strings in your own namespaces; `console.warn` lists each override in development |
|
|
193
584
|
| Hydration mismatch on every page | `<svg><title>` | `role="img"` + `aria-label` |
|
|
194
585
|
| `ReferenceError: DOMMatrix` at server boot | static `react-pdf` import | `import()` + `clientOnly` |
|
|
195
586
|
|
|
@@ -201,3 +592,8 @@ bun run build # what consumers read
|
|
|
201
592
|
bun run storybook
|
|
202
593
|
bun run test
|
|
203
594
|
```
|
|
595
|
+
|
|
596
|
+
## License
|
|
597
|
+
|
|
598
|
+
[MIT](https://opensource.org/license/mit). The `LICENSE` file ships in the
|
|
599
|
+
package.
|