@nxgt/material 2.16.0 → 2.18.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 +96 -0
- package/README.md +9 -4
- package/dist/{_Uint8Array-CjLUgWgf.js → _Uint8Array-C7apDrb7.js} +1 -1
- package/dist/{_overRest-HfSwfmH1.js → _overRest-CCAbV-eT.js} +1 -1
- package/dist/async-slice-Cuekts5f.js +459 -0
- package/dist/{blockDiagram-BEXU5L5S-DSNWJcbS.js → blockDiagram-BEXU5L5S-B63zbmDg.js} +2 -2
- package/dist/{chunk-3FUC2YCW-CcZvlyvW.js → chunk-3FUC2YCW-CE9T5wr6.js} +2 -2
- package/dist/{chunk-7M6MHVWA-21OdxoBq.js → chunk-7M6MHVWA-BjaezAbj.js} +1 -1
- package/dist/{chunk-GNY47TPC-BZdgq2LF.js → chunk-GNY47TPC-DjnciAsL.js} +4 -4
- package/dist/{chunk-NETBCI7D-CAgvlb0w.js → chunk-NETBCI7D-CxQxB74H.js} +1 -1
- package/dist/{chunk-Z7XXMR3K-BSXPgLtN.js → chunk-Z7XXMR3K-BBrCUBwp.js} +1 -1
- package/dist/{classDiagram-v2-NBCMYWYE-D_BHO1iT.js → classDiagram-v2-NBCMYWYE-FeyVcYCs.js} +2 -2
- package/dist/components/components.css +1 -0
- package/dist/components/print-only.css +44 -0
- package/dist/{components-Bkdm6jn6.js → components-CsPEBzNF.js} +59383 -58881
- package/dist/components.js +6 -6
- package/dist/{dagre-6A5THRUB-CsnftAPx.js → dagre-6A5THRUB-BjO_Ytfq.js} +64 -64
- package/dist/{diagram-22UHCM2B-D0yPa8vo.js → diagram-22UHCM2B-BBKawlhX.js} +2 -2
- package/dist/{diagram-3UASUU5V-f8LIX2sj.js → diagram-3UASUU5V-CKj_37_k.js} +1 -1
- package/dist/dnd.js +1 -1
- package/dist/{elk-276RUBZZ-DI8bDQAL.js → elk-276RUBZZ-DmkPwZLS.js} +3 -3
- package/dist/{erDiagram-OPXOYQCR-BGHFtxmB.js → erDiagram-OPXOYQCR-Dja943M3.js} +2 -2
- package/dist/{field-blur-C-5K6U1F.js → field-blur-DNHXOY0J.js} +3 -3
- package/dist/{flowDiagram-KWPJA3E3-CnFLTW-3.js → flowDiagram-KWPJA3E3-jmbjSQZS.js} +3 -3
- package/dist/{ganttDiagram-FUAMR5RP-B5uyVKE4.js → ganttDiagram-FUAMR5RP-BONNpqJt.js} +1 -1
- package/dist/{graphlib-BqO9Go2u.js → graphlib-DxjKaXeR.js} +42 -42
- package/dist/hooks.js +38 -26
- package/dist/{i18n-provider-C3SlA4J0.js → i18n-provider-Dv9ZSmgO.js} +1 -1
- package/dist/i18n.js +6 -6
- package/dist/{isArrayLikeObject-83P1fvEs.js → isArrayLikeObject-H8k6W51O.js} +3 -3
- package/dist/{isEmpty-C2z3Hypl.js → isEmpty-B0Bavg-e.js} +9 -9
- package/dist/{journeyDiagram-ZHPQQLJL-CKtbGcVT.js → journeyDiagram-ZHPQQLJL-C_omtnEz.js} +1 -1
- package/dist/lib/components/ui/actions/copy-button/use-copy-status.d.ts +13 -0
- package/dist/lib/components/ui/display/enrolment-secret/enrolment-secret.d.ts +30 -0
- package/dist/lib/components/ui/display/enrolment-secret/index.d.ts +2 -0
- package/dist/lib/components/ui/display/enrolment-secret/use-enrolment-secret-labels.d.ts +11 -0
- package/dist/lib/components/ui/display/index.d.ts +2 -0
- package/dist/lib/components/ui/display/recovery-codes/index.d.ts +4 -0
- package/dist/lib/components/ui/display/recovery-codes/partials/recovery-codes-actions.d.ts +14 -0
- package/dist/lib/components/ui/display/recovery-codes/partials/recovery-codes-confirm.d.ts +13 -0
- package/dist/lib/components/ui/display/recovery-codes/partials/recovery-codes-list.d.ts +5 -0
- package/dist/lib/components/ui/display/recovery-codes/recovery-codes.d.ts +8 -0
- package/dist/lib/components/ui/display/recovery-codes/types.d.ts +64 -0
- package/dist/lib/components/ui/display/recovery-codes/use-recovery-codes-labels.d.ts +7 -0
- package/dist/lib/components/ui/fields/form-section/form-section-classes.d.ts +30 -0
- package/dist/lib/components/ui/fields/form-section/form-section.d.ts +25 -0
- package/dist/lib/components/ui/fields/form-section/index.d.ts +1 -0
- package/dist/lib/components/ui/fields/index.d.ts +1 -0
- package/dist/lib/components/ui/forms/index.d.ts +1 -0
- package/dist/lib/components/ui/forms/use-code-resolver.d.ts +42 -0
- package/dist/lib/components/ui/layout/auth-card/auth-card-notice.d.ts +18 -0
- package/dist/lib/components/ui/layout/auth-card/auth-card.d.ts +35 -0
- package/dist/lib/components/ui/layout/auth-card/index.d.ts +1 -0
- package/dist/lib/components/ui/layout/index.d.ts +1 -0
- package/dist/lib/components/ui/selection/autocomplete/types.d.ts +9 -1
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-status.d.ts +2 -2
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete.d.ts +2 -2
- package/dist/lib/hooks/index.d.ts +2 -0
- package/dist/lib/hooks/use-focus-on-mount.d.ts +24 -0
- package/dist/lib/hooks/use-submit-once.d.ts +32 -0
- package/dist/lib/i18n/resources/en/en.d.ts +21 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +21 -0
- package/dist/lib/i18n/resources/fr/fr.d.ts +21 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +21 -0
- package/dist/lib/i18n/resources/resources.d.ts +42 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib/lib/index.d.ts +1 -0
- package/dist/lib.js +58 -102
- package/dist/main.js +16 -16
- package/dist/map.js +22 -22
- package/dist/material.css +1 -1
- package/dist/{merge-CZIEHTTe.js → merge-Js8537dg.js} +4 -4
- package/dist/{mermaid.core-Cp75fWA9.js → mermaid.core-9dpDfc6Y.js} +21 -21
- package/dist/{mindmap-definition-NLK3R4M7-CFYIlEfW.js → mindmap-definition-NLK3R4M7-CjYayluH.js} +2 -2
- package/dist/{pieDiagram-5QR66LMP-CjvtBYDr.js → pieDiagram-5QR66LMP-BfFcf84S.js} +1 -1
- package/dist/print.js +2 -2
- package/dist/{quadrantDiagram-O4NWA36T-DPj8ndqA.js → quadrantDiagram-O4NWA36T-DdvYjvR0.js} +1 -1
- package/dist/{requirementDiagram-PLB6GJNP-DjVFwRJg.js → requirementDiagram-PLB6GJNP-CGG6Y3SN.js} +2 -2
- package/dist/{sankeyDiagram-IPEJSGJF-63wsgHUY.js → sankeyDiagram-IPEJSGJF-DJufZkAf.js} +1 -1
- package/dist/{sortable-provider-Chbn1x1i.js → sortable-provider-CUT5Wfdl.js} +1 -1
- package/dist/{stateDiagram-v2-GCMORJYK-DNc8m371.js → stateDiagram-v2-GCMORJYK-vRvpKK9I.js} +2 -2
- package/dist/{stored-language-DPqzxRmf.js → stored-language-BKoohv2_.js} +42 -0
- package/dist/{swimlanes-2SLR337P-B7_gOJxx.js → swimlanes-2SLR337P-Czy9f6gp.js} +3 -3
- package/dist/{swimlanesDiagram-TC7HE7FX-tqlBrGuu.js → swimlanesDiagram-TC7HE7FX-C6RYBQ-A.js} +3 -3
- package/dist/{timeline-definition-EJHVYXUP-DIA9CBZK.js → timeline-definition-EJHVYXUP-CS9RiAiW.js} +1 -1
- package/dist/{translate-material-CqB-j9WD.js → translate-material-CCJg3yfc.js} +2 -2
- package/dist/{translator-DTl9h__E.js → translator-DEde7BKz.js} +1 -1
- package/dist/{use-heading-spy-C1KA3PrF.js → use-heading-spy-XkSExwoT.js} +67 -59
- package/dist/{use-material-translation-DMa4Xrnd.js → use-material-translation-Cndoq_iK.js} +2 -2
- package/dist/{usecaseDiagram-POWQR4AR-FMjCkoxs.js → usecaseDiagram-POWQR4AR-CW-8YHgN.js} +2 -2
- package/dist/{xychartDiagram-PMCCYNJV-B76HOkCh.js → xychartDiagram-PMCCYNJV-G4PopeeF.js} +1 -1
- package/docs/components/README.md +3 -3
- package/docs/components/data-display.md +101 -0
- package/docs/components/feedback-and-status.md +2 -0
- package/docs/components/form-fields.md +78 -0
- package/docs/components/navigation-and-layout.md +51 -0
- package/docs/components/overlays-and-menus.md +18 -0
- package/docs/components/selection-and-choice.md +11 -3
- package/docs/guides/forms.md +111 -0
- package/docs/guides/helpers.md +81 -0
- package/docs/guides/i18n.md +17 -0
- package/docs/guides/printing.md +27 -0
- package/docs/previews/data-display-enrolmentsecret.webp +0 -0
- package/docs/previews/data-display-recoverycodes.webp +0 -0
- package/docs/previews/form-fields-formsection.webp +0 -0
- package/docs/previews/navigation-layout-authcard.webp +0 -0
- package/docs/roadmap.md +15 -0
- package/docs/troubleshooting.md +141 -0
- package/lib/components/components.css +1 -0
- package/lib/components/print-only.css +44 -0
- package/package.json +2 -2
- package/dist/async-slice-CsE3hkCD.js +0 -411
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { n as e } from "./stored-language-
|
|
2
|
-
import { r as t } from "./i18n-provider-
|
|
1
|
+
import { n as e } from "./stored-language-BKoohv2_.js";
|
|
2
|
+
import { r as t } from "./i18n-provider-Dv9ZSmgO.js";
|
|
3
3
|
import { _ as n, g as r, h as i, n as a, v as o, y as s } from "./number.utils-BiBN2hWJ.js";
|
|
4
|
-
import { createContext as c, useCallback as l, useContext as u, useEffect as d, useMemo as f,
|
|
4
|
+
import { createContext as c, useCallback as l, useContext as u, useEffect as d, useMemo as f, useRef as p, useSyncExternalStore as m } from "react";
|
|
5
5
|
//#region lib/hooks/resolve-theme.ts
|
|
6
|
-
function
|
|
6
|
+
function h(e, t) {
|
|
7
7
|
let n = e === "light" || e === "dark" ? e : "system";
|
|
8
8
|
return {
|
|
9
9
|
theme: n === "system" ? t ? "dark" : "light" : n,
|
|
10
10
|
preference: n
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function g(e) {
|
|
14
14
|
typeof document > "u" || (document.documentElement.classList.toggle("dark", e === "dark"), document.documentElement.style.colorScheme = e);
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region lib/hooks/theme-store.ts
|
|
18
|
-
var
|
|
19
|
-
function
|
|
20
|
-
let t = e(
|
|
21
|
-
if (t == null) return
|
|
18
|
+
var _ = "theme", v = /* @__PURE__ */ new Set(), y;
|
|
19
|
+
function b() {
|
|
20
|
+
let t = e(_);
|
|
21
|
+
if (t == null) return y;
|
|
22
22
|
try {
|
|
23
23
|
let e = JSON.parse(t);
|
|
24
24
|
return typeof e == "string" ? e : void 0;
|
|
@@ -26,63 +26,63 @@ function y() {
|
|
|
26
26
|
return t;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
for (let e of
|
|
29
|
+
function x() {
|
|
30
|
+
for (let e of v) e();
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
(e.key ===
|
|
32
|
+
function S(e) {
|
|
33
|
+
(e.key === _ || e.key === null) && x();
|
|
34
34
|
}
|
|
35
|
-
var
|
|
35
|
+
var C = {
|
|
36
36
|
subscribe(e) {
|
|
37
|
-
return
|
|
38
|
-
|
|
37
|
+
return v.add(e), v.size === 1 && typeof window < "u" && window.addEventListener("storage", S), () => {
|
|
38
|
+
v.delete(e), v.size === 0 && typeof window < "u" && window.removeEventListener("storage", S);
|
|
39
39
|
};
|
|
40
40
|
},
|
|
41
|
-
getSnapshot:
|
|
41
|
+
getSnapshot: b,
|
|
42
42
|
getServerSnapshot: () => void 0,
|
|
43
43
|
set(e) {
|
|
44
|
-
|
|
44
|
+
y = e === "system" ? void 0 : e;
|
|
45
45
|
try {
|
|
46
|
-
e === "system" ? globalThis.localStorage?.removeItem(
|
|
46
|
+
e === "system" ? globalThis.localStorage?.removeItem(_) : globalThis.localStorage?.setItem(_, JSON.stringify(e));
|
|
47
47
|
} catch {}
|
|
48
|
-
|
|
48
|
+
x();
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
//#endregion
|
|
52
52
|
//#region lib/hooks/use-ssr-media-query.ts
|
|
53
|
-
function
|
|
54
|
-
return
|
|
53
|
+
function w(e, t) {
|
|
54
|
+
return m(l((t) => {
|
|
55
55
|
let n = window.matchMedia(e);
|
|
56
56
|
return n.addEventListener("change", t), () => n.removeEventListener("change", t);
|
|
57
57
|
}, [e]), () => window.matchMedia(e).matches, () => t);
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
60
|
//#region lib/hooks/use-theme.ts
|
|
61
|
-
function
|
|
62
|
-
let e =
|
|
61
|
+
function T() {
|
|
62
|
+
let e = w("(prefers-color-scheme: dark)", !1), { theme: t, preference: n } = h(m(C.subscribe, C.getSnapshot, C.getServerSnapshot), e);
|
|
63
63
|
return {
|
|
64
64
|
theme: t,
|
|
65
65
|
preference: n,
|
|
66
66
|
updateTheme: l((t) => {
|
|
67
|
-
|
|
67
|
+
C.set(t), g(h(t === "system" ? void 0 : t, e).theme);
|
|
68
68
|
}, [e])
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
//#endregion
|
|
72
72
|
//#region lib/hooks/use-csp-nonce.ts
|
|
73
|
-
var
|
|
74
|
-
function
|
|
75
|
-
return u(
|
|
73
|
+
var E = c(void 0), D = c(0);
|
|
74
|
+
function O() {
|
|
75
|
+
return u(E);
|
|
76
76
|
}
|
|
77
77
|
//#endregion
|
|
78
78
|
//#region lib/hooks/use-mobile.ts
|
|
79
|
-
var
|
|
80
|
-
function
|
|
81
|
-
return
|
|
79
|
+
var k = 768;
|
|
80
|
+
function A() {
|
|
81
|
+
return w(`(max-width: ${k - 1}px)`, !1);
|
|
82
82
|
}
|
|
83
83
|
//#endregion
|
|
84
84
|
//#region ../../node_modules/date-fns/locale/fr/_lib/formatDistance.js
|
|
85
|
-
var
|
|
85
|
+
var j = {
|
|
86
86
|
lessThanXSeconds: {
|
|
87
87
|
one: "moins d’une seconde",
|
|
88
88
|
other: "moins de {{count}} secondes"
|
|
@@ -144,10 +144,10 @@ var A = {
|
|
|
144
144
|
one: "presqu’un an",
|
|
145
145
|
other: "presque {{count}} ans"
|
|
146
146
|
}
|
|
147
|
-
},
|
|
148
|
-
let r, i =
|
|
147
|
+
}, M = (e, t, n) => {
|
|
148
|
+
let r, i = j[e];
|
|
149
149
|
return r = typeof i == "string" ? i : t === 1 ? i.one : i.other.replace("{{count}}", String(t)), n?.addSuffix ? n.comparison && n.comparison > 0 ? "dans " + r : "il y a " + r : r;
|
|
150
|
-
},
|
|
150
|
+
}, N = {
|
|
151
151
|
date: s({
|
|
152
152
|
formats: {
|
|
153
153
|
full: "EEEE d MMMM y",
|
|
@@ -175,18 +175,18 @@ var A = {
|
|
|
175
175
|
},
|
|
176
176
|
defaultWidth: "full"
|
|
177
177
|
})
|
|
178
|
-
},
|
|
178
|
+
}, P = {
|
|
179
179
|
lastWeek: "eeee 'dernier à' p",
|
|
180
180
|
yesterday: "'hier à' p",
|
|
181
181
|
today: "'aujourd’hui à' p",
|
|
182
182
|
tomorrow: "'demain à' p'",
|
|
183
183
|
nextWeek: "eeee 'prochain à' p",
|
|
184
184
|
other: "P"
|
|
185
|
-
},
|
|
185
|
+
}, F = (e, t, n, r) => P[e], I = {
|
|
186
186
|
narrow: ["av. J.-C", "ap. J.-C"],
|
|
187
187
|
abbreviated: ["av. J.-C", "ap. J.-C"],
|
|
188
188
|
wide: ["avant Jésus-Christ", "après Jésus-Christ"]
|
|
189
|
-
},
|
|
189
|
+
}, L = {
|
|
190
190
|
narrow: [
|
|
191
191
|
"T1",
|
|
192
192
|
"T2",
|
|
@@ -205,7 +205,7 @@ var A = {
|
|
|
205
205
|
"3ème trimestre",
|
|
206
206
|
"4ème trimestre"
|
|
207
207
|
]
|
|
208
|
-
},
|
|
208
|
+
}, R = {
|
|
209
209
|
narrow: [
|
|
210
210
|
"J",
|
|
211
211
|
"F",
|
|
@@ -248,7 +248,7 @@ var A = {
|
|
|
248
248
|
"novembre",
|
|
249
249
|
"décembre"
|
|
250
250
|
]
|
|
251
|
-
},
|
|
251
|
+
}, z = {
|
|
252
252
|
narrow: [
|
|
253
253
|
"D",
|
|
254
254
|
"L",
|
|
@@ -285,7 +285,7 @@ var A = {
|
|
|
285
285
|
"vendredi",
|
|
286
286
|
"samedi"
|
|
287
287
|
]
|
|
288
|
-
},
|
|
288
|
+
}, B = {
|
|
289
289
|
narrow: {
|
|
290
290
|
am: "AM",
|
|
291
291
|
pm: "PM",
|
|
@@ -316,7 +316,7 @@ var A = {
|
|
|
316
316
|
evening: "du soir",
|
|
317
317
|
night: "du matin"
|
|
318
318
|
}
|
|
319
|
-
},
|
|
319
|
+
}, V = (e, t) => {
|
|
320
320
|
let n = Number(e), r = t?.unit;
|
|
321
321
|
if (n === 0) return "0";
|
|
322
322
|
let i = [
|
|
@@ -327,38 +327,38 @@ var A = {
|
|
|
327
327
|
"second"
|
|
328
328
|
], a;
|
|
329
329
|
return a = n === 1 ? r && i.includes(r) ? "ère" : "er" : "ème", n + a;
|
|
330
|
-
},
|
|
330
|
+
}, H = ["MMM", "MMMM"], U = {
|
|
331
331
|
en: i,
|
|
332
332
|
fr: {
|
|
333
333
|
code: "fr",
|
|
334
|
-
formatDistance:
|
|
335
|
-
formatLong:
|
|
336
|
-
formatRelative:
|
|
334
|
+
formatDistance: M,
|
|
335
|
+
formatLong: N,
|
|
336
|
+
formatRelative: F,
|
|
337
337
|
localize: {
|
|
338
|
-
preprocessor: (e, t) => e.getDate() === 1 || !t.some((e) => e.isToken &&
|
|
338
|
+
preprocessor: (e, t) => e.getDate() === 1 || !t.some((e) => e.isToken && H.includes(e.value)) ? t : t.map((e) => e.isToken && e.value === "do" ? {
|
|
339
339
|
isToken: !0,
|
|
340
340
|
value: "d"
|
|
341
341
|
} : e),
|
|
342
|
-
ordinalNumber:
|
|
342
|
+
ordinalNumber: V,
|
|
343
343
|
era: o({
|
|
344
|
-
values:
|
|
344
|
+
values: I,
|
|
345
345
|
defaultWidth: "wide"
|
|
346
346
|
}),
|
|
347
347
|
quarter: o({
|
|
348
|
-
values:
|
|
348
|
+
values: L,
|
|
349
349
|
defaultWidth: "wide",
|
|
350
350
|
argumentCallback: (e) => e - 1
|
|
351
351
|
}),
|
|
352
352
|
month: o({
|
|
353
|
-
values:
|
|
353
|
+
values: R,
|
|
354
354
|
defaultWidth: "wide"
|
|
355
355
|
}),
|
|
356
356
|
day: o({
|
|
357
|
-
values:
|
|
357
|
+
values: z,
|
|
358
358
|
defaultWidth: "wide"
|
|
359
359
|
}),
|
|
360
360
|
dayPeriod: o({
|
|
361
|
-
values:
|
|
361
|
+
values: B,
|
|
362
362
|
defaultWidth: "wide"
|
|
363
363
|
})
|
|
364
364
|
},
|
|
@@ -488,8 +488,8 @@ var A = {
|
|
|
488
488
|
}
|
|
489
489
|
}
|
|
490
490
|
};
|
|
491
|
-
function
|
|
492
|
-
let e = t()?.language ?? "en", n = f(() =>
|
|
491
|
+
function W() {
|
|
492
|
+
let e = t()?.language ?? "en", n = f(() => U[e] ?? i, [e]);
|
|
493
493
|
return {
|
|
494
494
|
language: e,
|
|
495
495
|
locale: n,
|
|
@@ -497,10 +497,18 @@ function U() {
|
|
|
497
497
|
};
|
|
498
498
|
}
|
|
499
499
|
//#endregion
|
|
500
|
+
//#region lib/hooks/use-focus-on-mount.ts
|
|
501
|
+
function G(e = !0) {
|
|
502
|
+
let t = p(null);
|
|
503
|
+
return d(() => {
|
|
504
|
+
e && t.current?.focus();
|
|
505
|
+
}, [e]), t;
|
|
506
|
+
}
|
|
507
|
+
//#endregion
|
|
500
508
|
//#region lib/hooks/use-heading-spy.ts
|
|
501
|
-
var
|
|
502
|
-
function
|
|
503
|
-
let r = n?.rootMargin ??
|
|
509
|
+
var K = "0px 0px -65% 0px", q = [0, 1];
|
|
510
|
+
function J(e, t, n) {
|
|
511
|
+
let r = n?.rootMargin ?? K, i = n?.threshold ?? q;
|
|
504
512
|
d(() => {
|
|
505
513
|
if (e.length === 0) return;
|
|
506
514
|
let n = e.map((e) => document.getElementById(e)).filter((e) => e != null);
|
|
@@ -522,4 +530,4 @@ function K(e, t, n) {
|
|
|
522
530
|
]);
|
|
523
531
|
}
|
|
524
532
|
//#endregion
|
|
525
|
-
export { E as a,
|
|
533
|
+
export { E as a, T as c, h as d, A as i, w as l, G as n, D as o, W as r, O as s, J as t, g as u };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as e } from "./i18n-provider-
|
|
2
|
-
import { t } from "./translate-material-
|
|
1
|
+
import { r as e } from "./i18n-provider-Dv9ZSmgO.js";
|
|
2
|
+
import { t } from "./translate-material-CCJg3yfc.js";
|
|
3
3
|
import { useCallback as n } from "react";
|
|
4
4
|
//#region lib/i18n/use-material-translation.ts
|
|
5
5
|
function r() {
|
|
@@ -8,11 +8,11 @@ import "./chunk-7PRAP22T-0C6_H8Li.js";
|
|
|
8
8
|
import { a as g, i as _, o as v, r as y } from "./chunk-J5ZVWO5B-DmRRmhon.js";
|
|
9
9
|
import "./chunk-7INBJB4K-k-I67NSP.js";
|
|
10
10
|
import "./chunk-5DYCD2WN-Cd1zazNp.js";
|
|
11
|
-
import "./chunk-Z7XXMR3K-
|
|
11
|
+
import "./chunk-Z7XXMR3K-BBrCUBwp.js";
|
|
12
12
|
import { t as ee } from "./chunk-XXDRQBXY-dKXxu_aj.js";
|
|
13
13
|
import { t as te } from "./chunk-WEXAMYUT-CbFOhEve.js";
|
|
14
14
|
import "./chunk-UA2S7LBM-ChuksCDg.js";
|
|
15
|
-
import { r as ne, t as re } from "./chunk-GNY47TPC-
|
|
15
|
+
import { r as ne, t as re } from "./chunk-GNY47TPC-DjnciAsL.js";
|
|
16
16
|
//#region ../../node_modules/chevrotain/node_modules/lodash-es/_freeGlobal.js
|
|
17
17
|
var ie = typeof global == "object" && global && global.Object === Object && global, ae = typeof self == "object" && self && self.Object === Object && self, b = ie || ae || Function("return this")(), oe = b.Symbol, se = Object.prototype, ce = se.hasOwnProperty, le = se.toString, ue = oe ? oe.toStringTag : void 0;
|
|
18
18
|
function de(e) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { at as e, rt as t, st as n } from "./components-
|
|
1
|
+
import { at as e, rt as t, st as n } from "./components-CsPEBzNF.js";
|
|
2
2
|
import { n as r } from "./src-CsLQInsN.js";
|
|
3
3
|
import { i } from "./chunk-ZIGJFQKS-9VXArDKF.js";
|
|
4
4
|
import { n as a } from "./chunk-Y2CYZVJY-BAad7w_K.js";
|
|
@@ -26,7 +26,7 @@ Anything you press that is not a field: buttons, link buttons, copy, load more,
|
|
|
26
26
|
|
|
27
27
|
## [Form fields](form-fields.md)
|
|
28
28
|
|
|
29
|
-
Labelled inputs with a value, each with its form-library wrapper, and the composite values (attributes, contacts, address, opening hours).
|
|
29
|
+
Labelled inputs with a value, each with its form-library wrapper, and the composite values (attributes, contacts, address, opening hours), and the titled sections a long form is laid out in. 25 entries.
|
|
30
30
|
|
|
31
31
|
[<img src="../previews/form-fields-textfield.webp" height="72" alt="TextField">](form-fields.md#textfield)
|
|
32
32
|
[<img src="../previews/form-fields-phonefield.webp" height="72" alt="PhoneField">](form-fields.md#phonefield)
|
|
@@ -53,7 +53,7 @@ Picking among options: select, combobox, autocomplete, checkbox, radio, card and
|
|
|
53
53
|
|
|
54
54
|
## [Data display](data-display.md)
|
|
55
55
|
|
|
56
|
-
Read-only presentation: avatar, badge, chip, stat and metric cards, card presets, list tile, timeline, code, markdown, terminal, API docs blocks, QR and barcode.
|
|
56
|
+
Read-only presentation: avatar, badge, chip, stat and metric cards, card presets, list tile, timeline, code, markdown, terminal, API docs blocks, QR and barcode, two-step verification (enrolment secret, recovery codes). 26 entries.
|
|
57
57
|
|
|
58
58
|
[<img src="../previews/data-display-avatar.webp" height="72" alt="Avatar">](data-display.md#avatar)
|
|
59
59
|
[<img src="../previews/data-display-statcard.webp" height="72" alt="StatCard">](data-display.md#statcard)
|
|
@@ -71,7 +71,7 @@ Collections you query: data table, filter, pagination, tree, drag and drop. 6 en
|
|
|
71
71
|
|
|
72
72
|
## [Navigation & layout](navigation-and-layout.md)
|
|
73
73
|
|
|
74
|
-
Where a page sits and how you move: app shell, sidebar, app bars, breadcrumb, page layouts, grid, resizable, skip link, pager, TOC, steppers, hero, doc site shell.
|
|
74
|
+
Where a page sits and how you move: app shell, sidebar, app bars, breadcrumb, page layouts, grid, resizable, skip link, pager, TOC, steppers, hero, doc site shell, signed-out page frame. 18 entries.
|
|
75
75
|
|
|
76
76
|
[<img src="../previews/navigation-layout-appshell.webp" height="72" alt="ActivityLayout">](navigation-and-layout.md#activitylayout)
|
|
77
77
|
[<img src="../previews/navigation-layout-sidebar.webp" height="72" alt="Sidebar">](navigation-and-layout.md#sidebar)
|
|
@@ -30,6 +30,8 @@ from `@nxgt/material/components`.
|
|
|
30
30
|
| <img src="../previews/data-display-paramtable.webp" width="96" alt=""> | [ParamTable](#paramtable) | Name / type / default / description table |
|
|
31
31
|
| <img src="../previews/data-display-qrcode.webp" width="96" alt=""> | [QRCode](#qrcode) | QR code on a padded tile |
|
|
32
32
|
| <img src="../previews/data-display-barecode.webp" width="96" alt=""> | [Barecode](#barecode) | 1D barcode |
|
|
33
|
+
| <img src="../previews/data-display-enrolmentsecret.webp" width="96" alt=""> | [EnrolmentSecret](#enrolmentsecret) | A TOTP enrolment: QR code, app link, the key grouped by four |
|
|
34
|
+
| <img src="../previews/data-display-recoverycodes.webp" width="96" alt=""> | [RecoveryCodes](#recoverycodes) | One-time recovery codes: copy, download, print, confirm |
|
|
33
35
|
|
|
34
36
|
## Avatar
|
|
35
37
|
|
|
@@ -703,3 +705,102 @@ The props are those of `react-barcode`. The barcode sits in an
|
|
|
703
705
|
not that span.
|
|
704
706
|
|
|
705
707
|
**Storybook:** `Data display/Barecode` · **Vue:** `Barecode`
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
## EnrolmentSecret
|
|
712
|
+
|
|
713
|
+

|
|
714
|
+
|
|
715
|
+
A TOTP enrolment (two-step verification): the QR code of the `otpauth://` URI, the URI as a link — a phone cannot scan its own screen, and an authenticator app on it opens the link — and the secret in groups of four, to type or copy.
|
|
716
|
+
|
|
717
|
+
```tsx
|
|
718
|
+
import { EnrolmentSecret } from '@nxgt/material/components';
|
|
719
|
+
|
|
720
|
+
<EnrolmentSecret
|
|
721
|
+
uri="otpauth://totp/Acme:ada%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=Acme"
|
|
722
|
+
secret="JBSWY3DPEHPK3PXP"
|
|
723
|
+
/>
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
| Prop | Type | Default | Effect |
|
|
727
|
+
| --- | --- | --- | --- |
|
|
728
|
+
| `uri` | `string` | — | the QR code's content and the link's `href`; the link renders only when it starts with `otpauth:` |
|
|
729
|
+
| `secret` | `string` | — | shown as `JBSW Y3DP EHPK 3PXP`; the copy button copies it without spaces |
|
|
730
|
+
| `showQrCode` | `boolean` | `true` | `false`: the link and the key alone |
|
|
731
|
+
| `qrSize` | `number` | `192` | the QR code's size in pixels (it shrinks to fit a narrower box) |
|
|
732
|
+
| `qrLabel`, `openAppLabel`, `manualLabel`, `secretLabel`, `copyLabel`, `copiedLabel` | `string` | translated | the QR code's name, the link, the line before the key, the key's group name, the copy button's name, what it announces |
|
|
733
|
+
|
|
734
|
+
The QR code sits beside the rest once the component is 28rem wide (a
|
|
735
|
+
container query), above it on a phone. The key is a `<code>` in a
|
|
736
|
+
`fieldset` named "Setup key" (a group may be named, a `code` element may
|
|
737
|
+
not) beside a `CopyButton`, which announces "Key copied" in a polite status
|
|
738
|
+
region; it wraps at the group boundaries, never past the card's edge.
|
|
739
|
+
`groupSecret(secret, size?)` (from `@nxgt/material-core/two-factor`) is
|
|
740
|
+
re-exported for a layout of your own.
|
|
741
|
+
|
|
742
|
+
**Storybook:** `Data display/EnrolmentSecret` · **Vue:** `EnrolmentSecret`
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## RecoveryCodes
|
|
747
|
+
|
|
748
|
+

|
|
749
|
+
|
|
750
|
+
One-time recovery codes, shown once: read as a list, copied, downloaded as a text file, printed (the card alone), and an "I have saved these codes" confirmation before "Done".
|
|
751
|
+
|
|
752
|
+
```tsx
|
|
753
|
+
import { RecoveryCodes } from '@nxgt/material/components';
|
|
754
|
+
|
|
755
|
+
<RecoveryCodes
|
|
756
|
+
codes={codes}
|
|
757
|
+
description="Use one of them to sign in if you lose your phone."
|
|
758
|
+
fileHeading={`Recovery codes for ${email}`}
|
|
759
|
+
saved={saved}
|
|
760
|
+
onSavedChange={setSaved}
|
|
761
|
+
onDone={() => navigate('/settings/security')}
|
|
762
|
+
/>
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
| Prop | Type | Default | Effect |
|
|
766
|
+
| --- | --- | --- | --- |
|
|
767
|
+
| `codes` | `readonly string[]` | — | an ordered list named "Recovery codes" |
|
|
768
|
+
| `title`, `titleAs` | `ReactNode`, `'h2' \| 'h3' \| 'h4'` | "Recovery codes", `'h2'` | the card's heading |
|
|
769
|
+
| `description` | `ReactNode` | — | a line under it |
|
|
770
|
+
| `warning` | `ReactNode \| false` | "Each code works once…" | an `Alert` above the codes, not printed; `false` hides it |
|
|
771
|
+
| `focusTitle` | `boolean` | `true` | the heading takes the focus once shown: the codes replaced what the user acted on |
|
|
772
|
+
| `fileName`, `fileHeading`, `fileNote` | `string` | `"recovery-codes.txt"`, the title, the warning | the downloaded file and its first two lines |
|
|
773
|
+
| `onDone` | `() => void` | — | shows "Done", which calls it once the confirmation is ticked |
|
|
774
|
+
| `saved` / `onSavedChange` | `boolean` / `(saved) => void` | uncontrolled | the confirmation |
|
|
775
|
+
| `labels` | `Partial<RecoveryCodesLabels>` | translated | `list`, `copy`, `copied`, `copyFailed`, `download`, `print`, `saved`, `savedRequired`, `done` |
|
|
776
|
+
|
|
777
|
+
- **Copy** puts the codes on the clipboard one per line; "Codes copied" (or
|
|
778
|
+
"Copy failed") is announced by the component's own polite status region,
|
|
779
|
+
so it needs no `Toaster`.
|
|
780
|
+
- **Download** saves `recoveryCodesText(codes, { heading, note })` with
|
|
781
|
+
`downloadText` (both re-exported from `@nxgt/material-core/two-factor`).
|
|
782
|
+
- **Print** prints the card and nothing else, with no inline style and no new
|
|
783
|
+
window: `printOnly` (`@nxgt/material/lib`) marks `<html data-nxgt-print>` and the card
|
|
784
|
+
while the dialog is open, and the rules in `styles.css` hide the rest of the page in
|
|
785
|
+
print. The buttons, the confirmation and the warning are not printed.
|
|
786
|
+
- **Done** before the box is ticked moves the focus to the box, marks it
|
|
787
|
+
`aria-invalid` and says "Tick the box once your codes are safe" under it.
|
|
788
|
+
|
|
789
|
+
Leaving the page before the codes are saved is the app's to guard, with its
|
|
790
|
+
router: block the navigation while `saved` is false, and ask the browser
|
|
791
|
+
too:
|
|
792
|
+
|
|
793
|
+
```tsx
|
|
794
|
+
const [saved, setSaved] = useState(false);
|
|
795
|
+
useBlocker(() => !saved); // React Router: confirm, then blocker.proceed()
|
|
796
|
+
useEffect(() => {
|
|
797
|
+
if (saved) return;
|
|
798
|
+
const ask = (event: BeforeUnloadEvent) => event.preventDefault();
|
|
799
|
+
window.addEventListener('beforeunload', ask);
|
|
800
|
+
return () => window.removeEventListener('beforeunload', ask);
|
|
801
|
+
}, [saved]);
|
|
802
|
+
|
|
803
|
+
<RecoveryCodes codes={codes} saved={saved} onSavedChange={setSaved} onDone={done} />
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
**Storybook:** `Data display/RecoveryCodes` · **Vue:** `RecoveryCodes` (`v-model:saved`, `@done`; slots `title`, `description`, `warning`)
|
|
@@ -149,6 +149,8 @@ the element that had it when it opened (the button of yours that opened a
|
|
|
149
149
|
controlled `AlertDialog`, too), unless focus already went elsewhere or your
|
|
150
150
|
`onCloseAutoFocus` calls `event.preventDefault()`.
|
|
151
151
|
|
|
152
|
+
`AlertDialogContent` is capped to the viewport height and scrolls inside itself, like `DialogContent` ([Dialog](overlays-and-menus.md#dialog)).
|
|
153
|
+
|
|
152
154
|
**Storybook:** `Feedback & status/AlertDialog` · **Vue:** `AlertDialog` (same parts)
|
|
153
155
|
|
|
154
156
|
---
|
|
@@ -10,6 +10,7 @@ for the value type each one writes. Everything is imported from
|
|
|
10
10
|
| | Component | What it does |
|
|
11
11
|
| --- | --- | --- |
|
|
12
12
|
| <img src="../previews/form-fields-field.webp" width="96" alt=""> | [Field](#field) | Renders the field matching a config `type` |
|
|
13
|
+
| <img src="../previews/form-fields-formsection.webp" width="96" alt=""> | [FormSection](#formsection) | Titled section of a form, one column on a phone |
|
|
13
14
|
| <img src="../previews/form-fields-textfield.webp" width="96" alt=""> | [TextField](#textfield) | Labelled input with adornments and helper text |
|
|
14
15
|
| <img src="../previews/form-fields-textareafield.webp" width="96" alt=""> | [TextareaField](#textareafield) | Labelled textarea with row sizing and a counter |
|
|
15
16
|
| <img src="../previews/form-fields-emailfield.webp" width="96" alt=""> | [EmailField](#emailfield) | Validates on blur, `mailto:` button |
|
|
@@ -85,6 +86,83 @@ config: the map is browser-only and lives on `@nxgt/material/map`, so use
|
|
|
85
86
|
|
|
86
87
|
---
|
|
87
88
|
|
|
89
|
+
## FormSection
|
|
90
|
+
|
|
91
|
+

|
|
92
|
+
|
|
93
|
+
A titled section of a form: a heading (an `h2` by default), an optional
|
|
94
|
+
description and actions, then its fields in the form grid's columns; one
|
|
95
|
+
column on a phone.
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
import { useForm } from 'react-hook-form';
|
|
99
|
+
import {
|
|
100
|
+
Button,
|
|
101
|
+
EmailFormField,
|
|
102
|
+
FormSection,
|
|
103
|
+
SwitchFormField,
|
|
104
|
+
TextFormField,
|
|
105
|
+
} from '@nxgt/material/components';
|
|
106
|
+
|
|
107
|
+
type Values = { firstName: string; email: string; contact: string; digest: boolean };
|
|
108
|
+
|
|
109
|
+
export function SettingsForm({ onSave }: { onSave: (values: Values) => void }) {
|
|
110
|
+
const { control, handleSubmit } = useForm<Values>({
|
|
111
|
+
defaultValues: { firstName: '', email: '', contact: '', digest: false },
|
|
112
|
+
});
|
|
113
|
+
return (
|
|
114
|
+
<form className="form-grid-layout" onSubmit={handleSubmit(onSave)}>
|
|
115
|
+
<div data-slot="form-fields">
|
|
116
|
+
<FormSection title="Profile">
|
|
117
|
+
<TextFormField control={control} name="firstName" label="First name" />
|
|
118
|
+
<EmailFormField control={control} name="email" label="Email" />
|
|
119
|
+
</FormSection>
|
|
120
|
+
<FormSection
|
|
121
|
+
title="Emergency contact"
|
|
122
|
+
description="Who we call when you cannot be reached."
|
|
123
|
+
actions={<Button variant="outlined" size="sm">Add another</Button>}
|
|
124
|
+
>
|
|
125
|
+
<TextFormField control={control} name="contact" label="Name" />
|
|
126
|
+
</FormSection>
|
|
127
|
+
<FormSection title="Notifications">
|
|
128
|
+
<SwitchFormField control={control} name="digest" label="Digest" placeholder="Email me a weekly digest" />
|
|
129
|
+
</FormSection>
|
|
130
|
+
</div>
|
|
131
|
+
<div data-slot="form-actions">
|
|
132
|
+
<Button type="submit">Save</Button>
|
|
133
|
+
</div>
|
|
134
|
+
</form>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Prop | Type | Default | Effect |
|
|
140
|
+
| --- | --- | --- | --- |
|
|
141
|
+
| `title` | `ReactNode` | — | the section's heading, which names the group |
|
|
142
|
+
| `titleAs` | `'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `'h2'` | the heading level: `'h3'` when the form already sits under an `h2` |
|
|
143
|
+
| `description` | `ReactNode` | — | a muted line under the title; the group's accessible description |
|
|
144
|
+
| `actions` | `ReactNode` | — | controls beside the title, wrapping under it on a phone |
|
|
145
|
+
| `separated` | `boolean` | `true` | a rule above the section when it follows another `FormSection` |
|
|
146
|
+
|
|
147
|
+
The section is a `role="group"` named by its heading (`aria-labelledby`) and
|
|
148
|
+
described by its description (`aria-describedby`), so a screen reader
|
|
149
|
+
announces "Profile, group" on entering it, and a test finds it with
|
|
150
|
+
`getByRole('group', { name: 'Profile' })`. It is not a `<fieldset>`: a
|
|
151
|
+
fieldset would be one cell of the form's grid, and its fields would not take
|
|
152
|
+
the grid's columns. Inside `.form-grid-layout`'s `[data-slot="form-fields"]`
|
|
153
|
+
it spans the whole row and lays its fields out in the same columns the form
|
|
154
|
+
grid uses, by the section's own width (it is a container query container, so
|
|
155
|
+
it works outside a form grid too). The form grid's wide-field rules still
|
|
156
|
+
apply inside it: a switch, a textarea, chips, files and the rich text editor
|
|
157
|
+
take a row of their own. The rule between sections is a top border drawn on
|
|
158
|
+
each section that follows another; the first has none. The heading is small,
|
|
159
|
+
semibold, uppercase and muted, set apart from the fields' labels, and reads
|
|
160
|
+
4.5:1 in both themes.
|
|
161
|
+
|
|
162
|
+
**Storybook:** `Form fields/FormSection` · **Vue:** `FormSection`
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
88
166
|
## TextField
|
|
89
167
|
|
|
90
168
|

|
|
@@ -8,6 +8,7 @@ documentation-site shell. Everything is imported from
|
|
|
8
8
|
| | Component | What it does |
|
|
9
9
|
| --- | --- | --- |
|
|
10
10
|
| <img src="../previews/navigation-layout-appshell.webp" width="96" alt=""> | [ActivityLayout](#activitylayout) | App shell: sidebar, header, breadcrumbs, titled page |
|
|
11
|
+
| <img src="../previews/navigation-layout-authcard.webp" width="96" alt=""> | [AuthCard](#authcard) | Signed-out page frame: one `main`, a centred card, its title the `h1` |
|
|
11
12
|
| <img src="../previews/navigation-layout-sidebar.webp" width="96" alt=""> | [Sidebar](#sidebar) | Collapsible navigation sidebar |
|
|
12
13
|
| <img src="../previews/navigation-layout-topappbar.webp" width="96" alt=""> | [TopAppBar, BottomAppBar](#topappbar) | Top and bottom bars |
|
|
13
14
|
| <img src="../previews/navigation-layout-breadcrumb.webp" width="96" alt=""> | [Breadcrumb](#breadcrumb) | Breadcrumb primitives |
|
|
@@ -81,6 +82,56 @@ the [app shell guide](../guides/app-shell.md#breadcrumbs)).
|
|
|
81
82
|
|
|
82
83
|
---
|
|
83
84
|
|
|
85
|
+
## AuthCard
|
|
86
|
+
|
|
87
|
+

|
|
88
|
+
|
|
89
|
+
The frame of a signed-out page (sign in, sign up, a reset link): one `main`, a centred card whose title is the page's `h1`, a row above it for the brand and a toolbar, padded clear of a phone's notch and home bar.
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { AuthCard, Button, EmailField, LanguageSwitcher, PasswordField } from '@nxgt/material/components';
|
|
93
|
+
|
|
94
|
+
<AuthCard
|
|
95
|
+
title="Sign in"
|
|
96
|
+
description="Welcome back."
|
|
97
|
+
notice={expired ? 'This link has expired.' : undefined}
|
|
98
|
+
noticeTone="error"
|
|
99
|
+
brand={<img src="/logo.svg" alt="Acme" height={24} />}
|
|
100
|
+
toolbar={<LanguageSwitcher />}
|
|
101
|
+
footer={<a href="/terms">Terms</a>}
|
|
102
|
+
>
|
|
103
|
+
<form className="flex flex-col gap-4" onSubmit={signIn}>
|
|
104
|
+
<EmailField label="Email" name="email" autoComplete="email" />
|
|
105
|
+
<PasswordField label="Password" name="password" autoComplete="current-password" />
|
|
106
|
+
<Button type="submit">Sign in</Button>
|
|
107
|
+
</form>
|
|
108
|
+
</AuthCard>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
| Prop | Type | Default | Effect |
|
|
112
|
+
| --- | --- | --- | --- |
|
|
113
|
+
| `title` | `ReactNode` | — | the page's `h1`, in the card's title |
|
|
114
|
+
| `description` | `ReactNode` | — | a line under the title |
|
|
115
|
+
| `notice` | `ReactNode` | — | an `Alert` above the form: an expired link, a signed-out message |
|
|
116
|
+
| `noticeTone` | `'info' \| 'success' \| 'warning' \| 'error'` | `'info'` | its colour; `'error'` is `role="alert"`, the others `role="status"` |
|
|
117
|
+
| `focusTitle` | `boolean` | `false` | the `h1` takes the focus once shown (`useFocusOnMount`): for an end state that replaced the form ("Check your inbox") |
|
|
118
|
+
| `brand`, `toolbar` | `ReactNode` | — | the row above the card, left and right; it renders only when one is given |
|
|
119
|
+
| `banner` | `ReactNode` | — | above that row (an update notice) |
|
|
120
|
+
| `footer` | `ReactNode` | — | under the card |
|
|
121
|
+
|
|
122
|
+
A non-error notice goes into a `role="status"` region that is always
|
|
123
|
+
rendered (zero height while empty), so a screen reader announces a notice
|
|
124
|
+
that appears later; an error is a `role="alert"` inserted when it shows.
|
|
125
|
+
|
|
126
|
+
The `main` has `tabIndex={-1}`: never reached by Tab, but what replaced a
|
|
127
|
+
control the user acted on (a dismissed banner) can hand it the focus. Its
|
|
128
|
+
padding is `max(1rem, env(safe-area-inset-*))` on each side, as classes: no
|
|
129
|
+
inline style. Other props reach the `main`.
|
|
130
|
+
|
|
131
|
+
**Storybook:** `Navigation & layout/AuthCard` · **Vue:** `AuthCard` (slots `title`, `description`, `notice`, `brand`, `toolbar`, `banner`, `footer`)
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
84
135
|
## Sidebar
|
|
85
136
|
|
|
86
137
|

|
|
@@ -109,6 +109,21 @@ export function Terms() {
|
|
|
109
109
|
| `asChild` (`DialogTrigger`) | `boolean` | **`true`** | the trigger is its child — pass one element, usually a `Button` |
|
|
110
110
|
| `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 |
|
|
111
111
|
|
|
112
|
+
`DialogContent` and `AlertDialogContent` are capped at `100dvh - 2rem` (`100vh`
|
|
113
|
+
where `dvh` is unsupported) and scroll inside themselves, so a long body never
|
|
114
|
+
pushes the title off-screen on a phone. A close button inside the content scrolls with it (`DialogContent` renders no X itself). On
|
|
115
|
+
browsers with `dvh` support, your own `max-h-*` through `className` wins over the
|
|
116
|
+
cap. To remove the cap and the scroll, pass `className="max-h-none overflow-visible"`:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
<DialogContent className="max-h-none overflow-visible">
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Content wider than the dialog now scrolls horizontally or is clipped
|
|
123
|
+
(`overflow-visible` restores the old behaviour). `DialogScrollContent` is for a
|
|
124
|
+
dialog that should grow taller than the screen and scroll inside the overlay
|
|
125
|
+
instead of capping; it does not pin the header or footer.
|
|
126
|
+
|
|
112
127
|
`DialogContent` does not render a close button by itself — add `DialogClose`.
|
|
113
128
|
It ignores outside clicks that land on an open `Combobox` list, so a combobox
|
|
114
129
|
inside a dialog works. On open it moves focus into the dialog: to its first
|
|
@@ -191,6 +206,9 @@ Parts: `Sheet`, `SheetTrigger`, `SheetContent`, `SheetHeader`, `SheetTitle`,
|
|
|
191
206
|
| `withCloseButton` (`SheetContent`) | `boolean` | — | adds a tonal X button top-right, named "Close" (`material.buttons.close`, translated) |
|
|
192
207
|
| `defaultOpen` / `open`, `onOpenChange`, `modal` (`Sheet`) | as `Dialog` | — | a sheet is a Radix dialog |
|
|
193
208
|
|
|
209
|
+
`SheetContent` scrolls inside itself, and a top or bottom sheet is capped at
|
|
210
|
+
`100dvh`. Override the cap with `max-h-*` through `className`.
|
|
211
|
+
|
|
194
212
|
`SheetTrigger` is **not** `asChild` by default, unlike `DialogTrigger`.
|
|
195
213
|
`SheetContent` moves focus in on open and hands it back on close as
|
|
196
214
|
`DialogContent` does: back to the
|