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