@leaflink/stash 42.4.1 → 42.4.2
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/Alert.js +58 -55
- package/dist/Alert.js.map +1 -1
- package/dist/Alert.vue.d.ts +16 -15
- package/dist/Avatar.js +31 -29
- package/dist/Avatar.js.map +1 -1
- package/dist/Avatar.vue.d.ts +131 -24
- package/dist/Chip.js +9 -8
- package/dist/Chip.js.map +1 -1
- package/dist/Chip.vue.d.ts +126 -19
- package/dist/Dialog.vue.d.ts +1 -1
- package/dist/FilterChip.js +23 -23
- package/dist/FilterChip.js.map +1 -1
- package/dist/Modal.js +12 -12
- package/dist/Modal.js.map +1 -1
- package/dist/components.css +1 -1
- package/package.json +1 -1
package/dist/Chip.vue.d.ts
CHANGED
|
@@ -34,6 +34,17 @@ declare type __VLS_WithTemplateSlots<T, S> = T & {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export declare interface ChipProps {
|
|
37
|
+
/**
|
|
38
|
+
* The color for the chip that determines both the text and bg color. Needs to
|
|
39
|
+
* be one of the brand colors in our design system (not a shade).
|
|
40
|
+
*/
|
|
41
|
+
color?: StashPrimaryColor;
|
|
42
|
+
/**
|
|
43
|
+
* The shade of the provided color to use for the background color. This effects the inferred
|
|
44
|
+
* text color unless a specific text color is provided. Currently only `light` and `main`
|
|
45
|
+
* shades are supported. `dark` may be added in the future.
|
|
46
|
+
*/
|
|
47
|
+
shade?: 'light' | 'main';
|
|
37
48
|
/**
|
|
38
49
|
* The size of the chip.
|
|
39
50
|
*/
|
|
@@ -45,22 +56,11 @@ export declare interface ChipProps {
|
|
|
45
56
|
/**
|
|
46
57
|
* The background color of the chip. Needs to be one of our design system colors.
|
|
47
58
|
*/
|
|
48
|
-
bgColor?:
|
|
49
|
-
/**
|
|
50
|
-
* The shade of the provided color to use for the background color. This effects the inferred
|
|
51
|
-
* text color unless a specific text color is provided. Currently only `light` and `main`
|
|
52
|
-
* shades are supported. `dark` may be added in the future.
|
|
53
|
-
*/
|
|
54
|
-
shade?: 'light' | 'main';
|
|
55
|
-
/**
|
|
56
|
-
* The color for the chip that determines both the text and bg color. Needs to
|
|
57
|
-
* be one of the brand colors in our design system (not a shade).
|
|
58
|
-
*/
|
|
59
|
-
color?: StashPrimaryColor;
|
|
59
|
+
bgColor?: StashColor;
|
|
60
60
|
/**
|
|
61
61
|
* The color of the chip text. Needs to be one of our design system colors.
|
|
62
62
|
*/
|
|
63
|
-
textColor?:
|
|
63
|
+
textColor?: StashColor;
|
|
64
64
|
/**
|
|
65
65
|
* Determines if a close icon is surfaced.
|
|
66
66
|
*/
|
|
@@ -76,8 +76,8 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<__VLS_WithDefaul
|
|
|
76
76
|
radius: string;
|
|
77
77
|
color: StashPrimaryColors;
|
|
78
78
|
shade: string;
|
|
79
|
-
bgColor:
|
|
80
|
-
textColor:
|
|
79
|
+
bgColor: undefined;
|
|
80
|
+
textColor: undefined;
|
|
81
81
|
isRemovable: boolean;
|
|
82
82
|
shouldOverrideColors: boolean;
|
|
83
83
|
}>, {}, unknown, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
@@ -88,8 +88,8 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<__VLS_WithDefaul
|
|
|
88
88
|
radius: string;
|
|
89
89
|
color: StashPrimaryColors;
|
|
90
90
|
shade: string;
|
|
91
|
-
bgColor:
|
|
92
|
-
textColor:
|
|
91
|
+
bgColor: undefined;
|
|
92
|
+
textColor: undefined;
|
|
93
93
|
isRemovable: boolean;
|
|
94
94
|
shouldOverrideColors: boolean;
|
|
95
95
|
}>>> & {
|
|
@@ -100,8 +100,8 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<__VLS_WithDefaul
|
|
|
100
100
|
size: "small" | "medium";
|
|
101
101
|
shade: "main" | "light";
|
|
102
102
|
radius: "standard" | "none" | "pill";
|
|
103
|
-
bgColor:
|
|
104
|
-
textColor:
|
|
103
|
+
bgColor: "blue" | "red" | "ice-700" | "green" | "royal" | "purple" | "ice" | "orange" | "seafoam" | "teal" | "yellow" | "purple-900" | "purple-800" | "purple-700" | "purple-600" | "purple-500" | "purple-400" | "purple-300" | "purple-200" | "purple-100" | "royal-900" | "royal-800" | "royal-700" | "royal-600" | "royal-500" | "royal-400" | "royal-300" | "royal-200" | "royal-100" | "blue-900" | "blue-800" | "blue-700" | "blue-600" | "blue-500" | "blue-400" | "blue-300" | "blue-200" | "blue-100" | "teal-900" | "teal-800" | "teal-700" | "teal-600" | "teal-500" | "teal-400" | "teal-300" | "teal-200" | "teal-100" | "green-900" | "green-800" | "green-700" | "green-600" | "green-500" | "green-400" | "green-300" | "green-200" | "green-100" | "seafoam-900" | "seafoam-800" | "seafoam-700" | "seafoam-600" | "seafoam-500" | "seafoam-400" | "seafoam-300" | "seafoam-200" | "seafoam-100" | "yellow-900" | "yellow-800" | "yellow-700" | "yellow-600" | "yellow-500" | "yellow-400" | "yellow-300" | "yellow-200" | "yellow-100" | "orange-900" | "orange-800" | "orange-700" | "orange-600" | "orange-500" | "orange-400" | "orange-300" | "orange-200" | "orange-100" | "red-900" | "red-800" | "red-700" | "red-600" | "red-500" | "red-400" | "red-300" | "red-200" | "red-100" | "ice-900" | "ice-800" | "ice-600" | "ice-500" | "ice-400" | "ice-300" | "ice-200" | "ice-100" | "white" | "black";
|
|
104
|
+
textColor: "blue" | "red" | "ice-700" | "green" | "royal" | "purple" | "ice" | "orange" | "seafoam" | "teal" | "yellow" | "purple-900" | "purple-800" | "purple-700" | "purple-600" | "purple-500" | "purple-400" | "purple-300" | "purple-200" | "purple-100" | "royal-900" | "royal-800" | "royal-700" | "royal-600" | "royal-500" | "royal-400" | "royal-300" | "royal-200" | "royal-100" | "blue-900" | "blue-800" | "blue-700" | "blue-600" | "blue-500" | "blue-400" | "blue-300" | "blue-200" | "blue-100" | "teal-900" | "teal-800" | "teal-700" | "teal-600" | "teal-500" | "teal-400" | "teal-300" | "teal-200" | "teal-100" | "green-900" | "green-800" | "green-700" | "green-600" | "green-500" | "green-400" | "green-300" | "green-200" | "green-100" | "seafoam-900" | "seafoam-800" | "seafoam-700" | "seafoam-600" | "seafoam-500" | "seafoam-400" | "seafoam-300" | "seafoam-200" | "seafoam-100" | "yellow-900" | "yellow-800" | "yellow-700" | "yellow-600" | "yellow-500" | "yellow-400" | "yellow-300" | "yellow-200" | "yellow-100" | "orange-900" | "orange-800" | "orange-700" | "orange-600" | "orange-500" | "orange-400" | "orange-300" | "orange-200" | "orange-100" | "red-900" | "red-800" | "red-700" | "red-600" | "red-500" | "red-400" | "red-300" | "red-200" | "red-100" | "ice-900" | "ice-800" | "ice-600" | "ice-500" | "ice-400" | "ice-300" | "ice-200" | "ice-100" | "white" | "black";
|
|
105
105
|
isRemovable: boolean;
|
|
106
106
|
shouldOverrideColors: boolean;
|
|
107
107
|
}, {}>, {
|
|
@@ -109,6 +109,113 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<__VLS_WithDefaul
|
|
|
109
109
|
}>;
|
|
110
110
|
export default _default;
|
|
111
111
|
|
|
112
|
+
declare type StashColor = `${StashColors}`;
|
|
113
|
+
|
|
114
|
+
declare enum StashColors {
|
|
115
|
+
Purple = "purple",
|
|
116
|
+
Purple900 = "purple-900",
|
|
117
|
+
Purple800 = "purple-800",
|
|
118
|
+
Purple700 = "purple-700",
|
|
119
|
+
Purple600 = "purple-600",
|
|
120
|
+
Purple500 = "purple-500",
|
|
121
|
+
Purple400 = "purple-400",
|
|
122
|
+
Purple300 = "purple-300",
|
|
123
|
+
Purple200 = "purple-200",
|
|
124
|
+
Purple100 = "purple-100",
|
|
125
|
+
Royal = "royal",
|
|
126
|
+
Royal900 = "royal-900",
|
|
127
|
+
Royal800 = "royal-800",
|
|
128
|
+
Royal700 = "royal-700",
|
|
129
|
+
Royal600 = "royal-600",
|
|
130
|
+
Royal500 = "royal-500",
|
|
131
|
+
Royal400 = "royal-400",
|
|
132
|
+
Royal300 = "royal-300",
|
|
133
|
+
Royal200 = "royal-200",
|
|
134
|
+
Royal100 = "royal-100",
|
|
135
|
+
Blue = "blue",
|
|
136
|
+
Blue900 = "blue-900",
|
|
137
|
+
Blue800 = "blue-800",
|
|
138
|
+
Blue700 = "blue-700",
|
|
139
|
+
Blue600 = "blue-600",
|
|
140
|
+
Blue500 = "blue-500",
|
|
141
|
+
Blue400 = "blue-400",
|
|
142
|
+
Blue300 = "blue-300",
|
|
143
|
+
Blue200 = "blue-200",
|
|
144
|
+
Blue100 = "blue-100",
|
|
145
|
+
Teal = "teal",
|
|
146
|
+
Teal900 = "teal-900",
|
|
147
|
+
Teal800 = "teal-800",
|
|
148
|
+
Teal700 = "teal-700",
|
|
149
|
+
Teal600 = "teal-600",
|
|
150
|
+
Teal500 = "teal-500",
|
|
151
|
+
Teal400 = "teal-400",
|
|
152
|
+
Teal300 = "teal-300",
|
|
153
|
+
Teal200 = "teal-200",
|
|
154
|
+
Teal100 = "teal-100",
|
|
155
|
+
Green = "green",
|
|
156
|
+
Green900 = "green-900",
|
|
157
|
+
Green800 = "green-800",
|
|
158
|
+
Green700 = "green-700",
|
|
159
|
+
Green600 = "green-600",
|
|
160
|
+
Green500 = "green-500",
|
|
161
|
+
Green400 = "green-400",
|
|
162
|
+
Green300 = "green-300",
|
|
163
|
+
Green200 = "green-200",
|
|
164
|
+
Green100 = "green-100",
|
|
165
|
+
Seafoam = "seafoam",
|
|
166
|
+
Seafoam900 = "seafoam-900",
|
|
167
|
+
Seafoam800 = "seafoam-800",
|
|
168
|
+
Seafoam700 = "seafoam-700",
|
|
169
|
+
Seafoam600 = "seafoam-600",
|
|
170
|
+
Seafoam500 = "seafoam-500",
|
|
171
|
+
Seafoam400 = "seafoam-400",
|
|
172
|
+
Seafoam300 = "seafoam-300",
|
|
173
|
+
Seafoam200 = "seafoam-200",
|
|
174
|
+
Seafoam100 = "seafoam-100",
|
|
175
|
+
Yellow = "yellow",
|
|
176
|
+
Yellow900 = "yellow-900",
|
|
177
|
+
Yellow800 = "yellow-800",
|
|
178
|
+
Yellow700 = "yellow-700",
|
|
179
|
+
Yellow600 = "yellow-600",
|
|
180
|
+
Yellow500 = "yellow-500",
|
|
181
|
+
Yellow400 = "yellow-400",
|
|
182
|
+
Yellow300 = "yellow-300",
|
|
183
|
+
Yellow200 = "yellow-200",
|
|
184
|
+
Yellow100 = "yellow-100",
|
|
185
|
+
Orange = "orange",
|
|
186
|
+
Orange900 = "orange-900",
|
|
187
|
+
Orange800 = "orange-800",
|
|
188
|
+
Orange700 = "orange-700",
|
|
189
|
+
Orange600 = "orange-600",
|
|
190
|
+
Orange500 = "orange-500",
|
|
191
|
+
Orange400 = "orange-400",
|
|
192
|
+
Orange300 = "orange-300",
|
|
193
|
+
Orange200 = "orange-200",
|
|
194
|
+
Orange100 = "orange-100",
|
|
195
|
+
Red = "red",
|
|
196
|
+
Red900 = "red-900",
|
|
197
|
+
Red800 = "red-800",
|
|
198
|
+
Red700 = "red-700",
|
|
199
|
+
Red600 = "red-600",
|
|
200
|
+
Red500 = "red-500",
|
|
201
|
+
Red400 = "red-400",
|
|
202
|
+
Red300 = "red-300",
|
|
203
|
+
Red200 = "red-200",
|
|
204
|
+
Red100 = "red-100",
|
|
205
|
+
Ice = "ice",
|
|
206
|
+
Ice900 = "ice-900",
|
|
207
|
+
Ice800 = "ice-800",
|
|
208
|
+
Ice700 = "ice-700",
|
|
209
|
+
Ice600 = "ice-600",
|
|
210
|
+
Ice500 = "ice-500",
|
|
211
|
+
Ice400 = "ice-400",
|
|
212
|
+
Ice300 = "ice-300",
|
|
213
|
+
Ice200 = "ice-200",
|
|
214
|
+
Ice100 = "ice-100",
|
|
215
|
+
White = "white",
|
|
216
|
+
Black = "black"
|
|
217
|
+
}
|
|
218
|
+
|
|
112
219
|
declare type StashPrimaryColor = `${StashPrimaryColors}`;
|
|
113
220
|
|
|
114
221
|
/**
|
package/dist/Dialog.vue.d.ts
CHANGED
|
@@ -64,10 +64,10 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<__VLS_WithDefaul
|
|
|
64
64
|
disabled: boolean;
|
|
65
65
|
description: string;
|
|
66
66
|
open: boolean;
|
|
67
|
-
alert: boolean;
|
|
68
67
|
dangerZone: boolean;
|
|
69
68
|
cancelText: string;
|
|
70
69
|
confirmText: string;
|
|
70
|
+
alert: boolean;
|
|
71
71
|
status: "error" | "warning" | "info" | "success";
|
|
72
72
|
}, {}>, {
|
|
73
73
|
default?(_: {}): any;
|
package/dist/FilterChip.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { defineComponent as u, useCssModule as f, computed as
|
|
1
|
+
import { defineComponent as u, useCssModule as f, computed as h, openBlock as s, createBlock as w, normalizeClass as r, unref as t, withCtx as v, createElementVNode as b, renderSlot as C, createElementBlock as i, toDisplayString as k, createCommentVNode as n, createVNode as y } from "vue";
|
|
2
2
|
import { t as c } from "./locale.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { _ as
|
|
3
|
+
import D from "./Chip.js";
|
|
4
|
+
import x from "./Icon.js";
|
|
5
|
+
import { _ as B } from "./_plugin-vue_export-helper-dad06003.js";
|
|
6
6
|
import "./get-27d90892.js";
|
|
7
7
|
import "./isObjectLike-54341556.js";
|
|
8
8
|
import "./toString-7d5bf363.js";
|
|
@@ -12,7 +12,7 @@ import "./utils/colorScheme.js";
|
|
|
12
12
|
import "./Icon.vue_used_vue_type_style_index_0_lang.module-d2507af3.js";
|
|
13
13
|
import "./uniqueId-847efe53.js";
|
|
14
14
|
import "./index-79ce320f.js";
|
|
15
|
-
const
|
|
15
|
+
const F = { class: "tw-flex tw-items-center" }, O = ["aria-label", "title"], R = { key: 1 }, S = /* @__PURE__ */ u({
|
|
16
16
|
__name: "FilterChip",
|
|
17
17
|
props: {
|
|
18
18
|
filterCount: { default: void 0 },
|
|
@@ -23,14 +23,14 @@ const x = { class: "tw-flex tw-items-center" }, B = ["aria-label", "title"], F =
|
|
|
23
23
|
},
|
|
24
24
|
emits: ["click", "remove"],
|
|
25
25
|
setup(d, { emit: l }) {
|
|
26
|
-
const e = d, o = f(), a =
|
|
26
|
+
const e = d, o = f(), a = h(() => Number(e.filterCount) > 0);
|
|
27
27
|
function p() {
|
|
28
28
|
l("click");
|
|
29
29
|
}
|
|
30
30
|
function m() {
|
|
31
31
|
l("remove");
|
|
32
32
|
}
|
|
33
|
-
return (_,
|
|
33
|
+
return (_, A) => (s(), w(D, {
|
|
34
34
|
"should-override-colors": "",
|
|
35
35
|
tabindex: "0",
|
|
36
36
|
class: r(["stash-filter-chip tw-leading-5 tw-text-sm tw-font-normal tw-text-ice-900 tw-normal-case", [
|
|
@@ -49,7 +49,7 @@ const x = { class: "tw-flex tw-items-center" }, B = ["aria-label", "title"], F =
|
|
|
49
49
|
onRemove: m
|
|
50
50
|
}, {
|
|
51
51
|
default: v(() => [
|
|
52
|
-
b("div",
|
|
52
|
+
b("div", F, [
|
|
53
53
|
C(_.$slots, "default"),
|
|
54
54
|
a.value ? (s(), i("span", {
|
|
55
55
|
key: 0,
|
|
@@ -57,9 +57,9 @@ const x = { class: "tw-flex tw-items-center" }, B = ["aria-label", "title"], F =
|
|
|
57
57
|
class: r(t(o)["filter-count"]),
|
|
58
58
|
"aria-label": t(c)("ll.numberOfActiveFilters"),
|
|
59
59
|
title: t(c)("ll.numberOfActiveFilters")
|
|
60
|
-
}, k(e.filterCount), 11,
|
|
61
|
-
e.hasDropdown ? (s(), i("span",
|
|
62
|
-
y(
|
|
60
|
+
}, k(e.filterCount), 11, O)) : n("", !0),
|
|
61
|
+
e.hasDropdown ? (s(), i("span", R, [
|
|
62
|
+
y(x, {
|
|
63
63
|
"data-test": "icon|caret",
|
|
64
64
|
name: "caret-down",
|
|
65
65
|
class: r([
|
|
@@ -75,18 +75,18 @@ const x = { class: "tw-flex tw-items-center" }, B = ["aria-label", "title"], F =
|
|
|
75
75
|
_: 3
|
|
76
76
|
}, 8, ["class", "is-removable"]));
|
|
77
77
|
}
|
|
78
|
-
}),
|
|
79
|
-
root:
|
|
80
|
-
"is-selected": "_is-
|
|
81
|
-
"is-removable": "_is-
|
|
82
|
-
"has-filter-count": "_has-filter-
|
|
83
|
-
"has-dropdown": "_has-
|
|
84
|
-
"filter-count": "_filter-
|
|
85
|
-
caret:
|
|
86
|
-
"caret-rotate": "_caret-
|
|
87
|
-
},
|
|
88
|
-
$style:
|
|
89
|
-
}, U = /* @__PURE__ */
|
|
78
|
+
}), N = "_root_1o49d_5", M = "_caret_1o49d_94", V = {
|
|
79
|
+
root: N,
|
|
80
|
+
"is-selected": "_is-selected_1o49d_24",
|
|
81
|
+
"is-removable": "_is-removable_1o49d_36",
|
|
82
|
+
"has-filter-count": "_has-filter-count_1o49d_49",
|
|
83
|
+
"has-dropdown": "_has-dropdown_1o49d_54",
|
|
84
|
+
"filter-count": "_filter-count_1o49d_67",
|
|
85
|
+
caret: M,
|
|
86
|
+
"caret-rotate": "_caret-rotate_1o49d_105"
|
|
87
|
+
}, g = {
|
|
88
|
+
$style: V
|
|
89
|
+
}, U = /* @__PURE__ */ B(S, [["__cssModules", g]]);
|
|
90
90
|
export {
|
|
91
91
|
U as default
|
|
92
92
|
};
|
package/dist/FilterChip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterChip.js","sources":["../src/components/FilterChip/FilterChip.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import Chip from '../Chip/Chip.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface FilterChipProps {\n /**\n * Used for conditionally rendering filter count chip\n */\n filterCount?: number;\n\n /**\n * Use for conditionally rendering caret\n */\n hasDropdown?: boolean;\n\n /**\n * Used for styling when `hasDropdown` is true\n */\n isDropdownOpen?: boolean;\n\n /**\n * Used for conditionally rendering close icon and exposing remove event\n */\n isRemovable?: boolean;\n\n /**\n * Used for conditionally applying styles\n */\n isSelected?: boolean;\n }\n\n const props = withDefaults(defineProps<FilterChipProps>(), {\n filterCount: undefined,\n hasDropdown: false,\n isDropdownOpen: false,\n isRemovable: false,\n isSelected: false,\n });\n\n const emit =\n defineEmits<{\n (e: 'click'): void;\n (e: 'remove'): void;\n }>();\n\n const classes = useCssModule();\n const hasFilterCount = computed(() => Number(props.filterCount) > 0);\n\n function handleClick() {\n emit('click');\n }\n\n function handleRemove() {\n emit('remove');\n }\n</script>\n\n<template>\n <Chip\n should-override-colors\n tabindex=\"0\"\n class=\"stash-filter-chip tw-leading-5 tw-text-sm tw-font-normal tw-text-ice-900 tw-normal-case\"\n radius=\"pill\"\n :class=\"[\n classes.root,\n {\n [classes['is-selected']]: props.isSelected,\n [classes['is-removable']]: props.isRemovable,\n [classes['is-dropdown-open']]: props.isDropdownOpen,\n [classes['has-dropdown']]: props.hasDropdown,\n [classes['has-filter-count']]: hasFilterCount,\n },\n ]\"\n :is-removable=\"props.isSelected && props.isRemovable && !props.hasDropdown\"\n @click=\"handleClick\"\n @remove=\"handleRemove\"\n >\n <div class=\"tw-flex tw-items-center\">\n <!-- @slot default -->\n <slot></slot>\n\n <span\n v-if=\"hasFilterCount\"\n data-test=\"span|filter-count\"\n :class=\"classes['filter-count']\"\n :aria-label=\"t('ll.numberOfActiveFilters')\"\n :title=\"t('ll.numberOfActiveFilters')\"\n >\n {{ props.filterCount }}\n </span>\n\n <span v-if=\"props.hasDropdown\">\n <Icon\n data-test=\"icon|caret\"\n name=\"caret-down\"\n :class=\"[\n classes.caret,\n {\n [classes['caret-rotate']]: props.isDropdownOpen,\n },\n ]\"\n />\n </span>\n </div>\n </Chip>\n</template>\n\n<style module>\n /**\n many styles declared here are overriding styles defined in Chip\n */\n .root {\n background-color: var(--color-white);\n border: 1px solid var(--color-ice);\n cursor: pointer;\n height: var(--ll-space-4);\n padding-left: var(--ll-space-2);\n padding-right: var(--ll-space-2);\n }\n\n .root:focus {\n box-shadow: 0 0 0 4px rgb(0 123 255 / 15%);\n outline: none;\n }\n\n .root:hover {\n background-color: var(--color-blue-100);\n border: 1px solid var(--color-blue-500);\n }\n\n .root.is-selected {\n color: var(--color-white);\n background-color: var(--color-blue-500);\n border: 1px solid var(--color-blue-500);\n }\n\n .root.is-selected:hover {\n color: var(--color-white);\n background-color: var(--color-blue-700);\n border: 1px solid var(--color-blue-700);\n }\n\n .root.is-selected.is-removable {\n background-color: var(--color-blue-500);\n }\n\n .root.is-selected.is-removable :global(.stash-
|
|
1
|
+
{"version":3,"file":"FilterChip.js","sources":["../src/components/FilterChip/FilterChip.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import Chip from '../Chip/Chip.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface FilterChipProps {\n /**\n * Used for conditionally rendering filter count chip\n */\n filterCount?: number;\n\n /**\n * Use for conditionally rendering caret\n */\n hasDropdown?: boolean;\n\n /**\n * Used for styling when `hasDropdown` is true\n */\n isDropdownOpen?: boolean;\n\n /**\n * Used for conditionally rendering close icon and exposing remove event\n */\n isRemovable?: boolean;\n\n /**\n * Used for conditionally applying styles\n */\n isSelected?: boolean;\n }\n\n const props = withDefaults(defineProps<FilterChipProps>(), {\n filterCount: undefined,\n hasDropdown: false,\n isDropdownOpen: false,\n isRemovable: false,\n isSelected: false,\n });\n\n const emit =\n defineEmits<{\n (e: 'click'): void;\n (e: 'remove'): void;\n }>();\n\n const classes = useCssModule();\n const hasFilterCount = computed(() => Number(props.filterCount) > 0);\n\n function handleClick() {\n emit('click');\n }\n\n function handleRemove() {\n emit('remove');\n }\n</script>\n\n<template>\n <Chip\n should-override-colors\n tabindex=\"0\"\n class=\"stash-filter-chip tw-leading-5 tw-text-sm tw-font-normal tw-text-ice-900 tw-normal-case\"\n radius=\"pill\"\n :class=\"[\n classes.root,\n {\n [classes['is-selected']]: props.isSelected,\n [classes['is-removable']]: props.isRemovable,\n [classes['is-dropdown-open']]: props.isDropdownOpen,\n [classes['has-dropdown']]: props.hasDropdown,\n [classes['has-filter-count']]: hasFilterCount,\n },\n ]\"\n :is-removable=\"props.isSelected && props.isRemovable && !props.hasDropdown\"\n @click=\"handleClick\"\n @remove=\"handleRemove\"\n >\n <div class=\"tw-flex tw-items-center\">\n <!-- @slot default -->\n <slot></slot>\n\n <span\n v-if=\"hasFilterCount\"\n data-test=\"span|filter-count\"\n :class=\"classes['filter-count']\"\n :aria-label=\"t('ll.numberOfActiveFilters')\"\n :title=\"t('ll.numberOfActiveFilters')\"\n >\n {{ props.filterCount }}\n </span>\n\n <span v-if=\"props.hasDropdown\">\n <Icon\n data-test=\"icon|caret\"\n name=\"caret-down\"\n :class=\"[\n classes.caret,\n {\n [classes['caret-rotate']]: props.isDropdownOpen,\n },\n ]\"\n />\n </span>\n </div>\n </Chip>\n</template>\n\n<style module>\n /**\n many styles declared here are overriding styles defined in Chip\n */\n .root {\n background-color: var(--color-white);\n border: 1px solid var(--color-ice);\n cursor: pointer;\n height: var(--ll-space-4);\n padding-left: var(--ll-space-2);\n padding-right: var(--ll-space-2);\n }\n\n .root:focus {\n box-shadow: 0 0 0 4px rgb(0 123 255 / 15%);\n outline: none;\n }\n\n .root:hover {\n background-color: var(--color-blue-100);\n border: 1px solid var(--color-blue-500);\n }\n\n .root.is-selected {\n color: var(--color-white);\n background-color: var(--color-blue-500);\n border: 1px solid var(--color-blue-500);\n }\n\n .root.is-selected:hover {\n color: var(--color-white);\n background-color: var(--color-blue-700);\n border: 1px solid var(--color-blue-700);\n }\n\n .root.is-selected.is-removable {\n background-color: var(--color-blue-500);\n }\n\n .root.is-selected.is-removable :global(.stash-chip__remove-button) {\n margin-right: -1px;\n padding-right: var(--ll-space-2);\n }\n\n .root.is-selected.is-removable :global(.stash-chip__remove-button):hover {\n background-color: var(--color-blue-700);\n }\n\n .root.is-selected.has-filter-count:hover {\n background-color: var(--color-blue-700);\n color: var(--color-white);\n }\n\n .root.has-dropdown {\n padding-right: var(--ll-space-1);\n }\n\n .root.has-filter-count:hover {\n background-color: var(--color-blue-100);\n color: var(--color-ice-900);\n }\n\n .root label {\n cursor: pointer;\n }\n\n .filter-count {\n display: inline-flex;\n align-items: center;\n border-radius: 5em;\n height: 16px;\n padding: 0 8px;\n margin-left: var(--ll-space-1);\n font-size: 10px;\n font-weight: bold;\n background-color: var(--color-blue-500);\n color: var(--color-white);\n }\n\n .is-selected .filter-count {\n background-color: var(--color-blue-700);\n }\n\n .is-selected:hover .filter-count {\n background-color: var(--color-white);\n color: var(--color-blue-700);\n }\n\n .is-selected.is-removable .filter-count {\n background-color: var(--color-blue-700);\n color: var(--color-white);\n }\n\n .caret {\n color: var(--color-ice-700);\n margin-left: var(--ll-space-1);\n transform: rotate(0);\n transition: all 0.5s;\n }\n\n .is-selected .caret {\n color: var(--color-white);\n }\n\n .caret-rotate {\n transform: rotate(-180deg);\n }\n</style>\n"],"names":["classes","useCssModule","hasFilterCount","computed","props","handleClick","emit","handleRemove"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;iBAgDQA,IAAUC,KACVC,IAAiBC,EAAS,MAAM,OAAOC,EAAM,WAAW,IAAI,CAAC;AAEnE,aAASC,IAAc;AACrB,MAAAC,EAAK,OAAO;AAAA,IACd;AAEA,aAASC,IAAe;AACtB,MAAAD,EAAK,QAAQ;AAAA,IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/Modal.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent as H, useSlots as I, ref as d, computed as x, watch as $, onBeforeUnmount as K, openBlock as a, createElementBlock as
|
|
1
|
+
import { defineComponent as H, useSlots as I, ref as d, computed as x, watch as $, onBeforeUnmount as K, openBlock as a, createElementBlock as w, normalizeClass as s, withKeys as R, createVNode as C, withModifiers as j, createElementVNode as g, unref as f, renderSlot as m, toDisplayString as T, createCommentVNode as i, createBlock as F, withCtx as L } from "vue";
|
|
2
2
|
import { u as V } from "./uniqueId-847efe53.js";
|
|
3
3
|
import { FOCUS_ELEMENTS_SELECTOR as A } from "./constants.js";
|
|
4
4
|
import { t as M } from "./locale.js";
|
|
@@ -68,7 +68,7 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
68
68
|
var c, S;
|
|
69
69
|
t.key === "Tab" && (t.shiftKey && document.activeElement === b.value ? ((c = k.value) == null || c.focus(), t.preventDefault()) : document.activeElement === k.value && ((S = b.value) == null || S.focus(), t.preventDefault()));
|
|
70
70
|
}
|
|
71
|
-
return (t, c) => l.value ? (a(),
|
|
71
|
+
return (t, c) => l.value ? (a(), w("div", {
|
|
72
72
|
key: 0,
|
|
73
73
|
ref_key: "rootRef",
|
|
74
74
|
ref: r,
|
|
@@ -88,7 +88,7 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
88
88
|
g("div", {
|
|
89
89
|
"aria-modal": "true",
|
|
90
90
|
role: "dialog",
|
|
91
|
-
"aria-labelledby":
|
|
91
|
+
"aria-labelledby": f(B),
|
|
92
92
|
class: s(["stash-modal__dialog tw-flex tw-flex-col tw-h-screen tw-w-full lg:tw-shadow tw-relative", [
|
|
93
93
|
`stash-modal__dialog--size-${e.size}`,
|
|
94
94
|
`stash-modal__dialog--position-${e.position}`,
|
|
@@ -109,7 +109,7 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
109
109
|
onClick: c[0] || (c[0] = j(() => {
|
|
110
110
|
}, ["stop"]))
|
|
111
111
|
}, [
|
|
112
|
-
e.hideHeader ? i("", !0) : (a(),
|
|
112
|
+
e.hideHeader ? i("", !0) : (a(), w("header", {
|
|
113
113
|
key: 0,
|
|
114
114
|
"data-test": "stash-modal__header",
|
|
115
115
|
class: s(["stash-modal__header tw-bg-purple tw-h-12 tw-grid tw-place-items-center", { "lg:tw-rounded-t": !n.value }])
|
|
@@ -117,16 +117,16 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
117
117
|
g("div", Q, [
|
|
118
118
|
m(t.$slots, "headerAction", {}, void 0, !0)
|
|
119
119
|
]),
|
|
120
|
-
e.title ? (a(),
|
|
120
|
+
e.title ? (a(), w("h3", {
|
|
121
121
|
key: 0,
|
|
122
|
-
id:
|
|
122
|
+
id: f(B),
|
|
123
123
|
class: "tw-text-white tw-flex-1 tw-leading-6 tw-m-0"
|
|
124
124
|
}, T(e.title), 9, X)) : i("", !0),
|
|
125
125
|
e.hideClose ? i("", !0) : (a(), F(N, {
|
|
126
126
|
key: 1,
|
|
127
127
|
icon: "",
|
|
128
128
|
"data-test": "ll-modal-close",
|
|
129
|
-
title:
|
|
129
|
+
title: f(M)("ll.closeModal"),
|
|
130
130
|
type: "button",
|
|
131
131
|
onClick: v
|
|
132
132
|
}, {
|
|
@@ -145,7 +145,7 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
145
145
|
icon: "",
|
|
146
146
|
"data-test": "ll-modal-close",
|
|
147
147
|
type: "button",
|
|
148
|
-
title:
|
|
148
|
+
title: f(M)("ll.closeModal"),
|
|
149
149
|
onClick: v
|
|
150
150
|
}, {
|
|
151
151
|
default: L(() => [
|
|
@@ -156,7 +156,7 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
156
156
|
]),
|
|
157
157
|
_: 1
|
|
158
158
|
}, 8, ["title"])) : i("", !0),
|
|
159
|
-
|
|
159
|
+
f(y)["featured-content"] ? (a(), w("div", {
|
|
160
160
|
key: 2,
|
|
161
161
|
class: s(["tw-relative stash-modal__featured-content", {
|
|
162
162
|
"tw-rounded-t": e.hideHeader
|
|
@@ -178,9 +178,9 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
178
178
|
}, [
|
|
179
179
|
m(t.$slots, "default", {}, void 0, !0)
|
|
180
180
|
], 2),
|
|
181
|
-
z.value ? (a(),
|
|
181
|
+
z.value ? (a(), w("footer", {
|
|
182
182
|
key: 3,
|
|
183
|
-
class: s(["stash-modal__footer tw-bg-ice-
|
|
183
|
+
class: s(["stash-modal__footer tw-bg-ice-100 tw-border-ice-500 tw-p-3 lg:tw-p-6", { "lg:tw-rounded-b": !n.value }])
|
|
184
184
|
}, [
|
|
185
185
|
m(t.$slots, "footer", {}, () => [
|
|
186
186
|
g("div", Y, [
|
|
@@ -192,7 +192,7 @@ const G = ["onKeydown"], J = ["aria-labelledby"], Q = { class: "tw-flex tw-place
|
|
|
192
192
|
], 42, G)) : i("", !0);
|
|
193
193
|
}
|
|
194
194
|
});
|
|
195
|
-
const pe = /* @__PURE__ */ P(Z, [["__scopeId", "data-v-
|
|
195
|
+
const pe = /* @__PURE__ */ P(Z, [["__scopeId", "data-v-c53d57a8"]]);
|
|
196
196
|
export {
|
|
197
197
|
W as ModalPosition,
|
|
198
198
|
U as ModalSize,
|
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</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: 'tw-text-white/50',\n });\n\n const emit =\n 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 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 // 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 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</script>\n\n<template>\n <div\n v-if=\"isModalOpen\"\n ref=\"rootRef\"\n class=\"stash-modal tw-fixed tw-inset-0 tw-overflow-y-auto\"\n :class=\"{\n 'tw-invisible tw-z-behind': !isModalOpen,\n 'tw-visible tw-z-modal': isModalOpen,\n 'lg:tw-flex lg:tw-flex-col lg:tw-justify-center lg:tw-items-center': props.position === 'center',\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 tw-flex tw-flex-col tw-h-screen tw-w-full lg:tw-shadow tw-relative\"\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:tw-w-[360px]': props.size === 'narrow',\n 'lg:tw-w-[648px]': props.size === 'medium',\n 'lg:tw-w-[960px]': props.size === 'wide',\n 'lg:tw-h-auto lg:tw-my-0 lg:tw-max-h-[90vh]': props.position === 'center',\n 'lg:tw-h-screen lg:tw-absolute': isDrawer,\n 'lg:tw-left-0': props.position === 'left',\n 'lg:tw-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 tw-bg-purple tw-h-12 tw-grid tw-place-items-center\"\n :class=\"{ 'lg:tw-rounded-t': !isDrawer }\"\n >\n <div class=\"tw-flex tw-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=\"tw-text-white tw-flex-1 tw-leading-6 tw-m-0\">\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=\"tw-text-white\" name=\"close\" />\n </Button>\n </header>\n\n <Button\n v-if=\"!props.hideClose && props.hideHeader\"\n class=\"tw-absolute tw-right-0 tw-top-0 tw-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=\"tw-drop-shadow-md\" name=\"close\" :class=\"[props.closeButtonColorClass]\" />\n </Button>\n\n <div\n v-if=\"!!slots['featured-content']\"\n class=\"tw-relative stash-modal__featured-content\"\n :class=\"{\n 'tw-rounded-t': props.hideHeader,\n }\"\n >\n <slot name=\"featured-content\"></slot>\n </div>\n\n <div\n class=\"stash-modal__body tw-flex-1 tw-overflow-y-auto\"\n :class=\"[\n {\n 'tw-p-3 lg:tw-p-6': !props.disableBodyPadding,\n 'lg:tw-overflow-y-visible': !props.scrollable && !isDrawer,\n 'lg:tw-rounded-b': !hasFooterContent && !isDrawer,\n 'tw-bg-white': !props.contrast,\n 'tw-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 tw-bg-ice-200 tw-border-ice-500 tw-p-3 lg:tw-p-6\"\n :class=\"{ 'lg:tw-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 tw-flex tw-flex-col tw-justify-end lg:tw-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 .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: var(--ll-space-2);\n order: 1;\n }\n\n @media screen and (width >= 961px) {\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</style>\n"],"names":["ModalSize","ModalPosition","slots","useSlots","rootRef","ref","lastExternalFocusedElement","focusElements","firstFocusElement","lastFocusElement","initialPageScrollingElementStyle","headerId","uniqueId","hasFooterContent","computed","isModalOpen","props","isDrawer","getPageScrollingElement","watch","onBeforeUnmount","handleTab","_a","dismiss","emit","FOCUS_ELEMENTS_SELECTOR","e","_b"],"mappings":";;;;;;;;;;;;;;;AAAY,IAAAA,sBAAAA,OACVA,EAAA,SAAS,UACTA,EAAA,SAAS,UACTA,EAAA,OAAO,QAHGA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACVA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAHEA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;iBCoGJC,IAAQC,KAERC,IAAUC,KACVC,IAA6BD,KAC7BE,IAAgBF,EAAmB,CAAA,CAAE,GACrCG,IAAoBH,KACpBI,IAAmBJ,KACnBK,IAAmCL,EAAI,EAAE,QAAQ,IAAI,UAAU,IAAI,GACnEM,IAAWC,EAAS,eAAe,GACnCC,IAAmBC,EAAS,MAAM,CAAC,CAACZ,EAAM,WAAW,CAAC,CAACA,EAAM,MAAM,GACnEa,IAAcD,EAAS,MAAME,EAAM,QAAQA,EAAM,MAAM,GACvDC,IAAWH,EAAS,MAAME,EAAM,aAAa,UAAUA,EAAM,aAAa,OAAO;AAEvF,aAASE,IAA0B;AACzB,aAAA,SAAS,oBAAoB,SAAS;AAAA,IAChD;AAEA,IAAAC;AAAA,MACEJ;AAAA,MACA,MAAM;AACJ,QAAIA,EAAY,SACP,OAAA,OAAOL,EAAiC,OAAO;AAAA,UACpD,QAAQQ,IAA0B,MAAM;AAAA,UACxC,UAAUA,IAA0B,MAAM;AAAA,QAAA,CAC3C,GAGI,OAAA,OAAOA,EAAwB,EAAE,OAAO;AAAA,UAC7C,UAAUH,EAAY,QAAQ,WAAWL,EAAiC,MAAM;AAAA;AAAA,UAChF,QAAQK,EAAY,QAAQ,SAASL,EAAiC,MAAM;AAAA;AAAA,QAAA,CAC7E;AAAA,MACH;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IAAA,GAGpBU,EAAgB,MAAM;;AAEb,aAAA,OAAOF,EAAwB,EAAE,OAAO;AAAA,QAC7C,UAAUR,EAAiC,MAAM;AAAA,QACjD,QAAQA,EAAiC,MAAM;AAAA,MAAA,CAChD,GAGQ,SAAA,oBAAoB,WAAWW,CAAS,IACjDC,IAAAhB,EAA2B,UAA3B,QAAAgB,EAAkC;AAAA,IAAM,CACzC;AAED,aAASC,IAAU;AACjB,MAAAC,EAAK,eAAe,EAAK,GACzBA,EAAK,kBAAkB,EAAK,GAC5BA,EAAK,SAAS;AAAA,IAChB;AAGA,IAAAL,EAAMf,GAAS,MAAM;AACf,MAACA,EAAQ,UAIbE,EAA2B,QAAQ,SAAS,eAC5CF,EAAQ,MAAM,SAEdG,EAAc,QAAQ,MAAM,KAAKH,EAAQ,MAAM,iBAA8BqB,CAAuB,CAAC,GACnFjB,EAAA,QAAQD,EAAc,MAAM,CAAC,GAC/CE,EAAiB,QAAQF,EAAc,MAAMA,EAAc,MAAM,SAAS,CAAC,GAClE,SAAA,iBAAiB,WAAWc,CAAS;AAAA,IAAA,CAC/C;AAED,aAASA,EAAUK,GAAG;;AAChB,MAAAA,EAAE,QAAQ,UACRA,EAAE,YAAY,SAAS,kBAAkBlB,EAAkB,UAC7Dc,IAAAb,EAAiB,UAAjB,QAAAa,EAAwB,SACxBI,EAAE,eAAe,KACR,SAAS,kBAAkBjB,EAAiB,WACrDkB,IAAAnB,EAAkB,UAAlB,QAAAmB,EAAyB,SACzBD,EAAE,eAAe;AAAA,IAGvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
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</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: 'tw-text-white/50',\n });\n\n const emit =\n 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 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 // 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 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</script>\n\n<template>\n <div\n v-if=\"isModalOpen\"\n ref=\"rootRef\"\n class=\"stash-modal tw-fixed tw-inset-0 tw-overflow-y-auto\"\n :class=\"{\n 'tw-invisible tw-z-behind': !isModalOpen,\n 'tw-visible tw-z-modal': isModalOpen,\n 'lg:tw-flex lg:tw-flex-col lg:tw-justify-center lg:tw-items-center': props.position === 'center',\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 tw-flex tw-flex-col tw-h-screen tw-w-full lg:tw-shadow tw-relative\"\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:tw-w-[360px]': props.size === 'narrow',\n 'lg:tw-w-[648px]': props.size === 'medium',\n 'lg:tw-w-[960px]': props.size === 'wide',\n 'lg:tw-h-auto lg:tw-my-0 lg:tw-max-h-[90vh]': props.position === 'center',\n 'lg:tw-h-screen lg:tw-absolute': isDrawer,\n 'lg:tw-left-0': props.position === 'left',\n 'lg:tw-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 tw-bg-purple tw-h-12 tw-grid tw-place-items-center\"\n :class=\"{ 'lg:tw-rounded-t': !isDrawer }\"\n >\n <div class=\"tw-flex tw-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=\"tw-text-white tw-flex-1 tw-leading-6 tw-m-0\">\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=\"tw-text-white\" name=\"close\" />\n </Button>\n </header>\n\n <Button\n v-if=\"!props.hideClose && props.hideHeader\"\n class=\"tw-absolute tw-right-0 tw-top-0 tw-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=\"tw-drop-shadow-md\" name=\"close\" :class=\"[props.closeButtonColorClass]\" />\n </Button>\n\n <div\n v-if=\"!!slots['featured-content']\"\n class=\"tw-relative stash-modal__featured-content\"\n :class=\"{\n 'tw-rounded-t': props.hideHeader,\n }\"\n >\n <slot name=\"featured-content\"></slot>\n </div>\n\n <div\n class=\"stash-modal__body tw-flex-1 tw-overflow-y-auto\"\n :class=\"[\n {\n 'tw-p-3 lg:tw-p-6': !props.disableBodyPadding,\n 'lg:tw-overflow-y-visible': !props.scrollable && !isDrawer,\n 'lg:tw-rounded-b': !hasFooterContent && !isDrawer,\n 'tw-bg-white': !props.contrast,\n 'tw-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 tw-bg-ice-100 tw-border-ice-500 tw-p-3 lg:tw-p-6\"\n :class=\"{ 'lg:tw-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 tw-flex tw-flex-col tw-justify-end lg:tw-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 .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: var(--ll-space-2);\n order: 1;\n }\n\n @media screen and (width >= 961px) {\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</style>\n"],"names":["ModalSize","ModalPosition","slots","useSlots","rootRef","ref","lastExternalFocusedElement","focusElements","firstFocusElement","lastFocusElement","initialPageScrollingElementStyle","headerId","uniqueId","hasFooterContent","computed","isModalOpen","props","isDrawer","getPageScrollingElement","watch","onBeforeUnmount","handleTab","_a","dismiss","emit","FOCUS_ELEMENTS_SELECTOR","e","_b"],"mappings":";;;;;;;;;;;;;;;AAAY,IAAAA,sBAAAA,OACVA,EAAA,SAAS,UACTA,EAAA,SAAS,UACTA,EAAA,OAAO,QAHGA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACVA,EAAA,SAAS,UACTA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAHEA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;iBCoGJC,IAAQC,KAERC,IAAUC,KACVC,IAA6BD,KAC7BE,IAAgBF,EAAmB,CAAA,CAAE,GACrCG,IAAoBH,KACpBI,IAAmBJ,KACnBK,IAAmCL,EAAI,EAAE,QAAQ,IAAI,UAAU,IAAI,GACnEM,IAAWC,EAAS,eAAe,GACnCC,IAAmBC,EAAS,MAAM,CAAC,CAACZ,EAAM,WAAW,CAAC,CAACA,EAAM,MAAM,GACnEa,IAAcD,EAAS,MAAME,EAAM,QAAQA,EAAM,MAAM,GACvDC,IAAWH,EAAS,MAAME,EAAM,aAAa,UAAUA,EAAM,aAAa,OAAO;AAEvF,aAASE,IAA0B;AACzB,aAAA,SAAS,oBAAoB,SAAS;AAAA,IAChD;AAEA,IAAAC;AAAA,MACEJ;AAAA,MACA,MAAM;AACJ,QAAIA,EAAY,SACP,OAAA,OAAOL,EAAiC,OAAO;AAAA,UACpD,QAAQQ,IAA0B,MAAM;AAAA,UACxC,UAAUA,IAA0B,MAAM;AAAA,QAAA,CAC3C,GAGI,OAAA,OAAOA,EAAwB,EAAE,OAAO;AAAA,UAC7C,UAAUH,EAAY,QAAQ,WAAWL,EAAiC,MAAM;AAAA;AAAA,UAChF,QAAQK,EAAY,QAAQ,SAASL,EAAiC,MAAM;AAAA;AAAA,QAAA,CAC7E;AAAA,MACH;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IAAA,GAGpBU,EAAgB,MAAM;;AAEb,aAAA,OAAOF,EAAwB,EAAE,OAAO;AAAA,QAC7C,UAAUR,EAAiC,MAAM;AAAA,QACjD,QAAQA,EAAiC,MAAM;AAAA,MAAA,CAChD,GAGQ,SAAA,oBAAoB,WAAWW,CAAS,IACjDC,IAAAhB,EAA2B,UAA3B,QAAAgB,EAAkC;AAAA,IAAM,CACzC;AAED,aAASC,IAAU;AACjB,MAAAC,EAAK,eAAe,EAAK,GACzBA,EAAK,kBAAkB,EAAK,GAC5BA,EAAK,SAAS;AAAA,IAChB;AAGA,IAAAL,EAAMf,GAAS,MAAM;AACf,MAACA,EAAQ,UAIbE,EAA2B,QAAQ,SAAS,eAC5CF,EAAQ,MAAM,SAEdG,EAAc,QAAQ,MAAM,KAAKH,EAAQ,MAAM,iBAA8BqB,CAAuB,CAAC,GACnFjB,EAAA,QAAQD,EAAc,MAAM,CAAC,GAC/CE,EAAiB,QAAQF,EAAc,MAAMA,EAAc,MAAM,SAAS,CAAC,GAClE,SAAA,iBAAiB,WAAWc,CAAS;AAAA,IAAA,CAC/C;AAED,aAASA,EAAUK,GAAG;;AAChB,MAAAA,EAAE,QAAQ,UACRA,EAAE,YAAY,SAAS,kBAAkBlB,EAAkB,UAC7Dc,IAAAb,EAAiB,UAAjB,QAAAa,EAAwB,SACxBI,EAAE,eAAe,KACR,SAAS,kBAAkBjB,EAAiB,WACrDkB,IAAAnB,EAAkB,UAAlB,QAAAmB,EAAyB,SACzBD,EAAE,eAAe;AAAA,IAGvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|