@sparklingopinions/sparkling-ui 0.4.2 → 0.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/README.md +1 -1
- package/dist/aliases.d.ts +176 -26
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.vue.d.ts +3 -2
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +20 -14
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Board/Board.js.map +1 -1
- package/dist/components/Board/Board.vue.d.ts +6 -2
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +142 -74
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Button/Button.vue.d.ts +1 -1
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +7 -0
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/components/ContextMenu/ContextMenu.vue.d.ts +44 -0
- package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +84 -0
- package/dist/components/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/ContextMenu/index.d.ts +2 -0
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataList/DataList.vue.d.ts +8 -0
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +71 -52
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DataList/types.d.ts +5 -1
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/Dialog/Dialog.vue.d.ts +22 -6
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +174 -72
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/useSheetDrag.d.ts +16 -0
- package/dist/components/Dialog/useSheetDrag.js +37 -0
- package/dist/components/Dialog/useSheetDrag.js.map +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.vue.d.ts +6 -30
- package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +54 -74
- package/dist/components/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.vue.d.ts +9 -3
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +35 -7
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterChip.js.map +1 -1
- package/dist/components/Filters/FilterChip.vue.d.ts +4 -1
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js +29 -24
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterMenu.js.map +1 -1
- package/dist/components/Filters/FilterMenu.vue.d.ts +20 -1
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js +78 -56
- package/dist/components/Filters/FilterMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/SortMenu.js.map +1 -1
- package/dist/components/Filters/SortMenu.vue.d.ts +21 -1
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js +90 -66
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/index.d.ts +2 -1
- package/dist/components/Filters/trigger.d.ts +17 -0
- package/dist/components/Filters/trigger.js +33 -0
- package/dist/components/Filters/trigger.js.map +1 -0
- package/dist/components/Filters/types.d.ts +8 -0
- package/dist/components/FormField/FormField.js.map +1 -1
- package/dist/components/FormField/FormField.vue.d.ts +10 -0
- package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js +31 -20
- package/dist/components/FormField/FormField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Icon/iconSet.js +9 -1
- package/dist/components/Icon/iconSet.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.vue.d.ts +6 -3
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +20 -17
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SegmentedControl/index.d.ts +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.vue.d.ts +4 -0
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +66 -56
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Table/types.d.ts +2 -0
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Tag/Tag.vue.d.ts +16 -3
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +42 -19
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Toast/ToastMessage.js.map +1 -1
- package/dist/components/Toast/ToastMessage.vue.d.ts +13 -1
- package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js +58 -23
- package/dist/components/Toast/ToastMessage.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Toast/Toaster.js.map +1 -1
- package/dist/components/Toast/Toaster.vue.d.ts +7 -3
- package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js +50 -21
- package/dist/components/Toast/Toaster.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/internal/MenuItemContent.js +7 -0
- package/dist/components/internal/MenuItemContent.js.map +1 -0
- package/dist/components/internal/MenuItemContent.vue.d.ts +7 -0
- package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js +26 -0
- package/dist/components/internal/MenuItemContent.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/internal/menu.d.ts +46 -0
- package/dist/components/internal/menu.js +33 -0
- package/dist/components/internal/menu.js.map +1 -0
- package/dist/composables/toast.d.ts +20 -5
- package/dist/composables/toast.js +28 -20
- package/dist/composables/toast.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +34 -33
- package/package.json +1 -1
- package/src/styles/tailwind.css +29 -0
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import e from "../Icon/Icon.js";
|
|
2
2
|
import t from "../Skeleton/Skeleton.js";
|
|
3
|
-
import { Fragment as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, createVNode as c, defineComponent as l, normalizeClass as u,
|
|
3
|
+
import { Fragment as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, createVNode as c, defineComponent as l, normalizeClass as u, onBeforeUnmount as d, openBlock as f, ref as p, renderList as m, renderSlot as h, resolveDynamicComponent as g, toDisplayString as _, unref as v, useId as y, withCtx as b, withModifiers as ee } from "vue";
|
|
4
4
|
//#region src/components/Board/Board.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var
|
|
5
|
+
var te = ["aria-labelledby"], ne = { class: "flex items-center justify-between px-1 pb-2.5" }, re = { class: "ml-2 inline-flex h-5 items-center justify-center rounded-full bg-sui-sunken px-2 text-xs text-sui-ink-muted tabular-nums" }, x = ["data-board-column"], S = {
|
|
6
6
|
key: 1,
|
|
7
7
|
class: "m-0 px-1 py-3 text-center text-13 text-sui-ink-muted"
|
|
8
|
-
},
|
|
8
|
+
}, C = {
|
|
9
9
|
key: 2,
|
|
10
10
|
class: "m-0 flex list-none flex-col gap-2.5 p-0"
|
|
11
|
-
},
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
11
|
+
}, w = [
|
|
12
|
+
"data-board-index",
|
|
13
|
+
"role",
|
|
14
|
+
"tabindex",
|
|
15
|
+
"onClickCapture",
|
|
16
|
+
"onKeydown",
|
|
17
|
+
"onPointerdown"
|
|
18
|
+
], T = { class: "m-0 text-sm font-semibold text-sui-ink" }, E = ["onClick"], D = 4, O = 8, k = 250, A = 48, j = "border border-sui-line-subtle bg-sui-surface p-4 transition-[border-color,opacity] duration-150 hover:border-sui-line", M = /*@__PURE__*/ l({
|
|
17
19
|
__name: "Board",
|
|
18
20
|
props: {
|
|
19
21
|
columns: {},
|
|
@@ -25,6 +27,14 @@ var b = ["aria-labelledby"], x = { class: "flex items-center justify-between px-
|
|
|
25
27
|
},
|
|
26
28
|
loading: { type: Boolean },
|
|
27
29
|
headingLevel: { default: 3 },
|
|
30
|
+
cardFrame: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
default: !0
|
|
33
|
+
},
|
|
34
|
+
onCardClick: {
|
|
35
|
+
type: Function,
|
|
36
|
+
default: void 0
|
|
37
|
+
},
|
|
28
38
|
onNew: {
|
|
29
39
|
type: Function,
|
|
30
40
|
default: void 0
|
|
@@ -32,104 +42,162 @@ var b = ["aria-labelledby"], x = { class: "flex items-center justify-between px-
|
|
|
32
42
|
newLabel: { default: "New" },
|
|
33
43
|
emptyLabel: { default: "No cards" }
|
|
34
44
|
},
|
|
35
|
-
emits: ["
|
|
36
|
-
setup(l, { emit:
|
|
37
|
-
let
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
emits: ["move"],
|
|
46
|
+
setup(l, { emit: M }) {
|
|
47
|
+
let N = l, P = M, F = y(), I = (e) => e[N.rowKey ?? "id"], L = p(), R = p(null), z = p(null), B = null, V, H = null, U = {
|
|
48
|
+
x: 0,
|
|
49
|
+
y: 0
|
|
50
|
+
}, W = !1;
|
|
51
|
+
function G(e, t, n, r) {
|
|
52
|
+
if (e.button !== 0 || e.target.closest("input, textarea, select, [contenteditable]")) return;
|
|
53
|
+
let i = e.pointerType === "touch";
|
|
54
|
+
B = {
|
|
55
|
+
item: t,
|
|
41
56
|
column: n,
|
|
42
|
-
index: r
|
|
57
|
+
index: r,
|
|
58
|
+
x: e.clientX,
|
|
59
|
+
y: e.clientY,
|
|
60
|
+
card: e.currentTarget,
|
|
61
|
+
touch: i
|
|
62
|
+
}, i && (V = window.setTimeout(() => B && K(), k)), window.addEventListener("pointermove", q), window.addEventListener("pointerup", X), window.addEventListener("pointercancel", $), window.addEventListener("touchmove", Z, { passive: !1 }), window.addEventListener("keydown", Q);
|
|
63
|
+
}
|
|
64
|
+
function K() {
|
|
65
|
+
if (!B) return;
|
|
66
|
+
let e = B.card.getBoundingClientRect();
|
|
67
|
+
U = {
|
|
68
|
+
x: B.x - e.left,
|
|
69
|
+
y: B.y - e.top
|
|
70
|
+
}, H = B.card.cloneNode(!0), H.removeAttribute("id"), H.setAttribute("aria-hidden", "true"), H.classList.add("pointer-events-none", "fixed", "top-0", "left-0", "z-[1300]", "shadow-lg", "opacity-95"), H.style.width = `${e.width}px`, document.body.appendChild(H), J(B.x, B.y), R.value = {
|
|
71
|
+
id: I(B.item),
|
|
72
|
+
column: B.column,
|
|
73
|
+
index: B.index
|
|
43
74
|
};
|
|
44
75
|
}
|
|
45
|
-
function
|
|
46
|
-
|
|
76
|
+
function q(e) {
|
|
77
|
+
if (B) {
|
|
78
|
+
if (!R.value) {
|
|
79
|
+
let t = Math.hypot(e.clientX - B.x, e.clientY - B.y);
|
|
80
|
+
if (B.touch) return t > O ? $() : void 0;
|
|
81
|
+
if (t < D) return;
|
|
82
|
+
K();
|
|
83
|
+
}
|
|
84
|
+
e.preventDefault(), J(e.clientX, e.clientY), Y(e.clientX, e.clientY), ie(e.clientX, e.clientY);
|
|
85
|
+
}
|
|
47
86
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
column: t.id,
|
|
51
|
-
index: t.items.length
|
|
52
|
-
}));
|
|
87
|
+
function J(e, t) {
|
|
88
|
+
H && (H.style.transform = `translate(${e - U.x}px, ${t - U.y}px) rotate(1.5deg)`);
|
|
53
89
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
90
|
+
function Y(e, t) {
|
|
91
|
+
let n = document.elementFromPoint(e, t), r = n?.closest("[data-board-column]");
|
|
92
|
+
if (!r || !L.value?.contains(r)) {
|
|
93
|
+
z.value = null;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let i = r.dataset.boardColumn, a = n.closest("[data-board-index]"), o = N.columns.find((e) => e.id === i)?.items.length ?? 0;
|
|
97
|
+
if (a && r.contains(a)) {
|
|
98
|
+
let e = a.getBoundingClientRect();
|
|
99
|
+
o = Number(a.dataset.boardIndex) + (t < e.top + e.height / 2 ? 0 : 1);
|
|
100
|
+
}
|
|
101
|
+
(z.value?.column !== i || z.value.index !== o) && (z.value = {
|
|
102
|
+
column: i,
|
|
103
|
+
index: o
|
|
61
104
|
});
|
|
62
105
|
}
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
function V(e, t) {
|
|
67
|
-
e.preventDefault();
|
|
68
|
-
let n = P.value;
|
|
106
|
+
function ie(e, t) {
|
|
107
|
+
let n = document.elementFromPoint(e, t)?.closest("[data-board-column]");
|
|
69
108
|
if (n) {
|
|
70
|
-
let e =
|
|
71
|
-
|
|
109
|
+
let e = n.getBoundingClientRect();
|
|
110
|
+
t < e.top + A ? n.scrollTop -= 12 : t > e.bottom - A && (n.scrollTop += 12);
|
|
111
|
+
}
|
|
112
|
+
let r = L.value?.getBoundingClientRect();
|
|
113
|
+
r && L.value && (e < r.left + A ? L.value.scrollLeft -= 12 : e > r.right - A && (L.value.scrollLeft += 12));
|
|
114
|
+
}
|
|
115
|
+
function X() {
|
|
116
|
+
let e = R.value, t = z.value;
|
|
117
|
+
if (e && t) {
|
|
118
|
+
let n = t.index;
|
|
119
|
+
e.column === t.column ? (n > e.index && n--, N.sortable && n !== e.index && P("move", e.id, t.column, n)) : P("move", e.id, t.column, n);
|
|
72
120
|
}
|
|
73
|
-
|
|
121
|
+
$();
|
|
122
|
+
}
|
|
123
|
+
function Z(e) {
|
|
124
|
+
R.value && e.preventDefault();
|
|
125
|
+
}
|
|
126
|
+
function Q(e) {
|
|
127
|
+
e.key === "Escape" && R.value && (e.preventDefault(), $());
|
|
128
|
+
}
|
|
129
|
+
function $() {
|
|
130
|
+
window.clearTimeout(V), window.removeEventListener("pointermove", q), window.removeEventListener("pointerup", X), window.removeEventListener("pointercancel", $), window.removeEventListener("touchmove", Z), window.removeEventListener("keydown", Q), H?.remove(), H = null, R.value && (W = !0, window.setTimeout(() => W = !1)), B = null, R.value = null, z.value = null;
|
|
131
|
+
}
|
|
132
|
+
d($);
|
|
133
|
+
function ae(e, t) {
|
|
134
|
+
W ? (e.preventDefault(), e.stopPropagation()) : N.onCardClick?.(t);
|
|
74
135
|
}
|
|
75
|
-
function
|
|
76
|
-
e.target !== e.currentTarget || e.key !== "Enter" && e.key !== " " || (e.preventDefault(),
|
|
136
|
+
function oe(e, t) {
|
|
137
|
+
!N.onCardClick || e.target !== e.currentTarget || e.key !== "Enter" && e.key !== " " || (e.preventDefault(), N.onCardClick(t));
|
|
77
138
|
}
|
|
78
|
-
let
|
|
79
|
-
return (
|
|
80
|
-
|
|
81
|
-
|
|
139
|
+
let se = (e, t, n) => z.value?.column === e && z.value.index === t && R.value?.id !== I(n);
|
|
140
|
+
return (d, p) => (f(), a("div", {
|
|
141
|
+
ref_key: "root",
|
|
142
|
+
ref: L,
|
|
143
|
+
class: u(["flex items-stretch gap-5 overflow-x-auto pb-2 after:w-1 after:shrink-0 after:content-['']", l.fill && "h-full min-h-0 flex-1"])
|
|
144
|
+
}, [(f(!0), a(n, null, m(l.columns, (y) => (f(), a("section", {
|
|
145
|
+
key: y.id,
|
|
146
|
+
"aria-labelledby": `${v(F)}-${y.id}`,
|
|
82
147
|
class: "flex min-h-0 w-full max-w-xs min-w-[16rem] shrink-0 flex-col"
|
|
83
|
-
}, [o("header",
|
|
84
|
-
id: `${
|
|
148
|
+
}, [o("header", ne, [(f(), r(g(`h${l.headingLevel}`), {
|
|
149
|
+
id: `${v(F)}-${y.id}`,
|
|
85
150
|
class: "m-0 flex items-center gap-2 text-sm font-semibold text-sui-ink"
|
|
86
151
|
}, {
|
|
87
|
-
default:
|
|
152
|
+
default: b(() => [y.icon ? (f(), r(e, {
|
|
88
153
|
key: 0,
|
|
89
|
-
color:
|
|
90
|
-
name:
|
|
91
|
-
}, null, 8, ["color", "name"])) : i("", !0), s(" " +
|
|
154
|
+
color: y.iconColor ?? "ink-subtle",
|
|
155
|
+
name: y.icon
|
|
156
|
+
}, null, 8, ["color", "name"])) : i("", !0), s(" " + _(y.name), 1)]),
|
|
92
157
|
_: 2
|
|
93
|
-
}, 1032, ["id"])), o("span",
|
|
94
|
-
class: u(["group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl bg-sui-sunken p-2.5 transition-shadow duration-150",
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
onDrop: (e) => V(e, k)
|
|
98
|
-
}, [l.loading ? (d(), a(n, { key: 0 }, p(3, (e) => o("div", {
|
|
158
|
+
}, 1032, ["id"])), o("span", re, [h(d.$slots, "count", { column: y }, () => [s(_(y.items.length), 1)])])]), o("div", {
|
|
159
|
+
class: u(["group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl bg-sui-sunken p-2.5 transition-shadow duration-150", z.value?.column === y.id && "ring-2 ring-sui-accent-line ring-inset"]),
|
|
160
|
+
"data-board-column": y.id
|
|
161
|
+
}, [l.loading ? (f(), a(n, { key: 0 }, m(3, (e) => o("div", {
|
|
99
162
|
key: e,
|
|
100
163
|
"aria-hidden": "true",
|
|
101
164
|
class: "rounded-xl border border-sui-line-subtle bg-sui-surface p-4"
|
|
102
165
|
}, [c(t, { class: "mb-3" }), c(t, {
|
|
103
166
|
height: "0.75rem",
|
|
104
167
|
width: "70%"
|
|
105
|
-
})])), 64)) :
|
|
106
|
-
class: u(["relative
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
168
|
+
})])), 64)) : y.items.length === 0 && !R.value ? (f(), a("p", S, _(l.emptyLabel), 1)) : (f(), a("ul", C, [(f(!0), a(n, null, m(y.items, (e, t) => (f(), a("li", { key: I(e) }, [o("div", {
|
|
169
|
+
class: u(["relative rounded-xl outline-hidden transition-opacity duration-150 select-none", [
|
|
170
|
+
l.cardFrame && j,
|
|
171
|
+
l.onCardClick && "cursor-pointer focus-visible:sui-ring",
|
|
172
|
+
R.value?.id === I(e) && "opacity-40",
|
|
173
|
+
se(y.id, t, e) && "shadow-[0_-6px_0_-4px_rgb(var(--sui-accent-solid))]"
|
|
174
|
+
]]),
|
|
175
|
+
"data-board-index": t,
|
|
176
|
+
role: l.onCardClick ? "button" : void 0,
|
|
177
|
+
tabindex: l.onCardClick ? 0 : void 0,
|
|
178
|
+
onClickCapture: (t) => ae(t, e),
|
|
179
|
+
onContextmenu: p[0] ||= (e) => R.value && e.preventDefault(),
|
|
180
|
+
onDragstart: p[1] ||= ee(() => {}, ["prevent"]),
|
|
181
|
+
onKeydown: (t) => oe(t, e),
|
|
182
|
+
onPointerdown: (n) => G(n, e, y.id, t)
|
|
183
|
+
}, [h(d.$slots, "card", {
|
|
184
|
+
column: y,
|
|
117
185
|
item: e
|
|
118
|
-
}, () => [o("p",
|
|
186
|
+
}, () => [o("p", T, _(e.name), 1)])], 42, w)]))), 128))])), l.onNew && !l.loading ? (f(), a("button", {
|
|
119
187
|
key: 3,
|
|
120
188
|
class: "flex h-9 w-full shrink-0 items-center justify-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong text-xs font-medium text-sui-ink-muted opacity-0 outline-hidden transition-all duration-150 group-hover/body:opacity-100 hover:border-sui-ink-muted hover:bg-sui-surface/60 hover:text-sui-ink-body focus-visible:opacity-100 focus-visible:sui-ring",
|
|
121
189
|
type: "button",
|
|
122
|
-
onClick: (e) => l.onNew(
|
|
123
|
-
}, [
|
|
190
|
+
onClick: (e) => l.onNew(y)
|
|
191
|
+
}, [p[2] ||= o("svg", {
|
|
124
192
|
"aria-hidden": "true",
|
|
125
193
|
class: "size-3.5 fill-none stroke-current",
|
|
126
194
|
"stroke-linecap": "round",
|
|
127
195
|
"stroke-width": "1.5",
|
|
128
196
|
viewBox: "0 0 14 14"
|
|
129
|
-
}, [o("path", { d: "M7 2.5v9M2.5 7h9" })], -1), s(" " +
|
|
197
|
+
}, [o("path", { d: "M7 2.5v9M2.5 7h9" })], -1), s(" " + _(l.newLabel), 1)], 8, E)) : i("", !0)], 10, x)], 8, te))), 128))], 2));
|
|
130
198
|
}
|
|
131
199
|
});
|
|
132
200
|
//#endregion
|
|
133
|
-
export {
|
|
201
|
+
export { M as default };
|
|
134
202
|
|
|
135
203
|
//# sourceMappingURL=Board.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Board.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_Fragment","_renderList","_unref","_createElementVNode","_createBlock","_resolveDynamicComponent","_withCtx","Icon","_createCommentVNode","_createTextVNode","_toDisplayString","_renderSlot","_createVNode","Skeleton","Icon_default","Skeleton_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","Board_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","id","useId","idOf","item","dragged","ref","target","onDragStart","event","onDragEnd","overColumn","column","overCard","rect","at","index","onLeave","onDrop","from","onCardKeydown","isTarget","openBlock","createElementBlock","normalizeClass","Fragment","renderList","unref","createElementVNode","createBlock","resolveDynamicComponent","withCtx","createCommentVNode","createTextVNode","toDisplayString","renderSlot","_ctx","$event","i","createVNode","_cache"],"sources":["../../../src/components/Board/Board.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { ref, useId } from 'vue'\n\nimport Icon from '../Icon/Icon.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { BoardColumn } from './types'\n\nexport interface BoardProps<T> {\n columns: BoardColumn<T>[]\n /** The item field that identifies it. */\n rowKey?: keyof T & string\n /** Cards also reorder within a column, for records that carry a position. */\n sortable?: boolean\n /** Columns run to the bottom of the parent and scroll inside it; give the parent a height. False sizes them to their cards. */\n fill?: boolean\n loading?: boolean\n /** The columns' heading level, to fit the page's outline. */\n headingLevel?: 2 | 3 | 4 | 5 | 6\n /** Adds a dashed \"New\" button at the foot of each column, shown on hover (`@new`). */\n onNew?: (column: BoardColumn<T>) => void\n newLabel?: string\n emptyLabel?: string\n}\n\nconst props = withDefaults(defineProps<BoardProps<T>>(), {\n rowKey: 'id' as never,\n fill: true,\n headingLevel: 3,\n onNew: undefined,\n newLabel: 'New',\n emptyLabel: 'No cards'\n})\n\nconst emit = defineEmits<{\n 'card-click': [item: T]\n /** A card dropped into a column, at its new index there. Show it moved at once; put it back if saving fails. */\n move: [id: unknown, column: string, index: number]\n}>()\n\ndefineSlots<{\n /** A card's content; `item.name` as a title by default. */\n card?: (props: { item: T; column: BoardColumn<T> }) => unknown\n /** Replaces a column's count, e.g. its summed deal value. */\n count?: (props: { column: BoardColumn<T> }) => unknown\n}>()\n\nconst id = useId()\nconst idOf = (item: T): unknown => item[props.rowKey ?? 'id']\n\nconst dragged = ref<{ id: unknown; column: string; index: number } | null>(null)\nconst target = ref<{ column: string; index: number } | null>(null)\n\nfunction onDragStart(event: DragEvent, item: T, column: string, index: number) {\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move'\n event.dataTransfer.setData('text/plain', String(idOf(item)))\n }\n dragged.value = { id: idOf(item), column, index }\n}\n\nfunction onDragEnd() {\n dragged.value = null\n target.value = null\n}\n\nfunction overColumn(event: DragEvent, column: BoardColumn<T>) {\n if (!dragged.value) return\n event.preventDefault()\n if (target.value?.column !== column.id) target.value = { column: column.id, index: column.items.length }\n}\n\n// The card's top half drops before it, the bottom half after.\nfunction overCard(event: DragEvent, column: string, index: number) {\n if (!dragged.value) return\n event.preventDefault()\n event.stopPropagation()\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()\n const at = event.clientY < rect.top + rect.height / 2 ? index : index + 1\n if (target.value?.column !== column || target.value.index !== at) target.value = { column, index: at }\n}\n\nfunction onLeave(event: DragEvent) {\n if (!(event.currentTarget as HTMLElement).contains(event.relatedTarget as Node | null)) target.value = null\n}\n\nfunction onDrop(event: DragEvent, column: BoardColumn<T>) {\n event.preventDefault()\n const from = dragged.value\n if (from) {\n let index = target.value?.column === column.id ? target.value.index : column.items.length\n if (from.column === column.id) {\n // Within a column the dragged card leaves its old slot first.\n if (index > from.index) index--\n if (props.sortable && index !== from.index) emit('move', from.id, column.id, index)\n } else {\n emit('move', from.id, column.id, index)\n }\n }\n onDragEnd()\n}\n\nfunction onCardKeydown(event: KeyboardEvent, item: T) {\n if (event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' ')) return\n event.preventDefault()\n emit('card-click', item)\n}\n\nconst isTarget = (column: string, index: number, item: T) =>\n target.value?.column === column && target.value.index === index && dragged.value?.id !== idOf(item)\n</script>\n\n<!-- A board: cards in columns by a field (a stage, a status), dragged between columns. -->\n<template>\n <div\n class=\"flex items-stretch gap-5 overflow-x-auto pb-2 after:w-1 after:shrink-0 after:content-['']\"\n :class=\"fill && 'h-full min-h-0 flex-1'\"\n >\n <section\n v-for=\"column in columns\"\n :key=\"column.id\"\n :aria-labelledby=\"`${id}-${column.id}`\"\n class=\"flex min-h-0 w-full max-w-xs min-w-[16rem] shrink-0 flex-col\"\n >\n <header class=\"flex items-center justify-between px-1 pb-2.5\">\n <component\n :is=\"`h${headingLevel}`\"\n :id=\"`${id}-${column.id}`\"\n class=\"m-0 flex items-center gap-2 text-sm font-semibold text-sui-ink\"\n >\n <Icon v-if=\"column.icon\" :color=\"column.iconColor ?? 'ink-subtle'\" :name=\"column.icon\" />\n {{ column.name }}\n </component>\n <span\n class=\"ml-2 inline-flex h-5 items-center justify-center rounded-full bg-sui-sunken px-2 text-xs text-sui-ink-muted tabular-nums\"\n >\n <slot :column=\"column\" name=\"count\">{{ column.items.length }}</slot>\n </span>\n </header>\n <div\n class=\"group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl bg-sui-sunken p-2.5 transition-shadow duration-150\"\n :class=\"target?.column === column.id && 'ring-2 ring-sui-accent-line ring-inset'\"\n @dragleave=\"onLeave\"\n @dragover=\"overColumn($event, column)\"\n @drop=\"onDrop($event, column)\"\n >\n <template v-if=\"loading\">\n <div\n v-for=\"i in 3\"\n :key=\"i\"\n aria-hidden=\"true\"\n class=\"rounded-xl border border-sui-line-subtle bg-sui-surface p-4\"\n >\n <Skeleton class=\"mb-3\" />\n <Skeleton height=\"0.75rem\" width=\"70%\" />\n </div>\n </template>\n <p\n v-else-if=\"column.items.length === 0 && !dragged\"\n class=\"m-0 px-1 py-3 text-center text-13 text-sui-ink-muted\"\n >\n {{ emptyLabel }}\n </p>\n <ul v-else class=\"m-0 flex list-none flex-col gap-2.5 p-0\">\n <li v-for=\"(item, index) in column.items\" :key=\"idOf(item) as PropertyKey\">\n <div\n class=\"relative cursor-pointer rounded-xl border border-sui-line-subtle bg-sui-surface p-4 outline-hidden transition-[border-color,opacity] duration-150 hover:border-sui-line focus-visible:sui-ring\"\n :class=\"[\n dragged?.id === idOf(item) && 'opacity-40',\n isTarget(column.id, index, item) && 'shadow-[0_-6px_0_-4px_rgb(var(--sui-accent-solid))]'\n ]\"\n draggable=\"true\"\n role=\"button\"\n tabindex=\"0\"\n @click=\"emit('card-click', item)\"\n @dragend=\"onDragEnd\"\n @dragover=\"overCard($event, column.id, index)\"\n @dragstart=\"onDragStart($event, item, column.id, index)\"\n @keydown=\"onCardKeydown($event, item)\"\n >\n <slot :column=\"column\" :item=\"item\" name=\"card\">\n <p class=\"m-0 text-sm font-semibold text-sui-ink\">{{ item.name }}</p>\n </slot>\n </div>\n </li>\n </ul>\n <button\n v-if=\"onNew && !loading\"\n class=\"flex h-9 w-full shrink-0 items-center justify-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong text-xs font-medium text-sui-ink-muted opacity-0 outline-hidden transition-all duration-150 group-hover/body:opacity-100 hover:border-sui-ink-muted hover:bg-sui-surface/60 hover:text-sui-ink-body focus-visible:opacity-100 focus-visible:sui-ring\"\n type=\"button\"\n @click=\"onNew(column)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 14 14\"\n >\n <path d=\"M7 2.5v9M2.5 7h9\" />\n </svg>\n {{ newLabel }}\n </button>\n </div>\n </section>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Board.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createElementBlock","_normalizeClass","_Fragment","_renderList","_unref","_createElementVNode","_createBlock","_resolveDynamicComponent","_withCtx","Icon","_createCommentVNode","_createTextVNode","_toDisplayString","_renderSlot","_createVNode","Skeleton","_withModifiers","Icon_default","Skeleton_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","MOUSE_SLOP","TOUCH_SLOP","TOUCH_DELAY","EDGE","frame","Board_vue_vue_type_script_setup_true_lang_default","__emit","props","__props","emit","id","useId","idOf","item","root","ref","dragged","target","pending","pressTimer","ghost","grab","justDragged","onPointerDown","event","touch","start","onPointerMove","onPointerUp","stop","holdScroll","onEscape","rect","follow","moved","aim","scrollNear","x","y","under","body","column","card","index","c","board","from","to","clickCard","onCardKeydown","isTarget","openBlock","createElementBlock","normalizeClass","Fragment","renderList","unref","createElementVNode","createBlock","resolveDynamicComponent","withCtx","createCommentVNode","createTextVNode","toDisplayString","renderSlot","_ctx","i","createVNode","$event","_cache","withModifiers"],"sources":["../../../src/components/Board/Board.vue"],"sourcesContent":["<script setup lang=\"ts\" generic=\"T extends Record<string, any>\">\nimport { onBeforeUnmount, ref, useId } from 'vue'\n\nimport Icon from '../Icon/Icon.vue'\nimport Skeleton from '../Skeleton/Skeleton.vue'\nimport type { BoardColumn } from './types'\n\nexport interface BoardProps<T> {\n columns: BoardColumn<T>[]\n /** The item field that identifies it. */\n rowKey?: keyof T & string\n /** Cards also reorder within a column, for records that carry a position. */\n sortable?: boolean\n /** Columns run to the bottom of the parent and scroll inside it; give the parent a height. False sizes them to their cards. */\n fill?: boolean\n loading?: boolean\n /** The columns' heading level, to fit the page's outline. */\n headingLevel?: 2 | 3 | 4 | 5 | 6\n /** Draws each card's border, padding and surface. False when the `card` slot draws its own. */\n cardFrame?: boolean\n /** Makes a card a button that opens on click, Enter and Space (`@card-click`). Without it, the card slot carries its\n * own link or buttons. */\n onCardClick?: (item: T) => void\n /** Adds a dashed \"New\" button at the foot of each column, shown on hover (`@new`). */\n onNew?: (column: BoardColumn<T>) => void\n newLabel?: string\n emptyLabel?: string\n}\n\nconst props = withDefaults(defineProps<BoardProps<T>>(), {\n rowKey: 'id' as never,\n fill: true,\n headingLevel: 3,\n cardFrame: true,\n onCardClick: undefined,\n onNew: undefined,\n newLabel: 'New',\n emptyLabel: 'No cards'\n})\n\nconst emit = defineEmits<{\n /** A card dropped into a column, at its new index there. Show it moved at once; put it back if saving fails. */\n move: [id: unknown, column: string, index: number]\n}>()\n\ndefineSlots<{\n /** A card's content; `item.name` as a title by default. */\n card?: (props: { item: T; column: BoardColumn<T> }) => unknown\n /** Replaces a column's count, e.g. its summed deal value. */\n count?: (props: { column: BoardColumn<T> }) => unknown\n}>()\n\nconst id = useId()\nconst idOf = (item: T): unknown => item[props.rowKey ?? 'id']\nconst root = ref<HTMLElement>()\n\nconst dragged = ref<{ id: unknown; column: string; index: number } | null>(null)\nconst target = ref<{ column: string; index: number } | null>(null)\n\n// Dragging runs on pointer events, so it works with a mouse, a pen and a finger. A mouse drags once it moves a few\n// pixels, so a click still clicks; a finger after a short press, so a swipe still scrolls.\nconst MOUSE_SLOP = 4\nconst TOUCH_SLOP = 8\nconst TOUCH_DELAY = 250\nconst EDGE = 48\n\nlet pending: {\n item: T\n column: string\n index: number\n x: number\n y: number\n card: HTMLElement\n touch: boolean\n} | null = null\nlet pressTimer: number | undefined\nlet ghost: HTMLElement | null = null\nlet grab = { x: 0, y: 0 }\nlet justDragged = false\n\nfunction onPointerDown(event: PointerEvent, item: T, column: string, index: number) {\n if (event.button !== 0 || (event.target as HTMLElement).closest('input, textarea, select, [contenteditable]')) return\n const touch = event.pointerType === 'touch'\n pending = { item, column, index, x: event.clientX, y: event.clientY, card: event.currentTarget as HTMLElement, touch }\n if (touch) pressTimer = window.setTimeout(() => pending && start(), TOUCH_DELAY)\n window.addEventListener('pointermove', onPointerMove)\n window.addEventListener('pointerup', onPointerUp)\n window.addEventListener('pointercancel', stop)\n window.addEventListener('touchmove', holdScroll, { passive: false })\n window.addEventListener('keydown', onEscape)\n}\n\nfunction start() {\n if (!pending) return\n const rect = pending.card.getBoundingClientRect()\n grab = { x: pending.x - rect.left, y: pending.y - rect.top }\n ghost = pending.card.cloneNode(true) as HTMLElement\n ghost.removeAttribute('id')\n ghost.setAttribute('aria-hidden', 'true')\n ghost.classList.add('pointer-events-none', 'fixed', 'top-0', 'left-0', 'z-[1300]', 'shadow-lg', 'opacity-95')\n ghost.style.width = `${rect.width}px`\n document.body.appendChild(ghost)\n follow(pending.x, pending.y)\n dragged.value = { id: idOf(pending.item), column: pending.column, index: pending.index }\n}\n\nfunction onPointerMove(event: PointerEvent) {\n if (!pending) return\n if (!dragged.value) {\n const moved = Math.hypot(event.clientX - pending.x, event.clientY - pending.y)\n // A finger that moves before the press is long enough is scrolling.\n if (pending.touch) return moved > TOUCH_SLOP ? stop() : undefined\n if (moved < MOUSE_SLOP) return\n start()\n }\n event.preventDefault()\n follow(event.clientX, event.clientY)\n aim(event.clientX, event.clientY)\n scrollNear(event.clientX, event.clientY)\n}\n\nfunction follow(x: number, y: number) {\n if (ghost) ghost.style.transform = `translate(${x - grab.x}px, ${y - grab.y}px) rotate(1.5deg)`\n}\n\n// What's under the pointer: a card's top half drops before it, the bottom half after; an empty spot, at the end.\nfunction aim(x: number, y: number) {\n const under = document.elementFromPoint(x, y)\n const body = under?.closest<HTMLElement>('[data-board-column]')\n if (!body || !root.value?.contains(body)) {\n target.value = null\n return\n }\n const column = body.dataset.boardColumn!\n const card = under!.closest<HTMLElement>('[data-board-index]')\n let index = props.columns.find((c) => c.id === column)?.items.length ?? 0\n if (card && body.contains(card)) {\n const rect = card.getBoundingClientRect()\n index = Number(card.dataset.boardIndex) + (y < rect.top + rect.height / 2 ? 0 : 1)\n }\n if (target.value?.column !== column || target.value.index !== index) target.value = { column, index }\n}\n\n// Near a column's top or bottom, or the board's sides, it scrolls that way.\nfunction scrollNear(x: number, y: number) {\n const body = document.elementFromPoint(x, y)?.closest<HTMLElement>('[data-board-column]')\n if (body) {\n const rect = body.getBoundingClientRect()\n if (y < rect.top + EDGE) body.scrollTop -= 12\n else if (y > rect.bottom - EDGE) body.scrollTop += 12\n }\n const board = root.value?.getBoundingClientRect()\n if (board && root.value) {\n if (x < board.left + EDGE) root.value.scrollLeft -= 12\n else if (x > board.right - EDGE) root.value.scrollLeft += 12\n }\n}\n\nfunction onPointerUp() {\n const from = dragged.value\n const to = target.value\n if (from && to) {\n let index = to.index\n if (from.column === to.column) {\n // Within a column the dragged card leaves its old slot first.\n if (index > from.index) index--\n if (props.sortable && index !== from.index) emit('move', from.id, to.column, index)\n } else {\n emit('move', from.id, to.column, index)\n }\n }\n stop()\n}\n\nfunction holdScroll(event: TouchEvent) {\n if (dragged.value) event.preventDefault()\n}\n\nfunction onEscape(event: KeyboardEvent) {\n if (event.key === 'Escape' && dragged.value) {\n event.preventDefault()\n stop()\n }\n}\n\nfunction stop() {\n window.clearTimeout(pressTimer)\n window.removeEventListener('pointermove', onPointerMove)\n window.removeEventListener('pointerup', onPointerUp)\n window.removeEventListener('pointercancel', stop)\n window.removeEventListener('touchmove', holdScroll)\n window.removeEventListener('keydown', onEscape)\n ghost?.remove()\n ghost = null\n // The click that ends a drag isn't a click on the card.\n if (dragged.value) {\n justDragged = true\n window.setTimeout(() => (justDragged = false))\n }\n pending = null\n dragged.value = null\n target.value = null\n}\n\nonBeforeUnmount(stop)\n\nfunction clickCard(event: MouseEvent, item: T) {\n if (justDragged) {\n event.preventDefault()\n event.stopPropagation()\n return\n }\n props.onCardClick?.(item)\n}\n\nfunction onCardKeydown(event: KeyboardEvent, item: T) {\n if (!props.onCardClick || event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' ')) return\n event.preventDefault()\n props.onCardClick(item)\n}\n\nconst isTarget = (column: string, index: number, item: T) =>\n target.value?.column === column && target.value.index === index && dragged.value?.id !== idOf(item)\n\nconst frame =\n 'border border-sui-line-subtle bg-sui-surface p-4 transition-[border-color,opacity] duration-150 hover:border-sui-line'\n</script>\n\n<!-- A board: cards in columns by a field (a stage, a status), dragged between columns. -->\n<template>\n <div\n ref=\"root\"\n class=\"flex items-stretch gap-5 overflow-x-auto pb-2 after:w-1 after:shrink-0 after:content-['']\"\n :class=\"fill && 'h-full min-h-0 flex-1'\"\n >\n <section\n v-for=\"column in columns\"\n :key=\"column.id\"\n :aria-labelledby=\"`${id}-${column.id}`\"\n class=\"flex min-h-0 w-full max-w-xs min-w-[16rem] shrink-0 flex-col\"\n >\n <header class=\"flex items-center justify-between px-1 pb-2.5\">\n <component\n :is=\"`h${headingLevel}`\"\n :id=\"`${id}-${column.id}`\"\n class=\"m-0 flex items-center gap-2 text-sm font-semibold text-sui-ink\"\n >\n <Icon v-if=\"column.icon\" :color=\"column.iconColor ?? 'ink-subtle'\" :name=\"column.icon\" />\n {{ column.name }}\n </component>\n <span\n class=\"ml-2 inline-flex h-5 items-center justify-center rounded-full bg-sui-sunken px-2 text-xs text-sui-ink-muted tabular-nums\"\n >\n <slot :column=\"column\" name=\"count\">{{ column.items.length }}</slot>\n </span>\n </header>\n <div\n class=\"group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl bg-sui-sunken p-2.5 transition-shadow duration-150\"\n :class=\"target?.column === column.id && 'ring-2 ring-sui-accent-line ring-inset'\"\n :data-board-column=\"column.id\"\n >\n <template v-if=\"loading\">\n <div\n v-for=\"i in 3\"\n :key=\"i\"\n aria-hidden=\"true\"\n class=\"rounded-xl border border-sui-line-subtle bg-sui-surface p-4\"\n >\n <Skeleton class=\"mb-3\" />\n <Skeleton height=\"0.75rem\" width=\"70%\" />\n </div>\n </template>\n <p\n v-else-if=\"column.items.length === 0 && !dragged\"\n class=\"m-0 px-1 py-3 text-center text-13 text-sui-ink-muted\"\n >\n {{ emptyLabel }}\n </p>\n <ul v-else class=\"m-0 flex list-none flex-col gap-2.5 p-0\">\n <li v-for=\"(item, index) in column.items\" :key=\"idOf(item) as PropertyKey\">\n <div\n class=\"relative rounded-xl outline-hidden transition-opacity duration-150 select-none\"\n :class=\"[\n cardFrame && frame,\n onCardClick && 'cursor-pointer focus-visible:sui-ring',\n dragged?.id === idOf(item) && 'opacity-40',\n isTarget(column.id, index, item) && 'shadow-[0_-6px_0_-4px_rgb(var(--sui-accent-solid))]'\n ]\"\n :data-board-index=\"index\"\n :role=\"onCardClick ? 'button' : undefined\"\n :tabindex=\"onCardClick ? 0 : undefined\"\n @click.capture=\"clickCard($event, item)\"\n @contextmenu=\"dragged && $event.preventDefault()\"\n @dragstart.prevent\n @keydown=\"onCardKeydown($event, item)\"\n @pointerdown=\"onPointerDown($event, item, column.id, index)\"\n >\n <slot :column=\"column\" :item=\"item\" name=\"card\">\n <p class=\"m-0 text-sm font-semibold text-sui-ink\">{{ item.name }}</p>\n </slot>\n </div>\n </li>\n </ul>\n <button\n v-if=\"onNew && !loading\"\n class=\"flex h-9 w-full shrink-0 items-center justify-center gap-1.5 rounded-lg border border-dashed border-sui-line-strong text-xs font-medium text-sui-ink-muted opacity-0 outline-hidden transition-all duration-150 group-hover/body:opacity-100 hover:border-sui-ink-muted hover:bg-sui-surface/60 hover:text-sui-ink-body focus-visible:opacity-100 focus-visible:sui-ring\"\n type=\"button\"\n @click=\"onNew(column)\"\n >\n <svg\n aria-hidden=\"true\"\n class=\"size-3.5 fill-none stroke-current\"\n stroke-linecap=\"round\"\n stroke-width=\"1.5\"\n viewBox=\"0 0 14 14\"\n >\n <path d=\"M7 2.5v9M2.5 7h9\" />\n </svg>\n {{ newLabel }}\n </button>\n </div>\n </section>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;A,6EA6DM6B,IAAa,GACbC,IAAa,GACbC,IAAc,KACdC,IAAO,IAgKPC,IACJ,yH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EApMF,IAAMG,IAAQC,GAWRC,IAAOH,GAYPI,IAAKC,EAAM,GACXC,KAAQ,MAAqBC,EAAKN,EAAM,UAAU,OAClDO,IAAOC,EAAiB,GAExBC,IAAUD,EAA2D,IAAI,GACzEE,IAASF,EAA8C,IAAI,GAS7DG,IAQO,MACPC,GACAC,IAA4B,MAC5BC,IAAO;GAAE,GAAG;GAAG,GAAG;EAAE,GACpBC,IAAc;EAElB,SAASC,EAAc,GAAqB,GAAS,GAAgB,GAAe;GAClF,IAAIC,EAAM,WAAW,KAAMA,EAAM,OAAuB,QAAQ,4CAA4C,GAAG;GAC/G,IAAMC,IAAQD,EAAM,gBAAgB;GAOpC,AANA,IAAU;IAAE;IAAM;IAAQ;IAAO,GAAGA,EAAM;IAAS,GAAGA,EAAM;IAAS,MAAMA,EAAM;IAA8B;GAAM,GACjHC,MAAO,IAAa,OAAO,iBAAiBP,KAAWQ,EAAM,GAAGxB,CAAW,IAC/E,OAAO,iBAAiB,eAAeyB,CAAa,GACpD,OAAO,iBAAiB,aAAaC,CAAW,GAChD,OAAO,iBAAiB,iBAAiBC,CAAI,GAC7C,OAAO,iBAAiB,aAAaC,GAAY,EAAE,SAAS,GAAM,CAAC,GACnE,OAAO,iBAAiB,WAAWC,CAAQ;EAC7C;EAEA,SAASL,IAAQ;GACf,IAAI,CAACR,GAAS;GACd,IAAMc,IAAOd,EAAQ,KAAK,sBAAsB;GAShD,AARA,IAAO;IAAE,GAAGA,EAAQ,IAAIc,EAAK;IAAM,GAAGd,EAAQ,IAAIc,EAAK;GAAI,GAC3D,IAAQd,EAAQ,KAAK,UAAU,EAAI,GACnCE,EAAM,gBAAgB,IAAI,GAC1BA,EAAM,aAAa,eAAe,MAAM,GACxCA,EAAM,UAAU,IAAI,uBAAuB,SAAS,SAAS,UAAU,YAAY,aAAa,YAAY,GAC5G,EAAM,MAAM,QAAQ,GAAGY,EAAK,MAAM,KAClC,SAAS,KAAK,YAAYZ,CAAK,GAC/Ba,EAAOf,EAAQ,GAAGA,EAAQ,CAAC,GAC3B,EAAQ,QAAQ;IAAE,IAAIN,EAAKM,EAAQ,IAAI;IAAG,QAAQA,EAAQ;IAAQ,OAAOA,EAAQ;GAAM;EACzF;EAEA,SAASS,EAAc,GAAqB;GAC1C,IAAKT,GACL;QAAI,CAACF,EAAQ,OAAO;KAClB,IAAMkB,IAAQ,KAAK,MAAMV,EAAM,UAAUN,EAAQ,GAAGM,EAAM,UAAUN,EAAQ,CAAC;KAE7E,IAAIA,EAAQ,OAAO,OAAOgB,IAAQjC,IAAa4B,EAAK,IAAI,KAAA;KACxD,IAAIK,IAAQlC,GAAY;KACxB,EAAM;IACR;IAIA,AAHAwB,EAAM,eAAe,GACrBS,EAAOT,EAAM,SAASA,EAAM,OAAO,GACnCW,EAAIX,EAAM,SAASA,EAAM,OAAO,GAChCY,GAAWZ,EAAM,SAASA,EAAM,OAAO;GAJvC;EAKF;EAEA,SAASS,EAAO,GAAW,GAAW;GACpC,AAAIb,MAAO,EAAM,MAAM,YAAY,aAAaiB,IAAIhB,EAAK,EAAE,MAAMiB,IAAIjB,EAAK,EAAE;EAC9E;EAGA,SAASc,EAAI,GAAW,GAAW;GACjC,IAAMI,IAAQ,SAAS,iBAAiBF,GAAGC,CAAC,GACtCE,IAAOD,GAAO,QAAqB,qBAAqB;GAC9D,IAAI,CAACC,KAAQ,CAAC1B,EAAK,OAAO,SAAS0B,CAAI,GAAG;IACxC,EAAO,QAAQ;IACf;GACF;GACA,IAAMC,IAASD,EAAK,QAAQ,aACtBE,IAAOH,EAAO,QAAqB,oBAAoB,GACzDI,IAAQpC,EAAM,QAAQ,MAAM,MAAMqC,EAAE,OAAOH,CAAM,CAAC,EAAE,MAAM,UAAU;GACxE,IAAIC,KAAQF,EAAK,SAASE,CAAI,GAAG;IAC/B,IAAMV,IAAOU,EAAK,sBAAsB;IACxC,IAAQ,OAAOA,EAAK,QAAQ,UAAU,KAAKJ,IAAIN,EAAK,MAAMA,EAAK,SAAS,IAAI,IAAI;GAClF;GACA,CAAIf,EAAO,OAAO,WAAWwB,KAAUxB,EAAO,MAAM,UAAU0B,OAAO,EAAO,QAAQ;IAAE;IAAQ;GAAM;EACtG;EAGA,SAASP,GAAW,GAAW,GAAW;GACxC,IAAMI,IAAO,SAAS,iBAAiBH,GAAGC,CAAC,CAAC,EAAE,QAAqB,qBAAqB;GACxF,IAAIE,GAAM;IACR,IAAMR,IAAOQ,EAAK,sBAAsB;IACxC,AAAIF,IAAIN,EAAK,MAAM7B,IAAM,EAAK,aAAa,KAClCmC,IAAIN,EAAK,SAAS7B,MAAM,EAAK,aAAa;GACrD;GACA,IAAM0C,IAAQ/B,EAAK,OAAO,sBAAsB;GAChD,AAAI+B,KAAS/B,EAAK,UACZuB,IAAIQ,EAAM,OAAO1C,IAAM,EAAK,MAAM,cAAc,KAC3CkC,IAAIQ,EAAM,QAAQ1C,MAAM,EAAK,MAAM,cAAc;EAE9D;EAEA,SAASyB,IAAc;GACrB,IAAMkB,IAAO9B,EAAQ,OACf+B,IAAK9B,EAAO;GAClB,IAAI6B,KAAQC,GAAI;IACd,IAAIJ,IAAQI,EAAG;IACf,AAAID,EAAK,WAAWC,EAAG,UAEjBJ,IAAQG,EAAK,SAAO,KACpBvC,EAAM,YAAYoC,MAAUG,EAAK,SAAOrC,EAAK,QAAQqC,EAAK,IAAIC,EAAG,QAAQJ,CAAK,KAElFlC,EAAK,QAAQqC,EAAK,IAAIC,EAAG,QAAQJ,CAAK;GAE1C;GACA,EAAK;EACP;EAEA,SAASb,EAAW,GAAmB;GACrC,AAAId,EAAQ,SAAOQ,EAAM,eAAe;EAC1C;EAEA,SAASO,EAAS,GAAsB;GACtC,AAAIP,EAAM,QAAQ,YAAYR,EAAQ,UACpCQ,EAAM,eAAe,GACrBK,EAAK;EAET;EAEA,SAASA,IAAO;GAgBd,AAfA,OAAO,aAAaV,CAAU,GAC9B,OAAO,oBAAoB,eAAeQ,CAAa,GACvD,OAAO,oBAAoB,aAAaC,CAAW,GACnD,OAAO,oBAAoB,iBAAiBC,CAAI,GAChD,OAAO,oBAAoB,aAAaC,CAAU,GAClD,OAAO,oBAAoB,WAAWC,CAAQ,GAC9CX,GAAO,OAAO,GACd,IAAQ,MAEJJ,EAAQ,UACV,IAAc,IACd,OAAO,iBAAkB,IAAc,EAAM,IAE/C,IAAU,MACV,EAAQ,QAAQ,MAChB,EAAO,QAAQ;EACjB;EAEA,EAAgBa,CAAI;EAEpB,SAASmB,GAAU,GAAmB,GAAS;GAC7C,AAAI1B,KACFE,EAAM,eAAe,GACrBA,EAAM,gBAAgB,KAGxBjB,EAAM,cAAcM,CAAI;EAC1B;EAEA,SAASoC,GAAc,GAAsB,GAAS;GACpD,AAAI,CAAC1C,EAAM,eAAeiB,EAAM,WAAWA,EAAM,iBAAkBA,EAAM,QAAQ,WAAWA,EAAM,QAAQ,QAC1GA,EAAM,eAAe,GACrBjB,EAAM,YAAYM,CAAI;EACxB;EAEA,IAAMqC,MAAY,GAAgB,GAAe,MAC/CjC,EAAO,OAAO,WAAWwB,KAAUxB,EAAO,MAAM,UAAU0B,KAAS3B,EAAQ,OAAO,OAAOJ,EAAKC,CAAI;E,kBAQlG1C,EAAA,GAAAC,EA4FM,OAAA;GA3FA,SAAA;GAAJ,KAAI0C;GACJ,OAAKzC,EAAA,CAAC,6FACEmC,EAAA,QAAI,uBAAA,CAAA;E,KAEZrC,EAAA,EAAA,GAAAC,EAsFUE,GAAA,MAAAC,EArFSiC,EAAA,UAAV,OADTrC,EAAA,GAAAC,EAsFU,WAAA;GApFP,KAAKqE,EAAO;GACZ,mBAAe,GAAKjE,EAAAkC,CAAA,EAAE,GAAI+B,EAAO;GAClC,OAAM;E,IAENhE,EAcS,UAdTe,IAcS,EAbPrB,EAAA,GAAAO,EAOYC,EAAA,IAND6B,EAAA,cAAY,GAAA;GACpB,IAAE,GAAKhC,EAAAkC,CAAA,EAAE,GAAI+B,EAAO;GACrB,OAAM;;GAEN,SAAA7D,QAAyF,CAA7E6D,EAAO,QAAnBtE,EAAA,GAAAO,EAAyFG,GAAA;;IAA/D,OAAO4D,EAAO,aAAS;IAAmB,MAAMA,EAAO;G,6CAAQ1D,EAAA,MACzFC,EAAGyD,EAAO,IAAI,GAAA,CAAA,C;;E,mBAEhBhE,EAIO,QAJPgB,IAIO,CADLR,EAAoEgF,EAAA,QAAA,SAAA,EAArD,UAAM,SAA+C,CAA7BlF,EAAAC,EAAAyD,EAAO,MAAM,MAAM,GAAA,CAAA,C,QAG9DhE,EAgEM,OAAA;GA/DJ,OAAKJ,EAAA,CAAC,uIACE4C,EAAA,OAAQ,WAAWwB,EAAO,MAAE,wCAAA,CAAA;GACnC,qBAAmBA,EAAO;E,IAEXjC,EAAA,WACdrC,EAAA,GAAAC,EAQME,GAAA,EAAA,KAAA,EAAA,GAAAC,EAPQ,IAAL,MADTE,EAQM,OAAA;GANH,KAAKyF;GACN,eAAY;GACZ,OAAM;E,IAENhF,EAAyBC,GAAA,EAAf,OAAM,OAAM,CAAA,GACtBD,EAAyCC,GAAA;GAA/B,QAAO;GAAU,OAAM;E,cAIxBsD,EAAO,MAAM,WAAM,KAAA,CAAWzB,EAAA,SAD3C7C,EAAA,GAAAC,EAKI,KALJuB,GAKIX,EADCwB,EAAA,UAAU,GAAA,CAAA,MAEfrC,EAAA,GAAAC,EAwBK,MAxBLwB,GAwBK,EAvBHzB,EAAA,EAAA,GAAAC,EAsBKE,GAAA,MAAAC,EAtBuBkE,EAAO,QAAvB,GAAM,OAAlBtE,EAAA,GAAAC,EAsBK,MAAA,EAtBsC,KAAKwC,EAAKC,CAAI,E,IACvDpC,EAoBM,OAAA;GAnBJ,OAAKJ,EAAA,CAAC,kFAAgF;IAC5DmC,EAAA,aAAaJ;IAAuBI,EAAA,eAAW;IAA6DQ,EAAA,OAAS,OAAOJ,EAAKC,CAAI,KAAA;IAAmCqC,GAAST,EAAO,IAAIE,GAAO9B,CAAI,KAAA;;GAMhO,oBAAkB8B;GAClB,MAAMnC,EAAA,cAAW,WAAc,KAAA;GAC/B,UAAUA,EAAA,cAAW,IAAO,KAAA;GACb,iBAAA,MAAAwC,GAAUoB,GAAQvD,CAAI;GACrC,eAAW,AAAAwD,EAAA,QAAA,MAAErD,EAAA,SAAWoD,EAAO,eAAc;GAC7C,aAAS,AAAAC,EAAA,OAAAjF,SAAV,CAAA,GAAkB,CAAA,SAAA,CAAA;GACjB,YAAO,MAAE6D,GAAcmB,GAAQvD,CAAI;GACnC,gBAAW,MAAEU,EAAc6C,GAAQvD,GAAM4B,EAAO,IAAIE,CAAK;E,IAE1D1D,EAEOgF,EAAA,QAAA,QAAA;GAFQ;GAAe;EAA9B,SAEO,CADLxF,EAAqE,KAArEqB,GAAqEd,EAAhB6B,EAAK,IAAI,GAAA,CAAA,C,2BAM9DL,EAAA,SAAK,CAAKA,EAAA,WADlBrC,EAAA,GAAAC,EAgBS,UAAA;;GAdP,OAAM;GACN,MAAK;GACJ,UAAK,MAAEoC,EAAA,MAAMiC,CAAM;E,IAEpB,AAAA4B,EAAA,OAAA5F,EAQM,OAAA;GAPJ,eAAY;GACZ,OAAM;GACN,kBAAe;GACf,gBAAa;GACb,SAAQ;E,IAERA,EAA6B,QAAA,EAAvB,GAAE,mBAAkB,CAAA,C,QACtBM,EAAA,MACNC,EAAGwB,EAAA,QAAQ,GAAA,CAAA,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","names":["_sfc_main","Button_vue_vue_type_script_setup_true_lang_default","Button_default"],"sources":["../../../src/components/Button/Button.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nexport type ButtonVariant
|
|
1
|
+
{"version":3,"file":"Button.js","names":["_sfc_main","Button_vue_vue_type_script_setup_true_lang_default","Button_default"],"sources":["../../../src/components/Button/Button.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nexport type ButtonVariant =\n 'primary' | 'secondary' | 'tinted' | 'ghost' | 'contrast' | 'danger' | 'danger-outline' | 'ghost-inverse'\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg'\n\nexport interface ButtonProps extends PrimitiveProps {\n variant?: ButtonVariant\n size?: ButtonSize\n /** Fully rounded ends. */\n pill?: boolean\n /** Square, for a single icon; give it an `aria-label`. */\n iconOnly?: boolean\n /** Where the icon sits next to the label; it's spaced from the text on the other side. */\n iconPosition?: 'start' | 'end'\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: 'button',\n variant: 'secondary',\n size: 'md',\n iconPosition: 'start'\n})\n\nconst variants: Record<ButtonVariant, string> = {\n primary:\n 'border border-sui-accent-solid bg-sui-accent-solid text-sui-on-accent not-data-disabled:hover:border-sui-accent-hover not-data-disabled:hover:bg-sui-accent-hover [&_svg]:stroke-sui-on-accent',\n secondary:\n 'border border-sui-line bg-sui-surface text-sui-ink-emphasis shadow-(--sui-shadow-raised) not-data-disabled:hover:border-sui-line-strong not-data-disabled:hover:bg-sui-canvas [&_svg]:stroke-sui-ink-emphasis',\n tinted:\n 'border border-sui-accent-line bg-sui-accent-wash text-sui-accent not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent',\n ghost:\n 'border border-transparent bg-transparent text-sui-ink-subtle not-data-disabled:hover:bg-sui-sunken not-data-disabled:hover:text-sui-ink-emphasis',\n contrast:\n 'border border-sui-contrast bg-sui-contrast text-sui-on-contrast not-data-disabled:hover:border-sui-contrast-hover not-data-disabled:hover:bg-sui-contrast-hover',\n // No border: it's 2px narrower than the other variants.\n danger: 'bg-sui-danger-solid text-sui-on-danger not-data-disabled:hover:bg-sui-danger-hover',\n 'danger-outline':\n 'border border-sui-danger-line bg-sui-surface text-sui-danger not-data-disabled:hover:bg-sui-danger-soft [&_svg]:stroke-sui-danger',\n // For inverse grounds: toasts, dark bands.\n 'ghost-inverse':\n 'border border-transparent bg-transparent text-sui-on-inverse not-data-disabled:hover:bg-sui-on-inverse/[0.12] not-data-disabled:active:bg-sui-on-inverse/[0.2] [&_svg]:stroke-sui-on-inverse'\n}\n\nconst heights: Record<ButtonSize, string> = {\n xs: 'h-6',\n sm: 'h-7',\n md: 'h-(--sui-button-height)',\n lg: 'h-12'\n}\n\nconst paddings: Record<ButtonSize, string> = {\n xs: 'px-2',\n sm: 'px-2.5',\n md: 'px-(--sui-button-padding-x)',\n lg: 'px-(--sui-button-padding-x)'\n}\n\nconst texts: Record<ButtonSize, string> = {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-(length:--sui-button-text) leading-5',\n lg: 'text-(length:--sui-button-text) leading-5'\n}\n\nconst classes = computed(() => [\n // no-underline: as a link, it shouldn't pick up the app's link styles.\n 'flex items-center justify-center font-medium text-nowrap no-underline transition-all duration-200 ease-in-out data-disabled:opacity-50',\n props.variant === 'ghost-inverse' ? 'focus-visible:sui-ring-inverse' : 'focus-visible:sui-ring',\n variants[props.variant],\n heights[props.size],\n texts[props.size],\n props.iconOnly ? 'aspect-square px-0' : paddings[props.size],\n // xs uses rounded-md: rounded-lg reads as a pill at that height.\n props.pill ? 'rounded-full' : props.size === 'xs' ? 'rounded-md' : 'rounded-(--sui-radius-button)',\n props.iconOnly ? '' : props.iconPosition === 'end' ? '[&_svg]:ml-2' : '[&_svg:first-child]:mr-2'\n])\n\n// A link or custom element can't be natively disabled: it says so to assistive tech instead.\nconst isNativeButton = computed(() => props.as === 'button' && !props.asChild)\n</script>\n\n<template>\n <Primitive\n :aria-disabled=\"disabled && !isNativeButton ? 'true' : undefined\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"classes\"\n :data-disabled=\"disabled ? '' : undefined\"\n :disabled=\"isNativeButton ? disabled : undefined\"\n >\n <slot />\n </Primitive>\n</template>\n"],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PrimitiveProps } from 'reka-ui';
|
|
2
|
-
export type ButtonVariant = 'primary' | 'secondary' | 'tinted' | 'ghost' | 'contrast' | 'danger' | 'danger-outline';
|
|
2
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'tinted' | 'ghost' | 'contrast' | 'danger' | 'danger-outline' | 'ghost-inverse';
|
|
3
3
|
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
4
4
|
export interface ButtonProps extends PrimitiveProps {
|
|
5
5
|
variant?: ButtonVariant;
|
|
@@ -21,7 +21,8 @@ var l = /*@__PURE__*/ n({
|
|
|
21
21
|
ghost: "border border-transparent bg-transparent text-sui-ink-subtle not-data-disabled:hover:bg-sui-sunken not-data-disabled:hover:text-sui-ink-emphasis",
|
|
22
22
|
contrast: "border border-sui-contrast bg-sui-contrast text-sui-on-contrast not-data-disabled:hover:border-sui-contrast-hover not-data-disabled:hover:bg-sui-contrast-hover",
|
|
23
23
|
danger: "bg-sui-danger-solid text-sui-on-danger not-data-disabled:hover:bg-sui-danger-hover",
|
|
24
|
-
"danger-outline": "border border-sui-danger-line bg-sui-surface text-sui-danger not-data-disabled:hover:bg-sui-danger-soft [&_svg]:stroke-sui-danger"
|
|
24
|
+
"danger-outline": "border border-sui-danger-line bg-sui-surface text-sui-danger not-data-disabled:hover:bg-sui-danger-soft [&_svg]:stroke-sui-danger",
|
|
25
|
+
"ghost-inverse": "border border-transparent bg-transparent text-sui-on-inverse not-data-disabled:hover:bg-sui-on-inverse/[0.12] not-data-disabled:active:bg-sui-on-inverse/[0.2] [&_svg]:stroke-sui-on-inverse"
|
|
25
26
|
}, d = {
|
|
26
27
|
xs: "h-6",
|
|
27
28
|
sm: "h-7",
|
|
@@ -38,7 +39,8 @@ var l = /*@__PURE__*/ n({
|
|
|
38
39
|
md: "text-(length:--sui-button-text) leading-5",
|
|
39
40
|
lg: "text-(length:--sui-button-text) leading-5"
|
|
40
41
|
}, m = e(() => [
|
|
41
|
-
"flex items-center justify-center font-medium text-nowrap no-underline transition-all duration-200 ease-in-out
|
|
42
|
+
"flex items-center justify-center font-medium text-nowrap no-underline transition-all duration-200 ease-in-out data-disabled:opacity-50",
|
|
43
|
+
l.variant === "ghost-inverse" ? "focus-visible:sui-ring-inverse" : "focus-visible:sui-ring",
|
|
42
44
|
u[l.variant],
|
|
43
45
|
d[l.size],
|
|
44
46
|
p[l.size],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_renderSlot","Button_vue_vue_type_script_setup_true_lang_default","props","__props","variants","heights","paddings","texts","classes","computed","isNativeButton","openBlock","createBlock","unref","Primitive","normalizeClass","withCtx","renderSlot","_ctx"],"sources":["../../../src/components/Button/Button.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nexport type ButtonVariant
|
|
1
|
+
{"version":3,"file":"Button.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_renderSlot","Button_vue_vue_type_script_setup_true_lang_default","props","__props","variants","heights","paddings","texts","classes","computed","isNativeButton","openBlock","createBlock","unref","Primitive","normalizeClass","withCtx","renderSlot","_ctx"],"sources":["../../../src/components/Button/Button.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nimport { Primitive, type PrimitiveProps } from 'reka-ui'\n\nexport type ButtonVariant =\n 'primary' | 'secondary' | 'tinted' | 'ghost' | 'contrast' | 'danger' | 'danger-outline' | 'ghost-inverse'\nexport type ButtonSize = 'xs' | 'sm' | 'md' | 'lg'\n\nexport interface ButtonProps extends PrimitiveProps {\n variant?: ButtonVariant\n size?: ButtonSize\n /** Fully rounded ends. */\n pill?: boolean\n /** Square, for a single icon; give it an `aria-label`. */\n iconOnly?: boolean\n /** Where the icon sits next to the label; it's spaced from the text on the other side. */\n iconPosition?: 'start' | 'end'\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: 'button',\n variant: 'secondary',\n size: 'md',\n iconPosition: 'start'\n})\n\nconst variants: Record<ButtonVariant, string> = {\n primary:\n 'border border-sui-accent-solid bg-sui-accent-solid text-sui-on-accent not-data-disabled:hover:border-sui-accent-hover not-data-disabled:hover:bg-sui-accent-hover [&_svg]:stroke-sui-on-accent',\n secondary:\n 'border border-sui-line bg-sui-surface text-sui-ink-emphasis shadow-(--sui-shadow-raised) not-data-disabled:hover:border-sui-line-strong not-data-disabled:hover:bg-sui-canvas [&_svg]:stroke-sui-ink-emphasis',\n tinted:\n 'border border-sui-accent-line bg-sui-accent-wash text-sui-accent not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent',\n ghost:\n 'border border-transparent bg-transparent text-sui-ink-subtle not-data-disabled:hover:bg-sui-sunken not-data-disabled:hover:text-sui-ink-emphasis',\n contrast:\n 'border border-sui-contrast bg-sui-contrast text-sui-on-contrast not-data-disabled:hover:border-sui-contrast-hover not-data-disabled:hover:bg-sui-contrast-hover',\n // No border: it's 2px narrower than the other variants.\n danger: 'bg-sui-danger-solid text-sui-on-danger not-data-disabled:hover:bg-sui-danger-hover',\n 'danger-outline':\n 'border border-sui-danger-line bg-sui-surface text-sui-danger not-data-disabled:hover:bg-sui-danger-soft [&_svg]:stroke-sui-danger',\n // For inverse grounds: toasts, dark bands.\n 'ghost-inverse':\n 'border border-transparent bg-transparent text-sui-on-inverse not-data-disabled:hover:bg-sui-on-inverse/[0.12] not-data-disabled:active:bg-sui-on-inverse/[0.2] [&_svg]:stroke-sui-on-inverse'\n}\n\nconst heights: Record<ButtonSize, string> = {\n xs: 'h-6',\n sm: 'h-7',\n md: 'h-(--sui-button-height)',\n lg: 'h-12'\n}\n\nconst paddings: Record<ButtonSize, string> = {\n xs: 'px-2',\n sm: 'px-2.5',\n md: 'px-(--sui-button-padding-x)',\n lg: 'px-(--sui-button-padding-x)'\n}\n\nconst texts: Record<ButtonSize, string> = {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-(length:--sui-button-text) leading-5',\n lg: 'text-(length:--sui-button-text) leading-5'\n}\n\nconst classes = computed(() => [\n // no-underline: as a link, it shouldn't pick up the app's link styles.\n 'flex items-center justify-center font-medium text-nowrap no-underline transition-all duration-200 ease-in-out data-disabled:opacity-50',\n props.variant === 'ghost-inverse' ? 'focus-visible:sui-ring-inverse' : 'focus-visible:sui-ring',\n variants[props.variant],\n heights[props.size],\n texts[props.size],\n props.iconOnly ? 'aspect-square px-0' : paddings[props.size],\n // xs uses rounded-md: rounded-lg reads as a pill at that height.\n props.pill ? 'rounded-full' : props.size === 'xs' ? 'rounded-md' : 'rounded-(--sui-radius-button)',\n props.iconOnly ? '' : props.iconPosition === 'end' ? '[&_svg]:ml-2' : '[&_svg:first-child]:mr-2'\n])\n\n// A link or custom element can't be natively disabled: it says so to assistive tech instead.\nconst isNativeButton = computed(() => props.as === 'button' && !props.asChild)\n</script>\n\n<template>\n <Primitive\n :aria-disabled=\"disabled && !isNativeButton ? 'true' : undefined\"\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"classes\"\n :data-disabled=\"disabled ? '' : undefined\"\n :disabled=\"isNativeButton ? disabled : undefined\"\n >\n <slot />\n </Primitive>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;EAqBA,IAAMO,IAAQC,GAORC,IAA0C;GAC9C,SACE;GACF,WACE;GACF,QACE;GACF,OACE;GACF,UACE;GAEF,QAAQ;GACR,kBACE;GAEF,iBACE;EACJ,GAEMC,IAAsC;GAC1C,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN,GAEMC,IAAuC;GAC3C,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN,GAEMC,IAAoC;GACxC,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN,GAEMC,IAAUC,QAAe;GAE7B;GACAP,EAAM,YAAY,kBAAkB,mCAAmC;GACvEE,EAASF,EAAM;GACfG,EAAQH,EAAM;GACdK,EAAML,EAAM;GACZA,EAAM,WAAW,uBAAuBI,EAASJ,EAAM;GAEvDA,EAAM,OAAO,iBAAiBA,EAAM,SAAS,OAAO,eAAe;GACnEA,EAAM,WAAW,KAAKA,EAAM,iBAAiB,QAAQ,iBAAiB;EACxE,CAAC,GAGKQ,IAAiBD,QAAeP,EAAM,OAAO,YAAY,CAACA,EAAM,OAAO;E,kBAI3EP,EAAA,GAAAC,EASYC,EAAAiB,CAAA,GAAA;GART,iBAAeX,EAAA,YAAQ,CAAKO,EAAA,QAAc,SAAY,KAAA;GACtD,IAAIP,EAAA;GACJ,YAAUA,EAAA;GACV,OAAKL,EAAEU,EAAA,KAAO;GACd,iBAAeL,EAAA,WAAQ,KAAQ,KAAA;GAC/B,UAAUO,EAAA,QAAiBP,EAAA,WAAW,KAAA;;GAEvC,SAAAJ,QAAQ,CAARC,EAAQkB,EAAA,QAAA,SAAA,C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextMenu.js","names":["_sfc_main","ContextMenu_vue_vue_type_script_setup_true_lang_default","ContextMenu_default"],"sources":["../../../src/components/ContextMenu/ContextMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuPortal,\n ContextMenuRoot,\n ContextMenuSeparator,\n ContextMenuTrigger\n} from 'reka-ui'\n\nimport MenuItemContent from '../internal/MenuItemContent.vue'\nimport {\n type DropdownMenuAction,\n type DropdownMenuEntry,\n type MenuConfirmLabels,\n menuConfirmDefaults,\n menuContentClass,\n menuItemClass,\n menuSeparatorClass,\n useMenuSelect\n} from '../internal/menu'\n\nexport interface ContextMenuProps extends MenuConfirmLabels {\n items?: DropdownMenuEntry[]\n /** The menu's accessible name, e.g. \"Post actions\". */\n label?: string\n /** Lets the browser's own menu through. */\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<ContextMenuProps>(), {\n ...menuConfirmDefaults,\n items: () => [],\n label: undefined\n})\n\nconst emit = defineEmits<{\n 'click-item': [item: DropdownMenuAction & { id?: string }]\n 'update:open': [open: boolean]\n show: []\n hide: []\n}>()\n\nconst select = useMenuSelect(props, (item) => emit('click-item', item))\n\nfunction onOpenChange(open: boolean) {\n emit('update:open', open)\n if (open) emit('show')\n else emit('hide')\n}\n\n// Shift+F10 and the Menu key open it at the focused element. Browsers fire `contextmenu` for these only on some\n// platforms, so the keys open it themselves, the way a right-click would, near the element's top left.\nfunction onKeydown(event: KeyboardEvent) {\n if (props.disabled || !((event.key === 'F10' && event.shiftKey) || event.key === 'ContextMenu')) return\n event.preventDefault()\n const target = event.currentTarget as HTMLElement\n const rect = (event.target as HTMLElement).getBoundingClientRect()\n target.dispatchEvent(\n new MouseEvent('contextmenu', {\n bubbles: true,\n cancelable: true,\n clientX: rect.left + 8,\n clientY: rect.top + Math.min(rect.height, 32)\n })\n )\n}\n</script>\n\n<!-- DropdownMenu's items at the pointer: right-click the default slot, or Shift+F10 or the Menu key while it has focus. -->\n<template>\n <ContextMenuRoot :modal=\"false\" @update:open=\"onOpenChange\">\n <ContextMenuTrigger as-child :disabled=\"disabled\" @keydown=\"onKeydown\">\n <slot />\n </ContextMenuTrigger>\n <ContextMenuPortal>\n <ContextMenuContent :aria-label=\"label\" :class=\"[menuContentClass, 'min-w-48']\" :collision-padding=\"8\">\n <template v-for=\"(item, index) in items\" :key=\"index\">\n <ContextMenuSeparator v-if=\"item.type === 'separator'\" :class=\"menuSeparatorClass\" />\n <ContextMenuItem v-else :class=\"menuItemClass\" @select=\"select(item)\">\n <MenuItemContent :item=\"item\" />\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n </ContextMenuRoot>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type DropdownMenuAction, type DropdownMenuEntry, type MenuConfirmLabels } from '../internal/menu';
|
|
2
|
+
export interface ContextMenuProps extends MenuConfirmLabels {
|
|
3
|
+
items?: DropdownMenuEntry[];
|
|
4
|
+
/** The menu's accessible name, e.g. "Post actions". */
|
|
5
|
+
label?: string;
|
|
6
|
+
/** Lets the browser's own menu through. */
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare var __VLS_17: {};
|
|
10
|
+
type __VLS_Slots = {} & {
|
|
11
|
+
default?: (props: typeof __VLS_17) => any;
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_base: import("vue").DefineComponent<ContextMenuProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
"click-item": (item: DropdownMenuAction & {
|
|
15
|
+
id?: string;
|
|
16
|
+
}) => any;
|
|
17
|
+
"update:open": (open: boolean) => any;
|
|
18
|
+
show: () => any;
|
|
19
|
+
hide: () => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<ContextMenuProps> & Readonly<{
|
|
21
|
+
"onClick-item"?: ((item: DropdownMenuAction & {
|
|
22
|
+
id?: string;
|
|
23
|
+
}) => any) | undefined;
|
|
24
|
+
"onUpdate:open"?: ((open: boolean) => any) | undefined;
|
|
25
|
+
onShow?: (() => any) | undefined;
|
|
26
|
+
onHide?: (() => any) | undefined;
|
|
27
|
+
}>, {
|
|
28
|
+
label: string;
|
|
29
|
+
confirmLabel: string;
|
|
30
|
+
cancelLabel: string;
|
|
31
|
+
id: string;
|
|
32
|
+
confirmTitle: string;
|
|
33
|
+
confirmMessage: string;
|
|
34
|
+
deleteLabel: string;
|
|
35
|
+
items: DropdownMenuEntry[];
|
|
36
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
37
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
38
|
+
declare const _default: typeof __VLS_export;
|
|
39
|
+
export default _default;
|
|
40
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
41
|
+
new (): {
|
|
42
|
+
$slots: S;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import e from "../internal/MenuItemContent.js";
|
|
2
|
+
import { menuConfirmDefaults as t, menuContentClass as n, menuItemClass as r, menuSeparatorClass as i, useMenuSelect as a } from "../internal/menu.js";
|
|
3
|
+
import { Fragment as o, createBlock as s, createElementBlock as c, createVNode as l, defineComponent as u, mergeDefaults as d, normalizeClass as f, openBlock as p, renderList as m, renderSlot as h, unref as g, withCtx as _ } from "vue";
|
|
4
|
+
import { ContextMenuContent as v, ContextMenuItem as y, ContextMenuPortal as b, ContextMenuRoot as x, ContextMenuSeparator as S, ContextMenuTrigger as C } from "reka-ui";
|
|
5
|
+
//#region src/components/ContextMenu/ContextMenu.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
+
var w = /*@__PURE__*/ u({
|
|
7
|
+
__name: "ContextMenu",
|
|
8
|
+
props: /*@__PURE__*/ d({
|
|
9
|
+
items: {},
|
|
10
|
+
label: {},
|
|
11
|
+
disabled: { type: Boolean },
|
|
12
|
+
id: {},
|
|
13
|
+
confirmTitle: {},
|
|
14
|
+
confirmMessage: {},
|
|
15
|
+
confirmLabel: {},
|
|
16
|
+
deleteLabel: {},
|
|
17
|
+
cancelLabel: {}
|
|
18
|
+
}, {
|
|
19
|
+
...t,
|
|
20
|
+
items: () => [],
|
|
21
|
+
label: void 0
|
|
22
|
+
}),
|
|
23
|
+
emits: [
|
|
24
|
+
"click-item",
|
|
25
|
+
"update:open",
|
|
26
|
+
"show",
|
|
27
|
+
"hide"
|
|
28
|
+
],
|
|
29
|
+
setup(t, { emit: u }) {
|
|
30
|
+
let d = t, w = u, T = a(d, (e) => w("click-item", e));
|
|
31
|
+
function E(e) {
|
|
32
|
+
w("update:open", e), w(e ? "show" : "hide");
|
|
33
|
+
}
|
|
34
|
+
function D(e) {
|
|
35
|
+
if (d.disabled || !(e.key === "F10" && e.shiftKey || e.key === "ContextMenu")) return;
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
let t = e.currentTarget, n = e.target.getBoundingClientRect();
|
|
38
|
+
t.dispatchEvent(new MouseEvent("contextmenu", {
|
|
39
|
+
bubbles: !0,
|
|
40
|
+
cancelable: !0,
|
|
41
|
+
clientX: n.left + 8,
|
|
42
|
+
clientY: n.top + Math.min(n.height, 32)
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
return (a, u) => (p(), s(g(x), {
|
|
46
|
+
modal: !1,
|
|
47
|
+
"onUpdate:open": E
|
|
48
|
+
}, {
|
|
49
|
+
default: _(() => [l(g(C), {
|
|
50
|
+
"as-child": "",
|
|
51
|
+
disabled: t.disabled,
|
|
52
|
+
onKeydown: D
|
|
53
|
+
}, {
|
|
54
|
+
default: _(() => [h(a.$slots, "default")]),
|
|
55
|
+
_: 3
|
|
56
|
+
}, 8, ["disabled"]), l(g(b), null, {
|
|
57
|
+
default: _(() => [l(g(v), {
|
|
58
|
+
"aria-label": t.label,
|
|
59
|
+
class: f([g(n), "min-w-48"]),
|
|
60
|
+
"collision-padding": 8
|
|
61
|
+
}, {
|
|
62
|
+
default: _(() => [(p(!0), c(o, null, m(t.items, (t, n) => (p(), c(o, { key: n }, [t.type === "separator" ? (p(), s(g(S), {
|
|
63
|
+
key: 0,
|
|
64
|
+
class: f(g(i))
|
|
65
|
+
}, null, 8, ["class"])) : (p(), s(g(y), {
|
|
66
|
+
key: 1,
|
|
67
|
+
class: f(g(r)),
|
|
68
|
+
onSelect: (e) => g(T)(t)
|
|
69
|
+
}, {
|
|
70
|
+
default: _(() => [l(e, { item: t }, null, 8, ["item"])]),
|
|
71
|
+
_: 2
|
|
72
|
+
}, 1032, ["class", "onSelect"]))], 64))), 128))]),
|
|
73
|
+
_: 1
|
|
74
|
+
}, 8, ["aria-label", "class"])]),
|
|
75
|
+
_: 1
|
|
76
|
+
})]),
|
|
77
|
+
_: 3
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
//#endregion
|
|
82
|
+
export { w as default };
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=ContextMenu.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextMenu.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_withCtx","_createVNode","_renderSlot","_normalizeClass","_createElementBlock","_Fragment","_renderList","MenuItemContent","MenuItemContent_default","ContextMenu_vue_vue_type_script_setup_true_lang_default","menuConfirmDefaults","__emit","props","__props","emit","select","useMenuSelect","item","onOpenChange","open","onKeydown","event","target","rect","openBlock","createBlock","unref","ContextMenuRoot","withCtx","createVNode","ContextMenuTrigger","renderSlot","_ctx","ContextMenuPortal","ContextMenuContent","normalizeClass","menuContentClass","createElementBlock","Fragment","renderList","index","ContextMenuSeparator","menuSeparatorClass","ContextMenuItem","menuItemClass"],"sources":["../../../src/components/ContextMenu/ContextMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport {\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuPortal,\n ContextMenuRoot,\n ContextMenuSeparator,\n ContextMenuTrigger\n} from 'reka-ui'\n\nimport MenuItemContent from '../internal/MenuItemContent.vue'\nimport {\n type DropdownMenuAction,\n type DropdownMenuEntry,\n type MenuConfirmLabels,\n menuConfirmDefaults,\n menuContentClass,\n menuItemClass,\n menuSeparatorClass,\n useMenuSelect\n} from '../internal/menu'\n\nexport interface ContextMenuProps extends MenuConfirmLabels {\n items?: DropdownMenuEntry[]\n /** The menu's accessible name, e.g. \"Post actions\". */\n label?: string\n /** Lets the browser's own menu through. */\n disabled?: boolean\n}\n\nconst props = withDefaults(defineProps<ContextMenuProps>(), {\n ...menuConfirmDefaults,\n items: () => [],\n label: undefined\n})\n\nconst emit = defineEmits<{\n 'click-item': [item: DropdownMenuAction & { id?: string }]\n 'update:open': [open: boolean]\n show: []\n hide: []\n}>()\n\nconst select = useMenuSelect(props, (item) => emit('click-item', item))\n\nfunction onOpenChange(open: boolean) {\n emit('update:open', open)\n if (open) emit('show')\n else emit('hide')\n}\n\n// Shift+F10 and the Menu key open it at the focused element. Browsers fire `contextmenu` for these only on some\n// platforms, so the keys open it themselves, the way a right-click would, near the element's top left.\nfunction onKeydown(event: KeyboardEvent) {\n if (props.disabled || !((event.key === 'F10' && event.shiftKey) || event.key === 'ContextMenu')) return\n event.preventDefault()\n const target = event.currentTarget as HTMLElement\n const rect = (event.target as HTMLElement).getBoundingClientRect()\n target.dispatchEvent(\n new MouseEvent('contextmenu', {\n bubbles: true,\n cancelable: true,\n clientX: rect.left + 8,\n clientY: rect.top + Math.min(rect.height, 32)\n })\n )\n}\n</script>\n\n<!-- DropdownMenu's items at the pointer: right-click the default slot, or Shift+F10 or the Menu key while it has focus. -->\n<template>\n <ContextMenuRoot :modal=\"false\" @update:open=\"onOpenChange\">\n <ContextMenuTrigger as-child :disabled=\"disabled\" @keydown=\"onKeydown\">\n <slot />\n </ContextMenuTrigger>\n <ContextMenuPortal>\n <ContextMenuContent :aria-label=\"label\" :class=\"[menuContentClass, 'min-w-48']\" :collision-padding=\"8\">\n <template v-for=\"(item, index) in items\" :key=\"index\">\n <ContextMenuSeparator v-if=\"item.type === 'separator'\" :class=\"menuSeparatorClass\" />\n <ContextMenuItem v-else :class=\"menuItemClass\" @select=\"select(item)\">\n <MenuItemContent :item=\"item\" />\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n </ContextMenuRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BA,IAAMe,IAAQC,GAMRC,IAAOH,GAOPI,IAASC,EAAcJ,IAAQ,MAASE,EAAK,cAAcG,CAAI,CAAC;EAEtE,SAASC,EAAa,GAAe;GAEnC,AADAJ,EAAK,eAAeK,CAAI,GACdL,EAANK,IAAW,SACL,MAAM;EAClB;EAIA,SAASC,EAAU,GAAsB;GACvC,IAAIR,EAAM,YAAY,EAAGS,EAAM,QAAQ,SAASA,EAAM,YAAaA,EAAM,QAAQ,gBAAgB;GACjG,EAAM,eAAe;GACrB,IAAMC,IAASD,EAAM,eACfE,IAAQF,EAAM,OAAuB,sBAAsB;GACjE,EAAO,cACL,IAAI,WAAW,eAAe;IAC5B,SAAS;IACT,YAAY;IACZ,SAASE,EAAK,OAAO;IACrB,SAASA,EAAK,MAAM,KAAK,IAAIA,EAAK,QAAQ,EAAE;GAC9C,CAAC,CACH;EACF;E,kBAKE1B,EAAA,GAAAC,EAckBC,EAAA4B,CAAA,GAAA;GAdA,OAAO;GAAQ,iBAAaT;;GAC5C,SAAAlB,QAEqB,CAFrBC,EAEqBF,EAAA+B,CAAA,GAAA;IAFD,YAAA;IAAU,UAAUjB,EAAA;IAAoB;;IAC1D,SAAAb,QAAQ,CAARE,EAAQ8B,EAAA,QAAA,SAAA,C;;G,qBAEV/B,EASoBF,EAAAkC,CAAA,GAAA,MAAA;IARlB,SAAAjC,QAOqB,CAPrBC,EAOqBF,EAAAmC,CAAA,GAAA;KAPA,cAAYrB,EAAA;KAAQ,OAAKV,EAAA,CAAGJ,EAAAqC,CAAA,GAAgB,UAAA,CAAA;KAAgB,qBAAmB;;KACxF,SAAApC,QAA8B,EAAxCH,EAAA,EAAA,GAAAO,EAKWC,GAAA,MAAAC,EALuBO,EAAA,QAAhB,GAAM,OAAuBhB,EAAA,GAAAO,EAAAC,GAAA,EAAA,KAAAmC,EAAK,GAAA,CACtBvB,EAAK,SAAI,eAArCpB,EAAA,GAAAC,EAAqFC,EAAA0C,CAAA,GAAA;;MAA7B,OAAKtC,EAAEJ,EAAA2C,CAAA,CAAkB;K,2BACjF7C,EAAA,GAAAC,EAEkBC,EAAA4C,CAAA,GAAA;;MAFO,OAAKxC,EAAEJ,EAAA6C,CAAA,CAAa;MAAG,WAAM,MAAE7C,EAAAgB,CAAA,CAAM,CAACE,CAAI;;MACjE,SAAAjB,QAAgC,CAAhCC,EAAgCM,GAAA,EAAR,QAAI,GAAA,MAAA,GAAA,CAAA,MAAA,CAAA,C"}
|