@nxgt/material 3.35.1 → 3.37.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 +12 -0
- package/README.md +1 -1
- package/dist/{button-EMWOFSDB.js → button-CB4nSAMd.js} +2 -1
- package/dist/charts.js +1 -1
- package/dist/components/ui/actions/icon-button/icon-button.css +58 -0
- package/dist/{components-jh9l5bIA.js → components-mqgqmfvj.js} +19761 -19742
- package/dist/components.js +20 -20
- package/dist/{dialog-Cdv9IXVo.js → dialog-DR9rACzY.js} +1 -1
- package/dist/dnd.js +1 -1
- package/dist/editor.js +906 -907
- package/dist/{icon-badge-BFScQnp9.js → icon-badge-DXEBeS1y.js} +2 -2
- package/dist/{icon-button-ifTpXt0A.js → icon-button-CN9r5TNE.js} +51 -32
- package/dist/lib/components/ui/actions/button/button.d.ts +8 -0
- package/dist/lib/components/ui/actions/icon-button/icon-button.d.ts +14 -0
- package/dist/lib/components/ui/collections/data-table/hooks.d.ts +6 -1
- package/dist/lib/components/ui/collections/filter/bar/filter-bar-view.d.ts +1 -1
- package/dist/lib/components/ui/collections/filter/facets/filter-facets.d.ts +1 -1
- package/dist/lib/components/ui/collections/filter/facets/partials/filter-facets-footer.d.ts +4 -1
- package/dist/lib/components/ui/collections/filter/facets/partials/filter-facets-panel.d.ts +3 -1
- package/dist/lib/components/ui/collections/filter/filter-presets.d.ts +1 -1
- package/dist/lib/components/ui/collections/filter/query/types.d.ts +13 -0
- package/dist/lib/components/ui/collections/filter/sections/sheet/filter-sheet-footer.d.ts +3 -1
- package/dist/lib/components/ui/collections/filter/sections/sheet/filter-sheet.d.ts +3 -1
- package/dist/lib/components/ui/collections/filter/types-props.d.ts +3 -0
- package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog.d.ts +7 -1
- package/dist/lib/components/ui/feedback/confirmation-dialog/confirmation-dialog.d.ts +7 -1
- package/dist/lib/components/ui/fields/attributes/attribute-dialog.d.ts +4 -1
- package/dist/lib/components/ui/fields/attributes/attributes-field/attributes-dialog-field.d.ts +4 -1
- package/dist/lib/components/ui/fields/attributes/attributes-field/attributes-inline-field.d.ts +1 -1
- package/dist/lib/components/ui/fields/contacts/contact-dialog.d.ts +4 -1
- package/dist/lib/components/ui/fields/contacts/contacts-dialog-form-field.d.ts +4 -1
- package/dist/lib/components/ui/fields/contacts/contacts-form-field.d.ts +4 -1
- package/dist/lib/components/ui/fields/opening-hours/opening-hours-dialog-form-field.d.ts +4 -1
- package/dist/lib/components/ui/fields/opening-hours/opening-hours-dialog.d.ts +4 -1
- package/dist/lib/components/ui/fields/opening-hours/opening-hours-form-field.d.ts +4 -1
- package/dist/lib/components/ui/fields/postal-address/postal-address-dialog.d.ts +4 -1
- package/dist/lib/components/ui/fields/postal-address/postal-address-form-field.d.ts +4 -1
- package/dist/lib/components/ui/media/image-cropper/image-cropper.d.ts +4 -1
- package/dist/lib/components/ui/widgets/rich-text-editor/types.d.ts +3 -0
- package/dist/main.js +32 -32
- package/dist/map.js +4 -4
- package/dist/material.css +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/{public-CYdnlHqA.js → public-BdJCVnGS.js} +3 -3
- package/dist/{sortable-provider-CY_YD3Ee.js → sortable-provider-BshacF8v.js} +1 -1
- package/dist/{use-chat-composer-CoyqPKbt.js → use-chat-composer-C82hvxm4.js} +11 -10
- package/docs/components/buttons-and-actions.md +29 -1
- package/docs/components/data-table-filter-and-lists.md +10 -1
- package/docs/components/feedback-and-status.md +3 -1
- package/docs/components/form-fields.md +10 -4
- package/docs/components/media-and-files.md +1 -0
- package/docs/components/primitives.md +1 -1
- package/docs/components/rich-widgets.md +2 -2
- package/lib/components/ui/actions/icon-button/icon-button.css +58 -0
- package/package.json +1 -1
package/dist/pdf-reader.js
CHANGED
|
@@ -6,12 +6,12 @@ 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-DR9rACzY.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-CpSnRXd-.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-B1W-uVHS.js";
|
|
12
12
|
import { t as N } from "./use-material-translation-BK2YYCY3.js";
|
|
13
|
-
import { t as _e } from "./button-
|
|
14
|
-
import { n as ve, t as ye } from "./icon-button-
|
|
13
|
+
import { t as _e } from "./button-CB4nSAMd.js";
|
|
14
|
+
import { n as ve, t as ye } from "./icon-button-CN9r5TNE.js";
|
|
15
15
|
import { t as be } from "./useEvent-2fKq-6w8.js";
|
|
16
16
|
import { n as xe, t as Se } from "./toggle-group-BMJNcFAC.js";
|
|
17
17
|
import { o as Ce } from "./escape-owner-C4W_sOAU.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as e } from "./utils-BLfntITJ.js";
|
|
2
2
|
import { t } from "./dist-DVRQkaTK.js";
|
|
3
3
|
import { t as n } from "./use-material-translation-BK2YYCY3.js";
|
|
4
|
-
import { t as r } from "./icon-button-
|
|
4
|
+
import { t as r } from "./icon-button-CN9r5TNE.js";
|
|
5
5
|
import { t as i } from "./compose-refs-DZ0iIVF-.js";
|
|
6
6
|
import { GripVertical as a } from "lucide-react";
|
|
7
7
|
import o, { cloneElement as s, createContext as c, forwardRef as l, memo as u, useCallback as d, useContext as f, useEffect as p, useLayoutEffect as m, useMemo as h, useReducer as g, useRef as _, useState as v } from "react";
|
|
@@ -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-DR9rACzY.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-CpSnRXd-.js";
|
|
13
13
|
import { a as ut, i as dt, n as ft } from "./field-blur-context-Cft9s7Hg.js";
|
|
@@ -21,8 +21,8 @@ import { t as jt } from "./isEmpty-F_g3jLf8.js";
|
|
|
21
21
|
import { t as L } from "./use-material-translation-BK2YYCY3.js";
|
|
22
22
|
import { t as Mt } from "./spinner-CKlDba5I.js";
|
|
23
23
|
import { a as Nt } from "./button-tones-BwuVvAmd.js";
|
|
24
|
-
import { a as Pt, i as Ft,
|
|
25
|
-
import { t as R } from "./icon-button-
|
|
24
|
+
import { a as Pt, i as Ft, o as It, r as Lt, t as Rt } from "./button-CB4nSAMd.js";
|
|
25
|
+
import { t as R } from "./icon-button-CN9r5TNE.js";
|
|
26
26
|
import { a as zt, r as Bt } from "./icon-sprites-CaYXzOL4.js";
|
|
27
27
|
import { t as Vt } from "./use-ssr-media-query-C6M5m8sf.js";
|
|
28
28
|
import { n as Ht, t as Ut } from "./util-4heV2LPI.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-B6m3yagf.js";
|
|
39
|
-
import { n as dn, t as fn } from "./icon-badge-
|
|
39
|
+
import { n as dn, t as fn } from "./icon-badge-DXEBeS1y.js";
|
|
40
40
|
import { r as pn } from "./use-csp-nonce-ZKs9k-ov.js";
|
|
41
41
|
import { t as mn } from "./empty-state-DMr94lsF.js";
|
|
42
42
|
import { t as hn } from "./skeleton-DSdtr2qc.js";
|
|
@@ -1232,18 +1232,18 @@ var _u = function(e, t, n) {
|
|
|
1232
1232
|
//#endregion
|
|
1233
1233
|
//#region lib/components/ui/actions/split-button/split-button-action.tsx
|
|
1234
1234
|
function vu({ children: e, loading: t = !1, lockOnClick: r, tooltip: i, filled: a, onClickCapture: o, type: s = "button", className: c, ...l }) {
|
|
1235
|
-
let u =
|
|
1235
|
+
let u = Lt(r, t), d = t || u.locked, f = /* @__PURE__ */ K("button", {
|
|
1236
1236
|
"data-slot": "split-button-action",
|
|
1237
1237
|
type: s,
|
|
1238
1238
|
...l,
|
|
1239
1239
|
className: n("nxgt-split-button-part", c),
|
|
1240
1240
|
"aria-disabled": d || l["aria-disabled"],
|
|
1241
1241
|
"aria-busy": d || l["aria-busy"],
|
|
1242
|
-
onClickCapture:
|
|
1242
|
+
onClickCapture: It(d, u, o),
|
|
1243
1243
|
children: [d ? /* @__PURE__ */ G(Mt, {
|
|
1244
1244
|
color: a ? "light" : "primary",
|
|
1245
1245
|
className: "nxgt-split-button-spinner size-(--sb-icon)"
|
|
1246
|
-
}) : null,
|
|
1246
|
+
}) : null, Ft(e)]
|
|
1247
1247
|
});
|
|
1248
1248
|
return i ? /* @__PURE__ */ G(S, {
|
|
1249
1249
|
content: i,
|
|
@@ -7283,7 +7283,7 @@ function Rv({ className: e, ...t }) {
|
|
|
7283
7283
|
}
|
|
7284
7284
|
function zv({ className: e, ...t }) {
|
|
7285
7285
|
return /* @__PURE__ */ G(Kc, {
|
|
7286
|
-
className: n(
|
|
7286
|
+
className: n(Pt({
|
|
7287
7287
|
variant: t.variant,
|
|
7288
7288
|
color: t.color
|
|
7289
7289
|
}), e),
|
|
@@ -7292,8 +7292,9 @@ function zv({ className: e, ...t }) {
|
|
|
7292
7292
|
}
|
|
7293
7293
|
function Bv({ className: e, ...t }) {
|
|
7294
7294
|
return /* @__PURE__ */ G(qc, {
|
|
7295
|
-
|
|
7296
|
-
|
|
7295
|
+
"data-variant": t.variant ?? "tonal",
|
|
7296
|
+
className: n(Pt({
|
|
7297
|
+
variant: t.variant ?? "tonal",
|
|
7297
7298
|
color: t.color
|
|
7298
7299
|
}), e),
|
|
7299
7300
|
...t
|
|
@@ -65,7 +65,7 @@ import { Mail } from 'lucide-react';
|
|
|
65
65
|
| `asChild` | `boolean` | `false` | styles its only child instead of rendering a `<button>` |
|
|
66
66
|
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | not `submit` by default — pass it inside a form |
|
|
67
67
|
|
|
68
|
-
The classes are exported as `buttonVariants` for styling your own element (Pagination, AlertDialog and the calendar's date picker use them).
|
|
68
|
+
The `ButtonVariant` type (one `variant` value) is exported too, to type a `cancelVariant` you forward. The classes are exported as `buttonVariants` for styling your own element (Pagination, AlertDialog and the calendar's date picker use them).
|
|
69
69
|
|
|
70
70
|
**The look.** The label is set in the type scale and is heavier than before (weights 560 at `xs` to 700 at `2xl`). The focus is a 2 px outline in the button's colour, 2 px off the button (the error colour with `aria-invalid`). A disabled button has neutral text (40 % of the text colour) and a neutral 12 % fill, none on `ghost` and `link`. `outlined` is a 1.5 px line inside the box at 55 % of the colour, and keeps a `ButtonText` outline in forced colours, where the inset shadow is removed. A `ghost` button is neutral without a `color`, and takes the tone of one it is given. On a coarse pointer every size has a 44 px hit area.
|
|
71
71
|
|
|
@@ -79,6 +79,24 @@ const [on, setOn] = useState(false);
|
|
|
79
79
|
<Button size="2xl" shape="square" variant="tonal">Start</Button>;
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
+
**Footer buttons.** In a footer (a dialog, a sheet, a form, an inline editor),
|
|
83
|
+
the confirming action is `filled` and the Cancel, Close or Discard beside it
|
|
84
|
+
is `tonal`: two clear buttons, one weight apart, where a text or outlined
|
|
85
|
+
Cancel read poorly and left its hit area invisible. The library draws its own
|
|
86
|
+
Cancel buttons that way (`AlertDialogCancel`, `ConfirmDialog`,
|
|
87
|
+
`ConfirmationDialog`, the field dialogs, `ImageCropper`, the filter sheet…),
|
|
88
|
+
and each takes `cancelVariant` (a `Button` `variant`, default `'tonal'`) to
|
|
89
|
+
restore `'outlined'` or `'ghost'`. Write yours the same way. An icon-only ✕ in
|
|
90
|
+
a corner, a toolbar button and a text link stay as they are; a destructive
|
|
91
|
+
confirm keeps its own variant and `color="error"`.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
<DialogFooter>
|
|
95
|
+
<Button variant="tonal" onClick={close}>Cancel</Button>
|
|
96
|
+
<Button type="submit">Save</Button>
|
|
97
|
+
</DialogFooter>;
|
|
98
|
+
```
|
|
99
|
+
|
|
82
100
|
**On a phone.** A button is never wider than its container, and keeps its
|
|
83
101
|
content's width in a column: a label too
|
|
84
102
|
long for it (a card on a phone) is cut with “…” on one line, and its
|
|
@@ -159,6 +177,16 @@ import { Pencil, Trash2 } from 'lucide-react';
|
|
|
159
177
|
| `aria-label` | `string` | the tooltip, if a string | give one when there is no string tooltip |
|
|
160
178
|
| `shape` | `ShapeName` | — | draws the button as one of the expressive shapes (`cookie-9`, `sunny`, `squircle`…) instead of a circle; changing it morphs. Unset: the round button, unchanged |
|
|
161
179
|
| `morph` | `'round' \| 'pill' \| 'none'` | `'pill'` | what a **toggle** (`aria-pressed` set) does when pressed: `pill` fills with its colour and widens by 14 px into a pill, `round` fills and stays a circle, `none` keeps the look your classes give it. Not set on a button without `aria-pressed`, one with a `shape`, or a Toolbar item (the Toolbar's own look) |
|
|
180
|
+
| `badge` | `number` | — | a count on the top end corner (top left in a right-to-left page): "99+" past 99, nothing at 0 or unset. It takes no room, so the box and the 44 px hit area are unchanged. It is **decorative** (`aria-hidden`): put the number in the accessible name yourself, e.g. `aria-label="Publish 2 items"` |
|
|
181
|
+
| `badgeTone` | `'primary' \| 'error' \| 'neutral'` | `'primary'` | the badge's colour: a count is not an alert, so `primary`; `error` for a notification; `neutral` is the page's text colour on its background |
|
|
182
|
+
|
|
183
|
+
**A count badge** (`badge`) is a primary pill (`badgeTone="error"` is the menu-item badge's red), ringed in the page background so it reads over any variant, and sits half outside the corner, over the neighbours' gap (leave 4 px; a `Toolbar` clips 4 px outside its items, so leave room there too). It does not dim when the button is disabled. It never names itself: `<IconButton badge={2} aria-label="Publish 2 items">`. `Button` has no `badge`: its label can be cut with an ellipsis and an `asChild` one clips, so compose a `CountBadge` around it.
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
<IconButton badge={count} aria-label={`Publish ${count} items`}>
|
|
187
|
+
<Send />
|
|
188
|
+
</IconButton>
|
|
189
|
+
```
|
|
162
190
|
|
|
163
191
|
**A toggle button** fills with the button's `color` (`primary` by default) through `data-selected` and the fill `Button` shares, and a pointer down squeezes the corners; `pill` widens the button itself by 14 px (its neighbours move by the 14 px), at any `size` (give the button a `size`, not a `size-*` class: the pressed width follows the `size`, see [troubleshooting](../troubleshooting.md#a-pill-iconbutton-toggle-is-the-wrong-width-with-a-size--class)). Below 600 px wide only the colour changes, so a phone row never reflows; `prefers-reduced-motion` keeps the colour change only; in forced colours the pressed fill is `SelectedItem`. The pressed fill and corners are the button's own (a `bg-*` or `rounded-*` class on a pressed toggle does not apply); a ghost toggle without a `color` is neutral when selected (a tint of the text colour), and primary only with a `color`. The focus is a 2 px outline 2 px off the button, a disabled button has a neutral 12 % fill (none on `ghost` and `link`), and on a coarse pointer every size has a 44 px hit area. The morph works with a `tooltip` too (the styles match `data-icon-button`, which the tooltip trigger does not replace). The date picker's input-mode switch uses `morph="round"`; `PasswordField`'s eye, which sits inside its field, and `RichChatComposer`'s format toggle, which draws its own pressed look, use `morph="none"`; the mini player's move button and the Gallery viewer's repeat are pills too, white with a black icon on their dark chrome. `CodeEditor`'s word-wrap pill takes the editor theme's tint.
|
|
164
192
|
|
|
@@ -83,7 +83,9 @@ truncates with an ellipsis and carries its full text as a `title`); `DataTablePa
|
|
|
83
83
|
"Toggle row details" (`material.table.labels.toggle-row`) with `aria-expanded`, under a
|
|
84
84
|
visually hidden header "Expand", `material.table.labels.expand`);
|
|
85
85
|
`useDeleteRowsHandler(onDelete)` returns a `handleDelete(rows)` click
|
|
86
|
-
handler and the `confirmDialog` to render
|
|
86
|
+
handler and the `confirmDialog` to render; its Cancel button is `tonal`
|
|
87
|
+
(`useDeleteRowsHandler(onDelete, { cancelVariant: 'outlined' })` restores the
|
|
88
|
+
earlier look).
|
|
87
89
|
`dataTableFeatures` / `DataTableFeatures` are the TanStack v9 features the
|
|
88
90
|
table enables, for typing your own column defs.
|
|
89
91
|
|
|
@@ -1402,6 +1404,13 @@ and `errors` shows a server's refusal of a condition (see
|
|
|
1402
1404
|
[A refused condition](#a-refused-condition)). A locked chip is a focusable group named by its text ("Year is 2026-2027"), with "Locked: <reason>" as its description. The other variants
|
|
1403
1405
|
and `FilterProps` are unchanged.
|
|
1404
1406
|
|
|
1407
|
+
#### The sheet's and the staged panel's secondary button
|
|
1408
|
+
|
|
1409
|
+
"Clear all" in the phone sheet's footer and "Reset" in the staged panel's are
|
|
1410
|
+
`tonal`, beside a filled "Show N results" / "Apply". `cancelVariant` on
|
|
1411
|
+
`Filter variant="bar"` or `"facets"` (a `Button` `variant`) restores
|
|
1412
|
+
`'outlined'`. `FilterPresets` takes the same prop for its save dialog's Cancel.
|
|
1413
|
+
|
|
1405
1414
|
#### A compact band for a list inside a page section
|
|
1406
1415
|
|
|
1407
1416
|
`bandDensity="compact"` is `ServerTable`'s prop, with the same values and the
|
|
@@ -167,7 +167,7 @@ Parts: `AlertDialog`, `AlertDialogTrigger`, `AlertDialogContent`,
|
|
|
167
167
|
`AlertDialogFooter`, `AlertDialogAction`, `AlertDialogCancel`,
|
|
168
168
|
`AlertDialogOverlay`, `AlertDialogPortal`. `AlertDialogAction` and
|
|
169
169
|
`AlertDialogCancel` take the `Button` `variant` and `color` (cancel defaults
|
|
170
|
-
to `outlined
|
|
170
|
+
to `tonal`, under a filled action; `variant="outlined"` restores the earlier look; a `ghost` one in a colour shows it, as a ghost `Button` does). Radix props (`open`, `defaultOpen`, `onOpenChange`) go on
|
|
171
171
|
`AlertDialog`.
|
|
172
172
|
On open, `AlertDialogContent` focuses `AlertDialogCancel`, the least
|
|
173
173
|
destructive action (its first control when there is no Cancel, the content
|
|
@@ -225,6 +225,7 @@ function DeleteProject({ onDelete }: { onDelete: () => Promise<void> }) {
|
|
|
225
225
|
| `confirmDisabled` | `boolean` | `false` | disables the confirm button, for example while an error of yours stands |
|
|
226
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 |
|
|
227
227
|
| `confirmLabel` / `cancelLabel` | `string` | "Confirm" / "Cancel", translated (`material.confirm-dialog.confirm` / `.cancel`) | button text |
|
|
228
|
+
| `cancelVariant` | `ButtonVariant` | `'tonal'` | the Cancel button's variant; `'outlined'` restores the earlier look |
|
|
228
229
|
|
|
229
230
|
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
231
|
|
|
@@ -272,6 +273,7 @@ const schema = z.object({ reason: z.string().min(3) });
|
|
|
272
273
|
| `icon` | `ReactNode` | info icon | the glyph alone (not an `IconButton`): it is shown in a decorative, `aria-hidden` badge |
|
|
273
274
|
| `iconProps` | `IconButtonProps` | — | the badge's `variant`, `color`, `className` |
|
|
274
275
|
| `confirmText` / `cancelText` | `ReactNode` | "Confirm" / "Cancel", translated (`material.confirm-dialog.confirm` / `.cancel`) | button text |
|
|
276
|
+
| `cancelVariant` | `ButtonVariant` | `'tonal'` | the Cancel button's variant; `'outlined'` or `'ghost'` restores an earlier look |
|
|
275
277
|
|
|
276
278
|
**Several steps, one dialog.** Confirm closes it; to show the next step, change
|
|
277
279
|
its `title` (and `description`) and set `open` back to `true`, at once (from
|
|
@@ -1324,7 +1324,7 @@ Three parts, each for one job:
|
|
|
1324
1324
|
|
|
1325
1325
|
| Part | Use it for |
|
|
1326
1326
|
| --- | --- |
|
|
1327
|
-
| `AttributesField` · `AttributesFormField` | the field, and its React Hook Form wrapper. Inline by default; `editing="dialog"` keeps the list and dialog |
|
|
1327
|
+
| `AttributesField` · `AttributesFormField` | the field, and its React Hook Form wrapper. Inline by default; `editing="dialog"` keeps the list and dialog, whose Cancel button is `tonal` (`cancelVariant` restores `'outlined'`) |
|
|
1328
1328
|
| `AttributesEditor` | the same inline editor, controlled (`value`, `onValueChange`), outside a form |
|
|
1329
1329
|
| `AttributesSummary` | the read-only display: type icons, labels and default values |
|
|
1330
1330
|
|
|
@@ -1536,8 +1536,9 @@ only, and a value that fails its check is shown without a link.
|
|
|
1536
1536
|
`ContactsEditor` takes `value`, `onValueChange`, `label`, `headingLevel` (`3`
|
|
1537
1537
|
by default; the type headings sit one below it), `variant` and `disabled`. A
|
|
1538
1538
|
wrong format is said once the field was left, a duplicate at once. `ContactsFormField` takes `editing` (`'inline' \| 'dialog'`,
|
|
1539
|
-
default `'inline'`)
|
|
1540
|
-
|
|
1539
|
+
default `'inline'`), `variant` (inline only) and `cancelVariant` (dialog only,
|
|
1540
|
+
the Cancel button's `Button` variant, default `'tonal'`; `'outlined'` restores
|
|
1541
|
+
the earlier look). `Contacts` takes `data`, `onAdd`, `onEdit` and `disabled`.
|
|
1541
1542
|
|
|
1542
1543
|
`contactsListSchema()` is the zod schema of a whole list, with the editor's
|
|
1543
1544
|
own rules (the same functions): the value's format by type (an email, an
|
|
@@ -1592,6 +1593,10 @@ Parts: `PostalAddress` (the card), `PostalAddressDialog` (the edit form).
|
|
|
1592
1593
|
| `onEdit` | `() => void` | — | shows the edit button |
|
|
1593
1594
|
| `disabled` | `boolean` | — | hides it |
|
|
1594
1595
|
|
|
1596
|
+
`PostalAddressFormField` and `PostalAddressDialog` take `cancelVariant` (the
|
|
1597
|
+
dialog's Cancel button, a `Button` `variant`, default `'tonal'`; `'outlined'`
|
|
1598
|
+
restores the earlier look).
|
|
1599
|
+
|
|
1595
1600
|
**Emits:** `PostalAddressFormField` stores a `PostalAddressFieldValue`
|
|
1596
1601
|
object, and `{}` when the address is removed.
|
|
1597
1602
|
**Form wrapper:** `PostalAddressFormField` — `control` and `name`, see
|
|
@@ -1671,7 +1676,8 @@ summary shows a quiet "Hours not set" (`empty` replaces the text,
|
|
|
1671
1676
|
`OpeningHoursEditor` takes `value`, `onValueChange`, `label`, `headingLevel` (`3` by default), `weekStartsOn`,
|
|
1672
1677
|
`locale` and `disabled`. `OpeningHoursFormField` takes `editing`
|
|
1673
1678
|
(`'inline' \| 'dialog'`, default `'inline'`), `weekStartsOn` and `locale`
|
|
1674
|
-
(inline), and `showAddAllDays` (dialog, default `false`)
|
|
1679
|
+
(inline), and `showAddAllDays` (dialog, default `false`) and `cancelVariant`
|
|
1680
|
+
(dialog, the Cancel button's `Button` variant, default `'tonal'`).
|
|
1675
1681
|
|
|
1676
1682
|
`openingHoursSchema()` returns the zod schema of one `OpeningHour`
|
|
1677
1683
|
(`dayOfWeek` coerced from a string), built on the first call. It is unchanged.
|
|
@@ -429,6 +429,7 @@ after `onCrop`).
|
|
|
429
429
|
| `cropShape` | `'rect' \| 'round'` | `'rect'` | round mask for avatars |
|
|
430
430
|
| `fileName` | `string` | — | name of the produced `File` |
|
|
431
431
|
| `onCancel` | `() => void` | — | `ImageCropper`: shows a Cancel button |
|
|
432
|
+
| `cancelVariant` | `ButtonVariant` | `'tonal'` | `ImageCropper`: the Cancel button's variant; `'ghost'` restores the earlier look |
|
|
432
433
|
| `open` / `onOpenChange` / `trigger` | | — | `ImageCropperDialog`: controlled or trigger-opened |
|
|
433
434
|
|
|
434
435
|
**Storybook:** `Media & files/ImageCropper` · **Vue:** `ImageCropper`, `ImageCropperDialog`
|
|
@@ -151,7 +151,7 @@ import {
|
|
|
151
151
|
</CardHeader>
|
|
152
152
|
<CardContent>Pick a name and a framework.</CardContent>
|
|
153
153
|
<CardFooter className="justify-end gap-2">
|
|
154
|
-
<Button variant="
|
|
154
|
+
<Button variant="tonal">Cancel</Button>
|
|
155
155
|
<Button>Deploy</Button>
|
|
156
156
|
</CardFooter>
|
|
157
157
|
</Card>;
|
|
@@ -1728,7 +1728,7 @@ function Reply({ onSubmit }: { onSubmit: (html: string) => void }) {
|
|
|
1728
1728
|
mentions={['Ada', 'Grace']}
|
|
1729
1729
|
actions={
|
|
1730
1730
|
<>
|
|
1731
|
-
<Button variant="
|
|
1731
|
+
<Button variant="tonal" onClick={() => setHtml('')}>
|
|
1732
1732
|
Cancel
|
|
1733
1733
|
</Button>
|
|
1734
1734
|
<Button onClick={() => onSubmit(html)}>Reply</Button>
|
|
@@ -1965,7 +1965,7 @@ function Comment() {
|
|
|
1965
1965
|
| `editable` | `boolean` | `true` | read-only when `false` (toolbar hidden) |
|
|
1966
1966
|
| `options.features` | `RichTextEditorFeatures` | all `true` | turn off tables, images, YouTube, slash commands, custom blocks… |
|
|
1967
1967
|
| `options.mentions.suggestions` | `(string \| MentionItem)[]` | — | enables `@` mentions; a `MentionItem` (as `MentionList` / `ChatComposer` take) shows its avatar and handle in the list and inserts its `id` with its `label` as text |
|
|
1968
|
-
| `options.onSave` / `onCancel` | `() => void` | — | adds Save / Cancel buttons |
|
|
1968
|
+
| `options.onSave` / `onCancel` | `() => void` | — | adds Save / Cancel buttons; Cancel is `tonal`, `options.cancelVariant` restores `'ghost'` |
|
|
1969
1969
|
| `characterLimit` | `number` | — | caps the text and shows the count |
|
|
1970
1970
|
| `placeholder` | `string` | "Write something …" (translated, `material['rich-text-editor'].placeholder`) | shown in an empty editor; a change shows at once |
|
|
1971
1971
|
| `required` | `boolean` | — | the asterisk, and `aria-required` on the editable area |
|
|
@@ -113,3 +113,61 @@
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
/* The `badge` count: on the top end corner (logical edges, so a right-to-left
|
|
118
|
+
* page mirrors it), outside the box so the button keeps its size, and
|
|
119
|
+
* `pointer-events: none` so the 44px hit area (button.css) stays the button's.
|
|
120
|
+
* Fill and text follow `badgeTone` (primary by default; error is the menu-item badge's `bg-error` under `text-error-foreground`);
|
|
121
|
+
* a ring in the page background detaches it from the fill of any variant. It
|
|
122
|
+
* does not follow the button's hover, focus, disabled or pressed look. */
|
|
123
|
+
@layer utilities {
|
|
124
|
+
.nxgt-icon-button-badge {
|
|
125
|
+
position: absolute;
|
|
126
|
+
inset-block-start: -0.25rem;
|
|
127
|
+
inset-inline-end: -0.25rem;
|
|
128
|
+
box-sizing: border-box;
|
|
129
|
+
display: inline-flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
block-size: 1rem;
|
|
133
|
+
min-inline-size: 1rem;
|
|
134
|
+
padding-inline: 0.25rem;
|
|
135
|
+
border-radius: 9999px;
|
|
136
|
+
/* The text-safe primary (AA on the page, light and dark) under the page
|
|
137
|
+
* colour: the plain fill is 2.7:1 against the dark page's ring. */
|
|
138
|
+
background: var(--color-primary-text);
|
|
139
|
+
color: var(--color-background);
|
|
140
|
+
box-shadow: 0 0 0 2px var(--color-background);
|
|
141
|
+
font-size: 10px;
|
|
142
|
+
font-weight: 500;
|
|
143
|
+
line-height: 1;
|
|
144
|
+
font-variant-numeric: tabular-nums;
|
|
145
|
+
white-space: nowrap;
|
|
146
|
+
pointer-events: none;
|
|
147
|
+
z-index: 1;
|
|
148
|
+
}
|
|
149
|
+
.nxgt-icon-button-badge[data-tone="error"] {
|
|
150
|
+
background: var(--color-error);
|
|
151
|
+
color: var(--color-error-foreground);
|
|
152
|
+
}
|
|
153
|
+
.nxgt-icon-button-badge[data-tone="neutral"] {
|
|
154
|
+
background: var(--color-foreground);
|
|
155
|
+
color: var(--color-background);
|
|
156
|
+
}
|
|
157
|
+
/* The 24px button: a smaller badge, further out, so it leaves the icon. */
|
|
158
|
+
[data-size="xs"] > .nxgt-icon-button-badge {
|
|
159
|
+
block-size: 0.875rem;
|
|
160
|
+
min-inline-size: 0.875rem;
|
|
161
|
+
padding-inline: 0.1875rem;
|
|
162
|
+
inset-block-start: -0.4375rem;
|
|
163
|
+
inset-inline-end: -0.4375rem;
|
|
164
|
+
}
|
|
165
|
+
@media (forced-colors: active) {
|
|
166
|
+
.nxgt-icon-button-badge {
|
|
167
|
+
border: 1px solid CanvasText;
|
|
168
|
+
background: Highlight;
|
|
169
|
+
color: HighlightText;
|
|
170
|
+
forced-color-adjust: none;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|