@leaflink/stash 53.4.5 → 53.4.7
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/dist/AppSidebar.js +43 -41
- package/dist/AppSidebar.js.map +1 -1
- package/dist/AppTopbar.js +1 -1
- package/dist/Copy.js +1 -1
- package/dist/DataTable/index.js +2400 -0
- package/dist/DataTable/index.js.map +1 -0
- package/dist/DataViewFilters.js +1 -1
- package/dist/DataViewFilters.js.map +1 -1
- package/dist/DataViewToolbar.js +139 -125
- package/dist/DataViewToolbar.js.map +1 -1
- package/dist/DatePicker.js +1114 -1113
- package/dist/DatePicker.js.map +1 -1
- package/dist/Modal.js +104 -90
- package/dist/Modal.js.map +1 -1
- package/dist/MoreActions.js +294 -288
- package/dist/MoreActions.js.map +1 -1
- package/dist/PageNavigation.js +1 -1
- package/dist/RadioGroup.js +69 -62
- package/dist/RadioGroup.js.map +1 -1
- package/dist/Select.js +90 -90
- package/dist/Select.js.map +1 -1
- package/dist/Stepper.js +1 -1
- package/dist/Tab.js +1 -1
- package/dist/Table.js +36 -36
- package/dist/Table.js.map +1 -1
- package/dist/Table.vue.d.ts +12 -0
- package/dist/TableCell.js +17 -17
- package/dist/TableCell.js.map +1 -1
- package/dist/TableHeaderCell.js +44 -38
- package/dist/TableHeaderCell.js.map +1 -1
- package/dist/TableHeaderCell.vue.d.ts +10 -0
- package/dist/TableHeaderRow.js +32 -32
- package/dist/TableHeaderRow.js.map +1 -1
- package/dist/TableRow.js +82 -74
- package/dist/TableRow.js.map +1 -1
- package/dist/TableRow.vue.d.ts +9 -2
- package/dist/Tabs.js +2 -2
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-DEopbeSY.js +131 -0
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-DEopbeSY.js.map +1 -0
- package/dist/Thumbnail.js +42 -42
- package/dist/Thumbnail.js.map +1 -1
- package/dist/Toast.vue.d.ts +1 -1
- package/dist/Tooltip.js +1 -1
- package/dist/{Tooltip.vue_vue_type_script_setup_true_lang-CFpM7Ldj.js → Tooltip.vue_vue_type_script_setup_true_lang-UUjw5O1x.js} +2 -2
- package/dist/{Tooltip.vue_vue_type_script_setup_true_lang-CFpM7Ldj.js.map → Tooltip.vue_vue_type_script_setup_true_lang-UUjw5O1x.js.map} +1 -1
- package/dist/components.css +1 -1
- package/dist/getContrastingTextColor.d.ts +8 -0
- package/dist/index-t9tXBnql.js +469 -0
- package/dist/{index-DA70nQCT.js.map → index-t9tXBnql.js.map} +1 -1
- package/dist/templateRefNarrowing-CeANDylX.js +22 -0
- package/dist/templateRefNarrowing-CeANDylX.js.map +1 -0
- package/dist/useMediaQuery.d.ts +12 -10
- package/dist/useMediaQuery.js +7 -29
- package/dist/useMediaQuery.js.map +1 -1
- package/dist/useSortable.js +1 -1
- package/dist/utils/getContrastingTextColor.js +36 -24
- package/dist/utils/getContrastingTextColor.js.map +1 -1
- package/package.json +7 -1
- package/types/tanstack-vue-table.d.ts +18 -0
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-B3FBaVP5.js +0 -130
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-B3FBaVP5.js.map +0 -1
- package/dist/index-DA70nQCT.js +0 -424
package/dist/Modal.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { defineComponent as R, useSlots as
|
|
2
|
-
import
|
|
3
|
-
import { FOCUS_ELEMENTS_SELECTOR as
|
|
4
|
-
import { t as
|
|
5
|
-
import
|
|
1
|
+
import { defineComponent as R, useSlots as V, ref as c, computed as C, watch as T, onBeforeUnmount as K, createElementBlock as m, createCommentVNode as n, openBlock as i, withKeys as q, normalizeClass as d, createVNode as z, createElementVNode as _, withModifiers as $, unref as p, createBlock as D, renderSlot as v, toDisplayString as P, withCtx as H } from "vue";
|
|
2
|
+
import U from "lodash-es/uniqueId";
|
|
3
|
+
import { FOCUS_ELEMENTS_SELECTOR as W } from "./constants.js";
|
|
4
|
+
import { t as j } from "./locale.js";
|
|
5
|
+
import G from "./Backdrop.js";
|
|
6
6
|
import I from "./Button.js";
|
|
7
|
-
import
|
|
8
|
-
import { _ as
|
|
9
|
-
var
|
|
10
|
-
const
|
|
7
|
+
import M from "./Icon.js";
|
|
8
|
+
import { _ as J } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
9
|
+
var Q = /* @__PURE__ */ ((a) => (a.Narrow = "narrow", a.Medium = "medium", a.Wide = "wide", a))(Q || {}), X = /* @__PURE__ */ ((a) => (a.Center = "center", a.Left = "left", a.Right = "right", a))(X || {});
|
|
10
|
+
const Y = ["aria-labelledby"], Z = { class: "flex place-items-center" }, ee = ["id"], te = { class: "stash-modal__footer__actions flex flex-col justify-end lg:flex-row" }, le = /* @__PURE__ */ R({
|
|
11
11
|
name: "ll-modal",
|
|
12
12
|
__name: "Modal",
|
|
13
13
|
props: {
|
|
@@ -26,74 +26,88 @@ const Q = ["aria-labelledby"], X = { class: "flex place-items-center" }, Y = ["i
|
|
|
26
26
|
preventDismiss: { type: Boolean, default: !1 }
|
|
27
27
|
},
|
|
28
28
|
emits: ["update:open", "update:is-open", "dismiss"],
|
|
29
|
-
setup(
|
|
30
|
-
const e =
|
|
31
|
-
|
|
29
|
+
setup(a, { emit: N }) {
|
|
30
|
+
const e = a, w = N, b = V(), r = c(), E = c(null), h = c([]), k = c(), x = c(), f = c({ height: "", overflow: "" }), L = U("modal-header-"), O = C(() => !!b.actions || !!b.footer), l = C(() => e.open || e.isOpen), s = C(() => e.position === "left" || e.position === "right");
|
|
31
|
+
let u = !1;
|
|
32
|
+
function g() {
|
|
32
33
|
return document.scrollingElement || document.body;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
T(
|
|
36
|
+
l,
|
|
36
37
|
() => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
var t;
|
|
39
|
+
if (!(typeof document > "u")) {
|
|
40
|
+
if (S(l.value ? "hide" : "show"), l.value) {
|
|
41
|
+
const o = document.activeElement;
|
|
42
|
+
E.value = o instanceof HTMLElement ? o : null;
|
|
43
|
+
} else
|
|
44
|
+
u && (document.removeEventListener("keydown", B), u = !1), (t = E.value) == null || t.focus();
|
|
45
|
+
l.value && Object.assign(f.value, {
|
|
46
|
+
height: g().style.height,
|
|
47
|
+
overflow: g().style.overflow
|
|
48
|
+
}), Object.assign(g().style, {
|
|
49
|
+
overflow: l.value ? "hidden" : f.value.overflow,
|
|
50
|
+
// Prevents page from scrolling when modal is open
|
|
51
|
+
height: l.value ? "100%" : f.value.height
|
|
52
|
+
// Ensures the backdrop covers the entire page when modal is open; see https://github.com/LeafLink/stash/pull/713#issuecomment-1184602535
|
|
53
|
+
});
|
|
54
|
+
}
|
|
46
55
|
},
|
|
47
56
|
{ immediate: !0 }
|
|
48
|
-
),
|
|
57
|
+
), K(() => {
|
|
49
58
|
var t;
|
|
50
|
-
S("show"), Object.assign(
|
|
51
|
-
overflow:
|
|
52
|
-
height:
|
|
53
|
-
}), document.removeEventListener("keydown",
|
|
59
|
+
typeof document > "u" || (S("show"), Object.assign(g().style, {
|
|
60
|
+
overflow: f.value.overflow,
|
|
61
|
+
height: f.value.height
|
|
62
|
+
}), u && (document.removeEventListener("keydown", B), u = !1), (t = E.value) == null || t.focus());
|
|
54
63
|
});
|
|
55
|
-
function
|
|
56
|
-
e.preventDismiss || (
|
|
64
|
+
function y() {
|
|
65
|
+
e.preventDismiss || (w("update:open", !1), w("update:is-open", !1), w("dismiss"));
|
|
57
66
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
function O(t) {
|
|
62
|
-
var a, $;
|
|
63
|
-
t.key === "Tab" && (t.shiftKey && document.activeElement === b.value ? ((a = E.value) == null || a.focus(), t.preventDefault()) : document.activeElement === E.value && (($ = b.value) == null || $.focus(), t.preventDefault()));
|
|
67
|
+
function B(t) {
|
|
68
|
+
var o, F;
|
|
69
|
+
t.key === "Tab" && (t.shiftKey && document.activeElement === k.value ? ((o = x.value) == null || o.focus(), t.preventDefault()) : document.activeElement === x.value && ((F = k.value) == null || F.focus(), t.preventDefault()));
|
|
64
70
|
}
|
|
71
|
+
function A() {
|
|
72
|
+
typeof document > "u" || !r.value || !l.value || (r.value.focus(), h.value = Array.from(r.value.querySelectorAll(W)), k.value = h.value[0], x.value = h.value[h.value.length - 1], u || (document.addEventListener("keydown", B), u = !0));
|
|
73
|
+
}
|
|
74
|
+
T(r, () => {
|
|
75
|
+
!r.value || !l.value || A();
|
|
76
|
+
});
|
|
65
77
|
function S(t) {
|
|
66
|
-
|
|
67
|
-
|
|
78
|
+
if (typeof document > "u")
|
|
79
|
+
return;
|
|
80
|
+
const o = document.getElementById("launcher");
|
|
81
|
+
!o || !o.parentElement || (o.parentElement.style.display = t === "show" ? "block" : "none");
|
|
68
82
|
}
|
|
69
|
-
return (t,
|
|
83
|
+
return (t, o) => l.value ? (i(), m("div", {
|
|
70
84
|
key: 0,
|
|
71
85
|
ref_key: "rootRef",
|
|
72
|
-
ref:
|
|
73
|
-
class:
|
|
74
|
-
"invisible z-behind": !
|
|
75
|
-
"visible z-modal":
|
|
86
|
+
ref: r,
|
|
87
|
+
class: d(["stash-modal fixed inset-0", {
|
|
88
|
+
"invisible z-behind": !l.value,
|
|
89
|
+
"visible z-modal": l.value,
|
|
76
90
|
"lg:flex lg:flex-col lg:items-center lg:justify-center": e.position === "center",
|
|
77
91
|
"overflow-y-auto": !e.scrollable && !s.value,
|
|
78
92
|
"overflow-y-hidden": s.value
|
|
79
93
|
}]),
|
|
80
94
|
"data-test": "ll-modal",
|
|
81
95
|
tabindex: "0",
|
|
82
|
-
onKeydown:
|
|
96
|
+
onKeydown: q(y, ["esc"])
|
|
83
97
|
}, [
|
|
84
|
-
|
|
98
|
+
z(G, {
|
|
85
99
|
class: "stash-modal__backdrop",
|
|
86
|
-
onClick:
|
|
100
|
+
onClick: $(y, ["stop"])
|
|
87
101
|
}),
|
|
88
|
-
|
|
102
|
+
_("div", {
|
|
89
103
|
"aria-modal": "true",
|
|
90
104
|
role: "dialog",
|
|
91
|
-
"aria-labelledby":
|
|
92
|
-
class:
|
|
105
|
+
"aria-labelledby": p(L),
|
|
106
|
+
class: d(["stash-modal__dialog relative flex h-screen w-full flex-col lg:shadow-3xl", [
|
|
93
107
|
`stash-modal__dialog--size-${e.size}`,
|
|
94
108
|
`stash-modal__dialog--position-${e.position}`,
|
|
95
109
|
{
|
|
96
|
-
"stash-modal__dialog--is-open":
|
|
110
|
+
"stash-modal__dialog--is-open": l.value,
|
|
97
111
|
"stash-modal__dialog--is-drawer": s.value,
|
|
98
112
|
"stash-modal__dialog--is-contrast": e.contrast,
|
|
99
113
|
"stash-modal__dialog--is-scrollable": e.scrollable,
|
|
@@ -107,32 +121,32 @@ const Q = ["aria-labelledby"], X = { class: "flex place-items-center" }, Y = ["i
|
|
|
107
121
|
"lg:right-0": e.position === "right"
|
|
108
122
|
}
|
|
109
123
|
]]),
|
|
110
|
-
onClick:
|
|
124
|
+
onClick: o[0] || (o[0] = $(() => {
|
|
111
125
|
}, ["stop"]))
|
|
112
126
|
}, [
|
|
113
|
-
e.hideHeader ?
|
|
127
|
+
e.hideHeader ? n("", !0) : (i(), m("header", {
|
|
114
128
|
key: 0,
|
|
115
129
|
"data-test": "stash-modal__header",
|
|
116
|
-
class:
|
|
130
|
+
class: d(["stash-modal__header grid h-12 place-items-center bg-purple-500", { "lg:rounded-t": !s.value }])
|
|
117
131
|
}, [
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
_("div", Z, [
|
|
133
|
+
v(t.$slots, "headerAction", {}, void 0, !0)
|
|
120
134
|
]),
|
|
121
|
-
e.title ? (
|
|
135
|
+
e.title ? (i(), m("h3", {
|
|
122
136
|
key: 0,
|
|
123
|
-
id:
|
|
137
|
+
id: p(L),
|
|
124
138
|
class: "m-0 flex-1 leading-6 text-white"
|
|
125
|
-
},
|
|
126
|
-
e.hideClose ?
|
|
139
|
+
}, P(e.title), 9, ee)) : n("", !0),
|
|
140
|
+
e.hideClose ? n("", !0) : (i(), D(I, {
|
|
127
141
|
key: 1,
|
|
128
142
|
icon: "",
|
|
129
143
|
"data-test": "ll-modal-close",
|
|
130
|
-
title:
|
|
144
|
+
title: p(j)("ll.closeModal"),
|
|
131
145
|
type: "button",
|
|
132
|
-
onClick:
|
|
146
|
+
onClick: y
|
|
133
147
|
}, {
|
|
134
|
-
default:
|
|
135
|
-
|
|
148
|
+
default: H(() => [
|
|
149
|
+
z(M, {
|
|
136
150
|
class: "text-white",
|
|
137
151
|
name: "close"
|
|
138
152
|
})
|
|
@@ -140,62 +154,62 @@ const Q = ["aria-labelledby"], X = { class: "flex place-items-center" }, Y = ["i
|
|
|
140
154
|
_: 1
|
|
141
155
|
}, 8, ["title"]))
|
|
142
156
|
], 2)),
|
|
143
|
-
!e.hideClose && e.hideHeader ? (
|
|
157
|
+
!e.hideClose && e.hideHeader ? (i(), D(I, {
|
|
144
158
|
key: 1,
|
|
145
159
|
class: "absolute right-0 top-0 z-10",
|
|
146
160
|
icon: "",
|
|
147
161
|
"data-test": "ll-modal-close",
|
|
148
162
|
type: "button",
|
|
149
|
-
title:
|
|
150
|
-
onClick:
|
|
163
|
+
title: p(j)("ll.closeModal"),
|
|
164
|
+
onClick: y
|
|
151
165
|
}, {
|
|
152
|
-
default:
|
|
153
|
-
|
|
154
|
-
class:
|
|
166
|
+
default: H(() => [
|
|
167
|
+
z(M, {
|
|
168
|
+
class: d(["drop-shadow-md", [e.closeButtonColorClass]]),
|
|
155
169
|
name: "close"
|
|
156
170
|
}, null, 8, ["class"])
|
|
157
171
|
]),
|
|
158
172
|
_: 1
|
|
159
|
-
}, 8, ["title"])) :
|
|
160
|
-
|
|
173
|
+
}, 8, ["title"])) : n("", !0),
|
|
174
|
+
p(b)["featured-content"] ? (i(), m("div", {
|
|
161
175
|
key: 2,
|
|
162
|
-
class:
|
|
176
|
+
class: d(["stash-modal__featured-content relative", {
|
|
163
177
|
"rounded-t": e.hideHeader
|
|
164
178
|
}])
|
|
165
179
|
}, [
|
|
166
|
-
|
|
167
|
-
], 2)) :
|
|
168
|
-
|
|
169
|
-
class:
|
|
180
|
+
v(t.$slots, "featured-content", {}, void 0, !0)
|
|
181
|
+
], 2)) : n("", !0),
|
|
182
|
+
_("div", {
|
|
183
|
+
class: d(["stash-modal__body flex-1 overflow-y-auto", [
|
|
170
184
|
{
|
|
171
185
|
"p-3 lg:p-6": !e.disableBodyPadding,
|
|
172
186
|
"lg:overflow-y-visible": !e.scrollable && !s.value,
|
|
173
|
-
"lg:rounded-b": !
|
|
187
|
+
"lg:rounded-b": !O.value && !s.value,
|
|
174
188
|
"bg-white": !e.contrast,
|
|
175
189
|
"bg-ice-200": e.contrast
|
|
176
190
|
}
|
|
177
191
|
]]),
|
|
178
192
|
"data-test": "stash-modal__body"
|
|
179
193
|
}, [
|
|
180
|
-
|
|
194
|
+
v(t.$slots, "default", {}, void 0, !0)
|
|
181
195
|
], 2),
|
|
182
|
-
|
|
196
|
+
O.value ? (i(), m("footer", {
|
|
183
197
|
key: 3,
|
|
184
|
-
class:
|
|
198
|
+
class: d(["stash-modal__footer border-t border-ice-500 bg-ice-100 p-3 lg:p-6", { "lg:rounded-b": !s.value }])
|
|
185
199
|
}, [
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
v(t.$slots, "footer", {}, () => [
|
|
201
|
+
_("div", te, [
|
|
202
|
+
v(t.$slots, "actions", {}, void 0, !0)
|
|
189
203
|
])
|
|
190
204
|
], !0)
|
|
191
|
-
], 2)) :
|
|
192
|
-
], 10,
|
|
193
|
-
], 34)) :
|
|
205
|
+
], 2)) : n("", !0)
|
|
206
|
+
], 10, Y)
|
|
207
|
+
], 34)) : n("", !0);
|
|
194
208
|
}
|
|
195
|
-
}),
|
|
209
|
+
}), ce = /* @__PURE__ */ J(le, [["__scopeId", "data-v-60489fbd"]]);
|
|
196
210
|
export {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
211
|
+
X as ModalPosition,
|
|
212
|
+
Q as ModalSize,
|
|
213
|
+
ce as default
|
|
200
214
|
};
|
|
201
215
|
//# sourceMappingURL=Modal.js.map
|
package/dist/Modal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sources":["../src/components/Modal/Modal.types.ts","../src/components/Modal/Modal.vue"],"sourcesContent":["export enum ModalSize {\n Narrow = 'narrow',\n Medium = 'medium',\n Wide = 'wide',\n}\n\nexport type ModalSizes = `${ModalSize}`;\n\nexport enum ModalPosition {\n Center = 'center',\n Left = 'left',\n Right = 'right',\n}\n\nexport type ModalPositions = `${ModalPosition}`;\n","<script lang=\"ts\">\n import { ModalPositions, ModalSizes } from './Modal.types';\n\n export * from './Modal.types';\n\n export interface ModalProps {\n /**\n * Hides the \"close\" button\n */\n hideClose?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n * @deprecated Use `isOpen` instead\n */\n open?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n */\n isOpen?: boolean;\n\n /**\n * Use v-model:is-open or :is-open instead of :model-value and v-model.\n * @deprecated\n */\n modelValue?: boolean;\n\n /**\n * Sets a preset max-width on the modal.\n * Options: default (648px), narrow (360px), wide (960px)\n */\n size?: ModalSizes;\n\n /**\n * Should the modal be scrollable within the content area. This prop is treated as `true` when the `position` prop is set to \"left\" or \"right\".\n */\n scrollable?: boolean;\n\n /**\n * Gives the modal body have a light gray background\n */\n contrast?: boolean;\n\n /**\n * Text to display in the modal header\n */\n title?: string;\n\n /**\n * Disables the default padding in the modal body.\n */\n disableBodyPadding?: boolean;\n\n /**\n * The position on the screen to display the modal.\n */\n position?: ModalPositions;\n\n /**\n * Hide the header. Typically used with the featuredContent slot to display a graphic and create a \"promo\" modal.\n */\n hideHeader?: boolean;\n\n /**\n * Add classes to the close button. This can be used with the hideHeader prop and featuredContent slot to\n * accommodate images with different color backgrounds.\n */\n closeButtonColorClass?: string;\n\n /**\n * Prevents the modal from being dismissed by clicking the backdrop or pressing the escape key.\n * Example: There are in-flight api requests and you do not want the modal to close until they are done.\n */\n preventDismiss?: boolean;\n }\n</script>\n\n<script setup lang=\"ts\">\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, onBeforeUnmount, ref, useSlots, watch } from 'vue';\n\n import { FOCUS_ELEMENTS_SELECTOR } from '../../constants';\n import { t } from '../../locale';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({ name: 'll-modal' });\n\n const props = withDefaults(defineProps<ModalProps>(), {\n hideClose: false,\n open: false,\n isOpen: false,\n modelValue: false,\n size: 'medium',\n scrollable: false,\n contrast: false,\n title: '',\n position: 'center',\n hideHeader: false,\n closeButtonColorClass: 'text-white/50',\n preventDismiss: false,\n });\n\n const emit = defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'update:open', isOpen?: boolean): void;\n (e: 'update:is-open', isOpen?: boolean): void;\n (e: 'dismiss'): void;\n }>();\n\n const slots = useSlots();\n\n const rootRef = ref<HTMLElement>();\n const lastExternalFocusedElement = ref<HTMLElement>();\n const focusElements = ref<HTMLElement[]>([]);\n const firstFocusElement = ref<HTMLElement>();\n const lastFocusElement = ref<HTMLElement>();\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const headerId = uniqueId('modal-header-');\n const hasFooterContent = computed(() => !!slots.actions || !!slots.footer);\n const isModalOpen = computed(() => props.open || props.isOpen);\n const isDrawer = computed(() => props.position === 'left' || props.position === 'right');\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watch(\n isModalOpen,\n () => {\n toggleHelpWidgetLauncher(isModalOpen.value ? 'hide' : 'show');\n\n if (isModalOpen.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n height: getPageScrollingElement().style.height,\n overflow: getPageScrollingElement().style.overflow,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isModalOpen.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when modal is open\n height: isModalOpen.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when modal is open; see https://github.com/LeafLink/stash/pull/713#issuecomment-1184602535\n });\n },\n { immediate: true },\n );\n\n onBeforeUnmount(() => {\n toggleHelpWidgetLauncher('show');\n\n // In cases where the watchEffect for isModalOpen isn't triggered while closing/nagivating away from modal, this ensures scrolling returns to normal\n Object.assign(getPageScrollingElement().style, {\n overflow: initialPageScrollingElementStyle.value.overflow,\n height: initialPageScrollingElementStyle.value.height,\n });\n\n // Clear focus trap tab listener\n document.removeEventListener('keydown', handleTab);\n lastExternalFocusedElement.value?.focus();\n });\n\n function dismiss() {\n if (props.preventDismiss) {\n return;\n }\n emit('update:open', false);\n emit('update:is-open', false);\n emit('dismiss');\n }\n\n // This watcher ensures the Tab key cycles through focusable elements within the modal.\n watch(rootRef, () => {\n if (!rootRef.value) {\n return;\n }\n\n lastExternalFocusedElement.value = document.activeElement as HTMLElement;\n rootRef.value.focus();\n\n focusElements.value = Array.from(rootRef.value.querySelectorAll<HTMLElement>(FOCUS_ELEMENTS_SELECTOR));\n firstFocusElement.value = focusElements.value[0];\n lastFocusElement.value = focusElements.value[focusElements.value.length - 1];\n document.addEventListener('keydown', handleTab);\n });\n\n function handleTab(e) {\n if (e.key === 'Tab') {\n if (e.shiftKey && document.activeElement === firstFocusElement.value) {\n lastFocusElement.value?.focus();\n e.preventDefault();\n } else if (document.activeElement === lastFocusElement.value) {\n firstFocusElement.value?.focus();\n e.preventDefault();\n }\n }\n }\n\n /**\n * The customer support \"help widget launcher\" covers the action buttons in the Modal when the Modal uses a position value of \"right\" (for drawers).\n */\n function toggleHelpWidgetLauncher(nextState: 'show' | 'hide') {\n const launcherElement = document.getElementById('launcher');\n\n if (!launcherElement || !launcherElement.parentElement) {\n return;\n }\n\n launcherElement.parentElement.style.display = nextState === 'show' ? 'block' : 'none';\n }\n</script>\n\n<template>\n <div\n v-if=\"isModalOpen\"\n ref=\"rootRef\"\n class=\"stash-modal fixed inset-0\"\n :class=\"{\n 'invisible z-behind': !isModalOpen,\n 'visible z-modal': isModalOpen,\n 'lg:flex lg:flex-col lg:items-center lg:justify-center': props.position === 'center',\n 'overflow-y-auto': !props.scrollable && !isDrawer,\n 'overflow-y-hidden': isDrawer,\n }\"\n data-test=\"ll-modal\"\n tabindex=\"0\"\n @keydown.esc=\"dismiss\"\n >\n <Backdrop class=\"stash-modal__backdrop\" @click.stop=\"dismiss\" />\n <div\n aria-modal=\"true\"\n role=\"dialog\"\n :aria-labelledby=\"headerId\"\n class=\"stash-modal__dialog relative flex h-screen w-full flex-col lg:shadow-3xl\"\n :class=\"[\n `stash-modal__dialog--size-${props.size}`,\n `stash-modal__dialog--position-${props.position}`,\n {\n 'stash-modal__dialog--is-open': isModalOpen,\n 'stash-modal__dialog--is-drawer': isDrawer,\n 'stash-modal__dialog--is-contrast': props.contrast,\n 'stash-modal__dialog--is-scrollable': props.scrollable,\n 'lg:w-[360px]': props.size === 'narrow',\n 'lg:w-[648px]': props.size === 'medium',\n 'lg:w-[960px]': props.size === 'wide',\n 'lg:my-0 lg:h-auto lg:max-h-[90vh]': props.position === 'center',\n // absolute causing this to break when items in bottom of container get focus\n 'lg:fixed lg:h-screen': isDrawer,\n 'lg:left-0': props.position === 'left',\n 'lg:right-0': props.position === 'right',\n },\n ]\"\n @click.stop\n >\n <header\n v-if=\"!props.hideHeader\"\n data-test=\"stash-modal__header\"\n class=\"stash-modal__header grid h-12 place-items-center bg-purple-500\"\n :class=\"{ 'lg:rounded-t': !isDrawer }\"\n >\n <div class=\"flex place-items-center\">\n <!-- @slot Adds an action to the left side of the header bar. An example usage is a modal with multiple pages and a back button can be inserted here -->\n <slot name=\"headerAction\"></slot>\n </div>\n\n <h3 v-if=\"props.title\" :id=\"headerId\" class=\"m-0 flex-1 leading-6 text-white\">\n {{ props.title }}\n </h3>\n\n <Button\n v-if=\"!props.hideClose\"\n icon\n data-test=\"ll-modal-close\"\n :title=\"t('ll.closeModal')\"\n type=\"button\"\n @click=\"dismiss\"\n >\n <Icon class=\"text-white\" name=\"close\" />\n </Button>\n </header>\n\n <Button\n v-if=\"!props.hideClose && props.hideHeader\"\n class=\"absolute right-0 top-0 z-10\"\n icon\n data-test=\"ll-modal-close\"\n type=\"button\"\n :title=\"t('ll.closeModal')\"\n @click=\"dismiss\"\n >\n <Icon class=\"drop-shadow-md\" name=\"close\" :class=\"[props.closeButtonColorClass]\" />\n </Button>\n\n <div\n v-if=\"!!slots['featured-content']\"\n class=\"stash-modal__featured-content relative\"\n :class=\"{\n 'rounded-t': props.hideHeader,\n }\"\n >\n <slot name=\"featured-content\"></slot>\n </div>\n\n <div\n class=\"stash-modal__body flex-1 overflow-y-auto\"\n :class=\"[\n {\n 'p-3 lg:p-6': !props.disableBodyPadding,\n 'lg:overflow-y-visible': !props.scrollable && !isDrawer,\n 'lg:rounded-b': !hasFooterContent && !isDrawer,\n 'bg-white': !props.contrast,\n 'bg-ice-200': props.contrast,\n },\n ]\"\n data-test=\"stash-modal__body\"\n >\n <slot></slot>\n </div>\n\n <footer\n v-if=\"hasFooterContent\"\n class=\"stash-modal__footer border-t border-ice-500 bg-ice-100 p-3 lg:p-6\"\n :class=\"{ 'lg:rounded-b': !isDrawer }\"\n >\n <!-- @slot Overrides the whole footer section. Used for rendering custom footers with more than 2 actions. If defined, \"actions\" slot will get ignored. -->\n <slot name=\"footer\">\n <div class=\"stash-modal__footer__actions flex flex-col justify-end lg:flex-row\">\n <!-- @slot Modal footer actions, supports rendering up to 2 `<Button>` children -->\n <slot name=\"actions\"></slot>\n </div>\n </slot>\n </footer>\n </div>\n </div>\n</template>\n\n<style scoped>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .stash-modal__header {\n grid-template-columns: 48px 1fr 48px;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(1) {\n order: 2;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(2) {\n margin-bottom: --spacing(3);\n order: 1;\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(1) {\n order: 1;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(2) {\n margin-bottom: 0;\n order: 2;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button + .stash-button) {\n margin-left: var(--grid-gutter);\n }\n }\n\n .stash-modal__featured-content > :deep(*) {\n border-radius: inherit;\n }\n }\n</style>\n"],"names":["ModalSize","ModalPosition","props","__props","emit","__emit","slots","useSlots","rootRef","ref","lastExternalFocusedElement","focusElements","firstFocusElement","lastFocusElement","initialPageScrollingElementStyle","headerId","uniqueId","hasFooterContent","computed","isModalOpen","isDrawer","getPageScrollingElement","watch","toggleHelpWidgetLauncher","onBeforeUnmount","handleTab","_a","dismiss","FOCUS_ELEMENTS_SELECTOR","e","_b","nextState","launcherElement","_createElementBlock","_createVNode","Backdrop","_createElementVNode","_unref","_normalizeClass","_hoisted_2","_renderSlot","_ctx","_toDisplayString","_hoisted_3","_createBlock","Button","t","Icon","_hoisted_4"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Modal.js","sources":["../src/components/Modal/Modal.types.ts","../src/components/Modal/Modal.vue"],"sourcesContent":["export enum ModalSize {\n Narrow = 'narrow',\n Medium = 'medium',\n Wide = 'wide',\n}\n\nexport type ModalSizes = `${ModalSize}`;\n\nexport enum ModalPosition {\n Center = 'center',\n Left = 'left',\n Right = 'right',\n}\n\nexport type ModalPositions = `${ModalPosition}`;\n","<script lang=\"ts\">\n import { ModalPositions, ModalSizes } from './Modal.types';\n\n export * from './Modal.types';\n\n export interface ModalProps {\n /**\n * Hides the \"close\" button\n */\n hideClose?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n * @deprecated Use `isOpen` instead\n */\n open?: boolean;\n\n /**\n * Opens the modal when truthy; hides the modal when falsy.\n */\n isOpen?: boolean;\n\n /**\n * Use v-model:is-open or :is-open instead of :model-value and v-model.\n * @deprecated\n */\n modelValue?: boolean;\n\n /**\n * Sets a preset max-width on the modal.\n * Options: default (648px), narrow (360px), wide (960px)\n */\n size?: ModalSizes;\n\n /**\n * Should the modal be scrollable within the content area. This prop is treated as `true` when the `position` prop is set to \"left\" or \"right\".\n */\n scrollable?: boolean;\n\n /**\n * Gives the modal body have a light gray background\n */\n contrast?: boolean;\n\n /**\n * Text to display in the modal header\n */\n title?: string;\n\n /**\n * Disables the default padding in the modal body.\n */\n disableBodyPadding?: boolean;\n\n /**\n * The position on the screen to display the modal.\n */\n position?: ModalPositions;\n\n /**\n * Hide the header. Typically used with the featuredContent slot to display a graphic and create a \"promo\" modal.\n */\n hideHeader?: boolean;\n\n /**\n * Add classes to the close button. This can be used with the hideHeader prop and featuredContent slot to\n * accommodate images with different color backgrounds.\n */\n closeButtonColorClass?: string;\n\n /**\n * Prevents the modal from being dismissed by clicking the backdrop or pressing the escape key.\n * Example: There are in-flight api requests and you do not want the modal to close until they are done.\n */\n preventDismiss?: boolean;\n }\n</script>\n\n<script setup lang=\"ts\">\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, onBeforeUnmount, ref, useSlots, watch } from 'vue';\n\n import { FOCUS_ELEMENTS_SELECTOR } from '../../constants';\n import { t } from '../../locale';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({ name: 'll-modal' });\n\n const props = withDefaults(defineProps<ModalProps>(), {\n hideClose: false,\n open: false,\n isOpen: false,\n modelValue: false,\n size: 'medium',\n scrollable: false,\n contrast: false,\n title: '',\n position: 'center',\n hideHeader: false,\n closeButtonColorClass: 'text-white/50',\n preventDismiss: false,\n });\n\n const emit = defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'update:open', isOpen?: boolean): void;\n (e: 'update:is-open', isOpen?: boolean): void;\n (e: 'dismiss'): void;\n }>();\n\n const slots = useSlots();\n\n const rootRef = ref<HTMLElement>();\n const lastExternalFocusedElement = ref<HTMLElement | null>(null);\n const focusElements = ref<HTMLElement[]>([]);\n const firstFocusElement = ref<HTMLElement>();\n const lastFocusElement = ref<HTMLElement>();\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const headerId = uniqueId('modal-header-');\n const hasFooterContent = computed(() => !!slots.actions || !!slots.footer);\n const isModalOpen = computed(() => props.open || props.isOpen);\n const isDrawer = computed(() => props.position === 'left' || props.position === 'right');\n\n let isFocusTrapAttached = false;\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watch(\n isModalOpen,\n () => {\n if (typeof document === 'undefined') {\n return;\n }\n toggleHelpWidgetLauncher(isModalOpen.value ? 'hide' : 'show');\n\n if (isModalOpen.value) {\n const active = document.activeElement;\n lastExternalFocusedElement.value = active instanceof HTMLElement ? active : null;\n } else {\n if (isFocusTrapAttached) {\n document.removeEventListener('keydown', handleTab);\n isFocusTrapAttached = false;\n }\n\n lastExternalFocusedElement.value?.focus();\n }\n\n if (isModalOpen.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n height: getPageScrollingElement().style.height,\n overflow: getPageScrollingElement().style.overflow,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isModalOpen.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when modal is open\n height: isModalOpen.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when modal is open; see https://github.com/LeafLink/stash/pull/713#issuecomment-1184602535\n });\n },\n { immediate: true },\n );\n\n onBeforeUnmount(() => {\n if (typeof document === 'undefined') {\n return;\n }\n toggleHelpWidgetLauncher('show');\n\n // In cases where the watchEffect for isModalOpen isn't triggered while closing/nagivating away from modal, this ensures scrolling returns to normal\n Object.assign(getPageScrollingElement().style, {\n overflow: initialPageScrollingElementStyle.value.overflow,\n height: initialPageScrollingElementStyle.value.height,\n });\n\n // Clear focus trap tab listener\n if (isFocusTrapAttached) {\n document.removeEventListener('keydown', handleTab);\n isFocusTrapAttached = false;\n }\n\n lastExternalFocusedElement.value?.focus();\n });\n\n function dismiss() {\n if (props.preventDismiss) {\n return;\n }\n emit('update:open', false);\n emit('update:is-open', false);\n emit('dismiss');\n }\n\n function handleTab(e: KeyboardEvent) {\n if (e.key === 'Tab') {\n if (e.shiftKey && document.activeElement === firstFocusElement.value) {\n lastFocusElement.value?.focus();\n e.preventDefault();\n } else if (document.activeElement === lastFocusElement.value) {\n firstFocusElement.value?.focus();\n e.preventDefault();\n }\n }\n }\n\n function setupFocusTrap() {\n if (typeof document === 'undefined' || !rootRef.value || !isModalOpen.value) {\n return;\n }\n\n rootRef.value.focus();\n\n focusElements.value = Array.from(rootRef.value.querySelectorAll<HTMLElement>(FOCUS_ELEMENTS_SELECTOR));\n firstFocusElement.value = focusElements.value[0];\n lastFocusElement.value = focusElements.value[focusElements.value.length - 1];\n\n if (!isFocusTrapAttached) {\n document.addEventListener('keydown', handleTab);\n isFocusTrapAttached = true;\n }\n }\n\n // Ensure the Tab key cycles through focusable elements within the modal only while it is open.\n watch(rootRef, () => {\n if (!rootRef.value || !isModalOpen.value) {\n return;\n }\n\n setupFocusTrap();\n });\n\n /**\n * The customer support \"help widget launcher\" covers the action buttons in the Modal when the Modal uses a position value of \"right\" (for drawers).\n */\n function toggleHelpWidgetLauncher(nextState: 'show' | 'hide') {\n if (typeof document === 'undefined') {\n return;\n }\n const launcherElement = document.getElementById('launcher');\n\n if (!launcherElement || !launcherElement.parentElement) {\n return;\n }\n\n launcherElement.parentElement.style.display = nextState === 'show' ? 'block' : 'none';\n }\n</script>\n\n<template>\n <div\n v-if=\"isModalOpen\"\n ref=\"rootRef\"\n class=\"stash-modal fixed inset-0\"\n :class=\"{\n 'invisible z-behind': !isModalOpen,\n 'visible z-modal': isModalOpen,\n 'lg:flex lg:flex-col lg:items-center lg:justify-center': props.position === 'center',\n 'overflow-y-auto': !props.scrollable && !isDrawer,\n 'overflow-y-hidden': isDrawer,\n }\"\n data-test=\"ll-modal\"\n tabindex=\"0\"\n @keydown.esc=\"dismiss\"\n >\n <Backdrop class=\"stash-modal__backdrop\" @click.stop=\"dismiss\" />\n <div\n aria-modal=\"true\"\n role=\"dialog\"\n :aria-labelledby=\"headerId\"\n class=\"stash-modal__dialog relative flex h-screen w-full flex-col lg:shadow-3xl\"\n :class=\"[\n `stash-modal__dialog--size-${props.size}`,\n `stash-modal__dialog--position-${props.position}`,\n {\n 'stash-modal__dialog--is-open': isModalOpen,\n 'stash-modal__dialog--is-drawer': isDrawer,\n 'stash-modal__dialog--is-contrast': props.contrast,\n 'stash-modal__dialog--is-scrollable': props.scrollable,\n 'lg:w-[360px]': props.size === 'narrow',\n 'lg:w-[648px]': props.size === 'medium',\n 'lg:w-[960px]': props.size === 'wide',\n 'lg:my-0 lg:h-auto lg:max-h-[90vh]': props.position === 'center',\n // absolute causing this to break when items in bottom of container get focus\n 'lg:fixed lg:h-screen': isDrawer,\n 'lg:left-0': props.position === 'left',\n 'lg:right-0': props.position === 'right',\n },\n ]\"\n @click.stop\n >\n <header\n v-if=\"!props.hideHeader\"\n data-test=\"stash-modal__header\"\n class=\"stash-modal__header grid h-12 place-items-center bg-purple-500\"\n :class=\"{ 'lg:rounded-t': !isDrawer }\"\n >\n <div class=\"flex place-items-center\">\n <!-- @slot Adds an action to the left side of the header bar. An example usage is a modal with multiple pages and a back button can be inserted here -->\n <slot name=\"headerAction\"></slot>\n </div>\n\n <h3 v-if=\"props.title\" :id=\"headerId\" class=\"m-0 flex-1 leading-6 text-white\">\n {{ props.title }}\n </h3>\n\n <Button\n v-if=\"!props.hideClose\"\n icon\n data-test=\"ll-modal-close\"\n :title=\"t('ll.closeModal')\"\n type=\"button\"\n @click=\"dismiss\"\n >\n <Icon class=\"text-white\" name=\"close\" />\n </Button>\n </header>\n\n <Button\n v-if=\"!props.hideClose && props.hideHeader\"\n class=\"absolute right-0 top-0 z-10\"\n icon\n data-test=\"ll-modal-close\"\n type=\"button\"\n :title=\"t('ll.closeModal')\"\n @click=\"dismiss\"\n >\n <Icon class=\"drop-shadow-md\" name=\"close\" :class=\"[props.closeButtonColorClass]\" />\n </Button>\n\n <div\n v-if=\"!!slots['featured-content']\"\n class=\"stash-modal__featured-content relative\"\n :class=\"{\n 'rounded-t': props.hideHeader,\n }\"\n >\n <slot name=\"featured-content\"></slot>\n </div>\n\n <div\n class=\"stash-modal__body flex-1 overflow-y-auto\"\n :class=\"[\n {\n 'p-3 lg:p-6': !props.disableBodyPadding,\n 'lg:overflow-y-visible': !props.scrollable && !isDrawer,\n 'lg:rounded-b': !hasFooterContent && !isDrawer,\n 'bg-white': !props.contrast,\n 'bg-ice-200': props.contrast,\n },\n ]\"\n data-test=\"stash-modal__body\"\n >\n <slot></slot>\n </div>\n\n <footer\n v-if=\"hasFooterContent\"\n class=\"stash-modal__footer border-t border-ice-500 bg-ice-100 p-3 lg:p-6\"\n :class=\"{ 'lg:rounded-b': !isDrawer }\"\n >\n <!-- @slot Overrides the whole footer section. Used for rendering custom footers with more than 2 actions. If defined, \"actions\" slot will get ignored. -->\n <slot name=\"footer\">\n <div class=\"stash-modal__footer__actions flex flex-col justify-end lg:flex-row\">\n <!-- @slot Modal footer actions, supports rendering up to 2 `<Button>` children -->\n <slot name=\"actions\"></slot>\n </div>\n </slot>\n </footer>\n </div>\n </div>\n</template>\n\n<style scoped>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .stash-modal__header {\n grid-template-columns: 48px 1fr 48px;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(1) {\n order: 2;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(2) {\n margin-bottom: --spacing(3);\n order: 1;\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(1) {\n order: 1;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button):nth-of-type(2) {\n margin-bottom: 0;\n order: 2;\n }\n\n .stash-modal__footer__actions > :deep(.stash-button + .stash-button) {\n margin-left: var(--grid-gutter);\n }\n }\n\n .stash-modal__featured-content > :deep(*) {\n border-radius: inherit;\n }\n }\n</style>\n"],"names":["ModalSize","ModalPosition","props","__props","emit","__emit","slots","useSlots","rootRef","ref","lastExternalFocusedElement","focusElements","firstFocusElement","lastFocusElement","initialPageScrollingElementStyle","headerId","uniqueId","hasFooterContent","computed","isModalOpen","isDrawer","isFocusTrapAttached","getPageScrollingElement","watch","toggleHelpWidgetLauncher","active","handleTab","_a","onBeforeUnmount","dismiss","e","_b","setupFocusTrap","FOCUS_ELEMENTS_SELECTOR","nextState","launcherElement","_createElementBlock","_createVNode","Backdrop","_createElementVNode","_unref","_normalizeClass","_hoisted_2","_renderSlot","_ctx","_toDisplayString","_hoisted_3","_createBlock","Button","t","Icon","_hoisted_4"],"mappings":"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"}
|