@nxgt/material-vue 0.24.0 → 0.25.1
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/README.md +17 -19
- package/dist/{Button-DOcT4Pej.js → Button-C1aaI0Gw.js} +1 -1
- package/dist/{HoverCardTrigger-WQe85PCH.js → HoverCardTrigger-JtHn0IFQ.js} +2 -2
- package/dist/{camera-BNbLUPb1.js → camera-BacVyXl0.js} +13 -13
- package/dist/{components-YlYuHLEI.js → components-DRBKkOqk.js} +15333 -13879
- package/dist/components.js +8 -8
- package/dist/composables.js +2 -2
- package/dist/dnd.js +1 -1
- package/dist/form-scope-VxlJuvFe.js +43 -0
- package/dist/{i18n-provider-DTuxugHO.js → i18n-provider-D0oYv0XS.js} +1 -1
- package/dist/i18n.js +4 -4
- package/dist/{icon-button-DKLuZ2c-.js → icon-button-B2FQtIHS.js} +1 -1
- package/dist/lib/components/ui/collections/tree/use-tree.d.ts +2 -0
- package/dist/lib/components/ui/dates/date-field/date-field.vue.d.ts +10 -1
- package/dist/lib/components/ui/dates/date-field/date-form-field.vue.d.ts +3 -1
- package/dist/lib/components/ui/dates/date-field/day-matcher.d.ts +26 -0
- package/dist/lib/components/ui/dates/date-field/index.d.ts +1 -0
- package/dist/lib/components/ui/dates/date-field/partials/date-field-content.vue.d.ts +2 -0
- package/dist/lib/components/ui/dates/date-range-field/date-range-field.utils.d.ts +11 -0
- package/dist/lib/components/ui/dates/date-range-field/date-range-field.vue.d.ts +26 -1
- package/dist/lib/components/ui/dates/date-range-field/date-range-form-field.vue.d.ts +3 -1
- package/dist/lib/components/ui/dates/date-range-field/index.d.ts +1 -0
- package/dist/lib/components/ui/dates/date-range-field/partials/date-range-calendar.vue.d.ts +5 -0
- package/dist/lib/components/ui/dates/date-range-field/partials/date-range-field-trigger.vue.d.ts +2 -0
- package/dist/lib/components/ui/dates/date-range-field/partials/date-range-presets.vue.d.ts +12 -0
- package/dist/lib/components/ui/dates/date-range-field/partials/date-range-times.vue.d.ts +13 -0
- package/dist/lib/components/ui/dates/date-range-field/use-date-range-presets.d.ts +23 -0
- package/dist/lib/components/ui/dates/time-picker/time-picker-utils.d.ts +7 -0
- package/dist/lib/components/ui/display/accordion-card/accordion-card.vue.d.ts +29 -1
- package/dist/lib/components/ui/display/avatar/Avatar.vue.d.ts +14 -3
- package/dist/lib/components/ui/display/avatar/index.d.ts +1 -0
- package/dist/lib/components/ui/display/cards/cards.gallery.d.ts +5 -9
- package/dist/lib/components/ui/display/qrcode/qrcode.vue.d.ts +5 -3
- package/dist/lib/components/ui/display/status-indicator/status-tone.d.ts +3 -0
- package/dist/lib/components/ui/feedback/confirmation-dialog/async-form-scope.d.ts +15 -0
- package/dist/lib/components/ui/feedback/confirmation-dialog/confirmation-dialog.vue.d.ts +37 -24
- package/dist/lib/components/ui/feedback/confirmation-dialog/index.d.ts +1 -1
- package/dist/lib/components/ui/feedback/confirmation-dialog/partials/confirmation-dialog-form-error.vue.d.ts +3 -0
- package/dist/lib/components/ui/fields/attributes/form-schema.d.ts +24 -22
- package/dist/lib/components/ui/fields/contacts/consts.d.ts +1 -1
- package/dist/lib/components/ui/fields/number-field/number-field.vue.d.ts +2 -0
- package/dist/lib/components/ui/fields/slider/partials/slider-field-row.vue.d.ts +32 -0
- package/dist/lib/components/ui/fields/slider/slider-field.vue.d.ts +22 -1
- package/dist/lib/components/ui/fields/slider/slider-form-field.vue.d.ts +13 -1
- package/dist/lib/components/ui/forms/form-scope-schema.d.ts +43 -0
- package/dist/lib/components/ui/forms/form-scope.vue.d.ts +33 -0
- package/dist/lib/components/ui/media/file-preview/file-preview-pdf.lazy.d.ts +8 -0
- package/dist/lib/components/ui/media/file-preview/file-preview.vue.d.ts +9 -0
- package/dist/lib/components/ui/media/file-preview/index.d.ts +3 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-body.vue.d.ts +21 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-card.vue.d.ts +15 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-download.vue.d.ts +11 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-media.vue.d.ts +17 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-pdf.vue.d.ts +21 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-status.vue.d.ts +22 -0
- package/dist/lib/components/ui/media/file-preview/partials/file-preview-text.vue.d.ts +16 -0
- package/dist/lib/components/ui/media/file-preview/types.d.ts +19 -0
- package/dist/lib/components/ui/media/file-preview/use-file-preview.d.ts +21 -0
- package/dist/lib/components/ui/media/file-preview/use-text-preview.d.ts +17 -0
- package/dist/lib/components/ui/media/files-form-field/files-form-field.vue.d.ts +29 -0
- package/dist/lib/components/ui/media/files-form-field/index.d.ts +2 -0
- package/dist/lib/components/ui/media/image-cropper/partials/image-cropper-canvas.vue.d.ts +1 -1
- package/dist/lib/components/ui/media/index.d.ts +2 -0
- package/dist/lib/components/ui/media/pdf-viewer/partials/pdf-page.vue.d.ts +1 -1
- package/dist/lib/components/ui/media/pdf-viewer/partials/pdf-reader-body.vue.d.ts +2 -2
- package/dist/lib/components/ui/media/upload/network-upload-field/use-image-preview.d.ts +9 -1
- package/dist/lib/components/ui/primitives/tabs/Tabs.vue.d.ts +3 -0
- package/dist/lib/components/ui/primitives/tabs/index.d.ts +1 -0
- package/dist/lib/components/ui/primitives/tabs/tabs-variant.d.ts +9 -0
- package/dist/lib/components/ui/selection/autocomplete/autocomplete-form-field.vue.d.ts +31 -5
- package/dist/lib/components/ui/selection/autocomplete/autocomplete-items.d.ts +23 -0
- package/dist/lib/components/ui/selection/autocomplete/autocomplete.vue.d.ts +48 -13
- package/dist/lib/components/ui/selection/autocomplete/filter-options.d.ts +2 -1
- package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-box.vue.d.ts +13 -1
- package/dist/lib/components/ui/selection/autocomplete/partials/autocomplete-list.vue.d.ts +17 -3
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-items.d.ts +15 -0
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-open.d.ts +15 -0
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete-texts.d.ts +14 -0
- package/dist/lib/components/ui/selection/autocomplete/use-autocomplete.d.ts +34 -0
- package/dist/lib/components/ui/selection/index.d.ts +1 -0
- package/dist/lib/components/ui/selection/select-field/select-field.vue.d.ts +16 -1
- package/dist/lib/components/ui/selection/select-field/select-form-field.vue.d.ts +16 -2
- package/dist/lib/components/ui/selection/tree-select-field/index.d.ts +3 -0
- package/dist/lib/components/ui/selection/tree-select-field/partials/tree-select-panel.vue.d.ts +27 -0
- package/dist/lib/components/ui/selection/tree-select-field/partials/tree-select-trigger.vue.d.ts +28 -0
- package/dist/lib/components/ui/selection/tree-select-field/tree-select-field.vue.d.ts +8 -0
- package/dist/lib/components/ui/selection/tree-select-field/tree-select-form-field.vue.d.ts +8 -0
- package/dist/lib/components/ui/selection/tree-select-field/tree-select.utils.d.ts +29 -0
- package/dist/lib/components/ui/selection/tree-select-field/types.d.ts +28 -0
- package/dist/lib/components/ui/selection/tree-select-field/use-tree-select-field.d.ts +19 -0
- package/dist/lib/components/ui/widgets/code-editor/code-editor-options.d.ts +4 -1
- package/dist/lib/components/ui/widgets/code-editor/code-editor.vue.d.ts +7 -0
- package/dist/lib/components/ui/widgets/code-editor/index.d.ts +1 -0
- package/dist/lib/components/ui/widgets/code-editor/monaco-editor.vue.d.ts +3 -0
- package/dist/lib/i18n/resources/en/en.d.ts +33 -0
- package/dist/lib/i18n/resources/en/material.json.d.ts +36 -3
- package/dist/lib/i18n/resources/fr/fr.d.ts +33 -0
- package/dist/lib/i18n/resources/fr/material.json.d.ts +36 -3
- package/dist/lib/i18n/resources/resources.d.ts +66 -0
- package/dist/lib/i18n/translator.d.ts +1 -1
- package/dist/lib/nuxt/component-names.d.ts +1 -1
- package/dist/lib.js +2 -2
- package/dist/main.js +17 -17
- package/dist/map.js +4 -4
- package/dist/material-vue.css +1 -1
- package/dist/{pdf-outline-sidebar-0I-LGrgY.js → pdf-outline-sidebar-jJfhNjnN.js} +2 -2
- package/dist/{pdf-page-C74-6lyZ.js → pdf-page-BW1hXzPu.js} +1 -1
- package/dist/{pdf-page-list-DPsquYPY.js → pdf-page-list-D277RtWS.js} +2 -2
- package/dist/{pdf-reader-Bkpp7UZ7.js → pdf-reader-BReUTsn_.js} +73 -71
- package/dist/{pdf-sidebar-BH-1jvy-.js → pdf-sidebar-Bk6PowY1.js} +3 -3
- package/dist/{pdf-thumbnail-sidebar-ByqNaYfz.js → pdf-thumbnail-sidebar-BcNDFsks.js} +3 -3
- package/dist/{pdf-toolbar-BRnmzddi.js → pdf-toolbar-CHjaMhH9.js} +4 -4
- package/dist/pdf.js +2 -2
- package/dist/{sortable-provider-CC9eO1nm.js → sortable-provider-C83VBfGl.js} +2 -2
- package/dist/{stored-language-N_UoPJsY.js → stored-language-CC_vdcCN.js} +72 -6
- package/dist/{stx-player-BGKIDqNX.js → stx-player-BMQ1D2Li.js} +20 -20
- package/dist/{translator-CU0jKvzB.js → translator-B-X_1taI.js} +1 -1
- package/dist/{use-heading-spy-Bw1LIAkC.js → use-heading-spy-C_ySuvTl.js} +1 -1
- package/dist/{use-material-translation-8hUB2M-S.js → use-material-translation-B6sIk0mF.js} +3 -3
- package/docs/components/README.md +2 -1
- package/docs/components/data-display.md +51 -10
- package/docs/components/data-table-filter-and-lists.md +4 -0
- package/docs/components/date-and-time.md +116 -9
- package/docs/components/feedback-and-status.md +56 -4
- package/docs/components/form-fields.md +15 -5
- package/docs/components/media-and-files.md +119 -5
- package/docs/components/navigation-and-layout.md +2 -1
- package/docs/components/primitives.md +21 -4
- package/docs/components/rich-widgets.md +20 -3
- package/docs/components/selection-and-choice.md +135 -9
- package/docs/guides/forms.md +3 -4
- package/docs/guides/i18n.md +44 -4
- package/docs/previews/date-time-daterangefield.webp +0 -0
- package/docs/previews/media-files-filepreview.webp +0 -0
- package/docs/previews/selection-choice-treeselectfield.webp +0 -0
- package/docs/roadmap.md +45 -37
- package/docs/troubleshooting.md +140 -1
- package/lib/nuxt/component-names.ts +4 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./utils-CykWQ0iJ.js";
|
|
2
|
-
import {
|
|
3
|
-
import { t as l } from "./use-material-translation-
|
|
2
|
+
import { $t as t, Jt as n, Qt as r, Yt as i, Zt as a, en as o, jp as s, qt as c } from "./components-DRBKkOqk.js";
|
|
3
|
+
import { t as l } from "./use-material-translation-B6sIk0mF.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 = {
|
|
@@ -19,50 +19,50 @@ var S = ["data-layout", "aria-label"], C = {
|
|
|
19
19
|
Array
|
|
20
20
|
] }
|
|
21
21
|
},
|
|
22
|
-
setup(
|
|
23
|
-
let { containerRef: g, state: w } =
|
|
22
|
+
setup(i) {
|
|
23
|
+
let { containerRef: g, state: w } = o();
|
|
24
24
|
function T(e) {
|
|
25
25
|
g.value = e instanceof HTMLElement ? e : null;
|
|
26
26
|
}
|
|
27
27
|
let { t: E } = l();
|
|
28
|
-
return (
|
|
28
|
+
return (o, l) => (v(), f("section", {
|
|
29
29
|
ref: T,
|
|
30
30
|
"data-slot": "stx-player",
|
|
31
|
-
"data-layout":
|
|
31
|
+
"data-layout": i.layout,
|
|
32
32
|
"aria-label": b(w).current?.title ?? b(E)("material.stx-player.label", "Media player"),
|
|
33
|
-
class: _(b(e)("@container rounded outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
34
|
-
}, [
|
|
33
|
+
class: _(b(e)("@container rounded outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50", o.$props.class))
|
|
34
|
+
}, [i.layout === "mini" ? (v(), u(a, { key: 0 })) : (v(), f("div", {
|
|
35
35
|
key: 1,
|
|
36
|
-
class: _(b(e)("grid gap-3",
|
|
36
|
+
class: _(b(e)("grid gap-3", i.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(s, { 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(s, {
|
|
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(
|
|
49
|
-
default: x(() => [b(w).current?.kind === "audio" ? d("", !0) : (v(), u(
|
|
48
|
+
h(c, null, {
|
|
49
|
+
default: x(() => [b(w).current?.kind === "audio" ? d("", !0) : (v(), u(t, {
|
|
50
50
|
key: 0,
|
|
51
51
|
tone: "overlay"
|
|
52
52
|
}, {
|
|
53
|
-
trailing: x(() => [h(
|
|
53
|
+
trailing: x(() => [h(r, { tone: "overlay" })]),
|
|
54
54
|
_: 1
|
|
55
55
|
}))]),
|
|
56
56
|
_: 1
|
|
57
57
|
}),
|
|
58
|
-
b(w).current?.kind === "audio" ? (v(), u(
|
|
58
|
+
b(w).current?.kind === "audio" ? (v(), u(t, {
|
|
59
59
|
key: 1,
|
|
60
60
|
tone: "surface"
|
|
61
61
|
}, {
|
|
62
|
-
trailing: x(() => [h(
|
|
62
|
+
trailing: x(() => [h(r, { tone: "surface" })]),
|
|
63
63
|
_: 1
|
|
64
64
|
})) : d("", !0)
|
|
65
|
-
], 2),
|
|
65
|
+
], 2), i.showQueue ? (v(), u(n, {
|
|
66
66
|
key: 0,
|
|
67
67
|
class: "min-h-72"
|
|
68
68
|
})) : d("", !0)], 2))], 10, S));
|
|
@@ -99,16 +99,16 @@ var S = ["data-layout", "aria-label"], C = {
|
|
|
99
99
|
emits: ["trackChange"],
|
|
100
100
|
setup(e, { emit: t }) {
|
|
101
101
|
let n = e, r = t;
|
|
102
|
-
function
|
|
102
|
+
function a(e, t) {
|
|
103
103
|
n.onTrackChange?.(e, t), r("trackChange", e, t);
|
|
104
104
|
}
|
|
105
|
-
return (t, r) => (v(), u(
|
|
105
|
+
return (t, r) => (v(), u(i, {
|
|
106
106
|
tracks: e.tracks,
|
|
107
107
|
"current-index": e.currentIndex,
|
|
108
108
|
"default-index": e.defaultIndex,
|
|
109
109
|
"auto-play": e.autoPlay,
|
|
110
110
|
loop: e.loop,
|
|
111
|
-
"on-track-change":
|
|
111
|
+
"on-track-change": a
|
|
112
112
|
}, {
|
|
113
113
|
default: x(() => [h(w, {
|
|
114
114
|
layout: e.layout,
|
|
@@ -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-CC_vdcCN.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-D0oYv0XS.js";
|
|
2
2
|
import { c as t, d as n, f as r, l as i, n as a, u as o } from "./number.utils-Cy1z6qI7.js";
|
|
3
3
|
import { computed as s, getCurrentInstance as c, onMounted as l, ref as u, toValue as d } from "vue";
|
|
4
4
|
import { useIntersectionObserver as f, useMediaQuery as p, useSSRWidth as m, useStorage as h } from "@vueuse/core";
|
|
@@ -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-CC_vdcCN.js";
|
|
2
|
+
import { a as e } from "./i18n-provider-D0oYv0XS.js";
|
|
3
|
+
import { i as t, r as n } from "./translator-B-X_1taI.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]])) {
|
|
@@ -98,10 +98,11 @@ Telling the user what happened: alert, banner, confirm dialogs, empty state, pro
|
|
|
98
98
|
|
|
99
99
|
## [Media & files](media-and-files.md)
|
|
100
100
|
|
|
101
|
-
Uploads, file lists, images and cropping, galleries, carousel, PDF, audio/video player, camera, maps, print documents.
|
|
101
|
+
Uploads, file lists, file previews, images and cropping, galleries, carousel, PDF, audio/video player, camera, maps, print documents. 15 entries.
|
|
102
102
|
|
|
103
103
|
[<img src="../previews/media-files-uploadfield.webp" height="72" alt="UploadField">](media-and-files.md#uploadfield)
|
|
104
104
|
[<img src="../previews/media-files-filelist.webp" height="72" alt="FileList">](media-and-files.md#filelist)
|
|
105
|
+
[<img src="../previews/media-files-filepreview.webp" height="72" alt="FilePreview">](media-and-files.md#filepreview)
|
|
105
106
|
[<img src="../previews/media-files-imagecropper.webp" height="72" alt="ImageCropper">](media-and-files.md#imagecropper)
|
|
106
107
|
[<img src="../previews/media-files-pdfreader.webp" height="72" alt="PdfReader">](media-and-files.md#pdfreader)
|
|
107
108
|
|
|
@@ -35,7 +35,7 @@ from `@nxgt/material-vue/components`.
|
|
|
35
35
|
|
|
36
36
|

|
|
37
37
|
|
|
38
|
-
Round image with a fallback that shows while it loads or when it fails.
|
|
38
|
+
Round image with a fallback that shows while it loads or when it fails, and an optional presence dot.
|
|
39
39
|
|
|
40
40
|
```vue
|
|
41
41
|
<script setup lang="ts">
|
|
@@ -53,10 +53,23 @@ import { Avatar, AvatarFallback, AvatarImage } from '@nxgt/material-vue/componen
|
|
|
53
53
|
Parts: `Avatar` (the round frame), `AvatarImage` (`src`, `alt`),
|
|
54
54
|
`AvatarFallback` (initials or an icon in its slot). Size and shape come from
|
|
55
55
|
`class` (`size-12 rounded-md`). Unlike the React `Avatar`, there is no
|
|
56
|
-
`src` / `fallback`
|
|
57
|
-
[`StatusIndicator`](#statusindicator) beside it for an online dot.
|
|
56
|
+
`src` / `fallback` shorthand: compose the parts.
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
`status` adds a presence dot at the bottom right, named for a screen reader
|
|
59
|
+
(`role="img"`): `success` "Online", `neutral` "Offline", `warning` "Away",
|
|
60
|
+
`error` "Busy", any other tone "Active" (`material.avatar.*`, translated).
|
|
61
|
+
`status-pulse` animates it. Attributes still land on the avatar itself.
|
|
62
|
+
|
|
63
|
+
```vue
|
|
64
|
+
<template>
|
|
65
|
+
<Avatar status="success" class="size-10">
|
|
66
|
+
<AvatarImage src="/people/ada.png" alt="Ada Lovelace" />
|
|
67
|
+
<AvatarFallback>AL</AvatarFallback>
|
|
68
|
+
</Avatar>
|
|
69
|
+
</template>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Storybook:** `Data display/Avatar` (story `Status`) · **React:** `Avatar`, `AvatarImage`, `AvatarFallback`
|
|
60
73
|
|
|
61
74
|
---
|
|
62
75
|
|
|
@@ -463,7 +476,7 @@ import { Icon, ListTile } from '@nxgt/material-vue/components';
|
|
|
463
476
|
|
|
464
477
|

|
|
465
478
|
|
|
466
|
-
Renders `items` (title, content) as a styled accordion.
|
|
479
|
+
Renders `items` (title, content) as a styled accordion, with `#header`, `#title` and `#content` slots.
|
|
467
480
|
|
|
468
481
|
```vue
|
|
469
482
|
<script setup lang="ts">
|
|
@@ -492,11 +505,37 @@ const open = ref('shipping');
|
|
|
492
505
|
| `showIcon` | `boolean` | `true` | decorative chevron on each header, inside the trigger `<button>` |
|
|
493
506
|
| `v-model` | `string \| string[]` | — | open item(s); omit for an uncontrolled accordion |
|
|
494
507
|
|
|
495
|
-
Titles and content are strings;
|
|
496
|
-
|
|
508
|
+
Titles and content are strings; the slots take markup instead (React's
|
|
509
|
+
`title` / `content` nodes and `renderHeader`). Each receives `{ item, index }`:
|
|
510
|
+
|
|
511
|
+
| Slot | Replaces |
|
|
512
|
+
| --- | --- |
|
|
513
|
+
| `#title` | the header's text, beside the chevron |
|
|
514
|
+
| `#content` | the panel's content |
|
|
515
|
+
| `#header` (also `title`) | the whole header: one element, which becomes the trigger — a `<button>`, as React's `renderHeader` returns |
|
|
516
|
+
|
|
517
|
+
```vue
|
|
518
|
+
<script setup lang="ts">
|
|
519
|
+
import { ref } from 'vue';
|
|
520
|
+
import { AccordionCard } from '@nxgt/material-vue/components';
|
|
521
|
+
|
|
522
|
+
const open = ref('shipping');
|
|
523
|
+
const items = [
|
|
524
|
+
{ key: 'shipping', title: 'Shipping', content: 'Ships within two working days.' },
|
|
525
|
+
{ key: 'returns', title: 'Returns', content: 'Free returns for 30 days.' },
|
|
526
|
+
];
|
|
527
|
+
</script>
|
|
528
|
+
|
|
529
|
+
<template>
|
|
530
|
+
<AccordionCard v-model="open" :items="items">
|
|
531
|
+
<template #title="{ item, index }">{{ index + 1 }}. {{ item.title }}</template>
|
|
532
|
+
<template #content="{ item }"><p><strong>{{ item.title }}:</strong> {{ item.content }}</p></template>
|
|
533
|
+
</AccordionCard>
|
|
534
|
+
</template>
|
|
535
|
+
```
|
|
497
536
|
|
|
498
537
|
**Emits:** `update:modelValue` with `string | string[]`.
|
|
499
|
-
**Storybook:** `Data display/AccordionCard` · **React:** `AccordionCard`
|
|
538
|
+
**Storybook:** `Data display/AccordionCard` (story `Slots`) · **React:** `AccordionCard`
|
|
500
539
|
|
|
501
540
|
---
|
|
502
541
|
|
|
@@ -816,7 +855,9 @@ import { QRCode } from '@nxgt/material-vue/components';
|
|
|
816
855
|
|
|
817
856
|
<template>
|
|
818
857
|
<QRCode value="https://example.com/tickets/DS-184" :size="160" level="H">
|
|
819
|
-
<
|
|
858
|
+
<template #logo>
|
|
859
|
+
<img src="/logo.svg" alt="" width="32" />
|
|
860
|
+
</template>
|
|
820
861
|
</QRCode>
|
|
821
862
|
</template>
|
|
822
863
|
```
|
|
@@ -829,7 +870,7 @@ import { QRCode } from '@nxgt/material-vue/components';
|
|
|
829
870
|
| `fgColor`, `bgColor` | `string` | `'#000000'`, `'#FFFFFF'` | colours |
|
|
830
871
|
| `title` | `string` | — | accessible label of the SVG |
|
|
831
872
|
| `aria-label` | `string` | — | the SVG's name too, and wins over `title` |
|
|
832
|
-
|
|
|
873
|
+
| `#logo` | slot | — | the logo, centred over the code on a white pad (React's `logo`); the default slot still works |
|
|
833
874
|
|
|
834
875
|
The code is an `<svg role="img">` named by `aria-label`, else `title`, else
|
|
835
876
|
"QR code" (`material.qrcode.label`, translated):
|
|
@@ -392,6 +392,10 @@ own) and `TreeItem` (one row); `findTreeNode` and `flattenVisibleTree`.
|
|
|
392
392
|
Arrow keys move and expand / collapse, Home / End jump, Enter and Space
|
|
393
393
|
select.
|
|
394
394
|
|
|
395
|
+
Tab lands on the focused row, or on the first visible row when that one is
|
|
396
|
+
filtered or folded away. `useTree` returns that row as `tabbableId`: give it
|
|
397
|
+
`tabindex="0"` in a tree you build yourself.
|
|
398
|
+
|
|
395
399
|
**Emits:** `update:selectedIds` and `update:expandedIds` with `string[]`, `select`.
|
|
396
400
|
**Storybook:** `Data table, filter & lists/Tree` · **React:** `Tree`, `TreeItem`, `useTree`
|
|
397
401
|
|
|
@@ -70,7 +70,7 @@ No form wrapper — use `DateFormField`.
|
|
|
70
70
|
|
|
71
71
|

|
|
72
72
|
|
|
73
|
-
Labelled trigger that opens a calendar popover, with an optional time picker
|
|
73
|
+
Labelled trigger that opens a calendar popover, with an optional time picker and `disabled-days`.
|
|
74
74
|
|
|
75
75
|
```vue
|
|
76
76
|
<script setup lang="ts">
|
|
@@ -81,7 +81,12 @@ const delivery = ref<Date | undefined>();
|
|
|
81
81
|
</script>
|
|
82
82
|
|
|
83
83
|
<template>
|
|
84
|
-
<DateField
|
|
84
|
+
<DateField
|
|
85
|
+
v-model="delivery"
|
|
86
|
+
label="Delivery date"
|
|
87
|
+
placeholder="Pick a day"
|
|
88
|
+
:disabled-days="[{ dayOfWeek: [0] }, { before: new Date() }]"
|
|
89
|
+
/>
|
|
85
90
|
</template>
|
|
86
91
|
```
|
|
87
92
|
|
|
@@ -89,10 +94,12 @@ const delivery = ref<Date | undefined>();
|
|
|
89
94
|
| --- | --- | --- | --- |
|
|
90
95
|
| `v-model` | `Date \| undefined` | — | the selected day, shown in the short `P` format |
|
|
91
96
|
| `show-time-picker` | `boolean` | — | adds a `TimePicker` and an OK button; the popover stays open |
|
|
97
|
+
| `disabled-days` | `DisabledDays` | — | days that cannot be picked: a `Date`, a `Date[]`, `{ from, to }` (ends included), `{ before }`, `{ after }`, `{ before, after }`, `{ dayOfWeek }` (`0` is Sunday), a `(date) => boolean`, or a list of those (any that matches) — React's `disabledDays` |
|
|
92
98
|
| `placeholder`, `label`, `helper-text`, `error`, `required`, `disabled` | | — | `placeholder` is the trigger's text; `label` and `helper-text` sit beside it; `error`, `required` and `disabled` its state |
|
|
93
99
|
|
|
94
|
-
Unlike React, the calendar's
|
|
95
|
-
through
|
|
100
|
+
Unlike React, the calendar's other props (bounds, the first month) are not
|
|
101
|
+
passed through: use `disabled-days` for both bounds and days. A disabled day
|
|
102
|
+
is greyed out and cannot be picked. The popover closes on the first pick unless `show-time-picker` is
|
|
96
103
|
set, and picking a day keeps the time of the current value.
|
|
97
104
|
|
|
98
105
|
Attributes you put on the field (`id`, `aria-describedby`, `data-*`,
|
|
@@ -113,7 +120,7 @@ before your `aria-describedby` ids.
|
|
|
113
120
|
**Emits:** `update:modelValue` with `Date | undefined`.
|
|
114
121
|
**Form wrapper:** `DateFormField` — `name` inside a vee-validate form, see
|
|
115
122
|
[forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
|
|
116
|
-
**Storybook:** `Date & time/DateField` · **React:** `DateField`, `DateFormField`
|
|
123
|
+
**Storybook:** `Date & time/DateField` (story `DisabledDays`) · **React:** `DateField`, `DateFormField`
|
|
117
124
|
|
|
118
125
|
---
|
|
119
126
|
|
|
@@ -121,7 +128,7 @@ before your `aria-describedby` ids.
|
|
|
121
128
|
|
|
122
129
|

|
|
123
130
|
|
|
124
|
-
From / to range picked in a popover calendar.
|
|
131
|
+
From / to range picked in a popover calendar, with `disabled-days`, presets and times.
|
|
125
132
|
|
|
126
133
|
```vue
|
|
127
134
|
<script setup lang="ts">
|
|
@@ -132,17 +139,26 @@ const stay = ref<DateRange | undefined>();
|
|
|
132
139
|
</script>
|
|
133
140
|
|
|
134
141
|
<template>
|
|
135
|
-
<DateRangeField
|
|
142
|
+
<DateRangeField
|
|
143
|
+
v-model="stay"
|
|
144
|
+
label="Stay"
|
|
145
|
+
placeholder="Check-in – check-out"
|
|
146
|
+
:disabled-days="{ dayOfWeek: [0] }"
|
|
147
|
+
/>
|
|
136
148
|
</template>
|
|
137
149
|
```
|
|
138
150
|
|
|
139
151
|
| Prop | Type | Default | Effect |
|
|
140
152
|
| --- | --- | --- | --- |
|
|
141
153
|
| `v-model` | `DateRange \| undefined` | — | `{ from?: Date; to?: Date }` |
|
|
154
|
+
| `disabled-days` | `DisabledDays` | — | days that cannot be picked: a `Date`, a `Date[]`, `{ from, to }` (ends included), `{ before }`, `{ after }`, `{ before, after }`, `{ dayOfWeek }` (`0` is Sunday), a `(date) => boolean`, or a list of those (any that matches) — as on `DateField` |
|
|
142
155
|
| `placeholder`, `label`, `helper-text`, `error`, `required`, `disabled` | | — | `placeholder` is the trigger's text; `label` and `helper-text` sit beside it; `error`, `required` and `disabled` its state |
|
|
156
|
+
| `presets` | `readonly DateRangePresetOption[]` | — (no list) | one-click ranges beside the calendar: built-in ids (`DATE_RANGE_PRESET_IDS`) and `{ label, range }` of your own |
|
|
157
|
+
| `with-time` | `boolean` | `false` | a time of day on each end, under the calendar, and on the trigger; the popover stays open until OK |
|
|
158
|
+
| `min-date`, `max-date` | `Date` | — | the first and last day that can be picked (Reka's `minValue` / `maxValue`) |
|
|
143
159
|
|
|
144
160
|
It emits on each click (`to` is unset after the first) and closes the popover
|
|
145
|
-
once both ends are picked.
|
|
161
|
+
once both ends are picked (with `with-time`, OK closes it).
|
|
146
162
|
|
|
147
163
|
Attributes you put on the field (`id`, `aria-describedby`, `data-*`,
|
|
148
164
|
listeners) go on the trigger, the element that has focus, not on the field's
|
|
@@ -159,11 +175,97 @@ the helper text sit beside the trigger in the field's root `div`
|
|
|
159
175
|
(`data-slot="date-range-field"`), not in it; the helper text describes the trigger
|
|
160
176
|
before your `aria-describedby` ids.
|
|
161
177
|
|
|
178
|
+
### Presets
|
|
179
|
+
|
|
180
|
+
`presets` lists one-click ranges beside the calendar (above it on a narrow
|
|
181
|
+
screen), in the order you give them. A built-in id is translated
|
|
182
|
+
(`material.date-range-field.preset.<id>`); a preset of your own is
|
|
183
|
+
`{ label, range }`, where `range` is `{ from, to }` or `(now) => ({ from, to })`.
|
|
184
|
+
|
|
185
|
+
```vue
|
|
186
|
+
<script setup lang="ts">
|
|
187
|
+
import { ref } from 'vue';
|
|
188
|
+
import {
|
|
189
|
+
type DateRange,
|
|
190
|
+
DateRangeField,
|
|
191
|
+
type DateRangePreset,
|
|
192
|
+
} from '@nxgt/material-vue/components';
|
|
193
|
+
|
|
194
|
+
const lastQuarter: DateRangePreset = {
|
|
195
|
+
label: 'Last quarter',
|
|
196
|
+
range: (now) => {
|
|
197
|
+
const start = new Date(now.getFullYear(), Math.floor(now.getMonth() / 3) * 3 - 3, 1);
|
|
198
|
+
return { from: start, to: new Date(start.getFullYear(), start.getMonth() + 3, 0) };
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
const period = ref<DateRange | undefined>();
|
|
202
|
+
const today = new Date();
|
|
203
|
+
</script>
|
|
204
|
+
|
|
205
|
+
<template>
|
|
206
|
+
<DateRangeField
|
|
207
|
+
v-model="period"
|
|
208
|
+
label="Period"
|
|
209
|
+
:max-date="today"
|
|
210
|
+
:presets="['today', 'last-7-days', 'this-month', 'last-month', lastQuarter]"
|
|
211
|
+
/>
|
|
212
|
+
</template>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
| Built-in id | Range |
|
|
216
|
+
| --- | --- |
|
|
217
|
+
| `today`, `yesterday` | that day |
|
|
218
|
+
| `last-7-days`, `last-30-days` | ends today and counts it |
|
|
219
|
+
| `this-month`, `this-year` | from the first day to today |
|
|
220
|
+
| `last-month` | the whole previous month |
|
|
221
|
+
|
|
222
|
+
A built-in range starts at 00:00 (and with `with-time` ends at 23:59); your
|
|
223
|
+
own ranges keep the times you gave them. Picking a preset sets the value and
|
|
224
|
+
closes the popover (with `with-time` it stays open); open again, the calendar
|
|
225
|
+
is on that range's month. The list is a group named "Presets"
|
|
226
|
+
(`material.date-range-field.presets`) of buttons in the tab order, and the
|
|
227
|
+
one whose days are the value's has `aria-pressed="true"`. A preset is
|
|
228
|
+
disabled when its range starts before `min-date`, ends after `max-date`, or
|
|
229
|
+
either end is one of `disabled-days`; the days between are not checked, as the
|
|
230
|
+
calendar lets a range span a disabled day.
|
|
231
|
+
The built-in presets use the current date when the popover opens; there is
|
|
232
|
+
no `now` prop, and none is planned. A preset of your own whose end comes
|
|
233
|
+
before its start is disabled.
|
|
234
|
+
|
|
235
|
+
### Times
|
|
236
|
+
|
|
237
|
+
`with-time` adds two `TimePicker`s under the calendar, in groups named
|
|
238
|
+
"Start time" and "End time" (`material.date-range-field.start-time`,
|
|
239
|
+
`.end-time`), each disabled until its end has a day, and an OK button
|
|
240
|
+
(`material.buttons.ok`) that closes the popover. The trigger shows each end
|
|
241
|
+
with its time (date-fns `Pp`).
|
|
242
|
+
|
|
243
|
+
```vue
|
|
244
|
+
<script setup lang="ts">
|
|
245
|
+
import { ref } from 'vue';
|
|
246
|
+
import { type DateRange, DateRangeField } from '@nxgt/material-vue/components';
|
|
247
|
+
|
|
248
|
+
const slot = ref<DateRange | undefined>();
|
|
249
|
+
</script>
|
|
250
|
+
|
|
251
|
+
<template>
|
|
252
|
+
<DateRangeField v-model="slot" label="Booking" with-time :presets="['today']" />
|
|
253
|
+
</template>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
A day picked on the calendar keeps the time that end had; a new start is
|
|
257
|
+
00:00 and a new end 23:59, as a built-in preset ends, so a filter on
|
|
258
|
+
`<= to` keeps the last day. On the same day, an end time set before the
|
|
259
|
+
start time becomes the start time.
|
|
260
|
+
|
|
261
|
+
Without `with-time`, a picked day carries the current time of day.
|
|
262
|
+
(`@nxgt/material` gives it 00:00.)
|
|
263
|
+
|
|
162
264
|
**Emits:** `update:modelValue` with `DateRange | undefined` — `{ from, to }`,
|
|
163
265
|
where `to` stays `undefined` until the second day is picked.
|
|
164
266
|
**Form wrapper:** `DateRangeFormField` — `name` inside a vee-validate form, see
|
|
165
267
|
[forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
|
|
166
|
-
**Storybook:** `Date & time/DateRangeField` · **React:** `DateRangeField`, `DateRangeFormField`
|
|
268
|
+
**Storybook:** `Date & time/DateRangeField` (stories `DisabledDays`, `MinMaxDates`, `Presets`, `DisabledPresets`, `WithTime`) · **React:** `DateRangeField`, `DateRangeFormField` (`withTime`, `minDate` / `maxDate`; without time, a picked day is at 00:00 there, the current time of day here)
|
|
167
269
|
|
|
168
270
|
---
|
|
169
271
|
|
|
@@ -245,6 +347,11 @@ const time = ref<Date | undefined>(new Date());
|
|
|
245
347
|
| `label` | `string` | — | header text |
|
|
246
348
|
| `#footer` | slot | — | under the inputs (the OK button in `TimeField`) |
|
|
247
349
|
|
|
350
|
+
The hours and minutes inputs are named "Hours" and "Minutes"
|
|
351
|
+
(`material.time-picker.hours`, `.minutes`). AM / PM shows the half of the day
|
|
352
|
+
`date` is in, so a date changed from outside shows its own; switching it moves
|
|
353
|
+
the time 12 hours, and a click on the pressed half changes nothing.
|
|
354
|
+
|
|
248
355
|
**Emits:** `change` with `Date | undefined` (no `v-model`). No form wrapper —
|
|
249
356
|
use `TimeFormField`.
|
|
250
357
|
**Storybook:** `Date & time/TimePicker` · **React:** `TimePicker`
|
|
@@ -240,14 +240,66 @@ function archive() {}
|
|
|
240
240
|
| --- | --- | --- | --- |
|
|
241
241
|
| `#trigger` slot | — | — | becomes the dialog trigger (`as-child`, no extra button): pass one element, such as a `Button` |
|
|
242
242
|
| `v-model:open` | `boolean` | uncontrolled | open state; without it the dialog keeps its own |
|
|
243
|
-
| `@confirm` | `() => void` | — | emitted on confirm; the dialog then closes |
|
|
243
|
+
| `@confirm` | `(values?) => void` | — | emitted on confirm, with the form's parsed values when there is one; the dialog then closes |
|
|
244
|
+
| `form-options` | `ConfirmationDialogFormOptions` (`{ schema, defaultValues? }`) | — | a form in the dialog, below the default slot — see below |
|
|
244
245
|
| `color` | `IconButton` colour | `'warning'` | icon and both buttons |
|
|
245
246
|
| `variant` | `IconButton` variant | `'tonal'` | the icon's button style |
|
|
246
247
|
| `#icon` slot | — | info icon, in a decorative `aria-hidden` badge | replaces the badge: keep yours decorative (`<IconButton as="span" aria-hidden="true">`), not a button that does nothing |
|
|
247
248
|
| `confirm-text` / `cancel-text` | `string` | "Confirm" / "Cancel", translated (`material.confirm-dialog.confirm` / `.cancel`) | button text |
|
|
248
249
|
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
`form-options` puts a form in the confirmation, as React's `formOptions`:
|
|
251
|
+
`schema` is a Zod 4 schema (any Standard Schema, or a vee-validate typed
|
|
252
|
+
schema), `defaultValues` its initial values, and the `#form` slot renders the
|
|
253
|
+
fields — `*-form-field` wrappers in it join the form. The confirm button stays
|
|
254
|
+
disabled until the form is valid, and `@confirm` receives the schema's output
|
|
255
|
+
(transforms applied). The component is generic, so that payload is typed from
|
|
256
|
+
the schema; to type the options apart from the template, import
|
|
257
|
+
`ConfirmationDialogFormOptions<TInput, TOutput>` from
|
|
258
|
+
`@nxgt/material-vue/components`. Being generic, its ref is typed with
|
|
259
|
+
`ComponentExposed`, not `InstanceType`
|
|
260
|
+
([troubleshooting](../troubleshooting.md#does-not-satisfy-the-constraint-abstract-new-args-any--any)).
|
|
261
|
+
|
|
262
|
+
```vue
|
|
263
|
+
<script setup lang="ts">
|
|
264
|
+
import { z } from 'zod';
|
|
265
|
+
import { Button, ConfirmationDialog, TextFormField } from '@nxgt/material-vue/components';
|
|
266
|
+
|
|
267
|
+
const formOptions = {
|
|
268
|
+
schema: z.object({ project: z.string().trim().pipe(z.literal('my-project')) }),
|
|
269
|
+
defaultValues: { project: '' },
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
function remove(values?: { project: 'my-project' }) {
|
|
273
|
+
console.log('deleting', values?.project);
|
|
274
|
+
}
|
|
275
|
+
</script>
|
|
276
|
+
|
|
277
|
+
<template>
|
|
278
|
+
<ConfirmationDialog
|
|
279
|
+
title="Delete project"
|
|
280
|
+
description='Type "my-project" to confirm.'
|
|
281
|
+
color="error"
|
|
282
|
+
confirm-text="Delete"
|
|
283
|
+
:form-options="formOptions"
|
|
284
|
+
@confirm="remove"
|
|
285
|
+
>
|
|
286
|
+
<template #trigger>
|
|
287
|
+
<Button color="error">Delete project</Button>
|
|
288
|
+
</template>
|
|
289
|
+
<template #form>
|
|
290
|
+
<TextFormField name="project" label="Project name" />
|
|
291
|
+
</template>
|
|
292
|
+
</ConfirmationDialog>
|
|
293
|
+
</template>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
`#form` also receives `{ values, errors, meta, setFieldValue }` for fields
|
|
297
|
+
that are not form wrappers. The form lives with the dialog's content, so it
|
|
298
|
+
starts again from `defaultValues` each time the dialog opens. The form's code
|
|
299
|
+
(and vee-validate) loads only when a dialog has `form-options`; confirm stays
|
|
300
|
+
disabled until it has loaded and first validated. If it cannot load, after one
|
|
301
|
+
retry, a translated message takes its place
|
|
302
|
+
(`material.confirm-dialog.form-failed`).
|
|
251
303
|
|
|
252
304
|

|
|
253
305
|
|
|
@@ -257,7 +309,7 @@ but built on `AlertDialog`, so it does not close on an outside click. Put
|
|
|
257
309
|
`AlertDialogCancel` / `AlertDialogAction` in its `#footer`. Its trigger is
|
|
258
310
|
`as-child`, so a `Button` goes straight in.
|
|
259
311
|
|
|
260
|
-
**Storybook:** `Feedback & status/ConfirmDialog`, `Feedback & status/ConfirmationDialog
|
|
312
|
+
**Storybook:** `Feedback & status/ConfirmDialog`, `Feedback & status/ConfirmationDialog` (story `WithForm`),
|
|
261
313
|
`Feedback & status/CustomAlertDialog` · **React:** `ConfirmDialog`, `ConfirmationDialog`, `CustomAlertDialog`
|
|
262
314
|
|
|
263
315
|
---
|
|
@@ -267,6 +267,7 @@ const quantity = ref<number | null>(2);
|
|
|
267
267
|
| `hide-steppers` | `boolean` | `false` | hides the +/− buttons |
|
|
268
268
|
| `#suffix` | slot | — | unit after the input |
|
|
269
269
|
| `aria-label` | `string` | — | names the input when it has no `label` (a part of a larger field) |
|
|
270
|
+
| `aria-labelledby` | `string` | — | names the input by another element's id (a part of a larger field) |
|
|
270
271
|
|
|
271
272
|
**Emits:** `update:modelValue` with `number | null`.
|
|
272
273
|
**Form wrapper:** `NumberFormField` — `name` inside a vee-validate form, see
|
|
@@ -600,9 +601,14 @@ const title = ref('Spring catalogue');
|
|
|
600
601
|
| --- | --- | --- | --- |
|
|
601
602
|
| `v-model` | `string` | `''` | the committed text; updated on save only |
|
|
602
603
|
| `@save` | `(value: string) => void` | — | on save (Enter or the check button), not on each key |
|
|
604
|
+
| `label` | `string` | — | shown above the text; names the input while editing |
|
|
605
|
+
| `name` | `string` | — | the input's `name` while editing, and the field's `data-pw` |
|
|
603
606
|
| `placeholder` | `string` | "Click to edit" | shown while empty |
|
|
604
607
|
| `disabled` | `boolean` | `false` | read-only text |
|
|
605
608
|
|
|
609
|
+
Enter, Escape, Save and Cancel return focus to the field, while a click
|
|
610
|
+
elsewhere saves and leaves focus where it went.
|
|
611
|
+
|
|
606
612
|
**Emits:** `update:modelValue` and `save`, both `string`, trimmed, on save
|
|
607
613
|
only.
|
|
608
614
|
**Form wrapper:** `InlineEditFormField` (`name` plus the same props; the form
|
|
@@ -720,7 +726,7 @@ name: 'Satisfaction' })`.
|
|
|
720
726
|
|
|
721
727
|

|
|
722
728
|
|
|
723
|
-
Labelled single or range slider with a value readout.
|
|
729
|
+
Labelled single or range slider with a value readout, ticks and leading / trailing content.
|
|
724
730
|
|
|
725
731
|
```vue
|
|
726
732
|
<script setup lang="ts">
|
|
@@ -731,20 +737,24 @@ const price = ref<number[]>([20, 70]);
|
|
|
731
737
|
</script>
|
|
732
738
|
|
|
733
739
|
<template>
|
|
734
|
-
<SliderField v-model="price" label="Price" :min="0" :max="100" />
|
|
740
|
+
<SliderField v-model="price" label="Price" :min="0" :max="100" :ticks="5" leading="0" trailing="100" />
|
|
735
741
|
</template>
|
|
736
742
|
```
|
|
737
743
|
|
|
738
744
|
In Vue the labelled field is `SliderField`; `Slider` is the bare Reka UI
|
|
739
745
|
slider (track, range and thumbs, `v-model` always `number[]`) it is built on.
|
|
740
|
-
React's
|
|
741
|
-
|
|
746
|
+
React's editable readout inputs are not in `SliderField`: its readout is
|
|
747
|
+
text. `ticks`, `leading` and `trailing` are; for markup on either side of the
|
|
748
|
+
track, use the `#leading` / `#trailing` slots (`SliderFormField` passes them
|
|
749
|
+
through).
|
|
742
750
|
|
|
743
751
|
| Prop | Type | Default | Effect |
|
|
744
752
|
| --- | --- | --- | --- |
|
|
745
753
|
| `v-model` | `number \| number[]` | `[min]` shown when unset | a number for one thumb, an array for one thumb per entry: `[20, 70]` |
|
|
746
754
|
| `min`, `max`, `step` | `number` | `0`, `100`, `1` | range and increment |
|
|
747
755
|
| `show-readout` | `boolean` | `true` | the value(s) next to the label |
|
|
756
|
+
| `ticks` | `boolean \| number` | — | marks under the track: `true` one per `step` (at most 21), a number that many, ends included |
|
|
757
|
+
| `leading`, `trailing` | `string \| number` | — | small muted text before / after the track; the `#leading` / `#trailing` slots take markup |
|
|
748
758
|
| `required` | `boolean` | — | the asterisk, and `aria-required` on every thumb |
|
|
749
759
|
| `aria-invalid` | `boolean \| 'true' \| 'false'` | follows `error` | on every thumb; wins over `error` |
|
|
750
760
|
|
|
@@ -764,7 +774,7 @@ wins over `error` as on React's `Slider`) goes on every thumb, not on the root
|
|
|
764
774
|
stores the same — the initial value decides.
|
|
765
775
|
**Form wrapper:** `SliderFormField` — `name` inside a vee-validate form, see
|
|
766
776
|
[forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
|
|
767
|
-
**Storybook:** `Form fields/Slider` · **React:** `Slider`, `SliderField` (an alias of `Slider`), `SliderFormField`
|
|
777
|
+
**Storybook:** `Form fields/Slider` (story `TicksAndEnds`) · **React:** `Slider`, `SliderField` (an alias of `Slider`), `SliderFormField`
|
|
768
778
|
|
|
769
779
|
---
|
|
770
780
|
|