@sparklingopinions/sparkling-ui 0.14.0 → 0.16.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 +4 -0
- package/dist/components/ActionBar/ActionBar.js.map +1 -1
- package/dist/components/ActionBar/ActionBar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/ActionBar/ActionBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Alert/Alert.js.map +1 -1
- package/dist/components/Alert/Alert.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Alert/Alert.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/AlertDialog/AlertDialog.js.map +1 -1
- package/dist/components/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js +5 -5
- package/dist/components/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Badge/Badge.js.map +1 -1
- package/dist/components/Badge/Badge.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Badge/Badge.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 +3 -0
- package/dist/components/Board/Board.vue_vue_type_script_setup_true_lang.js +68 -63
- 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_vue_type_script_setup_true_lang.js +23 -22
- package/dist/components/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Calendar/Calendar.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Calendar/Calendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/DataList/DataList.js.map +1 -1
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js +103 -103
- package/dist/components/DataList/DataList.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/ContextSeparator.js +19 -0
- package/dist/components/Dialog/ContextSeparator.js.map +1 -0
- package/dist/components/Dialog/ContextSeparator.vue.d.ts +3 -0
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/Dialog/Dialog.vue.d.ts +16 -11
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +130 -119
- package/dist/components/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Dialog/focus.d.ts +2 -0
- package/dist/components/Dialog/focus.js +2 -2
- package/dist/components/Dialog/focus.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +1 -1
- 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_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/Filters/FilterChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Filters/FilterFrame.js.map +1 -1
- package/dist/components/Filters/FilterFrame.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Filters/FilterFrame.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_vue_type_script_setup_true_lang.js +3 -3
- 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_vue_type_script_setup_true_lang.js +7 -7
- package/dist/components/Filters/SortMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Input/Input.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Input/Input.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Kbd/Kbd.js +1 -1
- package/dist/components/Kbd/Kbd.js.map +1 -1
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Popover/Popover.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Popover/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Popover/PopoverDialog.js.map +1 -1
- package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Popover/PopoverDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/PropertyList/Editable.js.map +1 -1
- package/dist/components/PropertyList/Editable.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/PropertyList/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/Select.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Table/Table.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Tag/Tag.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/Textarea/Textarea.js.map +1 -1
- package/dist/components/Textarea/Textarea.vue.d.ts +3 -0
- package/dist/components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/components/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/internal/menu.d.ts +2 -2
- package/dist/components/internal/menu.js +1 -1
- package/dist/components/internal/menu.js.map +1 -1
- package/dist/index.js +15 -15
- package/package.json +1 -1
- package/src/styles/tailwind.css +93 -12
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import e from "../Icon/Icon.js";
|
|
2
2
|
import t from "../Skeleton/Skeleton.js";
|
|
3
|
-
import { Fragment as n,
|
|
3
|
+
import { Fragment as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, normalizeClass as d, onBeforeUnmount as f, openBlock as p, ref as m, renderList as h, renderSlot as g, resolveDynamicComponent as _, toDisplayString as v, unref as y, useId as ee, withCtx as te, withModifiers as ne } from "vue";
|
|
4
4
|
//#region src/components/Board/Board.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var
|
|
5
|
+
var re = ["aria-labelledby"], b = { class: "flex items-center justify-between px-1 pb-2.5" }, x = { class: "ml-2 inline-flex h-5 items-center justify-center rounded-full bg-sui-fill px-2 text-xs text-sui-ink-muted tabular-nums" }, S = ["data-board-column"], C = {
|
|
6
6
|
key: 1,
|
|
7
7
|
class: "m-0 px-1 py-3 text-center text-13 text-sui-ink-muted"
|
|
8
|
-
},
|
|
8
|
+
}, w = {
|
|
9
9
|
key: 2,
|
|
10
10
|
class: "m-0 flex list-none flex-col gap-2.5 p-0"
|
|
11
|
-
},
|
|
11
|
+
}, T = [
|
|
12
12
|
"data-board-index",
|
|
13
13
|
"role",
|
|
14
14
|
"tabindex",
|
|
15
15
|
"onClickCapture",
|
|
16
16
|
"onKeydown",
|
|
17
17
|
"onPointerdown"
|
|
18
|
-
],
|
|
18
|
+
], E = { class: "m-0 text-sm font-semibold text-sui-ink" }, D = ["onClick"], O = 4, k = 8, A = 250, j = 48, ie = "border border-sui-edge bg-sui-raised p-4 transition-[border-color,opacity] duration-150 hover:border-sui-line-strong", M = /*@__PURE__*/ u({
|
|
19
19
|
__name: "Board",
|
|
20
20
|
props: {
|
|
21
21
|
columns: {},
|
|
@@ -40,11 +40,12 @@ var te = ["aria-labelledby"], ne = { class: "flex items-center justify-between p
|
|
|
40
40
|
default: void 0
|
|
41
41
|
},
|
|
42
42
|
newLabel: { default: "New" },
|
|
43
|
-
emptyLabel: { default: "No cards" }
|
|
43
|
+
emptyLabel: { default: "No cards" },
|
|
44
|
+
columnTone: { default: "fill" }
|
|
44
45
|
},
|
|
45
46
|
emits: ["move"],
|
|
46
|
-
setup(
|
|
47
|
-
let N =
|
|
47
|
+
setup(u, { emit: M }) {
|
|
48
|
+
let N = u, P = M, F = ee(), I = (e) => e[N.rowKey ?? "id"], L = m(), R = m(null), z = m(null), B = null, V, H = null, U = {
|
|
48
49
|
x: 0,
|
|
49
50
|
y: 0
|
|
50
51
|
}, W = !1;
|
|
@@ -59,7 +60,7 @@ var te = ["aria-labelledby"], ne = { class: "flex items-center justify-between p
|
|
|
59
60
|
y: e.clientY,
|
|
60
61
|
card: e.currentTarget,
|
|
61
62
|
touch: i
|
|
62
|
-
}, i && (V = window.setTimeout(() => B && K(),
|
|
63
|
+
}, i && (V = window.setTimeout(() => B && K(), A)), window.addEventListener("pointermove", q), window.addEventListener("pointerup", Y), window.addEventListener("pointercancel", Q), window.addEventListener("touchmove", X, { passive: !1 }), window.addEventListener("keydown", Z);
|
|
63
64
|
}
|
|
64
65
|
function K() {
|
|
65
66
|
if (!B) return;
|
|
@@ -77,17 +78,17 @@ var te = ["aria-labelledby"], ne = { class: "flex items-center justify-between p
|
|
|
77
78
|
if (B) {
|
|
78
79
|
if (!R.value) {
|
|
79
80
|
let t = Math.hypot(e.clientX - B.x, e.clientY - B.y);
|
|
80
|
-
if (B.touch) return t >
|
|
81
|
-
if (t <
|
|
81
|
+
if (B.touch) return t > k ? Q() : void 0;
|
|
82
|
+
if (t < O) return;
|
|
82
83
|
K();
|
|
83
84
|
}
|
|
84
|
-
e.preventDefault(), J(e.clientX, e.clientY),
|
|
85
|
+
e.preventDefault(), J(e.clientX, e.clientY), ae(e.clientX, e.clientY), oe(e.clientX, e.clientY);
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
function J(e, t) {
|
|
88
89
|
H && (H.style.transform = `translate(${e - U.x}px, ${t - U.y}px) rotate(1.5deg)`);
|
|
89
90
|
}
|
|
90
|
-
function
|
|
91
|
+
function ae(e, t) {
|
|
91
92
|
let n = document.elementFromPoint(e, t), r = n?.closest("[data-board-column]");
|
|
92
93
|
if (!r || !L.value?.contains(r)) {
|
|
93
94
|
z.value = null;
|
|
@@ -103,98 +104,102 @@ var te = ["aria-labelledby"], ne = { class: "flex items-center justify-between p
|
|
|
103
104
|
index: o
|
|
104
105
|
});
|
|
105
106
|
}
|
|
106
|
-
function
|
|
107
|
+
function oe(e, t) {
|
|
107
108
|
let n = document.elementFromPoint(e, t)?.closest("[data-board-column]");
|
|
108
109
|
if (n) {
|
|
109
110
|
let e = n.getBoundingClientRect();
|
|
110
|
-
t < e.top +
|
|
111
|
+
t < e.top + j ? n.scrollTop -= 12 : t > e.bottom - j && (n.scrollTop += 12);
|
|
111
112
|
}
|
|
112
113
|
let r = L.value?.getBoundingClientRect();
|
|
113
|
-
r && L.value && (e < r.left +
|
|
114
|
+
r && L.value && (e < r.left + j ? L.value.scrollLeft -= 12 : e > r.right - j && (L.value.scrollLeft += 12));
|
|
114
115
|
}
|
|
115
|
-
function
|
|
116
|
+
function Y() {
|
|
116
117
|
let e = R.value, t = z.value;
|
|
117
118
|
if (e && t) {
|
|
118
119
|
let n = t.index;
|
|
119
120
|
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);
|
|
120
121
|
}
|
|
121
|
-
|
|
122
|
+
Q();
|
|
122
123
|
}
|
|
123
|
-
function
|
|
124
|
+
function X(e) {
|
|
124
125
|
R.value && e.preventDefault();
|
|
125
126
|
}
|
|
126
|
-
function
|
|
127
|
-
e.key === "Escape" && R.value && (e.preventDefault(),
|
|
127
|
+
function Z(e) {
|
|
128
|
+
e.key === "Escape" && R.value && (e.preventDefault(), Q());
|
|
128
129
|
}
|
|
129
|
-
function
|
|
130
|
-
window.clearTimeout(V), window.removeEventListener("pointermove", q), window.removeEventListener("pointerup",
|
|
130
|
+
function Q() {
|
|
131
|
+
window.clearTimeout(V), window.removeEventListener("pointermove", q), window.removeEventListener("pointerup", Y), window.removeEventListener("pointercancel", Q), window.removeEventListener("touchmove", X), window.removeEventListener("keydown", Z), H?.remove(), H = null, R.value && (W = !0, window.setTimeout(() => W = !1)), B = null, R.value = null, z.value = null;
|
|
131
132
|
}
|
|
132
|
-
|
|
133
|
-
function
|
|
133
|
+
f(Q);
|
|
134
|
+
function se(e, t) {
|
|
134
135
|
W ? (e.preventDefault(), e.stopPropagation()) : N.onCardClick?.(t);
|
|
135
136
|
}
|
|
136
|
-
function
|
|
137
|
+
function ce(e, t) {
|
|
137
138
|
!N.onCardClick || e.target !== e.currentTarget || e.key !== "Enter" && e.key !== " " || (e.preventDefault(), N.onCardClick(t));
|
|
138
139
|
}
|
|
139
|
-
let
|
|
140
|
-
|
|
140
|
+
let le = {
|
|
141
|
+
fill: "bg-sui-fill",
|
|
142
|
+
canvas: "border border-sui-line-subtle bg-sui-canvas",
|
|
143
|
+
sunken: "sui-band"
|
|
144
|
+
}, $ = r(() => le[N.columnTone]), ue = (e, t, n) => z.value?.column === e && z.value.index === t && R.value?.id !== I(n);
|
|
145
|
+
return (r, f) => (p(), o("div", {
|
|
141
146
|
ref_key: "root",
|
|
142
147
|
ref: L,
|
|
143
|
-
class:
|
|
144
|
-
}, [(
|
|
145
|
-
key:
|
|
146
|
-
"aria-labelledby": `${
|
|
148
|
+
class: d(["flex items-stretch gap-5 overflow-x-auto pb-2 after:w-1 after:shrink-0 after:content-['']", u.fill && "h-full min-h-0 flex-1"])
|
|
149
|
+
}, [(p(!0), o(n, null, h(u.columns, (m) => (p(), o("section", {
|
|
150
|
+
key: m.id,
|
|
151
|
+
"aria-labelledby": `${y(F)}-${m.id}`,
|
|
147
152
|
class: "flex min-h-0 w-full max-w-xs min-w-[16rem] shrink-0 flex-col"
|
|
148
|
-
}, [
|
|
149
|
-
id: `${
|
|
153
|
+
}, [s("header", b, [(p(), i(_(`h${u.headingLevel}`), {
|
|
154
|
+
id: `${y(F)}-${m.id}`,
|
|
150
155
|
class: "m-0 flex items-center gap-2 text-sm font-semibold text-sui-ink"
|
|
151
156
|
}, {
|
|
152
|
-
default:
|
|
157
|
+
default: te(() => [m.icon ? (p(), i(e, {
|
|
153
158
|
key: 0,
|
|
154
|
-
color:
|
|
155
|
-
name:
|
|
156
|
-
}, null, 8, ["color", "name"])) :
|
|
159
|
+
color: m.iconColor ?? "ink-subtle",
|
|
160
|
+
name: m.icon
|
|
161
|
+
}, null, 8, ["color", "name"])) : a("", !0), c(" " + v(m.name), 1)]),
|
|
157
162
|
_: 2
|
|
158
|
-
}, 1032, ["id"])),
|
|
159
|
-
class:
|
|
160
|
-
"data-board-column":
|
|
161
|
-
}, [
|
|
163
|
+
}, 1032, ["id"])), s("span", x, [g(r.$slots, "count", { column: m }, () => [c(v(m.items.length), 1)])])]), s("div", {
|
|
164
|
+
class: d(["group/body flex min-h-[120px] flex-1 flex-col gap-2.5 overflow-y-auto rounded-xl p-2.5 transition-shadow duration-150", [$.value, z.value?.column === m.id && "ring-2 ring-sui-accent-line ring-inset"]]),
|
|
165
|
+
"data-board-column": m.id
|
|
166
|
+
}, [u.loading ? (p(), o(n, { key: 0 }, h(3, (e) => s("div", {
|
|
162
167
|
key: e,
|
|
163
168
|
"aria-hidden": "true",
|
|
164
|
-
class: "rounded-xl border border-sui-
|
|
165
|
-
}, [
|
|
169
|
+
class: "rounded-xl border border-sui-edge bg-sui-raised p-4"
|
|
170
|
+
}, [l(t, { class: "mb-3" }), l(t, {
|
|
166
171
|
height: "0.75rem",
|
|
167
172
|
width: "70%"
|
|
168
|
-
})])), 64)) :
|
|
169
|
-
class:
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
})])), 64)) : m.items.length === 0 && !R.value ? (p(), o("p", C, v(u.emptyLabel), 1)) : (p(), o("ul", w, [(p(!0), o(n, null, h(m.items, (e, t) => (p(), o("li", { key: I(e) }, [s("div", {
|
|
174
|
+
class: d(["relative rounded-xl outline-hidden transition-opacity duration-150 select-none", [
|
|
175
|
+
u.cardFrame && ie,
|
|
176
|
+
u.onCardClick && "cursor-pointer focus-visible:sui-ring",
|
|
172
177
|
R.value?.id === I(e) && "opacity-40",
|
|
173
|
-
|
|
178
|
+
ue(m.id, t, e) && "shadow-[0_-6px_0_-4px_rgb(var(--sui-accent-solid))]"
|
|
174
179
|
]]),
|
|
175
180
|
"data-board-index": t,
|
|
176
|
-
role:
|
|
177
|
-
tabindex:
|
|
178
|
-
onClickCapture: (t) =>
|
|
179
|
-
onContextmenu:
|
|
180
|
-
onDragstart:
|
|
181
|
-
onKeydown: (t) =>
|
|
182
|
-
onPointerdown: (n) => G(n, e,
|
|
183
|
-
}, [
|
|
184
|
-
column:
|
|
181
|
+
role: u.onCardClick ? "button" : void 0,
|
|
182
|
+
tabindex: u.onCardClick ? 0 : void 0,
|
|
183
|
+
onClickCapture: (t) => se(t, e),
|
|
184
|
+
onContextmenu: f[0] ||= (e) => R.value && e.preventDefault(),
|
|
185
|
+
onDragstart: f[1] ||= ne(() => {}, ["prevent"]),
|
|
186
|
+
onKeydown: (t) => ce(t, e),
|
|
187
|
+
onPointerdown: (n) => G(n, e, m.id, t)
|
|
188
|
+
}, [g(r.$slots, "card", {
|
|
189
|
+
column: m,
|
|
185
190
|
item: e
|
|
186
|
-
}, () => [
|
|
191
|
+
}, () => [s("p", E, v(e.name), 1)])], 42, T)]))), 128))])), u.onNew && !u.loading ? (p(), o("button", {
|
|
187
192
|
key: 3,
|
|
188
|
-
class: "flex h-
|
|
193
|
+
class: "flex h-(--sui-control-height) 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",
|
|
189
194
|
type: "button",
|
|
190
|
-
onClick: (e) =>
|
|
191
|
-
}, [
|
|
195
|
+
onClick: (e) => u.onNew(m)
|
|
196
|
+
}, [f[2] ||= s("svg", {
|
|
192
197
|
"aria-hidden": "true",
|
|
193
198
|
class: "size-3.5 fill-none stroke-current",
|
|
194
199
|
"stroke-linecap": "round",
|
|
195
200
|
"stroke-width": "1.5",
|
|
196
201
|
viewBox: "0 0 14 14"
|
|
197
|
-
}, [
|
|
202
|
+
}, [s("path", { d: "M7 2.5v9M2.5 7h9" })], -1), c(" " + v(u.newLabel), 1)], 8, D)) : a("", !0)], 10, S)], 8, re))), 128))], 2));
|
|
198
203
|
}
|
|
199
204
|
});
|
|
200
205
|
//#endregion
|
|
@@ -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","_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
|
+
{"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","grounds","columnGround","computed","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 { computed, 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 /** The columns' ground: a soft fill by default; `canvas` (the page's, with a hairline) or `sunken` match a Table's or\n * DataList's header tone, so the cards stand out on it. */\n columnTone?: 'fill' | 'canvas' | 'sunken'\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 columnTone: 'fill'\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 grounds = { fill: 'bg-sui-fill', canvas: 'border border-sui-line-subtle bg-sui-canvas', sunken: 'sui-band' }\nconst columnGround = computed(() => grounds[props.columnTone])\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-edge bg-sui-raised p-4 transition-[border-color,opacity] duration-150 hover:border-sui-line-strong'\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-fill 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 p-2.5 transition-shadow duration-150\"\n :class=\"[columnGround, 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 v-for=\"i in 3\" :key=\"i\" aria-hidden=\"true\" class=\"rounded-xl border border-sui-edge bg-sui-raised p-4\">\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-(--sui-control-height) 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 +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 =\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 /** A toggle's state, as `aria-pressed`. Drawn on for ghost, ghost-inverse and secondary; leave it unset on a plain\n * button. */\n pressed?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: 'button',\n variant: 'secondary',\n size: 'md',\n iconPosition: 'start',\n pressed: undefined\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-
|
|
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 /** A toggle's state, as `aria-pressed`. Drawn on for ghost, ghost-inverse and secondary; leave it unset on a plain\n * button. */\n pressed?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: 'button',\n variant: 'secondary',\n size: 'md',\n iconPosition: 'start',\n pressed: undefined\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-fill-line bg-sui-fill text-sui-ink-emphasis not-data-disabled:hover:bg-sui-fill-hover not-data-disabled:hover:text-sui-ink [&_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-fill-hover 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\n// On is a step past hover, and hovering it deepens it again. On inverse, 22% is as deep as white text keeps 4.5:1.\nconst pressedVariants: Partial<Record<ButtonVariant, string>> = {\n secondary:\n 'border border-sui-accent-line bg-sui-accent-wash text-sui-accent shadow-(--sui-shadow-raised) not-data-disabled:hover:border-sui-accent-bright not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent',\n ghost:\n 'border border-transparent bg-sui-accent-wash text-sui-accent not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent',\n 'ghost-inverse':\n 'border border-transparent bg-sui-on-inverse/[0.18] text-sui-on-inverse not-data-disabled:hover:bg-sui-on-inverse/[0.22] [&_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\n// Filled buttons turn neutral when off, rather than fading their colour; ghosts, with nothing to fill, fade.\nconst ghosts: ButtonVariant[] = ['ghost', 'ghost-inverse']\nconst offClass =\n 'data-disabled:border-sui-fill-line data-disabled:bg-sui-fill data-disabled:text-sui-ink-muted data-disabled:shadow-none data-disabled:[&_svg]:stroke-sui-ink-muted'\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',\n ghosts.includes(props.variant) ? 'data-disabled:opacity-50' : offClass,\n props.variant === 'ghost-inverse' ? 'focus-visible:sui-ring-inverse' : 'focus-visible:sui-ring',\n (props.pressed && pressedVariants[props.variant]) || 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 :aria-pressed=\"pressed === undefined ? undefined : String(pressed)\"\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,7 +1,7 @@
|
|
|
1
1
|
import { computed as e, createBlock as t, defineComponent as n, normalizeClass as r, openBlock as i, renderSlot as a, unref as o, withCtx as s } from "vue";
|
|
2
2
|
import { Primitive as c } from "reka-ui";
|
|
3
3
|
//#region src/components/Button/Button.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
-
var l = /*@__PURE__*/ n({
|
|
4
|
+
var l = "data-disabled:border-sui-fill-line data-disabled:bg-sui-fill data-disabled:text-sui-ink-muted data-disabled:shadow-none data-disabled:[&_svg]:stroke-sui-ink-muted", u = /*@__PURE__*/ n({
|
|
5
5
|
__name: "Button",
|
|
6
6
|
props: {
|
|
7
7
|
variant: { default: "secondary" },
|
|
@@ -18,52 +18,53 @@ var l = /*@__PURE__*/ n({
|
|
|
18
18
|
as: { default: "button" }
|
|
19
19
|
},
|
|
20
20
|
setup(n) {
|
|
21
|
-
let
|
|
21
|
+
let u = n, d = {
|
|
22
22
|
primary: "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",
|
|
23
|
-
secondary: "border border-sui-line bg-sui-
|
|
23
|
+
secondary: "border border-sui-fill-line bg-sui-fill text-sui-ink-emphasis not-data-disabled:hover:bg-sui-fill-hover not-data-disabled:hover:text-sui-ink [&_svg]:stroke-sui-ink-emphasis",
|
|
24
24
|
tinted: "border border-sui-accent-line bg-sui-accent-wash text-sui-accent not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent",
|
|
25
|
-
ghost: "border border-transparent bg-transparent text-sui-ink-subtle not-data-disabled:hover:bg-sui-
|
|
25
|
+
ghost: "border border-transparent bg-transparent text-sui-ink-subtle not-data-disabled:hover:bg-sui-fill-hover not-data-disabled:hover:text-sui-ink-emphasis",
|
|
26
26
|
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",
|
|
27
27
|
danger: "bg-sui-danger-solid text-sui-on-danger not-data-disabled:hover:bg-sui-danger-hover",
|
|
28
28
|
"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",
|
|
29
29
|
"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"
|
|
30
|
-
},
|
|
30
|
+
}, f = {
|
|
31
31
|
secondary: "border border-sui-accent-line bg-sui-accent-wash text-sui-accent shadow-(--sui-shadow-raised) not-data-disabled:hover:border-sui-accent-bright not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent",
|
|
32
32
|
ghost: "border border-transparent bg-sui-accent-wash text-sui-accent not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent",
|
|
33
33
|
"ghost-inverse": "border border-transparent bg-sui-on-inverse/[0.18] text-sui-on-inverse not-data-disabled:hover:bg-sui-on-inverse/[0.22] [&_svg]:stroke-sui-on-inverse"
|
|
34
|
-
},
|
|
34
|
+
}, p = {
|
|
35
35
|
xs: "h-6",
|
|
36
36
|
sm: "h-7",
|
|
37
37
|
md: "h-(--sui-button-height)",
|
|
38
38
|
lg: "h-12"
|
|
39
|
-
},
|
|
39
|
+
}, m = {
|
|
40
40
|
xs: "px-2",
|
|
41
41
|
sm: "px-2.5",
|
|
42
42
|
md: "px-(--sui-button-padding-x)",
|
|
43
43
|
lg: "px-(--sui-button-padding-x)"
|
|
44
|
-
},
|
|
44
|
+
}, h = {
|
|
45
45
|
xs: "text-xs",
|
|
46
46
|
sm: "text-sm",
|
|
47
47
|
md: "text-(length:--sui-button-text) leading-5",
|
|
48
48
|
lg: "text-(length:--sui-button-text) leading-5"
|
|
49
|
-
},
|
|
50
|
-
"flex items-center justify-center font-medium text-nowrap no-underline transition-all duration-200 ease-in-out
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
f[
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
}, g = ["ghost", "ghost-inverse"], _ = e(() => [
|
|
50
|
+
"flex items-center justify-center font-medium text-nowrap no-underline transition-all duration-200 ease-in-out",
|
|
51
|
+
g.includes(u.variant) ? "data-disabled:opacity-50" : l,
|
|
52
|
+
u.variant === "ghost-inverse" ? "focus-visible:sui-ring-inverse" : "focus-visible:sui-ring",
|
|
53
|
+
u.pressed && f[u.variant] || d[u.variant],
|
|
54
|
+
p[u.size],
|
|
55
|
+
h[u.size],
|
|
56
|
+
u.iconOnly ? "aspect-square px-0" : m[u.size],
|
|
57
|
+
u.pill ? "rounded-full" : u.size === "xs" ? "rounded-md" : "rounded-(--sui-radius-button)",
|
|
58
|
+
u.iconOnly ? "" : u.iconPosition === "end" ? "[&_svg]:ml-2" : "[&_svg:first-child]:mr-2"
|
|
59
|
+
]), v = e(() => u.as === "button" && !u.asChild);
|
|
59
60
|
return (e, l) => (i(), t(o(c), {
|
|
60
|
-
"aria-disabled": n.disabled && !
|
|
61
|
+
"aria-disabled": n.disabled && !v.value ? "true" : void 0,
|
|
61
62
|
"aria-pressed": n.pressed === void 0 ? void 0 : String(n.pressed),
|
|
62
63
|
as: n.as,
|
|
63
64
|
"as-child": n.asChild,
|
|
64
|
-
class: r(
|
|
65
|
+
class: r(_.value),
|
|
65
66
|
"data-disabled": n.disabled ? "" : void 0,
|
|
66
|
-
disabled:
|
|
67
|
+
disabled: v.value ? n.disabled : void 0
|
|
67
68
|
}, {
|
|
68
69
|
default: s(() => [a(e.$slots, "default")]),
|
|
69
70
|
_: 3
|
|
@@ -79,6 +80,6 @@ var l = /*@__PURE__*/ n({
|
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
82
|
//#endregion
|
|
82
|
-
export {
|
|
83
|
+
export { u as default };
|
|
83
84
|
|
|
84
85
|
//# sourceMappingURL=Button.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -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","pressedVariants","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 /** A toggle's state, as `aria-pressed`. Drawn on for ghost, ghost-inverse and secondary; leave it unset on a plain\n * button. */\n pressed?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: 'button',\n variant: 'secondary',\n size: 'md',\n iconPosition: 'start',\n pressed: undefined\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-
|
|
1
|
+
{"version":3,"file":"Button.vue_vue_type_script_setup_true_lang.js","names":["_openBlock","_createBlock","_unref","_normalizeClass","_withCtx","_renderSlot","offClass","Button_vue_vue_type_script_setup_true_lang_default","props","__props","variants","pressedVariants","heights","paddings","texts","ghosts","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 /** A toggle's state, as `aria-pressed`. Drawn on for ghost, ghost-inverse and secondary; leave it unset on a plain\n * button. */\n pressed?: boolean\n}\n\nconst props = withDefaults(defineProps<ButtonProps>(), {\n as: 'button',\n variant: 'secondary',\n size: 'md',\n iconPosition: 'start',\n pressed: undefined\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-fill-line bg-sui-fill text-sui-ink-emphasis not-data-disabled:hover:bg-sui-fill-hover not-data-disabled:hover:text-sui-ink [&_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-fill-hover 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\n// On is a step past hover, and hovering it deepens it again. On inverse, 22% is as deep as white text keeps 4.5:1.\nconst pressedVariants: Partial<Record<ButtonVariant, string>> = {\n secondary:\n 'border border-sui-accent-line bg-sui-accent-wash text-sui-accent shadow-(--sui-shadow-raised) not-data-disabled:hover:border-sui-accent-bright not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent',\n ghost:\n 'border border-transparent bg-sui-accent-wash text-sui-accent not-data-disabled:hover:bg-sui-accent-soft [&_svg]:stroke-sui-accent',\n 'ghost-inverse':\n 'border border-transparent bg-sui-on-inverse/[0.18] text-sui-on-inverse not-data-disabled:hover:bg-sui-on-inverse/[0.22] [&_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\n// Filled buttons turn neutral when off, rather than fading their colour; ghosts, with nothing to fill, fade.\nconst ghosts: ButtonVariant[] = ['ghost', 'ghost-inverse']\nconst offClass =\n 'data-disabled:border-sui-fill-line data-disabled:bg-sui-fill data-disabled:text-sui-ink-muted data-disabled:shadow-none data-disabled:[&_svg]:stroke-sui-ink-muted'\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',\n ghosts.includes(props.variant) ? 'data-disabled:opacity-50' : offClass,\n props.variant === 'ghost-inverse' ? 'focus-visible:sui-ring-inverse' : 'focus-visible:sui-ring',\n (props.pressed && pressedVariants[props.variant]) || 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 :aria-pressed=\"pressed === undefined ? undefined : String(pressed)\"\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":";;;AAqFA,IAAMM,IACJ,sK;;;;;;;;;;;;;;;;;EA9DF,IAAME,IAAQC,GAQRC,IAA0C;GAC9C,SACE;GACF,WACE;GACF,QACE;GACF,OACE;GACF,UACE;GAEF,QAAQ;GACR,kBACE;GAEF,iBACE;EACJ,GAGMC,IAA0D;GAC9D,WACE;GACF,OACE;GACF,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,GAGMC,IAA0B,CAAC,SAAS,eAAe,GAInDC,IAAUC,QAAe;GAE7B;GACAF,EAAO,SAASP,EAAM,OAAO,IAAI,6BAA6BF;GAC9DE,EAAM,YAAY,kBAAkB,mCAAmC;GACtEA,EAAM,WAAWG,EAAgBH,EAAM,YAAaE,EAASF,EAAM;GACpEI,EAAQJ,EAAM;GACdM,EAAMN,EAAM;GACZA,EAAM,WAAW,uBAAuBK,EAASL,EAAM;GAEvDA,EAAM,OAAO,iBAAiBA,EAAM,SAAS,OAAO,eAAe;GACnEA,EAAM,WAAW,KAAKA,EAAM,iBAAiB,QAAQ,iBAAiB;EACxE,CAAC,GAGKU,IAAiBD,QAAeT,EAAM,OAAO,YAAY,CAACA,EAAM,OAAO;E,kBAI3ER,EAAA,GAAAC,EAUYC,EAAAoB,CAAA,GAAA;GATT,iBAAeb,EAAA,YAAQ,CAAKS,EAAA,QAAc,SAAY,KAAA;GACtD,gBAAcT,EAAA,YAAY,KAAA,IAAY,KAAA,IAAY,OAAOA,EAAA,OAAO;GAChE,IAAIA,EAAA;GACJ,YAAUA,EAAA;GACV,OAAKN,EAAEa,EAAA,KAAO;GACd,iBAAeP,EAAA,WAAQ,KAAQ,KAAA;GAC/B,UAAUS,EAAA,QAAiBT,EAAA,WAAW,KAAA;;GAEvC,SAAAL,QAAQ,CAARC,EAAQqB,EAAA,QAAA,SAAA,C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.js","names":["_sfc_main","Calendar_vue_vue_type_script_setup_true_lang_default","Calendar_default"],"sources":["../../../src/components/Calendar/Calendar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport {\n addDays,\n addMonths,\n differenceInDays,\n isSameDay,\n isSameMonth,\n startOfDay,\n startOfMonth,\n startOfWeek\n} from '../../utils/dates'\nimport Tooltip from '../Tooltip/Tooltip.vue'\nimport ChevronIcon from '../internal/ChevronIcon.vue'\n\nexport interface CalendarProps {\n /** Selects a day; with `end`, a range. */\n start?: Date | null\n end?: Date | null\n /** For the month's name and the weekdays; the browser's language by default. */\n locale?: string\n /** Monday first; the locale's narrow names by default. */\n weekdays?: string[]\n previousLabel?: string\n nextLabel?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n start: null,\n end: null,\n locale: undefined,\n weekdays: undefined,\n previousLabel: 'Previous month',\n nextLabel: 'Next month'\n})\n\nconst emit = defineEmits<{ pick: [date: Date] }>()\n\nconst view = ref(startOfMonth(props.end ?? props.start ?? new Date()))\n\n// Follows the selection to its month, when it's picked elsewhere (a shortcut, say).\nwatch(\n () => props.end ?? props.start,\n (date) => {\n if (date) view.value = startOfMonth(date)\n }\n)\n\nconst title = computed(() =>\n new Intl.DateTimeFormat(props.locale, { month: 'long', year: 'numeric' }).format(view.value)\n)\n\n// 1 January 2024 was a Monday.\nconst dayNames = computed(\n () =>\n props.weekdays ??\n Array.from({ length: 7 }, (_, i) =>\n new Intl.DateTimeFormat(props.locale, { weekday: 'narrow' }).format(new Date(2024, 0, 1 + i))\n )\n)\n\nconst shiftMonth = (months: number) => (view.value = addMonths(view.value, months))\n\nconst cells = computed(() => {\n const first = startOfWeek(view.value)\n const last = addDays(addMonths(view.value, 1), -1)\n const count = Math.ceil((differenceInDays(last, first) + 1) / 7) * 7\n const today = startOfDay(new Date())\n const [start, end] = [props.start, props.end].map((date) => (date ? startOfDay(date) : null))\n const ranged = !!start && !!end && !isSameDay(start, end)\n const [low, high] = ranged ? [start!, end!].sort((a, b) => a.getTime() - b.getTime()) : []\n\n return Array.from({ length: count }, (_, i) => {\n const date = addDays(first, i)\n const isStart = !!start && isSameDay(date, start)\n const isEnd = !!end && isSameDay(date, end)\n const selected = isStart || isEnd\n const inRange = ranged && date >= low! && date <= high!\n const isToday = isSameDay(date, today)\n const column = i % 7\n\n return {\n key: date.toISOString(),\n date,\n label: date.getDate(),\n selected,\n isToday,\n // The range is a band behind the days, rounded where it starts, ends or wraps.\n band: inRange\n ? ['bg-sui-accent-wash', (isStart || column === 0) && 'rounded-l-lg', (isEnd || column === 6) && 'rounded-r-lg']\n : '',\n classes: selected\n ? 'bg-sui-accent-solid font-semibold text-sui-on-accent'\n : [\n 'hover:bg-sui-
|
|
1
|
+
{"version":3,"file":"Calendar.js","names":["_sfc_main","Calendar_vue_vue_type_script_setup_true_lang_default","Calendar_default"],"sources":["../../../src/components/Calendar/Calendar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue'\n\nimport {\n addDays,\n addMonths,\n differenceInDays,\n isSameDay,\n isSameMonth,\n startOfDay,\n startOfMonth,\n startOfWeek\n} from '../../utils/dates'\nimport Tooltip from '../Tooltip/Tooltip.vue'\nimport ChevronIcon from '../internal/ChevronIcon.vue'\n\nexport interface CalendarProps {\n /** Selects a day; with `end`, a range. */\n start?: Date | null\n end?: Date | null\n /** For the month's name and the weekdays; the browser's language by default. */\n locale?: string\n /** Monday first; the locale's narrow names by default. */\n weekdays?: string[]\n previousLabel?: string\n nextLabel?: string\n}\n\nconst props = withDefaults(defineProps<CalendarProps>(), {\n start: null,\n end: null,\n locale: undefined,\n weekdays: undefined,\n previousLabel: 'Previous month',\n nextLabel: 'Next month'\n})\n\nconst emit = defineEmits<{ pick: [date: Date] }>()\n\nconst view = ref(startOfMonth(props.end ?? props.start ?? new Date()))\n\n// Follows the selection to its month, when it's picked elsewhere (a shortcut, say).\nwatch(\n () => props.end ?? props.start,\n (date) => {\n if (date) view.value = startOfMonth(date)\n }\n)\n\nconst title = computed(() =>\n new Intl.DateTimeFormat(props.locale, { month: 'long', year: 'numeric' }).format(view.value)\n)\n\n// 1 January 2024 was a Monday.\nconst dayNames = computed(\n () =>\n props.weekdays ??\n Array.from({ length: 7 }, (_, i) =>\n new Intl.DateTimeFormat(props.locale, { weekday: 'narrow' }).format(new Date(2024, 0, 1 + i))\n )\n)\n\nconst shiftMonth = (months: number) => (view.value = addMonths(view.value, months))\n\nconst cells = computed(() => {\n const first = startOfWeek(view.value)\n const last = addDays(addMonths(view.value, 1), -1)\n const count = Math.ceil((differenceInDays(last, first) + 1) / 7) * 7\n const today = startOfDay(new Date())\n const [start, end] = [props.start, props.end].map((date) => (date ? startOfDay(date) : null))\n const ranged = !!start && !!end && !isSameDay(start, end)\n const [low, high] = ranged ? [start!, end!].sort((a, b) => a.getTime() - b.getTime()) : []\n\n return Array.from({ length: count }, (_, i) => {\n const date = addDays(first, i)\n const isStart = !!start && isSameDay(date, start)\n const isEnd = !!end && isSameDay(date, end)\n const selected = isStart || isEnd\n const inRange = ranged && date >= low! && date <= high!\n const isToday = isSameDay(date, today)\n const column = i % 7\n\n return {\n key: date.toISOString(),\n date,\n label: date.getDate(),\n selected,\n isToday,\n // The range is a band behind the days, rounded where it starts, ends or wraps.\n band: inRange\n ? ['bg-sui-accent-wash', (isStart || column === 0) && 'rounded-l-lg', (isEnd || column === 6) && 'rounded-r-lg']\n : '',\n classes: selected\n ? 'bg-sui-accent-solid font-semibold text-sui-on-accent'\n : [\n 'hover:bg-sui-fill-hover',\n isToday\n ? 'font-semibold text-sui-accent ring-1 ring-sui-accent-line ring-inset'\n : inRange\n ? 'font-medium text-sui-accent'\n : !isSameMonth(date, view.value) || date > today\n ? 'text-sui-ink-muted'\n : 'text-sui-ink'\n ]\n }\n })\n})\n</script>\n\n<!-- A month of days, weeks from Monday: today outlined with a dot, future days and other months muted. Picking a day\n emits it; the host decides what it selects. -->\n<template>\n <div>\n <div class=\"flex h-11 items-center justify-between\">\n <span class=\"pl-1.5 text-13 font-semibold text-sui-ink\">{{ title }}</span>\n <div class=\"flex gap-0.5\">\n <Tooltip :text=\"previousLabel\">\n <button\n :aria-label=\"previousLabel\"\n class=\"flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-fill-hover focus-visible:sui-ring\"\n type=\"button\"\n @click=\"shiftMonth(-1)\"\n >\n <ChevronIcon class=\"h-4 w-4 fill-sui-ink-body stroke-sui-ink-body\" direction=\"left\" />\n </button>\n </Tooltip>\n <Tooltip :text=\"nextLabel\">\n <button\n :aria-label=\"nextLabel\"\n class=\"flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-fill-hover focus-visible:sui-ring\"\n type=\"button\"\n @click=\"shiftMonth(1)\"\n >\n <ChevronIcon class=\"h-4 w-4 fill-sui-ink-body stroke-sui-ink-body\" direction=\"right\" />\n </button>\n </Tooltip>\n </div>\n </div>\n <div aria-hidden=\"true\" class=\"grid h-5.5 grid-cols-7 items-center\">\n <span v-for=\"(day, i) in dayNames\" :key=\"i\" class=\"text-center text-11 font-semibold text-sui-ink-muted\">\n {{ day }}\n </span>\n </div>\n <div class=\"mt-0.5 grid grid-cols-7 gap-y-0.5\">\n <button\n v-for=\"cell in cells\"\n :key=\"cell.key\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.date.toLocaleDateString(locale, { dateStyle: 'full' })\"\n :aria-pressed=\"cell.selected\"\n :class=\"['group flex h-9 items-center justify-center outline-hidden', cell.band]\"\n type=\"button\"\n @click=\"emit('pick', cell.date)\"\n >\n <span\n class=\"relative flex h-8.5 w-9 items-center justify-center rounded-lg text-13 tabular-nums transition-colors group-focus-visible:sui-ring\"\n :class=\"cell.classes\"\n >\n {{ cell.label }}\n <span\n v-if=\"cell.isToday\"\n class=\"absolute bottom-1 left-1/2 h-1 w-1 -translate-x-1/2 rounded-full\"\n :class=\"cell.selected ? 'bg-sui-on-accent' : 'bg-sui-accent-solid'\"\n />\n </span>\n </button>\n </div>\n </div>\n</template>\n"],"mappings":""}
|
|
@@ -45,7 +45,7 @@ var T = { class: "flex h-11 items-center justify-between" }, E = { class: "pl-1.
|
|
|
45
45
|
(s || v === 0) && "rounded-l-lg",
|
|
46
46
|
(c || v === 6) && "rounded-r-lg"
|
|
47
47
|
] : "",
|
|
48
|
-
classes: l ? "bg-sui-accent-solid font-semibold text-sui-on-accent" : ["hover:bg-sui-
|
|
48
|
+
classes: l ? "bg-sui-accent-solid font-semibold text-sui-on-accent" : ["hover:bg-sui-fill-hover", _ ? "font-semibold text-sui-accent ring-1 ring-sui-accent-line ring-inset" : g ? "font-medium text-sui-accent" : !a(o, I.value) || o > u ? "text-sui-ink-muted" : "text-sui-ink"]
|
|
49
49
|
};
|
|
50
50
|
});
|
|
51
51
|
});
|
|
@@ -53,7 +53,7 @@ var T = { class: "flex h-11 items-center justify-between" }, E = { class: "pl-1.
|
|
|
53
53
|
m("div", T, [m("span", E, S(L.value), 1), m("div", D, [g(e, { text: _.previousLabel }, {
|
|
54
54
|
default: w(() => [m("button", {
|
|
55
55
|
"aria-label": _.previousLabel,
|
|
56
|
-
class: "flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-
|
|
56
|
+
class: "flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-fill-hover focus-visible:sui-ring",
|
|
57
57
|
type: "button",
|
|
58
58
|
onClick: n[0] ||= (e) => z(-1)
|
|
59
59
|
}, [g(l, {
|
|
@@ -64,7 +64,7 @@ var T = { class: "flex h-11 items-center justify-between" }, E = { class: "pl-1.
|
|
|
64
64
|
}, 8, ["text"]), g(e, { text: _.nextLabel }, {
|
|
65
65
|
default: w(() => [m("button", {
|
|
66
66
|
"aria-label": _.nextLabel,
|
|
67
|
-
class: "flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-
|
|
67
|
+
class: "flex h-7 w-7 items-center justify-center rounded-lg transition-colors hover:bg-sui-fill-hover focus-visible:sui-ring",
|
|
68
68
|
type: "button",
|
|
69
69
|
onClick: n[1] ||= (e) => z(1)
|
|
70
70
|
}, [g(l, {
|