@robuust-digital/vue-components 2.0.0-rc.9 → 2.1.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,4 +1,29 @@
1
- ## 2.0.0-rc.9 (15-05-2025)
1
+ ## 2.1.0 (05-08-2025)
2
+
3
+ ### Added
4
+
5
+ * `FormInput`: Added `suffix` slot for custom suffix content
6
+ * `FormSelect`: Added `options`, `optionValue`, and `optionLabel` props for programmatic option rendering
7
+ * `Drawer`: Added `resetHeader` and `resetFooter` props to reset/hide default header and footer content
8
+ * `Modal`: Added `resetHeader` and `resetFooter` props to reset/hide default header and footer content
9
+ * `DataTable`: Added `footer` slot for custom table footer content
10
+ * `DataTable`: Added `defaultSort` prop to set initial sorting state
11
+
12
+ ### Updated
13
+
14
+ * Improved `FormInput` CSS selectors for better maintainability (replaced generic SVG selectors with class-based selectors)
15
+ * `RichTextEditor`: Fixed duplicate extension warning by configuring link extension within StarterKit
16
+ * `Radio`: Improved accessibility by using proper `label` element wrapper and better CSS structure
17
+ * `Checkbox`: Improved accessibility by using proper `label` element wrapper and better CSS structure
18
+ * `Radio` and `Checkbox`: Enhanced cursor behavior and input hiding for better user experience
19
+
20
+ ## 2.0.0 (13-06-2025)
21
+
22
+ ### Added
23
+
24
+ * Added native input refs
25
+
26
+ ## 2.0.0-rc.11 (26-05-2025)
2
27
 
3
28
  ### Added
4
29
 
@@ -15,6 +40,9 @@
15
40
  * `Toast`: `open` prop is now `show`
16
41
  * `DataTable`: `items` slot is renamed to `item` and added a parent `items` slot to customize the whole row
17
42
  * `DataTable`: `headers` slot is renamed to `header` and added a parent `headers` slot to customize the whole row
43
+ * `Accordion`: `defaultOpenIndex` param can now accept `Number` and `String` as type
44
+ * `Accordion`: `active` prop is removed from the `summary` slot, as it's not needed
45
+ * `Accordion`: `items` prop can now also accept an `Object` as type
18
46
 
19
47
  ### Updated
20
48
 
@@ -0,0 +1,92 @@
1
+ import { computed as v, getCurrentInstance as $, useSlots as I, ref as b, createElementBlock as s, openBlock as n, normalizeClass as x, createCommentVNode as u, renderSlot as i, unref as r, createBlock as f, resolveDynamicComponent as m, normalizeProps as V, guardReactiveProps as B, withDirectives as C, mergeProps as y, vModelDynamic as O } from "vue";
2
+ const S = () => ({ hasModelBinding: v(() => {
3
+ var l;
4
+ const o = $();
5
+ return ((l = o == null ? void 0 : o.vnode) == null ? void 0 : l.props) && Object.prototype.hasOwnProperty.call(o.vnode.props, "onUpdate:modelValue");
6
+ }) }), j = {
7
+ key: 0,
8
+ class: "rvc-input-prefix"
9
+ }, z = ["type"], F = ["type"], M = {
10
+ key: 1,
11
+ class: "rvc-input-suffix"
12
+ }, D = /* @__PURE__ */ Object.assign({
13
+ inheritAttrs: !1
14
+ }, {
15
+ __name: "FormInput",
16
+ props: {
17
+ modelValue: {
18
+ type: [String, Number],
19
+ default: void 0
20
+ },
21
+ rootClass: {
22
+ type: String,
23
+ default: ""
24
+ },
25
+ prefixIcon: {
26
+ type: [Object, Function],
27
+ default: null
28
+ },
29
+ icon: {
30
+ type: [Object, Function],
31
+ default: null
32
+ },
33
+ size: {
34
+ type: String,
35
+ default: "base",
36
+ validator: (e) => ["sm", "base"].includes(e)
37
+ }
38
+ },
39
+ emits: ["update:modelValue"],
40
+ setup(e, { emit: o }) {
41
+ const l = e, g = o, { hasModelBinding: h } = S(), a = I(), c = b(null), d = v({
42
+ get: () => l.modelValue,
43
+ set: (t) => g("update:modelValue", t)
44
+ });
45
+ return (t, p) => (n(), s("div", {
46
+ class: x([
47
+ "rvc-input",
48
+ `rvc-input-${e.size}`,
49
+ e.rootClass
50
+ ])
51
+ }, [
52
+ r(a).prefix || r(a).prefixIcon || e.prefixIcon ? (n(), s("span", j, [
53
+ i(t.$slots, "prefix", {}, () => [
54
+ i(t.$slots, "prefixIcon", { icon: e.prefixIcon }, () => [
55
+ e.prefixIcon ? (n(), f(m(e.prefixIcon), {
56
+ key: 0,
57
+ "aria-hidden": "true"
58
+ })) : u("", !0)
59
+ ])
60
+ ])
61
+ ])) : u("", !0),
62
+ i(t.$slots, "input", V(B(t.$attrs)), () => [
63
+ r(h) ? C((n(), s("input", y({ key: 0 }, t.$attrs, {
64
+ ref_key: "input",
65
+ ref: c,
66
+ "onUpdate:modelValue": p[0] || (p[0] = (k) => d.value = k),
67
+ type: t.$attrs.type || "text"
68
+ }), null, 16, z)), [
69
+ [O, d.value]
70
+ ]) : (n(), s("input", y({ key: 1 }, t.$attrs, {
71
+ ref_key: "input",
72
+ ref: c,
73
+ type: t.$attrs.type || "text"
74
+ }), null, 16, F))
75
+ ]),
76
+ r(a).suffix || r(a).icon || e.icon ? (n(), s("span", M, [
77
+ i(t.$slots, "suffix", {}, () => [
78
+ i(t.$slots, "icon", { icon: e.icon }, () => [
79
+ e.icon ? (n(), f(m(e.icon), {
80
+ key: 0,
81
+ "aria-hidden": "true"
82
+ })) : u("", !0)
83
+ ])
84
+ ])
85
+ ])) : u("", !0)
86
+ ], 2));
87
+ }
88
+ });
89
+ export {
90
+ D as _,
91
+ S as u
92
+ };
@@ -0,0 +1,213 @@
1
+ import { ref as $, computed as f, createBlock as F, openBlock as p, unref as o, withCtx as m, createVNode as i, withModifiers as D, createElementVNode as r, normalizeClass as L, createElementBlock as k, renderSlot as s, createCommentVNode as T, createTextVNode as I, toDisplayString as N } from "vue";
2
+ import { TransitionRoot as R, Dialog as V, TransitionChild as C, DialogPanel as h, DialogTitle as S } from "@headlessui/vue";
3
+ import { _ as B } from "./ButtonBase-DfkwHIhN.js";
4
+ import { r as w } from "./XMarkIcon-90mcPzBs.js";
5
+ function q(t) {
6
+ const v = $(null), n = $(!1), b = f(() => t.as === "form"), y = f(() => `${t.id}-title`), c = f(() => `${t.id}-content`), u = f(() => {
7
+ var d;
8
+ return (d = v.value) == null ? void 0 : d.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
9
+ });
10
+ return {
11
+ contentRef: v,
12
+ ready: n,
13
+ isForm: b,
14
+ titleId: y,
15
+ descriptionId: c,
16
+ initialFocusElement: u
17
+ };
18
+ }
19
+ const A = {
20
+ role: "presentation",
21
+ class: "rvc-modal-presentation"
22
+ }, H = { class: "rvc-modal-container" }, M = {
23
+ key: 0,
24
+ class: "rvc-modal-header"
25
+ }, z = { class: "rvc-modal-header-inner" }, P = { class: "rvc-modal-close-wrapper" }, j = ["id"], G = {
26
+ key: 2,
27
+ class: "rvc-modal-footer"
28
+ }, U = {
29
+ __name: "Modal",
30
+ props: {
31
+ as: {
32
+ type: String,
33
+ default: "div"
34
+ },
35
+ id: {
36
+ type: String,
37
+ required: !0
38
+ },
39
+ title: {
40
+ type: String,
41
+ required: !0
42
+ },
43
+ showClose: {
44
+ type: Boolean
45
+ },
46
+ spinning: {
47
+ type: Boolean
48
+ },
49
+ submitLabel: {
50
+ type: String,
51
+ default: "Confirm"
52
+ },
53
+ cancelLabel: {
54
+ type: String,
55
+ default: "Cancel"
56
+ },
57
+ panelClass: {
58
+ type: String,
59
+ default: "rvc-modal-panel-max-width"
60
+ },
61
+ resetHeader: {
62
+ type: Boolean
63
+ },
64
+ resetFooter: {
65
+ type: Boolean
66
+ }
67
+ },
68
+ emits: ["modal:open", "modal:opened", "modal:close", "modal:save", "modal:closed"],
69
+ setup(t, { emit: v }) {
70
+ const n = v, b = t, {
71
+ contentRef: y,
72
+ ready: c,
73
+ isForm: u,
74
+ titleId: d,
75
+ descriptionId: g,
76
+ initialFocusElement: E
77
+ } = q(b);
78
+ return (l, e) => (p(), F(o(R), { as: "template" }, {
79
+ default: m(() => [
80
+ i(o(V), {
81
+ as: t.as,
82
+ class: "rvc-modal",
83
+ static: "",
84
+ "aria-modal": "true",
85
+ role: "dialog",
86
+ "initial-focus": o(E),
87
+ "aria-labelledby": o(d),
88
+ onClose: e[7] || (e[7] = (a) => l.$emit("modal:close")),
89
+ onSubmit: e[8] || (e[8] = D((a) => n("modal:save", a), ["prevent"]))
90
+ }, {
91
+ default: m(() => [
92
+ i(o(C), {
93
+ as: "template",
94
+ enter: "rvc-modal-backdrop-transition-enter",
95
+ "enter-from": "rvc-modal-backdrop-transition-enter-from",
96
+ "enter-to": "rvc-modal-backdrop-transition-enter-to",
97
+ leave: "rvc-modal-backdrop-transition-leave",
98
+ "leave-from": "rvc-modal-backdrop-transition-leave-from",
99
+ "leave-to": "rvc-modal-backdrop-transition-leave-to",
100
+ onBeforeEnter: e[0] || (e[0] = (a) => n("modal:open")),
101
+ onAfterEnter: e[1] || (e[1] = (a) => n("modal:opened"))
102
+ }, {
103
+ default: m(() => e[9] || (e[9] = [
104
+ r("div", {
105
+ "aria-hidden": "true",
106
+ class: "rvc-modal-backdrop"
107
+ }, null, -1)
108
+ ])),
109
+ _: 1,
110
+ __: [9]
111
+ }),
112
+ r("div", A, [
113
+ r("div", H, [
114
+ i(o(C), {
115
+ as: "template",
116
+ enter: "rvc-modal-transition-enter",
117
+ "enter-from": "rvc-modal-transition-enter-from",
118
+ "enter-to": "rvc-modal-transition-enter-to",
119
+ leave: "rvc-modal-transition-leave",
120
+ "leave-from": "rvc-modal-transition-leave-from",
121
+ "leave-to": "rvc-modal-transition-leave-to",
122
+ onBeforeEnter: e[5] || (e[5] = (a) => c.value = !0),
123
+ onAfterLeave: e[6] || (e[6] = (a) => (c.value = !1, n("modal:closed")))
124
+ }, {
125
+ default: m(() => [
126
+ i(o(h), {
127
+ class: L(["rvc-modal-panel", t.panelClass]),
128
+ "aria-busy": t.spinning,
129
+ "aria-describedby": o(g)
130
+ }, {
131
+ default: m(() => [
132
+ t.resetHeader ? s(l.$slots, "header", { key: 1 }) : (p(), k("header", M, [
133
+ s(l.$slots, "header", { title: t.title }, () => [
134
+ r("div", z, [
135
+ s(l.$slots, "title", {
136
+ id: o(d),
137
+ dialogTitle: o(S),
138
+ title: t.title
139
+ }, () => [
140
+ i(o(S), {
141
+ id: o(d),
142
+ class: "rvc-modal-title"
143
+ }, {
144
+ default: m(() => [
145
+ I(N(t.title), 1)
146
+ ]),
147
+ _: 1
148
+ }, 8, ["id"])
149
+ ]),
150
+ t.showClose ? s(l.$slots, "close", {
151
+ key: 0,
152
+ icon: o(w),
153
+ emitClose: () => n("drawer:close")
154
+ }, () => [
155
+ r("div", P, [
156
+ r("button", {
157
+ type: "button",
158
+ class: "rvc-modal-close",
159
+ "aria-label": "Close panel",
160
+ onClick: e[2] || (e[2] = (a) => n("modal:close"))
161
+ }, [
162
+ i(o(w), { "aria-hidden": "true" })
163
+ ])
164
+ ])
165
+ ]) : T("", !0)
166
+ ])
167
+ ])
168
+ ])),
169
+ r("div", {
170
+ id: o(g),
171
+ ref_key: "contentRef",
172
+ ref: y,
173
+ class: "rvc-modal-content"
174
+ }, [
175
+ s(l.$slots, "default", { ready: o(c) })
176
+ ], 8, j),
177
+ t.resetFooter ? s(l.$slots, "footer", { key: 3 }) : (p(), k("footer", G, [
178
+ s(l.$slots, "footer", { loading: t.spinning }, () => [
179
+ i(B, {
180
+ type: o(u) ? "submit" : "button",
181
+ label: t.submitLabel,
182
+ spinning: t.spinning,
183
+ disabled: t.spinning,
184
+ onClick: e[3] || (e[3] = (a) => !o(u) && l.$emit("modal:save"))
185
+ }, null, 8, ["type", "label", "spinning", "disabled"]),
186
+ i(B, {
187
+ type: "button",
188
+ color: "light",
189
+ label: t.cancelLabel,
190
+ onClick: e[4] || (e[4] = (a) => l.$emit("modal:close"))
191
+ }, null, 8, ["label"])
192
+ ])
193
+ ]))
194
+ ]),
195
+ _: 3
196
+ }, 8, ["class", "aria-busy", "aria-describedby"])
197
+ ]),
198
+ _: 3
199
+ })
200
+ ])
201
+ ])
202
+ ]),
203
+ _: 3
204
+ }, 8, ["as", "initial-focus", "aria-labelledby"])
205
+ ]),
206
+ _: 3
207
+ }));
208
+ }
209
+ };
210
+ export {
211
+ U as _,
212
+ q as u
213
+ };
@@ -214,15 +214,7 @@
214
214
  }
215
215
 
216
216
  .rvc-button-label {
217
- position: absolute;
218
- width: 1px;
219
- height: 1px;
220
- margin: -1px;
221
- padding: 0;
222
- overflow: hidden;
223
- clip: rect(0, 0, 0, 0);
224
- border-width: 0;
225
- white-space: nowrap;
217
+ @apply rvc-sr-only;
226
218
  }
227
219
 
228
220
  .rvc-button-icon.rvc-button-icon-loading {
@@ -25,7 +25,11 @@
25
25
  cursor: pointer;
26
26
  gap: var(--rvc-checkbox-gap);
27
27
 
28
- label {
28
+ &:has(*:disabled) {
29
+ cursor: default;
30
+ }
31
+
32
+ .rvc-checkbox-label {
29
33
  display: block;
30
34
  color: var(--rvc-checkbox-color);
31
35
  font-size: var(--rvc-checkbox-font-size);
@@ -53,14 +57,7 @@
53
57
  }
54
58
 
55
59
  input {
56
- position: absolute;
57
- opacity: 0;
58
- inset: 0;
59
- cursor: pointer;
60
-
61
- &:disabled {
62
- cursor: default;
63
- }
60
+ display: none;
64
61
  }
65
62
 
66
63
  input:checked + .rvc-checkbox-input {