@nxgt/material-vue 0.37.1 → 0.38.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 +80 -0
- package/README.md +1 -0
- package/dist/{Button-CurFF4Zt.js → Button-5UyKA-x_.js} +1 -1
- package/dist/{HoverCardTrigger-jCXl6TrX.js → HoverCardTrigger-CmCDiTn8.js} +2 -2
- package/dist/{camera-CYwiFuGE.js → camera-BWzF8sOW.js} +4 -4
- package/dist/components/base.css +3 -1
- package/dist/{components--v_k8diD.js → components-B_s5oxUp.js} +11816 -11302
- package/dist/components.js +8 -8
- package/dist/composables.js +2 -2
- package/dist/dnd.js +1 -1
- package/dist/{form-scope-B2oJ5fHr.js → form-scope-UzoU38db.js} +1 -1
- package/dist/{i18n-provider-B2q6vp6H.js → i18n-provider-BEvjls8b.js} +1 -1
- package/dist/i18n.js +4 -4
- package/dist/{icon-button-CIUc1bEp.js → icon-button-DhqJE6Ej.js} +1 -1
- package/dist/lib/components/ui/feedback/banner/banner.vue.d.ts +1 -1
- package/dist/lib/components/ui/fields/contacts/consts.d.ts +1 -1
- package/dist/lib/components/ui/fields/index.d.ts +1 -0
- package/dist/lib/components/ui/fields/repeatable-group/index.d.ts +4 -0
- package/dist/lib/components/ui/fields/repeatable-group/partials/repeatable-group-footer.vue.d.ts +14 -0
- package/dist/lib/components/ui/fields/repeatable-group/partials/repeatable-group-row.vue.d.ts +33 -0
- package/dist/lib/components/ui/fields/repeatable-group/repeatable-group-classes.d.ts +33 -0
- package/dist/lib/components/ui/fields/repeatable-group/repeatable-group-form-field.vue.d.ts +44 -0
- package/dist/lib/components/ui/fields/repeatable-group/repeatable-group-names.d.ts +16 -0
- package/dist/lib/components/ui/fields/repeatable-group/repeatable-group.vue.d.ts +69 -0
- package/dist/lib/components/ui/fields/repeatable-group/use-repeatable-group.d.ts +39 -0
- package/dist/lib/components/ui/fields/search-field/search-field.vue.d.ts +10 -1
- package/dist/lib/components/ui/media/stx-player/stx-player-extras.vue.d.ts +1 -1
- package/dist/lib/components/ui/overlays/command/CommandItem.vue.d.ts +10 -3
- package/dist/lib/components/ui/overlays/command/CommandList.vue.d.ts +4 -2
- package/dist/lib/components/ui/primitives/typography/typography.variants.d.ts +1 -0
- package/dist/lib/components/ui/primitives/typography/typography.vue.d.ts +2 -0
- package/dist/lib/components/ui/selection/checkbox-group/checkbox-group.vue.d.ts +2 -0
- package/dist/lib/components/ui/selection/option-count/option-count.vue.d.ts +25 -0
- package/dist/lib/components/ui/selection/option-count/use-option-count-text.d.ts +10 -0
- package/dist/lib/components/ui/selection/radio-group/radio-group-field.vue.d.ts +2 -0
- package/dist/lib/components/ui/selection/select-chip-field/select-chip-field.vue.d.ts +11 -0
- package/dist/lib/components/ui/selection/sortable-list/sortable-list.vue.d.ts +1 -1
- package/dist/lib/components/ui/selection/transfer-list/transfer-list.vue.d.ts +1 -1
- package/dist/lib/i18n/resources/en/en.d.ts +14 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +14 -0
- package/dist/lib/i18n/resources/fr/fr.d.ts +14 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +14 -0
- package/dist/lib/i18n/resources/resources.d.ts +28 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib/nuxt/component-names.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/main.js +17 -17
- package/dist/map.js +4 -4
- package/dist/material-vue.css +1 -1
- package/dist/{pdf-outline-sidebar-DJJ-ARco.js → pdf-outline-sidebar-BsePJlTi.js} +2 -2
- package/dist/{pdf-page-CRt6KXdJ.js → pdf-page-Ct313mNF.js} +1 -1
- package/dist/{pdf-page-list-BgCp5Asx.js → pdf-page-list-JrRo2BeU.js} +2 -2
- package/dist/{pdf-reader-BGxqEx8O.js → pdf-reader-tABBZMbZ.js} +8 -8
- package/dist/{pdf-sidebar-Cvtuomgp.js → pdf-sidebar-Caw9rzU-.js} +3 -3
- package/dist/{pdf-thumbnail-sidebar-CeWPs7o7.js → pdf-thumbnail-sidebar-ZybLeUG7.js} +3 -3
- package/dist/{pdf-toolbar-BtXcyEpd.js → pdf-toolbar-BM8Sz_JN.js} +4 -4
- package/dist/pdf.js +2 -2
- package/dist/{print-format.utils-keJqahvw.js → print-format.utils-CQFIVeUA.js} +2 -2
- package/dist/{sortable-provider-DMu8DL2z.js → sortable-provider-CKkWYijj.js} +2 -2
- package/dist/{stored-language-dtksFoGO.js → stored-language-CvOHC8AD.js} +24 -0
- package/dist/{stx-player-nDsDyvc-.js → stx-player-CsVKbwFk.js} +5 -5
- package/dist/{translator-DqiGrSH_.js → translator-k1rKIgC7.js} +1 -1
- package/dist/{use-heading-spy-BZ7ctGZ5.js → use-heading-spy-D-ipoQwl.js} +1 -1
- package/dist/{use-material-translation-DRB6oPdF.js → use-material-translation-1FdRx9I7.js} +3 -3
- package/docs/components/README.md +1 -1
- package/docs/components/form-fields.md +146 -0
- package/docs/components/overlays-and-menus.md +2 -0
- package/docs/components/primitives.md +3 -1
- package/docs/components/selection-and-choice.md +28 -4
- package/docs/guides/forms.md +34 -0
- package/docs/previews/form-fields-repeatablegroup.webp +0 -0
- package/docs/roadmap.md +7 -0
- package/docs/troubleshooting.md +43 -0
- package/lib/components/base.css +3 -1
- package/lib/nuxt/component-names.ts +2 -0
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as r } from "./use-material-translation-
|
|
3
|
+
import { Hf as n } from "./components-B_s5oxUp.js";
|
|
4
|
+
import { t as r } from "./use-material-translation-1FdRx9I7.js";
|
|
5
5
|
import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, defineComponent as u, normalizeClass as d, normalizeStyle as f, openBlock as p, ref as m, renderList as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
|
|
6
6
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-outline-row.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var y = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Gp as t } from "./components-B_s5oxUp.js";
|
|
3
3
|
import { computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, defineComponent as s, nextTick as c, normalizeClass as l, normalizeStyle as u, onBeforeUnmount as d, openBlock as f, ref as p, shallowRef as m, unref as h, watch as g } from "vue";
|
|
4
4
|
import { DEFAULT_PAGE_SIZE as _, escapeHtml as v, findTextMatches as y, highlightItemHtml as b, placeholderSize as x, rotatedSize as S } from "@nxgt/material-core/pdf-viewer";
|
|
5
5
|
//#region lib/components/ui/media/pdf-viewer/pdf-note-icons.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
|
-
import {
|
|
3
|
-
import { t as n } from "./pdf-page-
|
|
2
|
+
import { Hf as t } from "./components-B_s5oxUp.js";
|
|
3
|
+
import { t as n } from "./pdf-page-Ct313mNF.js";
|
|
4
4
|
import { Fragment as r, createBlock as i, createElementBlock as a, createElementVNode as o, defineComponent as s, openBlock as c, renderList as l, withCtx as u } from "vue";
|
|
5
5
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-page-list.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var d = { class: "flex flex-col items-center gap-4 px-4 py-4" }, f = /*@__PURE__*/ s({
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import { kn as t } from "./components
|
|
3
|
-
import { t as n } from "./use-material-translation-
|
|
4
|
-
import { t as r } from "./Button-
|
|
5
|
-
import { o as i } from "./HoverCardTrigger-
|
|
6
|
-
import { n as a } from "./pdf-page-
|
|
7
|
-
import { t as o } from "./pdf-page-list-
|
|
8
|
-
import { t as s } from "./pdf-sidebar-
|
|
9
|
-
import { t as c } from "./pdf-toolbar-
|
|
2
|
+
import { kn as t } from "./components-B_s5oxUp.js";
|
|
3
|
+
import { t as n } from "./use-material-translation-1FdRx9I7.js";
|
|
4
|
+
import { t as r } from "./Button-5UyKA-x_.js";
|
|
5
|
+
import { o as i } from "./HoverCardTrigger-CmCDiTn8.js";
|
|
6
|
+
import { n as a } from "./pdf-page-Ct313mNF.js";
|
|
7
|
+
import { t as o } from "./pdf-page-list-JrRo2BeU.js";
|
|
8
|
+
import { t as s } from "./pdf-sidebar-Caw9rzU-.js";
|
|
9
|
+
import { t as c } from "./pdf-toolbar-BM8Sz_JN.js";
|
|
10
10
|
import { computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, nextTick as _, normalizeClass as v, onBeforeUnmount as y, onMounted as b, openBlock as x, reactive as S, ref as C, shallowRef as w, toDisplayString as T, toRef as E, unref as D, useId as O, watch as k, withCtx as A } from "vue";
|
|
11
11
|
import { AlertCircle as j, FileX2 as M, KeyRound as N, Loader2 as P } from "@lucide/vue";
|
|
12
12
|
import { pdfSourceKey as F, toPdfjsParams as I } from "@nxgt/material-core/pdf-source";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
|
-
import { t as n } from "./use-material-translation-
|
|
4
|
-
import { t as r } from "./pdf-outline-sidebar-
|
|
5
|
-
import { t as i } from "./pdf-thumbnail-sidebar-
|
|
3
|
+
import { t as n } from "./use-material-translation-1FdRx9I7.js";
|
|
4
|
+
import { t as r } from "./pdf-outline-sidebar-BsePJlTi.js";
|
|
5
|
+
import { t as i } from "./pdf-thumbnail-sidebar-ZybLeUG7.js";
|
|
6
6
|
import { createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, normalizeClass as l, openBlock as u, toDisplayString as d, unref as f, useId as p, useTemplateRef as m } from "vue";
|
|
7
7
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-sidebar.vue?vue&type=script&setup=true&lang.ts
|
|
8
8
|
var h = ["aria-label"], g = ["aria-label"], _ = [
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as r } from "./use-material-translation-
|
|
5
|
-
import { t as i } from "./pdf-page-
|
|
3
|
+
import { Hf as n } from "./components-B_s5oxUp.js";
|
|
4
|
+
import { t as r } from "./use-material-translation-1FdRx9I7.js";
|
|
5
|
+
import { t as i } from "./pdf-page-Ct313mNF.js";
|
|
6
6
|
import { Fragment as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createVNode as l, defineComponent as u, normalizeClass as d, openBlock as f, renderList as p, toDisplayString as m, unref as h, withCtx as g } from "vue";
|
|
7
7
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-thumbnail-sidebar.vue?vue&type=script&setup=true&lang.ts
|
|
8
8
|
var _ = ["aria-label"], v = {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime-CWhphoD1.js";
|
|
2
2
|
import { t } from "./utils-CykWQ0iJ.js";
|
|
3
|
-
import { t as n } from "./use-material-translation-
|
|
4
|
-
import { d as r } from "./Button-
|
|
5
|
-
import { t as i } from "./icon-button-
|
|
3
|
+
import { t as n } from "./use-material-translation-1FdRx9I7.js";
|
|
4
|
+
import { d as r } from "./Button-5UyKA-x_.js";
|
|
5
|
+
import { t as i } from "./icon-button-DhqJE6Ej.js";
|
|
6
6
|
import { a, i as o, n as s, o as c, r as l, t as u } from "./DropdownMenuTrigger-BsuyNVzV.js";
|
|
7
|
-
import { o as d } from "./HoverCardTrigger-
|
|
7
|
+
import { o as d } from "./HoverCardTrigger-CmCDiTn8.js";
|
|
8
8
|
import { Fragment as f, computed as p, createBlock as m, createCommentVNode as h, createElementBlock as g, createElementVNode as _, createTextVNode as v, createVNode as y, defineComponent as b, nextTick as x, normalizeClass as S, openBlock as C, ref as w, renderList as T, toDisplayString as E, unref as D, useTemplateRef as O, watch as k, withCtx as A } from "vue";
|
|
9
9
|
import { ChevronDown as j, ChevronLeft as M, ChevronRight as N, ChevronUp as P, Download as F, Maximize2 as I, Minimize2 as L, Moon as R, Printer as z, RotateCw as B, Search as V, Sidebar as H, ZoomIn as U, ZoomOut as W } from "@lucide/vue";
|
|
10
10
|
//#region lib/components/ui/media/pdf-viewer/partials/pdf-toolbar-search.vue?vue&type=script&setup=true&lang.ts
|
package/dist/pdf.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as e, t } from "./use-material-translation-
|
|
2
|
-
import { t as n } from "./Button-
|
|
1
|
+
import { n as e, t } from "./use-material-translation-1FdRx9I7.js";
|
|
2
|
+
import { t as n } from "./Button-5UyKA-x_.js";
|
|
3
3
|
import { computed as r, createBlock as i, createTextVNode as a, defineComponent as o, getCurrentInstance as s, nextTick as c, onMounted as l, onScopeDispose as u, openBlock as d, ref as f, renderSlot as p, shallowRef as m, toDisplayString as ee, toValue as h, unref as g, watch as te, withCtx as ne } from "vue";
|
|
4
4
|
import { contentDisposition as re, pdfBytesResponse as ie, toWebStream as ae } from "@nxgt/material-core/pdf/http";
|
|
5
5
|
import { badge as oe, dataTable as se, defaultPdfTheme as ce, definePdfDocument as _, divider as v, header as y, heading as b, image as x, keyValue as S, keyValueOf as C, link as w, metric as T, page as E, pageBreak as D, pageNumber as O, pdfDocument as k, resolvePdfColor as A, resolvePdfTheme as j, row as M, section as N, spacer as P, stack as F, table as I, text as L, totals as R } from "@nxgt/material-core/pdf/model";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as e, r as t, t as n } from "./stored-language-
|
|
2
|
-
import { r } from "./translator-
|
|
1
|
+
import { i as e, r as t, t as n } from "./stored-language-CvOHC8AD.js";
|
|
2
|
+
import { r } from "./translator-k1rKIgC7.js";
|
|
3
3
|
import { t as i } from "./_baseIsEqual-BUD8VQJE.js";
|
|
4
4
|
import { n as a } from "./number.utils-Bpo9tUaJ.js";
|
|
5
5
|
import { defineComponent as o, getCurrentInstance as s, h as c, inject as l, provide as u, useId as d } from "vue";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import { t } from "./use-material-translation-
|
|
3
|
-
import { t as n } from "./icon-button-
|
|
2
|
+
import { t } from "./use-material-translation-1FdRx9I7.js";
|
|
3
|
+
import { t as n } from "./icon-button-DhqJE6Ej.js";
|
|
4
4
|
import { Teleport as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createVNode as c, defineComponent as l, inject as u, mergeProps as d, normalizeStyle as f, onUnmounted as p, openBlock as m, provide as h, reactive as g, ref as _, renderSlot as v, toValue as y, unref as b, useAttrs as x, watch as S, watchEffect as C, withCtx as w, withModifiers as T } from "vue";
|
|
5
5
|
import { GripVertical as E } from "@lucide/vue";
|
|
6
6
|
import { Primitive as D } from "reka-ui";
|
|
@@ -752,6 +752,7 @@ var e = {
|
|
|
752
752
|
placeholder: "Search…",
|
|
753
753
|
empty: "No results"
|
|
754
754
|
},
|
|
755
|
+
"option-count": { label: "{count, plural, one {result} other {results}}" },
|
|
755
756
|
autocomplete: {
|
|
756
757
|
empty: "No option found.",
|
|
757
758
|
add: "Add \"{query}\"",
|
|
@@ -1223,6 +1224,17 @@ var e = {
|
|
|
1223
1224
|
saved: "I have saved these codes",
|
|
1224
1225
|
"saved-required": "Tick the box once your codes are safe",
|
|
1225
1226
|
done: "Done"
|
|
1227
|
+
},
|
|
1228
|
+
"repeatable-group": {
|
|
1229
|
+
row: "row",
|
|
1230
|
+
add: "Add {label}",
|
|
1231
|
+
remove: "Remove {label} {index}",
|
|
1232
|
+
"move-up": "Move {label} {index} up",
|
|
1233
|
+
"move-down": "Move {label} {index} down",
|
|
1234
|
+
added: "Added {label} {index}",
|
|
1235
|
+
removed: "Removed {label} {index}",
|
|
1236
|
+
moved: "Moved {label} {from} to position {to}",
|
|
1237
|
+
"max-reached": "Maximum reached ({max})"
|
|
1226
1238
|
}
|
|
1227
1239
|
} },
|
|
1228
1240
|
fr: { material: {
|
|
@@ -1976,6 +1988,7 @@ var e = {
|
|
|
1976
1988
|
placeholder: "Rechercher…",
|
|
1977
1989
|
empty: "Aucun résultat"
|
|
1978
1990
|
},
|
|
1991
|
+
"option-count": { label: "{count, plural, one {résultat} other {résultats}}" },
|
|
1979
1992
|
autocomplete: {
|
|
1980
1993
|
empty: "Aucune option.",
|
|
1981
1994
|
add: "Ajouter « {query} »",
|
|
@@ -2447,6 +2460,17 @@ var e = {
|
|
|
2447
2460
|
saved: "J'ai enregistré ces codes",
|
|
2448
2461
|
"saved-required": "Cochez la case une fois vos codes en lieu sûr",
|
|
2449
2462
|
done: "Terminé"
|
|
2463
|
+
},
|
|
2464
|
+
"repeatable-group": {
|
|
2465
|
+
row: "ligne",
|
|
2466
|
+
add: "Ajouter une {label}",
|
|
2467
|
+
remove: "Retirer la {label} {index}",
|
|
2468
|
+
"move-up": "Monter la {label} {index}",
|
|
2469
|
+
"move-down": "Descendre la {label} {index}",
|
|
2470
|
+
added: "Ajout : {label} {index}",
|
|
2471
|
+
removed: "Suppression : {label} {index}",
|
|
2472
|
+
moved: "Déplacement : {label} {from} en position {to}",
|
|
2473
|
+
"max-reached": "Maximum atteint ({max})"
|
|
2450
2474
|
}
|
|
2451
2475
|
} }
|
|
2452
2476
|
}, t = "language", n = "en", r = Object.keys(e);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import { $t as t,
|
|
3
|
-
import { t as l } from "./use-material-translation-
|
|
2
|
+
import { $t as t, Jp as n, Jt as r, Qt as i, Xt as a, Yt as o, en as s, tn as c } from "./components-B_s5oxUp.js";
|
|
3
|
+
import { t as l } from "./use-material-translation-1FdRx9I7.js";
|
|
4
4
|
import { createBlock as u, createCommentVNode as d, createElementBlock as f, createElementVNode as p, createTextVNode as m, createVNode as h, defineComponent as g, normalizeClass as _, openBlock as v, toDisplayString as y, unref as b, withCtx as x } from "vue";
|
|
5
5
|
//#region lib/components/ui/media/stx-player/partials/stx-player-frame.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var S = ["data-layout", "aria-label"], C = {
|
|
@@ -35,17 +35,17 @@ var S = ["data-layout", "aria-label"], C = {
|
|
|
35
35
|
key: 1,
|
|
36
36
|
class: _(b(e)("grid gap-3", a.showQueue && "@min-[768px]:grid-cols-[minmax(0,1fr)_18rem] @min-[768px]:items-stretch"))
|
|
37
37
|
}, [p("div", { class: _(b(e)("bg-card overflow-hidden rounded border", b(w).current?.kind === "audio" && "flex flex-col gap-4 p-6")) }, [
|
|
38
|
-
b(w).current?.kind === "audio" ? (v(), f("div", C, [h(
|
|
38
|
+
b(w).current?.kind === "audio" ? (v(), f("div", C, [h(n, { variant: "title-medium" }, {
|
|
39
39
|
default: x(() => [m(y(b(w).current.title), 1)]),
|
|
40
40
|
_: 1
|
|
41
|
-
}), b(w).current.artist ? (v(), u(
|
|
41
|
+
}), b(w).current.artist ? (v(), u(n, {
|
|
42
42
|
key: 0,
|
|
43
43
|
class: "text-muted-foreground"
|
|
44
44
|
}, {
|
|
45
45
|
default: x(() => [m(y(b(w).current.artist) + " " + y(b(w).current.album ? ` · ${b(w).current.album}` : ""), 1)]),
|
|
46
46
|
_: 1
|
|
47
47
|
})) : d("", !0)])) : d("", !0),
|
|
48
|
-
h(
|
|
48
|
+
h(r, null, {
|
|
49
49
|
default: x(() => [b(w).current?.kind === "audio" ? d("", !0) : (v(), u(s, {
|
|
50
50
|
key: 0,
|
|
51
51
|
tone: "overlay"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, i as t, r as n, t as r } from "./stored-language-
|
|
1
|
+
import { a as e, i as t, r as n, t as r } from "./stored-language-CvOHC8AD.js";
|
|
2
2
|
import { t as i } from "./get-CTzJAwfc.js";
|
|
3
3
|
//#region ../../node_modules/@formatjs/fast-memoize/index.js
|
|
4
4
|
function a(e, t) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e } from "./i18n-provider-
|
|
1
|
+
import { a as e } from "./i18n-provider-BEvjls8b.js";
|
|
2
2
|
import { c as t, d as n, f as r, l as i, r as a, u as o } from "./number.utils-Bpo9tUaJ.js";
|
|
3
3
|
import { computed as s, getCurrentInstance as c, inject as l, onMounted as u, ref as d, shallowRef as f, toValue as p, watch as m } from "vue";
|
|
4
4
|
import { injectConfigProviderContext as h } from "reka-ui";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./stored-language-
|
|
2
|
-
import { a as e } from "./i18n-provider-
|
|
3
|
-
import { i as t, r as n } from "./translator-
|
|
1
|
+
import "./stored-language-CvOHC8AD.js";
|
|
2
|
+
import { a as e } from "./i18n-provider-BEvjls8b.js";
|
|
3
|
+
import { i as t, r as n } from "./translator-k1rKIgC7.js";
|
|
4
4
|
//#region lib/i18n/translate-material.ts
|
|
5
5
|
function r(e, r, i, a) {
|
|
6
6
|
if (e) for (let t of /* @__PURE__ */ new Set([e, e.split("-")[0]])) {
|
|
@@ -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), the titled sections a long form is laid out in, and the rows a user adds and removes. 26 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)
|
|
@@ -12,6 +12,7 @@ value type each one writes. Everything is imported from
|
|
|
12
12
|
| --- | --- | --- |
|
|
13
13
|
| <img src="../previews/form-fields-field.webp" width="96" alt=""> | [Field](#field) | Renders the field matching a config `type` |
|
|
14
14
|
| <img src="../previews/form-fields-formsection.webp" width="96" alt=""> | [FormSection](#formsection) | Titled section of a form, one column on a phone |
|
|
15
|
+
| <img src="../previews/form-fields-repeatablegroup.webp" width="96" alt=""> | [RepeatableGroup](#repeatablegroup) | Rows a user adds, removes and reorders |
|
|
15
16
|
| <img src="../previews/form-fields-textfield.webp" width="96" alt=""> | [TextField](#textfield) | Labelled input with adornments and helper text |
|
|
16
17
|
| <img src="../previews/form-fields-textareafield.webp" width="96" alt=""> | [TextareaField](#textareafield) | Labelled textarea with row sizing and a counter |
|
|
17
18
|
| <img src="../previews/form-fields-emailfield.webp" width="96" alt=""> | [EmailField](#emailfield) | Validates on blur, `mailto:` button |
|
|
@@ -171,6 +172,125 @@ semibold, uppercase and muted, set apart from the fields' labels, and reads
|
|
|
171
172
|
|
|
172
173
|
---
|
|
173
174
|
|
|
175
|
+
## RepeatableGroup
|
|
176
|
+
|
|
177
|
+

|
|
178
|
+
|
|
179
|
+
Rows of fields a user adds, removes and, optionally, reorders — a school
|
|
180
|
+
year's periods, a list of contacts. `RepeatableGroupFormField` wires it to
|
|
181
|
+
vee-validate's `useFieldArray`; each row's fields are your own form wrappers,
|
|
182
|
+
rendered by its `row` slot.
|
|
183
|
+
|
|
184
|
+
```vue
|
|
185
|
+
<script setup lang="ts">
|
|
186
|
+
import { useForm } from 'vee-validate';
|
|
187
|
+
import {
|
|
188
|
+
Button,
|
|
189
|
+
DateFormField,
|
|
190
|
+
RepeatableGroupFormField,
|
|
191
|
+
TextFormField,
|
|
192
|
+
} from '@nxgt/material-vue/components';
|
|
193
|
+
|
|
194
|
+
type Period = { name: string; start?: Date; end?: Date };
|
|
195
|
+
|
|
196
|
+
const { handleSubmit } = useForm<{ periods: Period[] }>({
|
|
197
|
+
initialValues: { periods: [{ name: 'Term 1' }] },
|
|
198
|
+
});
|
|
199
|
+
const onSubmit = handleSubmit((values) => console.log(values));
|
|
200
|
+
const newRow = (): Period => ({ name: '' });
|
|
201
|
+
</script>
|
|
202
|
+
|
|
203
|
+
<template>
|
|
204
|
+
<form class="form-grid-layout" @submit="onSubmit">
|
|
205
|
+
<div data-slot="form-fields">
|
|
206
|
+
<RepeatableGroupFormField
|
|
207
|
+
name="periods"
|
|
208
|
+
label="Periods"
|
|
209
|
+
row-label="period"
|
|
210
|
+
add-label="Add period"
|
|
211
|
+
:max="6"
|
|
212
|
+
reorderable
|
|
213
|
+
empty-title="No periods yet"
|
|
214
|
+
:new-row="newRow"
|
|
215
|
+
>
|
|
216
|
+
<template #row="{ path }">
|
|
217
|
+
<TextFormField :name="`${path}.name`" label="Name" />
|
|
218
|
+
<DateFormField :name="`${path}.start`" label="Start date" />
|
|
219
|
+
<DateFormField :name="`${path}.end`" label="End date" />
|
|
220
|
+
</template>
|
|
221
|
+
</RepeatableGroupFormField>
|
|
222
|
+
</div>
|
|
223
|
+
<div data-slot="form-actions">
|
|
224
|
+
<Button type="submit">Save</Button>
|
|
225
|
+
</div>
|
|
226
|
+
</form>
|
|
227
|
+
</template>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
| Prop / slot | Type | Default | Effect |
|
|
231
|
+
| --- | --- | --- | --- |
|
|
232
|
+
| `name` | `string` | — | the array's path in the form (`RepeatableGroupFormField`) |
|
|
233
|
+
| `new-row` | `() => TRow` | — | the value Add pushes |
|
|
234
|
+
| `#row` | slot | — | one row's fields; its props are `{ field, index, position, path }` (`index` 0-based, `position` 1-based, `path` `${name}[${index}]`) |
|
|
235
|
+
| `label` / `#label` | `string` / slot | — | names the group (the list inside it is not named again) |
|
|
236
|
+
| `row-label` | `string` | `'row'` (translated) | names each row's buttons ("Remove period 2") and the announcements |
|
|
237
|
+
| `add-label` | `string` | `'Add {rowLabel}'` | the Add button's text |
|
|
238
|
+
| `reorderable` | `boolean` | `false` | move up / move down buttons on each row |
|
|
239
|
+
| `max` | `number` | — | at this many rows, Add is disabled and says why |
|
|
240
|
+
| `min` | `number` | — | at this many rows, Remove is disabled |
|
|
241
|
+
| `empty-title`, `empty-description` / `#empty` | `string` / slot | — | an `EmptyState` when there is no row; the slot replaces it |
|
|
242
|
+
| `disabled` | `boolean` | `false` | disables every button |
|
|
243
|
+
|
|
244
|
+
Without a form library, `RepeatableGroup` takes the rows and listens to the
|
|
245
|
+
actions; the move buttons show only with a `@move` listener:
|
|
246
|
+
|
|
247
|
+
```vue
|
|
248
|
+
<script setup lang="ts">
|
|
249
|
+
import { ref } from 'vue';
|
|
250
|
+
import { RepeatableGroup, TextField } from '@nxgt/material-vue/components';
|
|
251
|
+
|
|
252
|
+
type Guest = { id: string; name: string };
|
|
253
|
+
const guests = ref<Guest[]>([]);
|
|
254
|
+
const add = () => guests.value.push({ id: crypto.randomUUID(), name: '' });
|
|
255
|
+
const remove = (index: number) => guests.value.splice(index, 1);
|
|
256
|
+
</script>
|
|
257
|
+
|
|
258
|
+
<template>
|
|
259
|
+
<RepeatableGroup label="Guests" row-label="guest" :items="guests" @add="add" @remove="remove">
|
|
260
|
+
<template #row="{ item }">
|
|
261
|
+
<TextField v-model="item.name" label="Name" />
|
|
262
|
+
</template>
|
|
263
|
+
</RepeatableGroup>
|
|
264
|
+
</template>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
`get-key` defaults to the item's `key`, then its `id`, then the index.
|
|
268
|
+
vee-validate's `useFieldArray` gives each entry a `key`, so
|
|
269
|
+
`RepeatableGroupFormField` needs none; a plain list keyed by `id` needs none
|
|
270
|
+
either. `error` shows an error under the rows.
|
|
271
|
+
|
|
272
|
+
`row-label` is a lower-case noun. The French templates carry the feminine
|
|
273
|
+
article ("Ajouter une ligne", "Retirer la ligne 2"), so a French app passes a
|
|
274
|
+
feminine noun (`row-label="période"`), or overrides `add-label` and the
|
|
275
|
+
`material.repeatable-group.*` keys in its own bundle (`mergeResources`) for a
|
|
276
|
+
masculine one.
|
|
277
|
+
|
|
278
|
+
- **Semantics:** a `role="group"` named by `label`, its rows a list
|
|
279
|
+
(`getAllByRole('listitem')`), each row's icon buttons named after it
|
|
280
|
+
("Remove period 2", "Move period 2 up").
|
|
281
|
+
- **Focus and announcements:** see
|
|
282
|
+
[Rows a user adds and removes](../guides/forms.md#rows-a-user-adds-and-removes);
|
|
283
|
+
at `max`, Add stays focusable (`aria-disabled`) and is described by
|
|
284
|
+
"Maximum reached (6)".
|
|
285
|
+
- **Errors:** the array's own error (the error at `name`) describes the group;
|
|
286
|
+
each row's fields show their own.
|
|
287
|
+
- **Layout:** one column on a phone, columns of at least 11rem from a container
|
|
288
|
+
width of `@xl`; no inline style.
|
|
289
|
+
|
|
290
|
+
**Storybook:** `Form fields/RepeatableGroup` · **React:** `RepeatableGroup`, `RepeatableGroupFormField`
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
174
294
|
## TextField
|
|
175
295
|
|
|
176
296
|

|
|
@@ -513,8 +633,34 @@ const query = ref('');
|
|
|
513
633
|
| `@value-change` | `(value: string) => void` | — | the text, debounced when `debounce-ms` is set |
|
|
514
634
|
| `debounce-ms` | `number` | `0` | delay before `value-change`; `0` emits it on every key |
|
|
515
635
|
| `loading` | `boolean` | `false` | spinner in the input |
|
|
636
|
+
| `shortcut` | `string` | — | a hint for the key that focuses the field, e.g. `"/"`: a `Kbd` at the end while the field is empty, not loading and not disabled (`aria-hidden`) and `aria-keyshortcuts` on the input. It binds no key; your page listens and calls `focus()` on the component ref (exposed) |
|
|
516
637
|
| `v-model` | `string` | — | still updated on every key, undebounced |
|
|
517
638
|
|
|
639
|
+
The `shortcut` hint binds no key; the page does, and calls the exposed
|
|
640
|
+
`focus()`:
|
|
641
|
+
|
|
642
|
+
```vue
|
|
643
|
+
<script setup lang="ts">
|
|
644
|
+
import { onMounted, onUnmounted, ref } from 'vue';
|
|
645
|
+
import { SearchField } from '@nxgt/material-vue/components';
|
|
646
|
+
|
|
647
|
+
const searchRef = ref<InstanceType<typeof SearchField> | null>(null);
|
|
648
|
+
const onKey = (event: KeyboardEvent) => {
|
|
649
|
+
const target = event.target as HTMLElement;
|
|
650
|
+
if (event.key === '/' && !target.closest('input, textarea, [contenteditable]')) {
|
|
651
|
+
event.preventDefault();
|
|
652
|
+
searchRef.value?.focus();
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
onMounted(() => document.addEventListener('keydown', onKey));
|
|
656
|
+
onUnmounted(() => document.removeEventListener('keydown', onKey));
|
|
657
|
+
</script>
|
|
658
|
+
|
|
659
|
+
<template>
|
|
660
|
+
<SearchField ref="searchRef" shortcut="/" />
|
|
661
|
+
</template>
|
|
662
|
+
```
|
|
663
|
+
|
|
518
664
|
**Emits:** `update:modelValue` and `value-change`, both `string`;
|
|
519
665
|
`SearchFormField` stores `string`.
|
|
520
666
|
**Form wrapper:** `SearchFormField` — `name` inside a vee-validate form, see
|
|
@@ -637,6 +637,8 @@ Parts: `Command`, `CommandDialog`, `CommandInput`, `CommandList`,
|
|
|
637
637
|
| Prop | Type | Default | Effect |
|
|
638
638
|
| --- | --- | --- | --- |
|
|
639
639
|
| `value` (`CommandItem`) | `string` | — (required) | the item's value, emitted by `@select` and by `Command`'s `v-model` |
|
|
640
|
+
| `checked` (`CommandItem`) | `boolean` | — | sets `aria-checked` and shows a checkbox indicator, for a multi-choice list; reka's `aria-selected` keeps meaning "selected value" (`multiple` is not used) |
|
|
641
|
+
| `multiselectable` (`CommandList`) | `boolean` | — | sets `aria-multiselectable` on the list |
|
|
640
642
|
| `@select` (`CommandItem`) | `(event) => void` | — | Enter or click on the item; `event.detail.value` is its `value` |
|
|
641
643
|
| `heading` (`CommandGroup`) | `string` | — | the group's label |
|
|
642
644
|
| `title` / `description` (`CommandDialog`) | `string` | `"Command Palette"` / `"Search for a command to run..."` (translated) | the dialog's title and description, visually hidden |
|
|
@@ -193,14 +193,16 @@ import { Typography } from '@nxgt/material-vue/components';
|
|
|
193
193
|
| Prop | Type | Default | Effect |
|
|
194
194
|
| --- | --- | --- | --- |
|
|
195
195
|
| `variant` | `'huge-larger' \| 'huge-large' \| 'huge-medium' \| 'huge-small' \| 'headline-larger' \| 'headline-large' \| 'headline-medium' \| 'headline-small' \| 'title-large' \| 'title-medium' \| 'title-small' \| 'body-medium' \| 'body-small' \| 'caption' \| 'normal'` | `'normal'` | size and weight; `caption` is also muted |
|
|
196
|
+
| `tone` | `'default' \| 'muted' \| 'primary' \| 'error'` | `'default'` | text colour: `muted` is `text-muted-foreground`, `primary` is `text-primary`, `error` is `text-error-text`; `default` inherits (a `class` colour still wins) |
|
|
196
197
|
| `as` | a tag name or a component | `'div'` | the element to render, keeping the variant, e.g. `as="h2"` or `as="span"` |
|
|
197
198
|
| `asChild` | `boolean` | `false` | merge the classes onto the single child instead of rendering an element |
|
|
198
199
|
|
|
199
|
-
It renders a `<div>` unless `as` or `asChild` says otherwise:
|
|
200
|
+
It renders a `<div>` unless `as` or `asChild` says otherwise. Use `as="span"` inside a `<button>` or a link, where a `<div>` is invalid HTML. It sets no `overflow`, so it is never a scroll region: text with break points wraps, while an unbreakable string can overflow its box (add `wrap-anywhere` or `min-w-0`; put your own wrapper with `overflow-auto` and `tabindex="0"` around it to scroll):
|
|
200
201
|
|
|
201
202
|
```vue
|
|
202
203
|
<Typography as="span" variant="title-small">Inline</Typography>
|
|
203
204
|
<Typography as-child variant="body-medium"><a href="/docs">Docs</a></Typography>
|
|
205
|
+
<Typography tone="muted" variant="body-medium">Jan 3 to Jan 9</Typography>
|
|
204
206
|
```
|
|
205
207
|
|
|
206
208
|
The variants are also exported as `typographyVariants` for use on your own elements. Vue has one more step than React, `huge-larger`.
|
|
@@ -463,7 +463,7 @@ const picked = ref<string[]>(['astro']);
|
|
|
463
463
|
|
|
464
464
|
| Prop | Type | Default | Effect |
|
|
465
465
|
| --- | --- | --- | --- |
|
|
466
|
-
| `options` | `{ value: string; label: string }[]` | — | required; the boxes |
|
|
466
|
+
| `options` | `{ value: string; label: string; count?: number }[]` | — | required; the boxes; `count`: see [option counts](#option-counts). |
|
|
467
467
|
| `v-model` | `string[]` | `[]` | the checked values; the new list on each toggle |
|
|
468
468
|
| `orientation` | `'vertical' \| 'horizontal'` | `'horizontal'` | layout |
|
|
469
469
|
| `label`, `helper-text` | `string` | — | the question and its help or error text, above the boxes |
|
|
@@ -487,6 +487,10 @@ stops matching.
|
|
|
487
487
|
The `#helper-text` slot replaces the helper text's content (shown only while
|
|
488
488
|
`helper-text` is set) and stays part of the group's description.
|
|
489
489
|
|
|
490
|
+
#### Option counts
|
|
491
|
+
|
|
492
|
+
`count` on an option of `CheckboxGroup`, `RadioGroupField` or `SelectChipField` shows a number after the label, in muted `tabular-nums` text, and joins the accessible name: the number as plain text plus a visually hidden unit word, so the option is named "CE1 24 results" (it starts with the visible label). The unit is the ICU plural `material.option-count.label` (`result` / `results`; `résultat` / `résultats` in French), so override it in your resources for another noun. `0` is a valid count.
|
|
493
|
+
|
|
490
494
|
**Emits:** `update:modelValue` with `string[]`.
|
|
491
495
|
**Form wrapper:** `CheckboxGroupFormField` — `name` inside a vee-validate form, see
|
|
492
496
|
[forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
|
|
@@ -524,7 +528,7 @@ React the labelled one is called `RadioGroup`.
|
|
|
524
528
|
|
|
525
529
|
| Prop | Type | Default | Effect |
|
|
526
530
|
| --- | --- | --- | --- |
|
|
527
|
-
| `options` | `{ value: string; label: string; disabled?: boolean }[]` | — | required; the radios; `disabled` on an option disables only it |
|
|
531
|
+
| `options` | `{ value: string; label: string; disabled?: boolean; count?: number }[]` | — | required; the radios; `disabled` on an option disables only it; `count`: see [option counts](#option-counts). |
|
|
528
532
|
| `v-model` | `string` | — | the selected `value` |
|
|
529
533
|
| `orientation` | `'vertical' \| 'horizontal'` | `'horizontal'` | layout |
|
|
530
534
|
| `label`, `helper-text`, `error`, `disabled` | | — | the field's text and state |
|
|
@@ -652,11 +656,31 @@ const picked = ref<string[]>([]);
|
|
|
652
656
|
</template>
|
|
653
657
|
```
|
|
654
658
|
|
|
659
|
+
With icons, counts, and a single choice that stays chosen when pressed again:
|
|
660
|
+
|
|
661
|
+
```vue
|
|
662
|
+
<script setup lang="ts">
|
|
663
|
+
import { AtomIcon } from '@lucide/vue';
|
|
664
|
+
import { markRaw, ref } from 'vue';
|
|
665
|
+
|
|
666
|
+
const level = ref<string[]>([]);
|
|
667
|
+
const levels = [
|
|
668
|
+
{ value: 'ce1', label: 'CE1', count: 24, icon: markRaw(AtomIcon) },
|
|
669
|
+
{ value: 'ce2', label: 'CE2', count: 1 },
|
|
670
|
+
];
|
|
671
|
+
</script>
|
|
672
|
+
|
|
673
|
+
<template>
|
|
674
|
+
<SelectChipField v-model="level" label="Level" :options="levels" :deselectable="false" />
|
|
675
|
+
</template>
|
|
676
|
+
```
|
|
677
|
+
|
|
655
678
|
| Prop | Type | Default | Effect |
|
|
656
679
|
| --- | --- | --- | --- |
|
|
657
|
-
| `mode` | `'single' \| 'multiple'` | `'single'` | clicking the selected chip in `single` mode clears it |
|
|
680
|
+
| `mode` | `'single' \| 'multiple'` | `'single'` | clicking the selected chip in `single` mode clears it, unless `deselectable` is `false` |
|
|
681
|
+
| `deselectable` | `boolean` | `true` | `false`: in `single` mode a second press keeps the chosen chip chosen, as a radio group does; another chip still replaces it |
|
|
658
682
|
| `v-model` | `string[]` | `[]` | the selected values, even in `single` mode |
|
|
659
|
-
| `options` | `{ value: string; label: string }[]` | — | required; the chips |
|
|
683
|
+
| `options` | `{ value: string; label: string; icon?: Component; count?: number }[]` | — | required; the chips (`icon`: a component, such as a `@lucide/vue` icon, shown before the label); `count`: see [option counts](#option-counts). |
|
|
660
684
|
| `label`, `helper-text`, `error`, `disabled` | | — | the field's text and state |
|
|
661
685
|
|
|
662
686
|
**Accessibility:** the chips are toggle buttons in a `role="group"` named by
|
package/docs/guides/forms.md
CHANGED
|
@@ -619,6 +619,40 @@ const onSubmit = handleSubmit((values) => emit('save', values));
|
|
|
619
619
|
`{ [attribute.name]: value }` to its `name`. Its starting values come from
|
|
620
620
|
its `default-values` prop, not from the form.
|
|
621
621
|
|
|
622
|
+
### Rows a user adds and removes
|
|
623
|
+
|
|
624
|
+
When the rows are fields of their own — a school year's periods, each with a
|
|
625
|
+
name, a start date and an end date — use
|
|
626
|
+
[`RepeatableGroupFormField`](../components/form-fields.md#repeatablegroup)
|
|
627
|
+
over vee-validate's `useFieldArray`, and render each row's fields with the
|
|
628
|
+
form's own wrappers in its `row` slot:
|
|
629
|
+
|
|
630
|
+
```vue
|
|
631
|
+
<RepeatableGroupFormField
|
|
632
|
+
name="periods"
|
|
633
|
+
label="Periods"
|
|
634
|
+
row-label="period"
|
|
635
|
+
:max="6"
|
|
636
|
+
reorderable
|
|
637
|
+
:new-row="() => ({ name: '' })"
|
|
638
|
+
>
|
|
639
|
+
<template #row="{ path }">
|
|
640
|
+
<TextFormField :name="`${path}.name`" label="Name" />
|
|
641
|
+
<DateFormField :name="`${path}.start`" label="Start date" />
|
|
642
|
+
</template>
|
|
643
|
+
</RepeatableGroupFormField>
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
- A row's field shows its own error (`periods[1].name`); the array's own
|
|
647
|
+
error (`.min(2)` on the array) shows under the rows and describes the group.
|
|
648
|
+
- The slot's `path` is `periods[1]`, not `name`: a slot's `name` attribute is
|
|
649
|
+
the slot's own.
|
|
650
|
+
- The group moves the focus as rows come and go (an added row's first field,
|
|
651
|
+
a removed row's neighbour or Add, a moved row's move button) and announces each change politely
|
|
652
|
+
("Added period 3"), after its own buttons only: a row your
|
|
653
|
+
own code pushes leaves the focus where it is
|
|
654
|
+
([what to do](../troubleshooting.md#the-focus-does-not-move-to-a-new-row-of-a-repeatablegroupformfield)).
|
|
655
|
+
|
|
622
656
|
## Config-driven forms
|
|
623
657
|
|
|
624
658
|
`Field` renders the field that matches a config `type`, which is useful when
|
|
Binary file
|
package/docs/roadmap.md
CHANGED
|
@@ -162,6 +162,13 @@ version they shipped in, and planned entries may name the major they target.
|
|
|
162
162
|
|
|
163
163
|
## Shipped
|
|
164
164
|
|
|
165
|
+
- **Rows a user adds, removes and reorders** — `RepeatableGroup` and
|
|
166
|
+
`RepeatableGroupFormField` over the form library's field array: rows from
|
|
167
|
+
the `row` slot, a list for assistive tech, Remove and move buttons named after
|
|
168
|
+
the row ("Remove period 2"), `max` and `min`, an empty state, focus that
|
|
169
|
+
follows each change, polite announcements, and the array's own error under
|
|
170
|
+
the rows. One column on a phone. 0.38.0.
|
|
171
|
+
|
|
165
172
|
- **Signed-out pages and two-step verification** — `AuthCard`, the frame of a
|
|
166
173
|
sign-in page (one `main`, the card's title its `h1`, a status or alert
|
|
167
174
|
notice, safe-area padding); `EnrolmentSecret`, a TOTP enrolment's QR code,
|