@robuust-digital/vue-components 2.5.0-beta.4 → 2.6.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 CHANGED
@@ -1,15 +1,49 @@
1
- ## 2.4.0 (UNRELEASED)
1
+ ## 2.6.0 (14-04-2026)
2
+
3
+ ### Added
4
+
5
+ * `DataTable`: Added optional `tbody` slot (`#tbody="{ items }"`) for full loaded-state tbody customization
6
+
7
+ ### Updated
8
+
9
+ * `DataTable` docs: Documented `tbody` slot and clarified that consumers own row markup when using it
10
+
11
+ ## 2.5.0 (14-04-2026)
12
+
13
+ ### Added
14
+
15
+ * `Modal`: Added `panel` slot to replace the full content inside `DialogPanel` with a custom modal layout
16
+ * `Drawer`: Added `panel` slot to replace the full content inside `DialogPanel` with a custom drawer layout
17
+
18
+ ### Updated
19
+
20
+ * `Modal` and `Drawer` docs: Added examples for the new full-panel override slot
21
+ * `Modal`: Forward `showClose` to the `header` slot to match the documented slot API
22
+
23
+ ## 2.4.1 (13-04-2026)
24
+
25
+ ### Fixed
26
+
27
+ * `Pagination`: Do not apply hover background styles to active pagination buttons
28
+
29
+ ## 2.4.0 (10-04-2026)
2
30
 
3
31
  ### Added
4
32
 
5
33
  * `Pagination`: Added `prevIcon` and `nextIcon` props to customize previous/next navigation icons
6
34
  * `Pagination`: Added `prevIcon` and `nextIcon` slots for full control over previous/next navigation icon rendering
7
35
  * `Pagination`: Added `--rvc-pagination-border-color` CSS variable for pagination button border customization
36
+ * `DataTable`: Added striped row token hooks (`--rvc-table-striped-cell-border-color`, `--rvc-table-striped-cell-border-style`, `--rvc-table-striped-cell-border-width`, `--rvc-table-striped-row-bg-color-hover`)
37
+ * `Pagination`: Added token hooks for active state and navigation layout (`--rvc-pagination-bg-color-active`, `--rvc-pagination-nav-gap-md`, `--rvc-pagination-nav-gap-xl`, `--rvc-pagination-icon-color`)
38
+ * `Tabs`: Added button variant border token hooks (`--rvc-tabs-tab-button-border-width`, `--rvc-tabs-tab-button-border-style`, `--rvc-tabs-tab-button-border-color`, `--rvc-tabs-tab-button-border-color-active`)
39
+ * `Badge`: Added border token hooks (`--rvc-badge-border-width`, `--rvc-badge-border-style`, `--rvc-badge-border-color`)
40
+ * `EmptyState`: Added border token hooks (`--rvc-empty-state-border-width`, `--rvc-empty-state-border-style`, `--rvc-empty-state-border-color`)
8
41
  * `DataTable`: Added support for forwarding `prevIcon` and `nextIcon` props to the built-in `Pagination` component
9
42
 
10
43
  ### Updated
11
44
 
12
45
  * `Pagination` and `DataTable` documentation: Added examples and prop documentation for custom pagination navigation icons
46
+ * Updated `DataTable`, `Pagination`, `Tabs`, `Badge`, and `EmptyState` docs with new CSS variables
13
47
 
14
48
  ## 2.3.5 (09-04-2026)
15
49
 
@@ -0,0 +1,197 @@
1
+ import { defineComponent as E, openBlock as v, createBlock as k, unref as e, withCtx as d, createVNode as s, withModifiers as T, createElementVNode as o, normalizeClass as m, renderSlot as i, createElementBlock as p, createTextVNode as F, toDisplayString as L, createCommentVNode as g } from "vue";
2
+ import { TransitionRoot as I, Dialog as N, TransitionChild as C, DialogPanel as R, DialogTitle as u } from "@headlessui/vue";
3
+ import { _ as $ } from "./ButtonBase.vue_vue_type_script_setup_true_lang-ZYVNEyNx.js";
4
+ import { u as V } from "./Modal.vue_vue_type_script_setup_true_lang-MN3D46CX.js";
5
+ import { r as B } from "./XMarkIcon-CPr_Rd8y.js";
6
+ const A = {
7
+ class: "rvc-drawer-presentation",
8
+ role: "presentation"
9
+ }, H = { class: "rvc-drawer-container" }, z = { class: "rvc-drawer-inner" }, M = { class: "rvc-drawer-panel-inner" }, P = { class: "rvc-drawer-header-inner" }, j = { class: "rvc-drawer-close-wrapper" }, q = ["id"], G = {
10
+ key: 2,
11
+ class: "rvc-drawer-footer"
12
+ }, W = /* @__PURE__ */ E({
13
+ __name: "Drawer",
14
+ props: {
15
+ as: { default: "form" },
16
+ id: {},
17
+ title: {},
18
+ showClose: { type: Boolean, default: !1 },
19
+ scrolledDown: { type: Boolean, default: !1 },
20
+ headerSticky: { type: Boolean, default: !1 },
21
+ spinning: { type: Boolean, default: !1 },
22
+ submitLabel: { default: "Save" },
23
+ cancelLabel: { default: "Cancel" },
24
+ panelClass: { default: "rvc-drawer-panel-max-width" },
25
+ resetHeader: { type: Boolean, default: !1 },
26
+ resetFooter: { type: Boolean, default: !1 }
27
+ },
28
+ emits: ["drawer:open", "drawer:opened", "drawer:close", "drawer:save", "drawer:closed"],
29
+ setup(r, { emit: h }) {
30
+ const D = r, a = h, {
31
+ contentRef: b,
32
+ ready: f,
33
+ isForm: y,
34
+ titleId: c,
35
+ descriptionId: w,
36
+ initialFocusElement: S
37
+ } = V(D);
38
+ return (n, t) => (v(), k(e(I), { as: "template" }, {
39
+ default: d(() => [
40
+ s(e(N), {
41
+ as: r.as,
42
+ class: "rvc-drawer",
43
+ static: "",
44
+ "aria-modal": "true",
45
+ role: "dialog",
46
+ "initial-focus": e(S),
47
+ "aria-labelledby": e(c),
48
+ onClose: t[6] || (t[6] = (l) => a("drawer:close")),
49
+ onSubmit: t[7] || (t[7] = T((l) => a("drawer:save", l), ["prevent"]))
50
+ }, {
51
+ default: d(() => [
52
+ s(e(C), {
53
+ as: "template",
54
+ enter: "rvc-drawer-backdrop-transition-enter",
55
+ "enter-from": "rvc-drawer-backdrop-transition-enter-from",
56
+ "enter-to": "rvc-drawer-backdrop-transition-enter-to",
57
+ leave: "rvc-drawer-backdrop-transition-leave",
58
+ "leave-from": "rvc-drawer-backdrop-transition-leave-from",
59
+ "leave-to": "rvc-drawer-backdrop-transition-leave-to",
60
+ onBeforeEnter: t[0] || (t[0] = (l) => a("drawer:open")),
61
+ onAfterEnter: t[1] || (t[1] = (l) => a("drawer:opened"))
62
+ }, {
63
+ default: d(() => [...t[8] || (t[8] = [
64
+ o("div", {
65
+ class: "rvc-drawer-backdrop",
66
+ "aria-hidden": "true"
67
+ }, null, -1)
68
+ ])]),
69
+ _: 1
70
+ }),
71
+ o("div", A, [
72
+ o("div", H, [
73
+ o("div", z, [
74
+ s(e(C), {
75
+ as: "template",
76
+ enter: "rvc-drawer-transition-enter",
77
+ "enter-from": "rvc-drawer-transition-enter-from",
78
+ "enter-to": "rvc-drawer-transition-enter-to",
79
+ leave: "rvc-drawer-transition-leave",
80
+ "leave-from": "rvc-drawer-transition-leave-from",
81
+ "leave-to": "rvc-drawer-transition-leave-to",
82
+ onBeforeEnter: t[4] || (t[4] = (l) => f.value = !0),
83
+ onAfterLeave: t[5] || (t[5] = (l) => (f.value = !1, a("drawer:closed")))
84
+ }, {
85
+ default: d(() => [
86
+ s(e(R), {
87
+ class: m(["rvc-drawer-panel", r.panelClass]),
88
+ "aria-busy": r.spinning,
89
+ "aria-describedby": e(w)
90
+ }, {
91
+ default: d(() => [
92
+ i(n.$slots, "panel", {
93
+ title: r.title,
94
+ loading: r.spinning,
95
+ isForm: e(y),
96
+ titleId: e(c),
97
+ descriptionId: e(w),
98
+ contentRef: e(b),
99
+ dialogTitle: e(u),
100
+ emitClose: () => a("drawer:close"),
101
+ emitSave: (l = void 0) => a("drawer:save", l)
102
+ }, () => [
103
+ o("div", M, [
104
+ r.resetHeader ? i(n.$slots, "header", { key: 1 }) : (v(), p("header", {
105
+ key: 0,
106
+ class: m([{ "rvc-drawer-header-sticky": r.headerSticky }, "rvc-drawer-header"])
107
+ }, [
108
+ i(n.$slots, "header", {
109
+ title: r.title,
110
+ showClose: r.showClose
111
+ }, () => [
112
+ o("div", P, [
113
+ i(n.$slots, "title", {
114
+ id: e(c),
115
+ dialogTitle: e(u),
116
+ title: r.title
117
+ }, () => [
118
+ s(e(u), {
119
+ id: e(c),
120
+ class: "rvc-drawer-title"
121
+ }, {
122
+ default: d(() => [
123
+ F(L(r.title), 1)
124
+ ]),
125
+ _: 1
126
+ }, 8, ["id"])
127
+ ]),
128
+ r.showClose ? i(n.$slots, "close", {
129
+ key: 0,
130
+ icon: e(B),
131
+ emitClose: () => a("drawer:close")
132
+ }, () => [
133
+ o("div", j, [
134
+ o("button", {
135
+ type: "button",
136
+ class: "rvc-drawer-close",
137
+ "aria-label": "Close panel",
138
+ onClick: t[2] || (t[2] = (l) => a("drawer:close"))
139
+ }, [
140
+ s(e(B), { "aria-hidden": "true" })
141
+ ])
142
+ ])
143
+ ]) : g("", !0)
144
+ ])
145
+ ])
146
+ ], 2)),
147
+ o("div", {
148
+ class: m([{ "rvc-drawer-scroll-reverse": r.scrolledDown }, "rvc-drawer-scroll"])
149
+ }, [
150
+ o("div", {
151
+ id: e(w),
152
+ ref_key: "contentRef",
153
+ ref: b,
154
+ class: "rvc-drawer-content"
155
+ }, [
156
+ i(n.$slots, "default", { ready: e(f) })
157
+ ], 8, q)
158
+ ], 2),
159
+ r.resetFooter ? i(n.$slots, "footer", { key: 3 }) : (v(), p("footer", G, [
160
+ i(n.$slots, "footer", { loading: r.spinning }, () => [
161
+ s($, {
162
+ type: "button",
163
+ label: r.cancelLabel,
164
+ color: "light",
165
+ onClick: t[3] || (t[3] = (l) => a("drawer:close"))
166
+ }, null, 8, ["label"]),
167
+ e(y) ? (v(), k($, {
168
+ key: 0,
169
+ type: "submit",
170
+ label: r.submitLabel,
171
+ spinning: r.spinning,
172
+ disabled: r.spinning
173
+ }, null, 8, ["label", "spinning", "disabled"])) : g("", !0)
174
+ ])
175
+ ]))
176
+ ])
177
+ ])
178
+ ]),
179
+ _: 3
180
+ }, 8, ["class", "aria-busy", "aria-describedby"])
181
+ ]),
182
+ _: 3
183
+ })
184
+ ])
185
+ ])
186
+ ])
187
+ ]),
188
+ _: 3
189
+ }, 8, ["as", "initial-focus", "aria-labelledby"])
190
+ ]),
191
+ _: 3
192
+ }));
193
+ }
194
+ });
195
+ export {
196
+ W as _
197
+ };
@@ -0,0 +1,198 @@
1
+ import { ref as k, computed as b, defineComponent as I, openBlock as C, createBlock as T, unref as e, withCtx as d, createVNode as i, withModifiers as h, createElementVNode as r, normalizeClass as D, renderSlot as s, createElementBlock as $, createTextVNode as L, toDisplayString as R, createCommentVNode as S } from "vue";
2
+ import { TransitionRoot as N, Dialog as V, TransitionChild as B, DialogPanel as A, DialogTitle as g } from "@headlessui/vue";
3
+ import { _ as w } from "./ButtonBase.vue_vue_type_script_setup_true_lang-ZYVNEyNx.js";
4
+ import { r as E } from "./XMarkIcon-CPr_Rd8y.js";
5
+ function H(t) {
6
+ const v = k(null), y = k(!1), l = b(() => t.as === "form"), f = b(() => `${t.id}-title`), m = b(() => `${t.id}-content`), c = b(() => v.value?.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'));
7
+ return {
8
+ contentRef: v,
9
+ ready: y,
10
+ isForm: l,
11
+ titleId: f,
12
+ descriptionId: m,
13
+ initialFocusElement: c
14
+ };
15
+ }
16
+ const M = {
17
+ role: "presentation",
18
+ class: "rvc-modal-presentation"
19
+ }, q = { class: "rvc-modal-container" }, x = {
20
+ key: 0,
21
+ class: "rvc-modal-header"
22
+ }, z = { class: "rvc-modal-header-inner" }, P = { class: "rvc-modal-close-wrapper" }, j = ["id"], G = {
23
+ key: 2,
24
+ class: "rvc-modal-footer"
25
+ }, U = /* @__PURE__ */ I({
26
+ __name: "Modal",
27
+ props: {
28
+ as: { default: "div" },
29
+ id: {},
30
+ title: {},
31
+ showClose: { type: Boolean, default: !1 },
32
+ spinning: { type: Boolean, default: !1 },
33
+ submitLabel: { default: "Confirm" },
34
+ cancelLabel: { default: "Cancel" },
35
+ panelClass: { default: "rvc-modal-panel-max-width" },
36
+ resetHeader: { type: Boolean, default: !1 },
37
+ resetFooter: { type: Boolean, default: !1 }
38
+ },
39
+ emits: ["modal:open", "modal:opened", "modal:close", "modal:save", "modal:closed"],
40
+ setup(t, { emit: v }) {
41
+ const y = t, l = v, {
42
+ contentRef: f,
43
+ ready: m,
44
+ isForm: c,
45
+ titleId: u,
46
+ descriptionId: p,
47
+ initialFocusElement: F
48
+ } = H(y);
49
+ return (n, o) => (C(), T(e(N), { as: "template" }, {
50
+ default: d(() => [
51
+ i(e(V), {
52
+ as: t.as,
53
+ class: "rvc-modal",
54
+ static: "",
55
+ "aria-modal": "true",
56
+ role: "dialog",
57
+ "initial-focus": e(F),
58
+ "aria-labelledby": e(u),
59
+ onClose: o[7] || (o[7] = (a) => l("modal:close")),
60
+ onSubmit: o[8] || (o[8] = h((a) => l("modal:save", a), ["prevent"]))
61
+ }, {
62
+ default: d(() => [
63
+ i(e(B), {
64
+ as: "template",
65
+ enter: "rvc-modal-backdrop-transition-enter",
66
+ "enter-from": "rvc-modal-backdrop-transition-enter-from",
67
+ "enter-to": "rvc-modal-backdrop-transition-enter-to",
68
+ leave: "rvc-modal-backdrop-transition-leave",
69
+ "leave-from": "rvc-modal-backdrop-transition-leave-from",
70
+ "leave-to": "rvc-modal-backdrop-transition-leave-to",
71
+ onBeforeEnter: o[0] || (o[0] = (a) => l("modal:open")),
72
+ onAfterEnter: o[1] || (o[1] = (a) => l("modal:opened"))
73
+ }, {
74
+ default: d(() => [...o[9] || (o[9] = [
75
+ r("div", {
76
+ "aria-hidden": "true",
77
+ class: "rvc-modal-backdrop"
78
+ }, null, -1)
79
+ ])]),
80
+ _: 1
81
+ }),
82
+ r("div", M, [
83
+ r("div", q, [
84
+ i(e(B), {
85
+ as: "template",
86
+ enter: "rvc-modal-transition-enter",
87
+ "enter-from": "rvc-modal-transition-enter-from",
88
+ "enter-to": "rvc-modal-transition-enter-to",
89
+ leave: "rvc-modal-transition-leave",
90
+ "leave-from": "rvc-modal-transition-leave-from",
91
+ "leave-to": "rvc-modal-transition-leave-to",
92
+ onBeforeEnter: o[5] || (o[5] = (a) => m.value = !0),
93
+ onAfterLeave: o[6] || (o[6] = (a) => (m.value = !1, l("modal:closed")))
94
+ }, {
95
+ default: d(() => [
96
+ i(e(A), {
97
+ class: D(["rvc-modal-panel", t.panelClass]),
98
+ "aria-busy": t.spinning,
99
+ "aria-describedby": e(p)
100
+ }, {
101
+ default: d(() => [
102
+ s(n.$slots, "panel", {
103
+ title: t.title,
104
+ loading: t.spinning,
105
+ isForm: e(c),
106
+ titleId: e(u),
107
+ descriptionId: e(p),
108
+ contentRef: e(f),
109
+ dialogTitle: e(g),
110
+ emitClose: () => l("modal:close"),
111
+ emitSave: (a = void 0) => l("modal:save", a)
112
+ }, () => [
113
+ t.resetHeader ? s(n.$slots, "header", { key: 1 }) : (C(), $("header", x, [
114
+ s(n.$slots, "header", {
115
+ title: t.title,
116
+ showClose: t.showClose
117
+ }, () => [
118
+ r("div", z, [
119
+ s(n.$slots, "title", {
120
+ id: e(u),
121
+ dialogTitle: e(g),
122
+ title: t.title
123
+ }, () => [
124
+ i(e(g), {
125
+ id: e(u),
126
+ class: "rvc-modal-title"
127
+ }, {
128
+ default: d(() => [
129
+ L(R(t.title), 1)
130
+ ]),
131
+ _: 1
132
+ }, 8, ["id"])
133
+ ]),
134
+ t.showClose ? s(n.$slots, "close", {
135
+ key: 0,
136
+ icon: e(E),
137
+ emitClose: () => l("modal:close")
138
+ }, () => [
139
+ r("div", P, [
140
+ r("button", {
141
+ type: "button",
142
+ class: "rvc-modal-close",
143
+ "aria-label": "Close panel",
144
+ onClick: o[2] || (o[2] = (a) => l("modal:close"))
145
+ }, [
146
+ i(e(E), { "aria-hidden": "true" })
147
+ ])
148
+ ])
149
+ ]) : S("", !0)
150
+ ])
151
+ ])
152
+ ])),
153
+ r("div", {
154
+ id: e(p),
155
+ ref_key: "contentRef",
156
+ ref: f,
157
+ class: "rvc-modal-content"
158
+ }, [
159
+ s(n.$slots, "default", { ready: e(m) })
160
+ ], 8, j),
161
+ t.resetFooter ? s(n.$slots, "footer", { key: 3 }) : (C(), $("footer", G, [
162
+ s(n.$slots, "footer", { loading: t.spinning }, () => [
163
+ i(w, {
164
+ type: e(c) ? "submit" : "button",
165
+ label: t.submitLabel,
166
+ spinning: t.spinning,
167
+ disabled: t.spinning,
168
+ onClick: o[3] || (o[3] = (a) => !e(c) && l("modal:save"))
169
+ }, null, 8, ["type", "label", "spinning", "disabled"]),
170
+ i(w, {
171
+ type: "button",
172
+ color: "light",
173
+ label: t.cancelLabel,
174
+ onClick: o[4] || (o[4] = (a) => l("modal:close"))
175
+ }, null, 8, ["label"])
176
+ ])
177
+ ]))
178
+ ])
179
+ ]),
180
+ _: 3
181
+ }, 8, ["class", "aria-busy", "aria-describedby"])
182
+ ]),
183
+ _: 3
184
+ })
185
+ ])
186
+ ])
187
+ ]),
188
+ _: 3
189
+ }, 8, ["as", "initial-focus", "aria-labelledby"])
190
+ ]),
191
+ _: 3
192
+ }));
193
+ }
194
+ });
195
+ export {
196
+ U as _,
197
+ H as u
198
+ };