@leaflink/stash 51.12.6 → 51.12.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/FilterDropdown.js +4 -4
- package/dist/FilterDropdown.js.map +1 -1
- package/dist/FilterSelect.js +58 -52
- package/dist/FilterSelect.js.map +1 -1
- package/package.json +1 -1
package/dist/FilterDropdown.js
CHANGED
|
@@ -8,10 +8,10 @@ import { D as F } from "./DataView.keys-aSOnA4AD.js";
|
|
|
8
8
|
import { D as G } from "./DataViewFilters.keys-BLu07FiP.js";
|
|
9
9
|
import $ from "./Dropdown.js";
|
|
10
10
|
import q from "./FilterChip.js";
|
|
11
|
-
const H = { class: "tw-flex tw-h-full tw-flex-col tw-rounded" }, K = { class: "tw-
|
|
11
|
+
const H = { class: "tw-flex tw-h-full tw-flex-col tw-rounded" }, K = { class: "tw-flex-1 tw-overflow-hidden tw-rounded-t" }, M = {
|
|
12
12
|
key: 0,
|
|
13
13
|
class: "tw-pointer-events-none tw-absolute tw-inset-x-0 tw-bottom-0 tw-z-10 tw-h-[20px] tw-bg-scroll-shadow"
|
|
14
|
-
}, P = { class: "tw-flex tw-justify-end tw-gap-6 tw-rounded-b tw-border tw-border-solid tw-border-x-ice-100 tw-border-b-ice-100 tw-border-t-ice-200 tw-bg-ice-100 tw-p-3.5" }, ne = /* @__PURE__ */ O({
|
|
14
|
+
}, P = { class: "tw-flex tw-shrink-0 tw-justify-end tw-gap-6 tw-rounded-b tw-border tw-border-solid tw-border-x-ice-100 tw-border-b-ice-100 tw-border-t-ice-200 tw-bg-ice-100 tw-p-3.5" }, ne = /* @__PURE__ */ O({
|
|
15
15
|
__name: "FilterDropdown",
|
|
16
16
|
props: {
|
|
17
17
|
label: {},
|
|
@@ -63,7 +63,7 @@ const H = { class: "tw-flex tw-h-full tw-flex-col tw-rounded" }, K = { class: "t
|
|
|
63
63
|
"data-test": "stash-filter-dropdown",
|
|
64
64
|
"fluid-content": "",
|
|
65
65
|
"close-manually": "",
|
|
66
|
-
"content-class": "tw-w-full tw-max-w-[600px] tw-h-
|
|
66
|
+
"content-class": "tw-w-full tw-max-w-[600px] tw-h-[400px]",
|
|
67
67
|
offset: { y: 6 },
|
|
68
68
|
onDismiss: B
|
|
69
69
|
}, {
|
|
@@ -86,7 +86,7 @@ const H = { class: "tw-flex tw-h-full tw-flex-col tw-rounded" }, K = { class: "t
|
|
|
86
86
|
d("div", H, [
|
|
87
87
|
d("div", K, [
|
|
88
88
|
d("div", {
|
|
89
|
-
class: "tw-h-full tw-overflow-auto tw-p-6",
|
|
89
|
+
class: "tw-relative tw-h-full tw-overflow-auto tw-p-6",
|
|
90
90
|
onScroll: t[0] || (t[0] = //@ts-ignore
|
|
91
91
|
(...a) => o(g) && o(g)(...a)),
|
|
92
92
|
onScrollend: L
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterDropdown.js","sources":["../src/components/FilterDropdown/FilterDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import throttle from 'lodash-es/throttle';\n import { computed, inject, ref } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from '../DataViewFilters/DataViewFilters.keys';\n import type { OnApplyFilters } from '../DataViewFilters/DataViewFilters.types';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n\n export interface FilterDropdownProps {\n label: string;\n /** The name of a filter group */\n group: string;\n onApply?: OnApplyFilters;\n }\n const props = withDefaults(defineProps<FilterDropdownProps>(), {\n activeFilterCount: 0,\n onApply: () => undefined,\n });\n\n const emit = defineEmits<{\n (e: 'reset'): void;\n (e: 'dismiss'): void;\n }>();\n\n const { isLoading: isDataViewLoading } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n const dataViewFiltersUtils = inject(DATA_VIEW_FILTERS_UTILS_INJECTION.key);\n\n if (!dataViewFiltersUtils?.useFiltersInstance) {\n throw new Error(\n 'FilterDropdown must be used within a <DataViewFilters> that receives an instance of useFilters().',\n );\n }\n\n const { applyFilters, resetFilterGroup, activeFiltersCounts, undoWorkingFilters } =\n dataViewFiltersUtils.useFiltersInstance;\n\n const dropdownRef = ref<InstanceType<typeof Dropdown>>();\n const isOpen = computed(() => dropdownRef.value?.isActive);\n\n function onToggleButtonClick() {\n const wasOpen = isOpen.value;\n\n dropdownRef.value?.toggle();\n\n if (wasOpen) {\n undoWorkingFilters();\n emit('dismiss');\n }\n }\n\n function handleResetClick() {\n resetFilterGroup(props.group);\n emit('reset');\n dropdownRef.value?.dismiss();\n }\n\n async function handleApplyClick() {\n const { preventDismiss } = (await props.onApply?.()) || applyFilters() || {};\n\n if (!preventDismiss) {\n dropdownRef.value?.dismiss();\n }\n }\n\n function onDismiss() {\n undoWorkingFilters();\n emit('dismiss');\n }\n\n const showShadow = ref(false);\n const onScroll = throttle((event: Event) => {\n if (!event.target) return;\n\n if ((event.target as HTMLElement).scrollTop > 0) {\n showShadow.value = true;\n } else {\n showShadow.value = false;\n }\n }, 500);\n\n function onScrollEnd() {\n setTimeout(() => {\n showShadow.value = false;\n }, 2000);\n }\n</script>\n\n<template>\n <Dropdown\n ref=\"dropdownRef\"\n align=\"left\"\n class=\"stash-filter-dropdown\"\n data-test=\"stash-filter-dropdown\"\n fluid-content\n close-manually\n content-class=\"tw-w-full tw-max-w-[600px] tw-h-
|
|
1
|
+
{"version":3,"file":"FilterDropdown.js","sources":["../src/components/FilterDropdown/FilterDropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import throttle from 'lodash-es/throttle';\n import { computed, inject, ref } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from '../DataViewFilters/DataViewFilters.keys';\n import type { OnApplyFilters } from '../DataViewFilters/DataViewFilters.types';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n\n export interface FilterDropdownProps {\n label: string;\n /** The name of a filter group */\n group: string;\n onApply?: OnApplyFilters;\n }\n const props = withDefaults(defineProps<FilterDropdownProps>(), {\n activeFilterCount: 0,\n onApply: () => undefined,\n });\n\n const emit = defineEmits<{\n (e: 'reset'): void;\n (e: 'dismiss'): void;\n }>();\n\n const { isLoading: isDataViewLoading } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n const dataViewFiltersUtils = inject(DATA_VIEW_FILTERS_UTILS_INJECTION.key);\n\n if (!dataViewFiltersUtils?.useFiltersInstance) {\n throw new Error(\n 'FilterDropdown must be used within a <DataViewFilters> that receives an instance of useFilters().',\n );\n }\n\n const { applyFilters, resetFilterGroup, activeFiltersCounts, undoWorkingFilters } =\n dataViewFiltersUtils.useFiltersInstance;\n\n const dropdownRef = ref<InstanceType<typeof Dropdown>>();\n const isOpen = computed(() => dropdownRef.value?.isActive);\n\n function onToggleButtonClick() {\n const wasOpen = isOpen.value;\n\n dropdownRef.value?.toggle();\n\n if (wasOpen) {\n undoWorkingFilters();\n emit('dismiss');\n }\n }\n\n function handleResetClick() {\n resetFilterGroup(props.group);\n emit('reset');\n dropdownRef.value?.dismiss();\n }\n\n async function handleApplyClick() {\n const { preventDismiss } = (await props.onApply?.()) || applyFilters() || {};\n\n if (!preventDismiss) {\n dropdownRef.value?.dismiss();\n }\n }\n\n function onDismiss() {\n undoWorkingFilters();\n emit('dismiss');\n }\n\n const showShadow = ref(false);\n const onScroll = throttle((event: Event) => {\n if (!event.target) return;\n\n if ((event.target as HTMLElement).scrollTop > 0) {\n showShadow.value = true;\n } else {\n showShadow.value = false;\n }\n }, 500);\n\n function onScrollEnd() {\n setTimeout(() => {\n showShadow.value = false;\n }, 2000);\n }\n</script>\n\n<template>\n <Dropdown\n ref=\"dropdownRef\"\n align=\"left\"\n class=\"stash-filter-dropdown\"\n data-test=\"stash-filter-dropdown\"\n fluid-content\n close-manually\n content-class=\"tw-w-full tw-max-w-[600px] tw-h-[400px]\"\n :offset=\"{ y: 6 }\"\n @dismiss=\"onDismiss\"\n >\n <template #toggle>\n <FilterChip\n class=\"tw-rounded-full\"\n has-dropdown\n :is-dropdown-open=\"isOpen\"\n :filter-count=\"activeFiltersCounts[props.group]\"\n :is-selected=\"isOpen\"\n @click=\"onToggleButtonClick\"\n >\n {{ props.label }}\n </FilterChip>\n </template>\n <template #default>\n <div class=\"tw-flex tw-h-full tw-flex-col tw-rounded\">\n <div class=\"tw-flex-1 tw-overflow-hidden tw-rounded-t\">\n <div class=\"tw-relative tw-h-full tw-overflow-auto tw-p-6\" @scroll=\"onScroll\" @scrollend=\"onScrollEnd\">\n <slot></slot>\n </div>\n <Transition name=\"fade\">\n <div\n v-if=\"showShadow\"\n class=\"tw-pointer-events-none tw-absolute tw-inset-x-0 tw-bottom-0 tw-z-10 tw-h-[20px] tw-bg-scroll-shadow\"\n ></div>\n </Transition>\n </div>\n\n <footer\n class=\"tw-flex tw-shrink-0 tw-justify-end tw-gap-6 tw-rounded-b tw-border tw-border-solid tw-border-x-ice-100 tw-border-b-ice-100 tw-border-t-ice-200 tw-bg-ice-100 tw-p-3.5\"\n >\n <Button\n v-if=\"activeFiltersCounts[props.group]\"\n secondary\n class=\"tw-min-w-[100px]\"\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button class=\"tw-min-w-[100px]\" :disabled=\"isDataViewLoading\" @click=\"handleApplyClick\">\n {{ t('ll.apply') }}\n </Button>\n </footer>\n </div>\n </template>\n </Dropdown>\n</template>\n"],"names":["props","__props","emit","__emit","isDataViewLoading","inject","DATA_VIEW_INJECTION","dataViewFiltersUtils","DATA_VIEW_FILTERS_UTILS_INJECTION","applyFilters","resetFilterGroup","activeFiltersCounts","undoWorkingFilters","dropdownRef","ref","isOpen","computed","_a","onToggleButtonClick","wasOpen","handleResetClick","handleApplyClick","preventDismiss","_b","onDismiss","showShadow","onScroll","throttle","event","onScrollEnd"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAkBE,UAAMA,IAAQC,GAKRC,IAAOC,GAKP,EAAE,WAAWC,MAAsBC,EAAOC,EAAoB,KAAKA,EAAoB,QAAQ,GAE/FC,IAAuBF,EAAOG,EAAkC,GAAG;AAEzE,QAAI,EAACD,KAAA,QAAAA,EAAsB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAIJ,UAAM,EAAE,cAAAE,GAAc,kBAAAC,GAAkB,qBAAAC,GAAqB,oBAAAC,EAAA,IAC3DL,EAAqB,oBAEjBM,IAAcC,EAAA,GACdC,IAASC,EAAS,MAAA;;AAAM,cAAAC,IAAAJ,EAAY,UAAZ,gBAAAI,EAAmB;AAAA,KAAQ;AAEzD,aAASC,IAAsB;;AAC7B,YAAMC,IAAUJ,EAAO;AAEvB,OAAAE,IAAAJ,EAAY,UAAZ,QAAAI,EAAmB,UAEfE,MACFP,EAAA,GACAV,EAAK,SAAS;AAAA,IAElB;AAEA,aAASkB,IAAmB;;AAC1B,MAAAV,EAAiBV,EAAM,KAAK,GAC5BE,EAAK,OAAO,IACZe,IAAAJ,EAAY,UAAZ,QAAAI,EAAmB;AAAA,IACrB;AAEA,mBAAeI,IAAmB;;AAChC,YAAM,EAAE,gBAAAC,MAAoB,QAAML,IAAAjB,EAAM,YAAN,gBAAAiB,EAAA,KAAAjB,OAAsBS,EAAA,KAAkB,CAAA;AAE1E,MAAKa,MACHC,IAAAV,EAAY,UAAZ,QAAAU,EAAmB;AAAA,IAEvB;AAEA,aAASC,IAAY;AACnB,MAAAZ,EAAA,GACAV,EAAK,SAAS;AAAA,IAChB;AAEA,UAAMuB,IAAaX,EAAI,EAAK,GACtBY,IAAWC,EAAS,CAACC,MAAiB;AAC1C,MAAKA,EAAM,WAENA,EAAM,OAAuB,YAAY,IAC5CH,EAAW,QAAQ,KAEnBA,EAAW,QAAQ;AAAA,IAEvB,GAAG,GAAG;AAEN,aAASI,IAAc;AACrB,iBAAW,MAAM;AACf,QAAAJ,EAAW,QAAQ;AAAA,MACrB,GAAG,GAAI;AAAA,IACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/FilterSelect.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { t as
|
|
3
|
-
import { _ as
|
|
4
|
-
import
|
|
5
|
-
const
|
|
1
|
+
import { defineComponent as $, computed as f, createBlock as C, openBlock as r, mergeProps as F, withCtx as d, createElementVNode as s, createElementBlock as u, createCommentVNode as O, withDirectives as v, vModelCheckbox as y, createVNode as h, withKeys as _, createTextVNode as b, toDisplayString as x, unref as A, Fragment as D, renderList as E } from "vue";
|
|
2
|
+
import { t as K } from "./locale.js";
|
|
3
|
+
import { _ as N } from "./Field.vue_vue_type_script_setup_true_lang-DI6z3AE9.js";
|
|
4
|
+
import B from "./FilterChip.js";
|
|
5
|
+
const I = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, L = ["id"], T = ["for"], R = ["id", "value"], U = ["for"], z = /* @__PURE__ */ $({
|
|
6
6
|
__name: "FilterSelect",
|
|
7
7
|
props: {
|
|
8
8
|
name: {},
|
|
@@ -24,97 +24,103 @@ const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, I = ["id"], L = ["for"],
|
|
|
24
24
|
disabled: { type: Boolean }
|
|
25
25
|
},
|
|
26
26
|
emits: ["update:modelValue"],
|
|
27
|
-
setup(
|
|
28
|
-
const
|
|
27
|
+
setup(g, { emit: V }) {
|
|
28
|
+
const l = g, c = V, a = f({
|
|
29
29
|
get() {
|
|
30
|
-
return
|
|
30
|
+
return l.modelValue;
|
|
31
31
|
},
|
|
32
|
-
set(
|
|
33
|
-
c("update:modelValue",
|
|
32
|
+
set(e) {
|
|
33
|
+
c("update:modelValue", e);
|
|
34
34
|
}
|
|
35
|
-
}), n =
|
|
35
|
+
}), n = f({
|
|
36
36
|
get() {
|
|
37
|
-
return
|
|
37
|
+
return l.options.length === l.modelValue.length;
|
|
38
38
|
},
|
|
39
|
-
set(
|
|
40
|
-
c("update:modelValue",
|
|
39
|
+
set(e) {
|
|
40
|
+
c("update:modelValue", e ? l.options.map((t) => t.value) : []);
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
|
-
function i(
|
|
44
|
-
return `${
|
|
43
|
+
function i(e) {
|
|
44
|
+
return `${l.name}--${e.value}`;
|
|
45
45
|
}
|
|
46
|
-
function
|
|
47
|
-
return
|
|
46
|
+
function w(e) {
|
|
47
|
+
return l.modelValue.includes(e.value);
|
|
48
48
|
}
|
|
49
|
-
function
|
|
50
|
-
const
|
|
51
|
-
|
|
49
|
+
function S(e) {
|
|
50
|
+
const t = a.value.filter((o) => o !== e);
|
|
51
|
+
t.length === a.value.length && t.push(e), a.value = t;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
53
|
+
function k() {
|
|
54
54
|
n.value = !n.value;
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
function p(e) {
|
|
57
|
+
var t;
|
|
58
|
+
e.preventDefault(), (t = e.target) == null || t.blur();
|
|
59
|
+
}
|
|
60
|
+
return (e, t) => (r(), C(N, F(l, {
|
|
57
61
|
class: "stash-filter-select",
|
|
58
62
|
"data-test": "stash-filter-select",
|
|
59
63
|
fieldset: ""
|
|
60
64
|
}), {
|
|
61
65
|
default: d(() => [
|
|
62
|
-
s("div",
|
|
63
|
-
|
|
64
|
-
key: `${
|
|
66
|
+
s("div", I, [
|
|
67
|
+
l.canSelectAll ? (r(), u("div", {
|
|
68
|
+
key: `${l.name}--all`
|
|
65
69
|
}, [
|
|
66
|
-
|
|
67
|
-
id: `${
|
|
68
|
-
"onUpdate:modelValue":
|
|
70
|
+
v(s("input", {
|
|
71
|
+
id: `${l.name}--all`,
|
|
72
|
+
"onUpdate:modelValue": t[0] || (t[0] = (o) => n.value = o),
|
|
69
73
|
class: "tw-sr-only",
|
|
70
74
|
tabindex: "-1",
|
|
71
75
|
type: "checkbox",
|
|
72
|
-
value: "all"
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
value: "all",
|
|
77
|
+
onFocus: p
|
|
78
|
+
}, null, 40, L), [
|
|
79
|
+
[y, n.value]
|
|
75
80
|
]),
|
|
76
81
|
s("label", {
|
|
77
|
-
for: `${
|
|
82
|
+
for: `${l.name}--all`
|
|
78
83
|
}, [
|
|
79
|
-
|
|
84
|
+
h(B, {
|
|
80
85
|
"is-selected": n.value,
|
|
81
86
|
tabindex: "0",
|
|
82
|
-
onKeypress:
|
|
87
|
+
onKeypress: _(k, ["enter"])
|
|
83
88
|
}, {
|
|
84
89
|
default: d(() => [
|
|
85
|
-
|
|
90
|
+
b(x(A(K)("ll.all")), 1)
|
|
86
91
|
]),
|
|
87
92
|
_: 1
|
|
88
93
|
}, 8, ["is-selected"])
|
|
89
|
-
], 8,
|
|
94
|
+
], 8, T)
|
|
90
95
|
])) : O("", !0),
|
|
91
|
-
(r(!0), u(
|
|
92
|
-
key: i(
|
|
96
|
+
(r(!0), u(D, null, E(l.options, (o) => (r(), u("div", {
|
|
97
|
+
key: i(o)
|
|
93
98
|
}, [
|
|
94
|
-
|
|
95
|
-
id: i(
|
|
96
|
-
"onUpdate:modelValue":
|
|
99
|
+
v(s("input", {
|
|
100
|
+
id: i(o),
|
|
101
|
+
"onUpdate:modelValue": t[1] || (t[1] = (m) => a.value = m),
|
|
97
102
|
class: "tw-sr-only",
|
|
98
103
|
tabindex: "-1",
|
|
99
104
|
type: "checkbox",
|
|
100
|
-
value:
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
value: o.value,
|
|
106
|
+
onFocus: p
|
|
107
|
+
}, null, 40, R), [
|
|
108
|
+
[y, a.value]
|
|
103
109
|
]),
|
|
104
110
|
s("label", {
|
|
105
|
-
for: i(
|
|
111
|
+
for: i(o)
|
|
106
112
|
}, [
|
|
107
|
-
|
|
108
|
-
"is-selected":
|
|
113
|
+
h(B, {
|
|
114
|
+
"is-selected": w(o),
|
|
109
115
|
tabindex: "0",
|
|
110
|
-
onKeypress:
|
|
116
|
+
onKeypress: _((m) => S(o.value), ["enter"])
|
|
111
117
|
}, {
|
|
112
118
|
default: d(() => [
|
|
113
|
-
|
|
119
|
+
b(x(o.label), 1)
|
|
114
120
|
]),
|
|
115
121
|
_: 2
|
|
116
122
|
}, 1032, ["is-selected", "onKeypress"])
|
|
117
|
-
], 8,
|
|
123
|
+
], 8, U)
|
|
118
124
|
]))), 128))
|
|
119
125
|
])
|
|
120
126
|
]),
|
|
@@ -123,6 +129,6 @@ const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, I = ["id"], L = ["for"],
|
|
|
123
129
|
}
|
|
124
130
|
});
|
|
125
131
|
export {
|
|
126
|
-
|
|
132
|
+
z as default
|
|
127
133
|
};
|
|
128
134
|
//# sourceMappingURL=FilterSelect.js.map
|
package/dist/FilterSelect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterSelect.js","sources":["../src/components/FilterSelect/FilterSelect.vue"],"sourcesContent":["<script lang=\"ts\">\n export * from './FilterSelect.types';\n</script>\n\n<script lang=\"ts\" setup>\n import { computed } from 'vue';\n\n import { t } from '../../locale';\n import { FieldProps } from '../Field/Field.types';\n import Field from '../Field/Field.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import { FilterSelectModelValue, FilterSelectOption } from './FilterSelect.types';\n\n export interface FilterSelectProps extends FieldProps {\n /**\n * The name attribute for the `<input>` elements. It is also used as a unique field to differentiate FilterSelect instances.\n */\n name: string;\n\n options: FilterSelectOption[];\n\n modelValue: FilterSelectModelValue;\n\n /**\n * When true, this prop adds an \"All\" option for selecting all options.\n */\n canSelectAll?: boolean;\n }\n\n const props = withDefaults(defineProps<FilterSelectProps>(), {\n canSelectAll: false,\n });\n\n const emit = defineEmits<{\n (e: 'update:modelValue', value: FilterSelectModelValue): void;\n }>();\n\n /**\n * @see: https://vuejs.org/guide/components/v-model.html#component-v-model\n */\n const selected = computed({\n get() {\n return props.modelValue;\n },\n set(value) {\n emit('update:modelValue', value);\n },\n });\n\n const isAllSelected = computed({\n get() {\n return props.options.length === props.modelValue.length;\n },\n set(isChecked) {\n emit('update:modelValue', isChecked ? props.options.map((option) => option.value) : []);\n },\n });\n\n function getOptionId(option: FilterSelectOption) {\n return `${props.name}--${option.value}`;\n }\n\n function isOptionSelected(option: FilterSelectOption) {\n return props.modelValue.includes(option.value);\n }\n\n function onEnter(enteredValue: FilterSelectOption['value']) {\n const newSelected = selected.value.filter((value) => value !== enteredValue);\n\n if (newSelected.length === selected.value.length) {\n newSelected.push(enteredValue);\n }\n\n selected.value = newSelected;\n }\n\n function onEnterAll() {\n isAllSelected.value = !isAllSelected.value;\n }\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-filter-select\" data-test=\"stash-filter-select\" fieldset>\n <div class=\"tw-flex tw-flex-wrap tw-gap-1.5\">\n <div v-if=\"props.canSelectAll\" :key=\"`${props.name}--all`\">\n <input\n :id=\"`${props.name}--all`\"\n v-model=\"isAllSelected\"\n class=\"tw-sr-only\"\n tabindex=\"-1\"\n type=\"checkbox\"\n value=\"all\"\n />\n <label :for=\"`${props.name}--all`\">\n <FilterChip :is-selected=\"isAllSelected\" tabindex=\"0\" @keypress.enter=\"onEnterAll\">\n {{ t('ll.all') }}\n </FilterChip>\n </label>\n </div>\n <div v-for=\"option in props.options\" :key=\"getOptionId(option)\">\n <input\n :id=\"getOptionId(option)\"\n v-model=\"selected\"\n class=\"tw-sr-only\"\n tabindex=\"-1\"\n type=\"checkbox\"\n :value=\"option.value\"\n />\n <label :for=\"getOptionId(option)\">\n <FilterChip :is-selected=\"isOptionSelected(option)\" tabindex=\"0\" @keypress.enter=\"onEnter(option.value)\">\n {{ option.label }}\n </FilterChip>\n </label>\n </div>\n </div>\n </Field>\n</template>\n"],"names":["props","__props","emit","__emit","selected","computed","value","isAllSelected","isChecked","option","getOptionId","isOptionSelected","onEnter","enteredValue","newSelected","onEnterAll"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BE,UAAMA,IAAQC,GAIRC,IAAOC,GAOPC,IAAWC,EAAS;AAAA,MACxB,MAAM;AACJ,eAAOL,EAAM;AAAA,MACf;AAAA,MACA,IAAIM,GAAO;AACT,QAAAJ,EAAK,qBAAqBI,CAAK;AAAA,MACjC;AAAA,IAAA,CACD,GAEKC,IAAgBF,EAAS;AAAA,MAC7B,MAAM;AACJ,eAAOL,EAAM,QAAQ,WAAWA,EAAM,WAAW;AAAA,MACnD;AAAA,MACA,IAAIQ,GAAW;AACb,QAAAN,EAAK,qBAAqBM,IAAYR,EAAM,QAAQ,IAAI,CAACS,MAAWA,EAAO,KAAK,IAAI,CAAA,CAAE;AAAA,MACxF;AAAA,IAAA,CACD;AAED,aAASC,EAAYD,GAA4B;AAC/C,aAAO,GAAGT,EAAM,IAAI,KAAKS,EAAO,KAAK;AAAA,IACvC;AAEA,aAASE,EAAiBF,GAA4B;AACpD,aAAOT,EAAM,WAAW,SAASS,EAAO,KAAK;AAAA,IAC/C;AAEA,aAASG,EAAQC,GAA2C;AAC1D,YAAMC,IAAcV,EAAS,MAAM,OAAO,CAACE,MAAUA,MAAUO,CAAY;AAE3E,MAAIC,EAAY,WAAWV,EAAS,MAAM,UACxCU,EAAY,KAAKD,CAAY,GAG/BT,EAAS,QAAQU;AAAA,IACnB;AAEA,aAASC,IAAa;AACpB,MAAAR,EAAc,QAAQ,CAACA,EAAc;AAAA,IACvC
|
|
1
|
+
{"version":3,"file":"FilterSelect.js","sources":["../src/components/FilterSelect/FilterSelect.vue"],"sourcesContent":["<script lang=\"ts\">\n export * from './FilterSelect.types';\n</script>\n\n<script lang=\"ts\" setup>\n import { computed } from 'vue';\n\n import { t } from '../../locale';\n import { FieldProps } from '../Field/Field.types';\n import Field from '../Field/Field.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import { FilterSelectModelValue, FilterSelectOption } from './FilterSelect.types';\n\n export interface FilterSelectProps extends FieldProps {\n /**\n * The name attribute for the `<input>` elements. It is also used as a unique field to differentiate FilterSelect instances.\n */\n name: string;\n\n options: FilterSelectOption[];\n\n modelValue: FilterSelectModelValue;\n\n /**\n * When true, this prop adds an \"All\" option for selecting all options.\n */\n canSelectAll?: boolean;\n }\n\n const props = withDefaults(defineProps<FilterSelectProps>(), {\n canSelectAll: false,\n });\n\n const emit = defineEmits<{\n (e: 'update:modelValue', value: FilterSelectModelValue): void;\n }>();\n\n /**\n * @see: https://vuejs.org/guide/components/v-model.html#component-v-model\n */\n const selected = computed({\n get() {\n return props.modelValue;\n },\n set(value) {\n emit('update:modelValue', value);\n },\n });\n\n const isAllSelected = computed({\n get() {\n return props.options.length === props.modelValue.length;\n },\n set(isChecked) {\n emit('update:modelValue', isChecked ? props.options.map((option) => option.value) : []);\n },\n });\n\n function getOptionId(option: FilterSelectOption) {\n return `${props.name}--${option.value}`;\n }\n\n function isOptionSelected(option: FilterSelectOption) {\n return props.modelValue.includes(option.value);\n }\n\n function onEnter(enteredValue: FilterSelectOption['value']) {\n const newSelected = selected.value.filter((value) => value !== enteredValue);\n\n if (newSelected.length === selected.value.length) {\n newSelected.push(enteredValue);\n }\n\n selected.value = newSelected;\n }\n\n function onEnterAll() {\n isAllSelected.value = !isAllSelected.value;\n }\n\n // Prevent the scroll from being triggered when the focus is on the input\n function preventScroll(event: FocusEvent) {\n event.preventDefault();\n (event.target as HTMLElement)?.blur();\n }\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-filter-select\" data-test=\"stash-filter-select\" fieldset>\n <div class=\"tw-flex tw-flex-wrap tw-gap-1.5\">\n <div v-if=\"props.canSelectAll\" :key=\"`${props.name}--all`\">\n <input\n :id=\"`${props.name}--all`\"\n v-model=\"isAllSelected\"\n class=\"tw-sr-only\"\n tabindex=\"-1\"\n type=\"checkbox\"\n value=\"all\"\n @focus=\"preventScroll\"\n />\n <label :for=\"`${props.name}--all`\">\n <FilterChip :is-selected=\"isAllSelected\" tabindex=\"0\" @keypress.enter=\"onEnterAll\">\n {{ t('ll.all') }}\n </FilterChip>\n </label>\n </div>\n <div v-for=\"option in props.options\" :key=\"getOptionId(option)\">\n <input\n :id=\"getOptionId(option)\"\n v-model=\"selected\"\n class=\"tw-sr-only\"\n tabindex=\"-1\"\n type=\"checkbox\"\n :value=\"option.value\"\n @focus=\"preventScroll\"\n />\n <label :for=\"getOptionId(option)\">\n <FilterChip :is-selected=\"isOptionSelected(option)\" tabindex=\"0\" @keypress.enter=\"onEnter(option.value)\">\n {{ option.label }}\n </FilterChip>\n </label>\n </div>\n </div>\n </Field>\n</template>\n"],"names":["props","__props","emit","__emit","selected","computed","value","isAllSelected","isChecked","option","getOptionId","isOptionSelected","onEnter","enteredValue","newSelected","onEnterAll","preventScroll","event","_a"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BE,UAAMA,IAAQC,GAIRC,IAAOC,GAOPC,IAAWC,EAAS;AAAA,MACxB,MAAM;AACJ,eAAOL,EAAM;AAAA,MACf;AAAA,MACA,IAAIM,GAAO;AACT,QAAAJ,EAAK,qBAAqBI,CAAK;AAAA,MACjC;AAAA,IAAA,CACD,GAEKC,IAAgBF,EAAS;AAAA,MAC7B,MAAM;AACJ,eAAOL,EAAM,QAAQ,WAAWA,EAAM,WAAW;AAAA,MACnD;AAAA,MACA,IAAIQ,GAAW;AACb,QAAAN,EAAK,qBAAqBM,IAAYR,EAAM,QAAQ,IAAI,CAACS,MAAWA,EAAO,KAAK,IAAI,CAAA,CAAE;AAAA,MACxF;AAAA,IAAA,CACD;AAED,aAASC,EAAYD,GAA4B;AAC/C,aAAO,GAAGT,EAAM,IAAI,KAAKS,EAAO,KAAK;AAAA,IACvC;AAEA,aAASE,EAAiBF,GAA4B;AACpD,aAAOT,EAAM,WAAW,SAASS,EAAO,KAAK;AAAA,IAC/C;AAEA,aAASG,EAAQC,GAA2C;AAC1D,YAAMC,IAAcV,EAAS,MAAM,OAAO,CAACE,MAAUA,MAAUO,CAAY;AAE3E,MAAIC,EAAY,WAAWV,EAAS,MAAM,UACxCU,EAAY,KAAKD,CAAY,GAG/BT,EAAS,QAAQU;AAAA,IACnB;AAEA,aAASC,IAAa;AACpB,MAAAR,EAAc,QAAQ,CAACA,EAAc;AAAA,IACvC;AAGA,aAASS,EAAcC,GAAmB;;AACxC,MAAAA,EAAM,eAAA,IACLC,IAAAD,EAAM,WAAN,QAAAC,EAA8B;AAAA,IACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|