@nxgt/material 3.14.0 → 3.15.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/CHANGELOG.md +6 -0
- package/dist/components/ui/display/chip/chip.css +12 -2
- package/dist/{components-BOwj2IuR.js → components-j0Iv8MZi.js} +1785 -1766
- package/dist/components.js +5 -5
- package/dist/{dialog-rOMjlKJ7.js → dialog-YHZJjDrI.js} +1 -0
- package/dist/editor.js +3 -3
- package/dist/{icon-badge-_tY1MwU9.js → icon-badge-C0TGvF9o.js} +2 -2
- package/dist/lib/components/ui/display/chip/chip.d.ts +1 -1
- package/dist/lib/components/ui/display/chip/chip.variants.d.ts +5 -2
- package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog-rules.d.ts +17 -0
- package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog.d.ts +10 -2
- package/dist/lib/components/ui/overlays/command/command.d.ts +7 -1
- package/dist/lib/components/ui/overlays/dialog/dialog-variants.d.ts +1 -1
- package/dist/main.js +5 -5
- package/dist/map.js +2 -2
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/{public-D_Gz7wgr.js → public-Bj3rGSfS.js} +1 -1
- package/dist/{use-chat-composer-P4GxmCHa.js → use-chat-composer-CoXmJCkr.js} +7 -7
- package/docs/components/data-display.md +2 -2
- package/docs/components/feedback-and-status.md +4 -0
- package/docs/components/overlays-and-menus.md +2 -1
- package/docs/components/primitives.md +2 -0
- package/docs/components/selection-and-choice.md +3 -1
- package/docs/troubleshooting.md +20 -0
- package/lib/components/ui/display/chip/chip.css +12 -2
- package/package.json +1 -1
package/dist/pdf-reader.js
CHANGED
|
@@ -6,7 +6,7 @@ import { c as i, i as a, l as o, n as s, o as c, s as l } from "./dist-lmHmz_bu.
|
|
|
6
6
|
import { a as u, o as d } from "./tooltip-CkttDIab.js";
|
|
7
7
|
import { i as f } from "./dist-C4wtXCjf.js";
|
|
8
8
|
import { r as p, t as m } from "./in-dialog-Vwkyp-M5.js";
|
|
9
|
-
import { C as h, D as g, E as _, O as v, S as y, T as b, _ as x, f as S, g as ee, k as te, r as ne, t as C, u as re, w } from "./dialog-
|
|
9
|
+
import { C as h, D as g, E as _, O as v, S as y, T as b, _ as x, f as S, g as ee, k as te, r as ne, t as C, u as re, w } from "./dialog-YHZJjDrI.js";
|
|
10
10
|
import { c as T, d as ie, f as E, i as ae, l as oe, n as se, o as D, t as ce, u as O } from "./dropdown-menu-BEyP-A0J.js";
|
|
11
11
|
import { S as le, a as k, d as A, g as ue, h as de, i as fe, m as pe, n as j, r as me, t as M, u as he, w as ge } from "./toolbar-items-CVQBYp4K.js";
|
|
12
12
|
import { t as N } from "./use-material-translation-DGeVp-qP.js";
|
|
@@ -7,7 +7,7 @@ import { a as o, c as s, i as c, l, n as u, o as d, r as f, s as p, t as m } fro
|
|
|
7
7
|
import { _ as h, a as g, g as _, h as v, m as y, o as b, p as x, t as S, v as C, y as w } from "./tooltip-CkttDIab.js";
|
|
8
8
|
import { a as T, i as E, n as D, r as O, t as k } from "./dist-C4wtXCjf.js";
|
|
9
9
|
import { i as A, n as ee, t as j } from "./in-dialog-Vwkyp-M5.js";
|
|
10
|
-
import { A as M, C as N, D as te, E as ne, O as P, S as re, T as ie, _ as F, b as ae, f as oe, g as se, k as I, l as ce, m as le, n as ue, o as de, r as fe, s as pe, t as me, u as he, v as ge, w as _e, x as ve, y as ye } from "./dialog-
|
|
10
|
+
import { A as M, C as N, D as te, E as ne, O as P, S as re, T as ie, _ as F, b as ae, f as oe, g as se, k as I, l as ce, m as le, n as ue, o as de, r as fe, s as pe, t as me, u as he, v as ge, w as _e, x as ve, y as ye } from "./dialog-YHZJjDrI.js";
|
|
11
11
|
import { A as be, C as xe, D as Se, E as Ce, O as we, S as Te, T as Ee, _ as De, a as Oe, b as ke, d as Ae, f as je, g as Me, h as Ne, i as Pe, k as Fe, l as Ie, m as Le, n as Re, o as ze, p as Be, r as Ve, s as He, t as Ue, u as We, v as Ge, w as Ke, x as qe, y as Je } from "./floating-ui.dom-KkZSW8_E.js";
|
|
12
12
|
import { D as Ye, E as Xe, N as Ze, O as Qe, c as $e, d as et, f as tt, i as nt, k as rt, m as it, n as at, o as ot, p as st, t as ct, u as lt } from "./dropdown-menu-BEyP-A0J.js";
|
|
13
13
|
import { a as ut, i as dt, n as ft } from "./field-blur-context-Cft9s7Hg.js";
|
|
@@ -36,7 +36,7 @@ import { n as an } from "./use-slice-reducer-BGkeGtML.js";
|
|
|
36
36
|
import { t as on } from "./browser-only-DQ94lWF8.js";
|
|
37
37
|
import { t as sn } from "./compose-refs-DZ0iIVF-.js";
|
|
38
38
|
import { n as cn, r as ln, t as un } from "./chip-BZu-bvAJ.js";
|
|
39
|
-
import { n as dn, t as fn } from "./icon-badge-
|
|
39
|
+
import { n as dn, t as fn } from "./icon-badge-C0TGvF9o.js";
|
|
40
40
|
import { r as pn } from "./use-csp-nonce-ZKs9k-ov.js";
|
|
41
41
|
import { t as mn } from "./empty-state-ZtqqpX0S.js";
|
|
42
42
|
import { t as hn } from "./skeleton-DSdtr2qc.js";
|
|
@@ -1324,7 +1324,7 @@ function xu({ className: e, ...t }) {
|
|
|
1324
1324
|
function Su({ className: e, ...t }) {
|
|
1325
1325
|
return /* @__PURE__ */ G("kbd", {
|
|
1326
1326
|
"data-slot": "kbd",
|
|
1327
|
-
className: n("pointer-events-none inline-flex h-5 min-w-5 items-center justify-center rounded border bg-muted px-1 font-mono text-[10px] font-medium text-muted-foreground", e),
|
|
1327
|
+
className: n("pointer-events-none inline-flex h-5 min-w-5 items-center justify-center rounded border bg-muted px-1 font-mono text-[10px] font-medium text-muted-foreground", "in-[[data-slot=button][data-variant=filled]]:border-current/40 in-[[data-slot=button][data-variant=filled]]:bg-current/15 in-[[data-slot=button][data-variant=filled]]:text-inherit", e),
|
|
1328
1328
|
...t
|
|
1329
1329
|
});
|
|
1330
1330
|
}
|
|
@@ -7969,7 +7969,7 @@ function Hy({ slot: e, values: t, getOptionValue: r = (e) => e.value, getOptionL
|
|
|
7969
7969
|
ref: o,
|
|
7970
7970
|
"data-slot": e ?? "autocomplete-field",
|
|
7971
7971
|
"data-mode": a.mode,
|
|
7972
|
-
className: n("grid w-full gap-1.5", a.className),
|
|
7972
|
+
className: n("grid w-full content-start gap-1.5", a.className),
|
|
7973
7973
|
children: [
|
|
7974
7974
|
/* @__PURE__ */ G(dt, {
|
|
7975
7975
|
id: c,
|
|
@@ -8432,7 +8432,7 @@ function ub({ group: e, name: t, slot: r, className: i, contentClassName: a, inl
|
|
|
8432
8432
|
return /* @__PURE__ */ K("div", {
|
|
8433
8433
|
"data-slot": r,
|
|
8434
8434
|
"data-pw": t ?? r,
|
|
8435
|
-
className: n("grid gap-1 w-full", i),
|
|
8435
|
+
className: n("grid content-start gap-1 w-full", i),
|
|
8436
8436
|
...l,
|
|
8437
8437
|
...d,
|
|
8438
8438
|
ref: u,
|
|
@@ -9542,7 +9542,7 @@ function kx({ error: e, helperText: t, label: r, className: i, placeholder: a, m
|
|
|
9542
9542
|
return /* @__PURE__ */ K("div", {
|
|
9543
9543
|
ref: m,
|
|
9544
9544
|
"data-slot": "textarea-field",
|
|
9545
|
-
className: n("grid w-full gap-1.5", i),
|
|
9545
|
+
className: n("grid w-full content-start gap-1.5", i),
|
|
9546
9546
|
children: [
|
|
9547
9547
|
r && /* @__PURE__ */ G(dt, {
|
|
9548
9548
|
withAsterisk: p.required,
|
|
@@ -12073,7 +12073,7 @@ function GC({ id: e, value: t, defaultValue: r = "", onChange: i, onValueChange:
|
|
|
12073
12073
|
return /* @__PURE__ */ K("div", {
|
|
12074
12074
|
"data-slot": "search-field",
|
|
12075
12075
|
"data-pw": m ?? "search-field",
|
|
12076
|
-
className: n("grid w-full gap-1.5", h),
|
|
12076
|
+
className: n("grid w-full content-start gap-1.5", h),
|
|
12077
12077
|
children: [
|
|
12078
12078
|
l && /* @__PURE__ */ G(dt, {
|
|
12079
12079
|
htmlFor: ee,
|
|
@@ -368,7 +368,7 @@ reads as a status (a stronger container of the tone, the label in the tone's
|
|
|
368
368
|
text colour, 4.5:1 or more on the page and in a card; the `outlined` hairline
|
|
369
369
|
and the `tag` dot still read `--chip-tone`, not the tone channel); `tag`
|
|
370
370
|
a smaller tag led by a colour dot; `dashed` a muted "add" pill. 28px tall,
|
|
371
|
-
24px with `size="sm"`. Selected (`active`, or `aria-pressed` on a toggle
|
|
371
|
+
24px with `size="sm"`, 44px with `size="lg"`. Selected (`active`, or `aria-pressed` on a toggle
|
|
372
372
|
chip) takes a primary tint and a primary edge, and a pressed toggle with
|
|
373
373
|
nothing leading draws a check. The label is truncated as one piece; the ✕
|
|
374
374
|
and `trailing` stay whole.
|
|
@@ -397,7 +397,7 @@ import { Avatar, Chip } from '@nxgt/material/components';
|
|
|
397
397
|
| `variant` | `'outlined' \| 'tonal' \| 'filled' \| 'tag' \| 'dashed'` | `'outlined'` | the look: hairline, soft (`tonal` and `filled`), tag, or a muted dashed "add" pill that turns solid once `active` or pressed. `ghost` (soft) and `link` (hairline) are still accepted, deprecated |
|
|
398
398
|
| `active` | `boolean` | — | selected: primary tint and edge |
|
|
399
399
|
| `aria-pressed` | `boolean` | — | a toggle chip: selected while pressed, with a check when nothing leads |
|
|
400
|
-
| `size` | `'default' \| 'sm'` | `'default'` | 28px or
|
|
400
|
+
| `size` | `'default' \| 'sm' \| 'lg'` | `'default'` | 28px, 24px, or `lg`, a 44px box at every pointer (the touch target); every target stays at least 24px |
|
|
401
401
|
| `color` | `'default' \| 'primary' \| 'secondary' \| 'info' \| 'success' \| 'warning' \| 'error'` | neutral | tone: the edge (outlined), the fill and label (tonal, `filled`: a status look) or the dot and tint (tag). A `tag` without `color` (or with `default`) draws no dot |
|
|
402
402
|
| `onDismiss` | `() => void` | — | adds the ✕ button, named "Remove {label}" (`material.chip.dismiss-label`), `{label}` being the text `label` shows, a node's included; "Remove" when it shows none; the ✕ is drawn 18px (16px small) with a 24px target |
|
|
403
403
|
| `dismissLabel` | `string \| ((label: string) => string)` | — | names the ✕ instead of "Remove {label}": a string as is, or a function of the text the chip shows |
|
|
@@ -222,8 +222,12 @@ function DeleteProject({ onDelete }: { onDelete: () => Promise<void> }) {
|
|
|
222
222
|
| `onConfirm` | `() => void \| Promise<void>` | required | awaited with the dialog open and both buttons disabled; closes on success; on a throw or rejection the dialog stays open and shows the error's message, or the translated `material.confirm-dialog.failed` ("The action failed.") when it has none |
|
|
223
223
|
| `variant` | `'default' \| 'destructive'` | `'default'` | `destructive` paints the confirm button `error` |
|
|
224
224
|
| `loading` | `boolean` | `false` | disables both buttons and shows the translated `material.confirm-dialog.processing` label, as a pending `onConfirm` does |
|
|
225
|
+
| `confirmDisabled` | `boolean` | `false` | disables the confirm button, for example while an error of yours stands |
|
|
226
|
+
| `lockOnRefusal` | `boolean` | `false` | once `onConfirm` has refused (thrown), the confirm button stays disabled while its error shows, so a retry that cannot succeed is not invited; Cancel stays enabled. The error clears when the dialog closes |
|
|
225
227
|
| `confirmLabel` / `cancelLabel` | `string` | "Confirm" / "Cancel", translated (`material.confirm-dialog.confirm` / `.cancel`) | button text |
|
|
226
228
|
|
|
229
|
+
On a phone (below 640 px) the footer stacks. A `destructive` dialog puts Cancel first and the destructive action last; a default one keeps the action on top.
|
|
230
|
+
|
|
227
231
|
`ConfirmDialog` opens with its Cancel focused, so Enter cancels. On closing
|
|
228
232
|
it hands the focus back to what opened it, or to the menu's trigger when
|
|
229
233
|
that was a `DropdownMenuItem` (gone by then); `Dialog`, `Sheet` and
|
|
@@ -131,7 +131,7 @@ export function Terms() {
|
|
|
131
131
|
| `asChild` (`DialogTrigger`) | `boolean` | **`true`** | the trigger is its child — pass one element, usually a `Button` |
|
|
132
132
|
| `variant`, `color` (`DialogClose`) | as `IconButton` | `'ghost'` | a top-right X button, named "Close" (`material.buttons.close`, translated) while it shows only the icon; text children or an `aria-label` name it instead, and icon-only children leave it unnamed; children replace the X |
|
|
133
133
|
| `size` (`DialogContent`) | `'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | its width from 640 px up: 384, 512, 672, 896 px, or the screen less 2rem a side |
|
|
134
|
-
| `mobilePresentation` (`DialogContent`) | `'dialog' \| 'bottom-sheet' \| 'fullscreen'` | `'dialog'` | below 640 px: a centred dialog, a sheet that springs up from the bottom edge (rounded top corners), or the whole screen |
|
|
134
|
+
| `mobilePresentation` (`DialogContent`) | `'dialog' \| 'bottom-sheet' \| 'top' \| 'fullscreen'` | `'dialog'` | below 640 px: a centred dialog, a sheet that springs up from the bottom edge (rounded top corners), a dialog pinned under the top edge, or the whole screen |
|
|
135
135
|
| `scrim` (`DialogContent`, `SheetContent`, `DrawerContent`) | `'dim' \| 'blur'` | `'dim'` | the scrim behind; `blur` also blurs the page a little |
|
|
136
136
|
|
|
137
137
|
The look lives in the stylesheet (`nxgt-dialog`, `nxgt-scrim`), under the
|
|
@@ -678,6 +678,7 @@ children and they replace that, as before.
|
|
|
678
678
|
| `alwaysRender` (`CommandSeparator`) | `boolean` | `false` | the separator is purely visual (`role="presentation"`, hidden from assistive technology) and hidden while the user searches; `true` keeps it visible then |
|
|
679
679
|
| `shouldFilter` (`Command`) | `boolean` | `true` | `false` when you filter the items yourself (server search) |
|
|
680
680
|
| `title` / `description` (`CommandDialog`) | `string` | `"Command Palette"` / `"Search for a command to run..."` (translated) | the dialog's title and description, inside the dialog and visually hidden |
|
|
681
|
+
| `mobilePresentation` (`CommandDialog`) | `'dialog' \| 'top' \| 'fullscreen'` | `'top'` | below 640 px: pinned under the top edge (so the input and the results stay above the on-screen keyboard), the whole screen, or the centred modal it was before |
|
|
681
682
|
| `open`, `onOpenChange` (`CommandDialog`) | as `Dialog` | — | `CommandDialog` takes every `Dialog` prop |
|
|
682
683
|
|
|
683
684
|
`CommandDialog` does not bind a keyboard shortcut; listen for ⌘K yourself and
|
|
@@ -526,6 +526,8 @@ import { Kbd, KbdShortcut } from '@nxgt/material/components';
|
|
|
526
526
|
| --- | --- | --- | --- |
|
|
527
527
|
| `keys` (`KbdShortcut`) | `string[]` | — (required) | one `Kbd` per key; `mod`, `shift` and `alt` become `⌘ ⇧ ⌥` on Apple platforms, `Ctrl Shift Alt` elsewhere |
|
|
528
528
|
|
|
529
|
+
Inside a filled `Button` the key, its border and the `+` between keys take the button's own text colour, so the shortcut keeps the contrast of the fill.
|
|
530
|
+
|
|
529
531
|
`Kbd` takes the props of `<kbd>`. `shortcutGlyph(key)` gives one glyph on its own.
|
|
530
532
|
|
|
531
533
|
**Storybook:** `Primitives/Kbd` · **Vue:** `Kbd`, `KbdShortcut`
|
|
@@ -328,6 +328,8 @@ when nothing matches. Options with a `group` are listed under its header
|
|
|
328
328
|
with their count, filtered within it (a group with no match goes); a
|
|
329
329
|
`description` is a muted line under the label, in the list only.
|
|
330
330
|
|
|
331
|
+
Once an option is picked, a round "Clear" button (`material.combobox.clear`, "Effacer" in French) appears at the end of the box, also in `ComboboxFormField`. It is a real button, named and exposed to assistive technology (`getByRole('button', { name: 'Clear' })`), described by the field's label, and kept out of the tab order like the other clearable fields: the keyboard clears with Backspace or by selecting the text and deleting it.
|
|
332
|
+
|
|
331
333
|
```tsx
|
|
332
334
|
import { ComboboxField } from '@nxgt/material/components';
|
|
333
335
|
import { useState } from 'react';
|
|
@@ -785,7 +787,7 @@ export function Topics() {
|
|
|
785
787
|
| `deselectable` | `boolean` | `false` | `single` only: pressing the chosen chip clears it |
|
|
786
788
|
| `max` / `min` | `number` | — | `multiple` only: `max` blocks the other chips once reached and speaks "{count} of {max} chosen"; `min` is a hint only |
|
|
787
789
|
| `options` | `{ value; label; icon?; count?; description?; disabled?; disabledReason? }[]` | — | the chips; `count`: see [option counts](#option-counts) |
|
|
788
|
-
| `size` | `'default' \| 'sm'` | `'default'` | the chip's size
|
|
790
|
+
| `size` | `'default' \| 'sm' \| 'lg'` | `'default'` | the chip's size: 28px, 24px, or `lg`, a 44px box at every pointer (a coarse pointer already gets a 44px box at any size) |
|
|
789
791
|
| `name` | `string` | — | put on every chip (`ChipGroupFormField` passes its field `name`), so `document.getElementsByName(name)` finds the group's chips in order |
|
|
790
792
|
| `label`, `helperText`, `error`, `required`, `disabled`, `id` | | — | the question and its help or error text, the required mark, disabling every chip, the group's `id` |
|
|
791
793
|
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | wrapping row or a column (each chip as wide as its label); in single mode it sets the `radiogroup`'s `aria-orientation` (ARIA allows none on a `group`), and every arrow key moves in both axes either way (the chips wrap) |
|
package/docs/troubleshooting.md
CHANGED
|
@@ -1975,6 +1975,26 @@ a few frames after the alert has gone) and look it up by selector rather
|
|
|
1975
1975
|
than by role: the closing alert still hides the page from the accessibility
|
|
1976
1976
|
tree.
|
|
1977
1977
|
|
|
1978
|
+
### A `ConfirmDialog` keeps offering a refused action
|
|
1979
|
+
|
|
1980
|
+
When `onConfirm` throws, the dialog shows the error and the confirm button
|
|
1981
|
+
stays active, so the user can retry. If a retry cannot succeed (the item is
|
|
1982
|
+
still referenced), lock it:
|
|
1983
|
+
|
|
1984
|
+
```tsx
|
|
1985
|
+
<ConfirmDialog variant="destructive" lockOnRefusal onConfirm={remove} … />
|
|
1986
|
+
```
|
|
1987
|
+
|
|
1988
|
+
Cancel stays enabled. `confirmDisabled` is the switch for your own condition.
|
|
1989
|
+
|
|
1990
|
+
### Fields in a two-column row sit at different heights
|
|
1991
|
+
|
|
1992
|
+
A field is a grid of a label and a control. In earlier versions its rows stretched when a
|
|
1993
|
+
neighbour in the same row was taller (a helper or error text under it), so the
|
|
1994
|
+
shorter field's control sank by half the difference. Fields now keep their rows
|
|
1995
|
+
at the top (`content-start`); upgrade, and drop any `mt-*` or `items-end`
|
|
1996
|
+
workaround. A `DateField`'s tonal fill is deliberate and not a misalignment.
|
|
1997
|
+
|
|
1978
1998
|
## Navigation
|
|
1979
1999
|
|
|
1980
2000
|
### A `ListTile` link shows two chevrons
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Chip: what the three looks share (data-look hairline, soft, tag). Sizes:
|
|
2
|
-
* default 28px, sm 24px (both at least the 24px target of WCAG 2.5.8)
|
|
3
|
-
* label truncates as one piece; the ✕ is drawn small, its target is 24×24
|
|
2
|
+
* default 28px, sm 24px (both at least the 24px target of WCAG 2.5.8), lg
|
|
3
|
+
* 44px (the touch target). The label truncates as one piece; the ✕ is drawn small, its target is 24×24
|
|
4
4
|
* through ::after, and it has its own focus ring. */
|
|
5
5
|
@layer components {
|
|
6
6
|
.nxgt-chip {
|
|
@@ -50,6 +50,16 @@
|
|
|
50
50
|
--chip-gap: 0.25rem;
|
|
51
51
|
--chip-x: 1rem;
|
|
52
52
|
}
|
|
53
|
+
/* lg: a 44px box at every pointer (the touch target, #1529). */
|
|
54
|
+
.nxgt-chip[data-size="lg"] {
|
|
55
|
+
--chip-h: 2.75rem;
|
|
56
|
+
--chip-px: 1rem;
|
|
57
|
+
--chip-font: 0.9375rem;
|
|
58
|
+
--chip-icon: 1rem;
|
|
59
|
+
--chip-gap: 0.375rem;
|
|
60
|
+
--chip-x: 1.5rem;
|
|
61
|
+
min-width: 2.75rem;
|
|
62
|
+
}
|
|
53
63
|
button.nxgt-chip,
|
|
54
64
|
.nxgt-chip > button[data-slot="chip-body"] {
|
|
55
65
|
cursor: pointer;
|