@leaflink/stash 42.8.0 → 43.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/AddressSelect.js +9 -10
- package/dist/AddressSelect.js.map +1 -1
- package/dist/Alert.js +9 -9
- package/dist/Alert.js.map +1 -1
- package/dist/AppSidebar.js +11 -11
- package/dist/AppSidebar.js.map +1 -1
- package/dist/Avatar.js +33 -32
- package/dist/Avatar.js.map +1 -1
- package/dist/Avatar.vue.d.ts +16 -95
- package/dist/Badge.js +2 -2
- package/dist/Badge.js.map +1 -1
- package/dist/Checkbox.js +4 -4
- package/dist/Checkbox.js.map +1 -1
- package/dist/{Checkbox.vue_vue_type_style_index_0_scoped_0cd31c8f_lang-4ed993c7.js → Checkbox.vue_vue_type_style_index_0_scoped_0d7e7fd0_lang-4ed993c7.js} +1 -1
- package/dist/Checkbox.vue_vue_type_style_index_0_scoped_0d7e7fd0_lang-4ed993c7.js.map +1 -0
- package/dist/Chip.js +32 -30
- package/dist/Chip.js.map +1 -1
- package/dist/Chip.vue.d.ts +16 -95
- package/dist/ConfirmationCodeInput.js +23 -23
- package/dist/ConfirmationCodeInput.js.map +1 -1
- package/dist/ContextSwitcher.js +2 -2
- package/dist/ContextSwitcher.js.map +1 -1
- package/dist/Copy.js +1 -1
- package/dist/Copy.js.map +1 -1
- package/dist/DataView.js +1 -1
- package/dist/DataViewFilters.js +23 -24
- package/dist/DataViewFilters.js.map +1 -1
- package/dist/DataViewSortButton.js +11 -11
- package/dist/DataViewSortButton.js.map +1 -1
- package/dist/DataViewToolbar.js +1 -1
- package/dist/Dialog.js +10 -10
- package/dist/Dialog.js.map +1 -1
- package/dist/Dropdown.js +7 -7
- package/dist/Dropdown.js.map +1 -1
- package/dist/FilterChip.js +2 -3
- package/dist/FilterChip.js.map +1 -1
- package/dist/FilterDrawerItem.js +5 -6
- package/dist/FilterDrawerItem.js.map +1 -1
- package/dist/FilterDropdown.js +3 -4
- package/dist/FilterDropdown.js.map +1 -1
- package/dist/FilterSelect.js +26 -27
- package/dist/FilterSelect.js.map +1 -1
- package/dist/Filters.js +3 -4
- package/dist/Filters.js.map +1 -1
- package/dist/HttpError.js +36 -39
- package/dist/HttpError.js.map +1 -1
- package/dist/IconLabel.js +12 -13
- package/dist/IconLabel.js.map +1 -1
- package/dist/IconLabel.vue.d.ts +9 -75
- package/dist/Illustration.js +1 -1
- package/dist/Illustration.js.map +1 -1
- package/dist/Illustration.vue.d.ts +19 -14
- package/dist/InputOptions.js +7 -8
- package/dist/InputOptions.js.map +1 -1
- package/dist/LicenseChip.js +32 -26
- package/dist/LicenseChip.js.map +1 -1
- package/dist/LicenseChip.vue.d.ts +2 -4
- package/dist/ListItem.js +1 -1
- package/dist/ListView.js +30 -31
- package/dist/ListView.js.map +1 -1
- package/dist/MenuItem.js +4 -4
- package/dist/MenuItem.js.map +1 -1
- package/dist/Metric.js +1 -1
- package/dist/Metric.js.map +1 -1
- package/dist/Metric.vue.d.ts +8 -74
- package/dist/Modal.js +13 -13
- package/dist/Modal.js.map +1 -1
- package/dist/Module.js +1 -1
- package/dist/Module.js.map +1 -1
- package/dist/ModuleFooter.js +1 -1
- package/dist/ModuleFooter.js.map +1 -1
- package/dist/ModuleHeader.js +1 -1
- package/dist/ModuleHeader.js.map +1 -1
- package/dist/PageNavigation.js +28 -29
- package/dist/PageNavigation.js.map +1 -1
- package/dist/Paginate.js +1 -1
- package/dist/Paginate.js.map +1 -1
- package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js +11 -0
- package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js.map +1 -0
- package/dist/QuickAction.js +14 -14
- package/dist/QuickAction.js.map +1 -1
- package/dist/RadioNew.js +14 -14
- package/dist/SearchBar.js +15 -15
- package/dist/SearchBar.js.map +1 -1
- package/dist/Select.js +92 -93
- package/dist/Select.js.map +1 -1
- package/dist/SelectStatus.js +53 -51
- package/dist/SelectStatus.js.map +1 -1
- package/dist/SelectStatus.vue.d.ts +52 -1
- package/dist/Step.js +28 -28
- package/dist/Step.js.map +1 -1
- package/dist/Tab.js +1 -1
- package/dist/Table.js +2 -2
- package/dist/TableCell.js +2 -2
- package/dist/TableHeaderCell.js +2 -2
- package/dist/TableHeaderRow.js +2 -2
- package/dist/TableRow.js +2 -2
- package/dist/Tabs.js +2 -2
- package/dist/{Tabs.vue_vue_type_script_setup_true_lang-aca4f8b8.js → Tabs.vue_vue_type_script_setup_true_lang-56e85faa.js} +3 -3
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-56e85faa.js.map +1 -0
- package/dist/Textarea.js +19 -19
- package/dist/Textarea.js.map +1 -1
- package/dist/Toast.js +1 -1
- package/dist/Toasts.js +1 -1
- package/dist/ToastsPlugin.js +1 -1
- package/dist/colorScheme.d.ts +3 -16
- package/dist/components.css +1 -1
- package/dist/index.d.ts +64 -25
- package/dist/index.js +188 -186
- package/dist/index.js.map +1 -1
- package/dist/statusLevels-a8b041f4.js +7 -0
- package/dist/statusLevels-a8b041f4.js.map +1 -0
- package/dist/tailwind-base.d.ts +0 -10
- package/dist/tailwind-base.js +22 -20
- package/dist/tailwind-base.js.map +1 -1
- package/dist/utils/colorScheme.js +1 -1
- package/dist/utils/colorScheme.js.map +1 -1
- package/package.json +1 -1
- package/styles/base.css +2 -2
- package/tailwind-base.ts +22 -21
- package/types/colors.ts +84 -26
- package/types/statusLevels.ts +4 -4
- package/dist/Checkbox.vue_vue_type_style_index_0_scoped_0cd31c8f_lang-4ed993c7.js.map +0 -1
- package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js +0 -11
- package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js.map +0 -1
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-aca4f8b8.js.map +0 -1
- package/dist/colors-13e95ebf.js +0 -6
- package/dist/colors-13e95ebf.js.map +0 -1
- package/dist/statusLevels-aabf1e3c.js +0 -7
- package/dist/statusLevels-aabf1e3c.js.map +0 -1
package/dist/Dropdown.js
CHANGED
|
@@ -14,7 +14,7 @@ import "./index-79ce320f.js";
|
|
|
14
14
|
import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
|
|
15
15
|
const Z = ["aria-expanded"], ee = {
|
|
16
16
|
key: 0,
|
|
17
|
-
class: "tw-font-medium tw-flex tw-items-center tw-text-blue hover:tw-text-blue-700"
|
|
17
|
+
class: "tw-font-medium tw-flex tw-items-center tw-text-blue-500 hover:tw-text-blue-700"
|
|
18
18
|
}, te = /* @__PURE__ */ R({
|
|
19
19
|
name: "ll-dropdown",
|
|
20
20
|
__name: "Dropdown",
|
|
@@ -74,9 +74,9 @@ const Z = ["aria-expanded"], ee = {
|
|
|
74
74
|
(e = t.value) == null || e.style.setProperty("--offset", "0");
|
|
75
75
|
}
|
|
76
76
|
async function O() {
|
|
77
|
-
var
|
|
77
|
+
var y, h;
|
|
78
78
|
await A();
|
|
79
|
-
const e = ((
|
|
79
|
+
const e = ((y = w.value) == null ? void 0 : y.getBoundingClientRect()) || {}, l = e.top + e.height, n = {
|
|
80
80
|
x: 0,
|
|
81
81
|
y: 0,
|
|
82
82
|
...a.offset
|
|
@@ -89,7 +89,7 @@ const Z = ["aria-expanded"], ee = {
|
|
|
89
89
|
const c = J(t == null ? void 0 : t.value);
|
|
90
90
|
if (c) {
|
|
91
91
|
const P = a.align === "left" ? "-" : "";
|
|
92
|
-
(
|
|
92
|
+
(h = t.value) == null || h.style.setProperty("--offset", `${P}${c.value}`);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
return $({
|
|
@@ -156,12 +156,12 @@ const Z = ["aria-expanded"], ee = {
|
|
|
156
156
|
[M(H), r]
|
|
157
157
|
]);
|
|
158
158
|
}
|
|
159
|
-
}), oe = "
|
|
159
|
+
}), oe = "_content_vy8m8_2", le = {
|
|
160
160
|
content: oe
|
|
161
161
|
}, ae = {
|
|
162
162
|
$style: le
|
|
163
|
-
},
|
|
163
|
+
}, he = /* @__PURE__ */ X(te, [["__cssModules", ae]]);
|
|
164
164
|
export {
|
|
165
|
-
|
|
165
|
+
he as default
|
|
166
166
|
};
|
|
167
167
|
//# sourceMappingURL=Dropdown.js.map
|
package/dist/Dropdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.js","sources":["../src/components/Dropdown/Dropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, nextTick, onBeforeUnmount, onMounted, ref, useCssModule, watch } from 'vue';\n\n import { KEY_CODES } from '../../constants';\n import vClickoutside from '../../directives/clickoutside/clickoutside';\n import calculateElementOverflow from '../../utils/calculateElementOverflow';\n import { getMountPoint } from '../../utils/helpers';\n import Icon from '../Icon/Icon.vue';\n\n export type DropdownOffset = {\n x?: number;\n y?: number;\n };\n\n export interface DropdownProps {\n /**\n * Used to position the dropdown relative to target\n * Options: left, right\n */\n align?: 'left' | 'right';\n /**\n * When passed, text with caret is displayed instead of default kebab menu.\n */\n label?: string;\n /**\n * If true, dropdown will remain open when clicking on its content. Otherwise, it'll close automatically on click.\n */\n closeManually?: boolean;\n /**\n * Used to horizontally and vertically offset the dropdown in pixels\n * Keep in mind, `x` value is relative to `align` value.\n */\n offset?: DropdownOffset;\n /**\n * If `reattach` is true, the contents will be mounted in the mount point container,\n * so as to circumvent clipping issues from a parent's overflow property.\n */\n reattach?: boolean;\n /**\n * Custom class to apply to the default dropdown content element\n */\n contentClass?: string | string[];\n /**\n * Removes content container's max width\n */\n fluidContent?: boolean;\n }\n\n type DropdownStyles = {\n left?: string;\n right?: string;\n top?: string;\n };\n\n defineOptions({\n name: 'll-dropdown',\n });\n\n const props = withDefaults(defineProps<DropdownProps>(), {\n align: 'right',\n label: '',\n closeManually: false,\n offset: () => ({}),\n reattach: true,\n contentClass: '',\n fluidContent: false,\n });\n\n const emit =\n defineEmits<{\n toggle: [isActive: boolean];\n dismiss: [];\n }>();\n\n const contentRef = ref<HTMLElement | null>(null);\n const dropdownRef = ref<HTMLDivElement | null>(null);\n\n const DEFAULT_ITEMS_LIST = [] as unknown as NodeListOf<Element>;\n\n const items = ref<NodeListOf<Element>>(DEFAULT_ITEMS_LIST);\n const itemIndex = ref(-1);\n const isActive = ref(false);\n\n const styles = ref<DropdownStyles>({});\n const classes = useCssModule();\n\n watch(isActive, (val) => {\n if (!val) {\n itemIndex.value = -1;\n }\n\n emit('toggle', val);\n });\n\n watch(itemIndex, (next, prev) => {\n next in items.value && items.value[next].classList.add('is-highlighted');\n prev in items.value && items.value[prev].classList.remove('is-highlighted');\n });\n\n onMounted(() => {\n if (props.reattach) {\n const target = getMountPoint();\n\n contentRef.value && target.appendChild(contentRef.value);\n }\n\n // if stash-menu exists, use it's items\n if (contentRef.value?.querySelector('.stash-menu')) {\n items.value = contentRef.value?.querySelectorAll('.stash-menu-item') ?? DEFAULT_ITEMS_LIST;\n } else {\n items.value = contentRef.value?.querySelectorAll('.dropdown__item') ?? DEFAULT_ITEMS_LIST;\n }\n\n // avoid calling dismiss with ResizeEvent because it's target is the Window element and it's not a valid Node element to be passed to dismiss\n window.addEventListener('resize', () => dismiss());\n });\n\n onBeforeUnmount(() => {\n window.removeEventListener('resize', () => dismiss());\n contentRef.value?.parentNode?.removeChild(contentRef.value);\n });\n\n /**\n * Dismisses the Dropdown.\n */\n function dismiss(event?: Event) {\n if (\n props.closeManually &&\n (contentRef.value?.contains(event?.target as HTMLElement) || contentRef.value === event?.target)\n ) {\n return;\n }\n\n const wasOpen = isActive.value;\n\n isActive.value = false;\n\n if (wasOpen) {\n emit('dismiss');\n }\n }\n\n /**\n * Opens or closes the Dropdown. If opening, positions and focuses its content.\n */\n async function toggle() {\n if (isActive.value) {\n isActive.value = false;\n } else {\n isActive.value = true;\n await calculateOffset();\n contentRef.value?.focus();\n }\n }\n\n /**\n * Handles all user keyboard input on the Dropdown.\n * @param {KeyboardEvent} e The native keydown event.\n */\n function onKeyDown(e: KeyboardEvent) {\n if (e.keyCode === KEY_CODES.ESCAPE) {\n dismiss();\n } else if (e.keyCode === KEY_CODES.DOWN && itemIndex.value < items.value.length - 1) {\n isActive.value && itemIndex.value++;\n } else if (e.keyCode === KEY_CODES.UP && itemIndex.value > -1) {\n isActive.value && itemIndex.value--;\n } else if (e.keyCode === KEY_CODES.ENTER && itemIndex.value !== -1) {\n isActive.value && items[itemIndex.value].click();\n } else {\n return;\n }\n\n e.preventDefault(); // if keyDown did something / we didn't return\n }\n\n /**\n * Reset any page overflow offset\n */\n function resetOffset() {\n contentRef.value?.style.setProperty('--offset', '0');\n }\n\n /**\n * Calculate the position for the Dropdown content element,\n * relative to the viewport.\n * Repositions the dropdown content element (& arrow)\n * if it overflows the page (including gutter).\n */\n async function calculateOffset() {\n await nextTick();\n\n const toggleBCR = dropdownRef.value?.getBoundingClientRect() || ({} as DOMRect);\n const top = toggleBCR.top + toggleBCR.height;\n const offset = {\n x: 0,\n y: 0,\n ...props.offset,\n };\n\n if (props.reattach) {\n styles.value = {\n left: props.align === 'left' ? `${Math.round(toggleBCR.left) + offset.x}px` : undefined,\n right:\n props.align === 'right'\n ? `${document.documentElement.clientWidth - Math.round(toggleBCR.right) + offset.x}px`\n : undefined,\n top: `${window.scrollY + top + offset.y}px`,\n };\n await nextTick(); // wait for style updates to sync in the DOM\n }\n\n const overflow = calculateElementOverflow(contentRef?.value);\n\n if (overflow) {\n const direction = props.align === 'left' ? '-' : '';\n contentRef.value?.style.setProperty('--offset', `${direction}${overflow.value}`);\n }\n }\n\n defineExpose({\n isActive: computed(() => isActive.value),\n toggle,\n dismiss,\n });\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n v-clickoutside=\"dismiss\"\n class=\"tw-inline-block tw-relative\"\n data-test=\"ll-dropdown\"\n @keydown=\"onKeyDown\"\n >\n <!-- @slot Toggle component slot, receives `toggle` method to trigger Dropdown display -->\n <slot name=\"toggle\" :is-active=\"isActive\" :toggle=\"toggle\">\n <button\n data-test=\"button|toggle\"\n :aria-expanded=\"isActive\"\n :class=\"[label ? 'button--tertiary tw-outline-none tw-min-w-auto' : 'button--icon button tw-rounded']\"\n @click=\"toggle\"\n >\n <span v-if=\"label\" class=\"tw-font-medium tw-flex tw-items-center tw-text-blue hover:tw-text-blue-700\">\n {{ label }}\n <Icon name=\"caret-down\" />\n </span>\n <Icon v-else name=\"ellipsis\" />\n </button>\n </slot>\n\n <transition name=\"fade\" @after-leave=\"resetOffset\">\n <div\n v-show=\"isActive\"\n ref=\"contentRef\"\n data-test=\"ll-dropdown-content\"\n :class=\"[\n classes.content,\n contentClass,\n {\n 'tw-left-0 after:tw-left-6': props.align === 'left',\n 'tw-right-0': props.align === 'right',\n 'tw-max-w-[360px]': !props.fluidContent,\n },\n ]\"\n :style=\"styles\"\n >\n <!-- @slot Dropdown content slot. Receives `dismiss` method, to trigger manual close. You must call dismiss with parentheses. Receives `is-active` prop. -->\n <slot :dismiss=\"dismiss\" :is-active=\"isActive\"></slot>\n </div>\n </transition>\n </div>\n</template>\n\n<style module>\n .content {\n --offset: 0;\n\n @apply tw-shadow\n tw-bg-white\n tw-border\n tw-border-solid\n tw-border-blue\n tw-rounded\n tw-absolute\n tw-z-control\n tw-min-w-[200px];\n\n transform: translateX(calc(var(--offset) * 1px));\n }\n\n /**\n * TODO: these global styles should be componentized in https://leaflink.atlassian.net/browse/STASH-566\n */\n :global(.dropdown__list) {\n @apply tw-bg-white tw-list-none tw-m-1.5 tw-p-0;\n }\n\n :global(.dropdown__item) {\n @apply tw-block tw-mx-0 tw-mt-0 tw-mb-1.5 tw-w-full first:tw-mt-0 last:tw-mb-0;\n }\n\n :global(.dropdown__item) button {\n @apply tw-border-none tw-text-left tw-p-1.5;\n }\n\n :global(.dropdown__item) :where(a, button) {\n @apply tw-rounded\n tw-text-ice-700\n tw-block\n tw-py-[10px]\n tw-px-1.5\n tw-w-full\n disabled:tw-text-ice\n disabled:tw-cursor-default\n hover:tw-bg-ice-200\n hover:tw-text-ice-700\n hover:tw-no-underline\n tw-transition-all\n tw-duration-fast\n tw-ease-swing;\n }\n</style>\n"],"names":["contentRef","ref","dropdownRef","DEFAULT_ITEMS_LIST","items","itemIndex","isActive","styles","classes","useCssModule","watch","val","emit","next","prev","onMounted","props","target","getMountPoint","_a","_b","_c","dismiss","onBeforeUnmount","event","wasOpen","toggle","calculateOffset","onKeyDown","KEY_CODES","resetOffset","nextTick","toggleBCR","top","offset","overflow","calculateElementOverflow","direction","__expose","computed"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Dropdown.js","sources":["../src/components/Dropdown/Dropdown.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, nextTick, onBeforeUnmount, onMounted, ref, useCssModule, watch } from 'vue';\n\n import { KEY_CODES } from '../../constants';\n import vClickoutside from '../../directives/clickoutside/clickoutside';\n import calculateElementOverflow from '../../utils/calculateElementOverflow';\n import { getMountPoint } from '../../utils/helpers';\n import Icon from '../Icon/Icon.vue';\n\n export type DropdownOffset = {\n x?: number;\n y?: number;\n };\n\n export interface DropdownProps {\n /**\n * Used to position the dropdown relative to target\n * Options: left, right\n */\n align?: 'left' | 'right';\n /**\n * When passed, text with caret is displayed instead of default kebab menu.\n */\n label?: string;\n /**\n * If true, dropdown will remain open when clicking on its content. Otherwise, it'll close automatically on click.\n */\n closeManually?: boolean;\n /**\n * Used to horizontally and vertically offset the dropdown in pixels\n * Keep in mind, `x` value is relative to `align` value.\n */\n offset?: DropdownOffset;\n /**\n * If `reattach` is true, the contents will be mounted in the mount point container,\n * so as to circumvent clipping issues from a parent's overflow property.\n */\n reattach?: boolean;\n /**\n * Custom class to apply to the default dropdown content element\n */\n contentClass?: string | string[];\n /**\n * Removes content container's max width\n */\n fluidContent?: boolean;\n }\n\n type DropdownStyles = {\n left?: string;\n right?: string;\n top?: string;\n };\n\n defineOptions({\n name: 'll-dropdown',\n });\n\n const props = withDefaults(defineProps<DropdownProps>(), {\n align: 'right',\n label: '',\n closeManually: false,\n offset: () => ({}),\n reattach: true,\n contentClass: '',\n fluidContent: false,\n });\n\n const emit =\n defineEmits<{\n toggle: [isActive: boolean];\n dismiss: [];\n }>();\n\n const contentRef = ref<HTMLElement | null>(null);\n const dropdownRef = ref<HTMLDivElement | null>(null);\n\n const DEFAULT_ITEMS_LIST = [] as unknown as NodeListOf<Element>;\n\n const items = ref<NodeListOf<Element>>(DEFAULT_ITEMS_LIST);\n const itemIndex = ref(-1);\n const isActive = ref(false);\n\n const styles = ref<DropdownStyles>({});\n const classes = useCssModule();\n\n watch(isActive, (val) => {\n if (!val) {\n itemIndex.value = -1;\n }\n\n emit('toggle', val);\n });\n\n watch(itemIndex, (next, prev) => {\n next in items.value && items.value[next].classList.add('is-highlighted');\n prev in items.value && items.value[prev].classList.remove('is-highlighted');\n });\n\n onMounted(() => {\n if (props.reattach) {\n const target = getMountPoint();\n\n contentRef.value && target.appendChild(contentRef.value);\n }\n\n // if stash-menu exists, use it's items\n if (contentRef.value?.querySelector('.stash-menu')) {\n items.value = contentRef.value?.querySelectorAll('.stash-menu-item') ?? DEFAULT_ITEMS_LIST;\n } else {\n items.value = contentRef.value?.querySelectorAll('.dropdown__item') ?? DEFAULT_ITEMS_LIST;\n }\n\n // avoid calling dismiss with ResizeEvent because it's target is the Window element and it's not a valid Node element to be passed to dismiss\n window.addEventListener('resize', () => dismiss());\n });\n\n onBeforeUnmount(() => {\n window.removeEventListener('resize', () => dismiss());\n contentRef.value?.parentNode?.removeChild(contentRef.value);\n });\n\n /**\n * Dismisses the Dropdown.\n */\n function dismiss(event?: Event) {\n if (\n props.closeManually &&\n (contentRef.value?.contains(event?.target as HTMLElement) || contentRef.value === event?.target)\n ) {\n return;\n }\n\n const wasOpen = isActive.value;\n\n isActive.value = false;\n\n if (wasOpen) {\n emit('dismiss');\n }\n }\n\n /**\n * Opens or closes the Dropdown. If opening, positions and focuses its content.\n */\n async function toggle() {\n if (isActive.value) {\n isActive.value = false;\n } else {\n isActive.value = true;\n await calculateOffset();\n contentRef.value?.focus();\n }\n }\n\n /**\n * Handles all user keyboard input on the Dropdown.\n * @param {KeyboardEvent} e The native keydown event.\n */\n function onKeyDown(e: KeyboardEvent) {\n if (e.keyCode === KEY_CODES.ESCAPE) {\n dismiss();\n } else if (e.keyCode === KEY_CODES.DOWN && itemIndex.value < items.value.length - 1) {\n isActive.value && itemIndex.value++;\n } else if (e.keyCode === KEY_CODES.UP && itemIndex.value > -1) {\n isActive.value && itemIndex.value--;\n } else if (e.keyCode === KEY_CODES.ENTER && itemIndex.value !== -1) {\n isActive.value && items[itemIndex.value].click();\n } else {\n return;\n }\n\n e.preventDefault(); // if keyDown did something / we didn't return\n }\n\n /**\n * Reset any page overflow offset\n */\n function resetOffset() {\n contentRef.value?.style.setProperty('--offset', '0');\n }\n\n /**\n * Calculate the position for the Dropdown content element,\n * relative to the viewport.\n * Repositions the dropdown content element (& arrow)\n * if it overflows the page (including gutter).\n */\n async function calculateOffset() {\n await nextTick();\n\n const toggleBCR = dropdownRef.value?.getBoundingClientRect() || ({} as DOMRect);\n const top = toggleBCR.top + toggleBCR.height;\n const offset = {\n x: 0,\n y: 0,\n ...props.offset,\n };\n\n if (props.reattach) {\n styles.value = {\n left: props.align === 'left' ? `${Math.round(toggleBCR.left) + offset.x}px` : undefined,\n right:\n props.align === 'right'\n ? `${document.documentElement.clientWidth - Math.round(toggleBCR.right) + offset.x}px`\n : undefined,\n top: `${window.scrollY + top + offset.y}px`,\n };\n await nextTick(); // wait for style updates to sync in the DOM\n }\n\n const overflow = calculateElementOverflow(contentRef?.value);\n\n if (overflow) {\n const direction = props.align === 'left' ? '-' : '';\n contentRef.value?.style.setProperty('--offset', `${direction}${overflow.value}`);\n }\n }\n\n defineExpose({\n isActive: computed(() => isActive.value),\n toggle,\n dismiss,\n });\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n v-clickoutside=\"dismiss\"\n class=\"tw-inline-block tw-relative\"\n data-test=\"ll-dropdown\"\n @keydown=\"onKeyDown\"\n >\n <!-- @slot Toggle component slot, receives `toggle` method to trigger Dropdown display -->\n <slot name=\"toggle\" :is-active=\"isActive\" :toggle=\"toggle\">\n <button\n data-test=\"button|toggle\"\n :aria-expanded=\"isActive\"\n :class=\"[label ? 'button--tertiary tw-outline-none tw-min-w-auto' : 'button--icon button tw-rounded']\"\n @click=\"toggle\"\n >\n <span v-if=\"label\" class=\"tw-font-medium tw-flex tw-items-center tw-text-blue-500 hover:tw-text-blue-700\">\n {{ label }}\n <Icon name=\"caret-down\" />\n </span>\n <Icon v-else name=\"ellipsis\" />\n </button>\n </slot>\n\n <transition name=\"fade\" @after-leave=\"resetOffset\">\n <div\n v-show=\"isActive\"\n ref=\"contentRef\"\n data-test=\"ll-dropdown-content\"\n :class=\"[\n classes.content,\n contentClass,\n {\n 'tw-left-0 after:tw-left-6': props.align === 'left',\n 'tw-right-0': props.align === 'right',\n 'tw-max-w-[360px]': !props.fluidContent,\n },\n ]\"\n :style=\"styles\"\n >\n <!-- @slot Dropdown content slot. Receives `dismiss` method, to trigger manual close. You must call dismiss with parentheses. Receives `is-active` prop. -->\n <slot :dismiss=\"dismiss\" :is-active=\"isActive\"></slot>\n </div>\n </transition>\n </div>\n</template>\n\n<style module>\n .content {\n --offset: 0;\n\n @apply tw-shadow\n tw-bg-white\n tw-border\n tw-border-solid\n tw-border-blue-500\n tw-rounded\n tw-absolute\n tw-z-control\n tw-min-w-[200px];\n\n transform: translateX(calc(var(--offset) * 1px));\n }\n\n /**\n * TODO: these global styles should be componentized in https://leaflink.atlassian.net/browse/STASH-566\n */\n :global(.dropdown__list) {\n @apply tw-bg-white tw-list-none tw-m-1.5 tw-p-0;\n }\n\n :global(.dropdown__item) {\n @apply tw-block tw-mx-0 tw-mt-0 tw-mb-1.5 tw-w-full first:tw-mt-0 last:tw-mb-0;\n }\n\n :global(.dropdown__item) button {\n @apply tw-border-none tw-text-left tw-p-1.5;\n }\n\n :global(.dropdown__item) :where(a, button) {\n @apply tw-rounded\n tw-text-ice-700\n tw-block\n tw-py-[10px]\n tw-px-1.5\n tw-w-full\n disabled:tw-text-ice-500\n disabled:tw-cursor-default\n hover:tw-bg-ice-200\n hover:tw-text-ice-700\n hover:tw-no-underline\n tw-transition-all\n tw-duration-fast\n tw-ease-swing;\n }\n</style>\n"],"names":["contentRef","ref","dropdownRef","DEFAULT_ITEMS_LIST","items","itemIndex","isActive","styles","classes","useCssModule","watch","val","emit","next","prev","onMounted","props","target","getMountPoint","_a","_b","_c","dismiss","onBeforeUnmount","event","wasOpen","toggle","calculateOffset","onKeyDown","KEY_CODES","resetOffset","nextTick","toggleBCR","top","offset","overflow","calculateElementOverflow","direction","__expose","computed"],"mappings":"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"}
|
package/dist/FilterChip.js
CHANGED
|
@@ -4,7 +4,6 @@ import D from "./Chip.js";
|
|
|
4
4
|
import x from "./Icon.js";
|
|
5
5
|
import { _ as B } from "./_plugin-vue_export-helper-dad06003.js";
|
|
6
6
|
import "lodash-es/get";
|
|
7
|
-
import "./colors-13e95ebf.js";
|
|
8
7
|
import "./utils/colorScheme.js";
|
|
9
8
|
import "lodash-es/uniqueId";
|
|
10
9
|
import "./index-79ce320f.js";
|
|
@@ -83,8 +82,8 @@ const F = { class: "tw-flex tw-items-center" }, O = ["aria-label", "title"], R =
|
|
|
83
82
|
"caret-rotate": "_caret-rotate_1o49d_105"
|
|
84
83
|
}, g = {
|
|
85
84
|
$style: V
|
|
86
|
-
},
|
|
85
|
+
}, L = /* @__PURE__ */ B(S, [["__cssModules", g]]);
|
|
87
86
|
export {
|
|
88
|
-
|
|
87
|
+
L as default
|
|
89
88
|
};
|
|
90
89
|
//# sourceMappingURL=FilterChip.js.map
|
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-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":"
|
|
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/FilterDrawerItem.js
CHANGED
|
@@ -4,7 +4,6 @@ import F from "./Chip.js";
|
|
|
4
4
|
import { D as I } from "./DataViewFilters.keys-c80ffabe.js";
|
|
5
5
|
import C from "./Icon.js";
|
|
6
6
|
import "lodash-es/get";
|
|
7
|
-
import "./colors-13e95ebf.js";
|
|
8
7
|
import "./utils/colorScheme.js";
|
|
9
8
|
import "./_plugin-vue_export-helper-dad06003.js";
|
|
10
9
|
import "lodash-es/uniqueId";
|
|
@@ -14,7 +13,7 @@ const g = { class: "tw-py-4" }, k = { class: "tw-flex tw-justify-between tw-item
|
|
|
14
13
|
key: 0,
|
|
15
14
|
class: "tw-text-xs",
|
|
16
15
|
"data-test": "description"
|
|
17
|
-
}, E = { class: "tw-inline-flex tw-items-center tw-gap-6" },
|
|
16
|
+
}, E = { class: "tw-inline-flex tw-items-center tw-gap-6" }, q = /* @__PURE__ */ w({
|
|
18
17
|
__name: "FilterDrawerItem",
|
|
19
18
|
props: {
|
|
20
19
|
group: {},
|
|
@@ -22,8 +21,8 @@ const g = { class: "tw-py-4" }, k = { class: "tw-flex tw-justify-between tw-item
|
|
|
22
21
|
description: {}
|
|
23
22
|
},
|
|
24
23
|
emits: ["navigate"],
|
|
25
|
-
setup(
|
|
26
|
-
const e =
|
|
24
|
+
setup(u, { emit: p }) {
|
|
25
|
+
const e = u, i = f(I.key);
|
|
27
26
|
if (!(i != null && i.useFiltersInstance))
|
|
28
27
|
throw new Error(
|
|
29
28
|
"FilterDropdown must be used within a <DataViewFilters> that receives an instance of useFilters()."
|
|
@@ -32,7 +31,7 @@ const g = { class: "tw-py-4" }, k = { class: "tw-flex tw-justify-between tw-item
|
|
|
32
31
|
return (N, n) => (o(), l("div", g, [
|
|
33
32
|
t("button", {
|
|
34
33
|
class: "tw-w-full tw-outline-none focus:tw-outline-blue-500 tw-border-b tw-border-ice-500",
|
|
35
|
-
onClick: n[0] || (n[0] = (T) =>
|
|
34
|
+
onClick: n[0] || (n[0] = (T) => p("navigate"))
|
|
36
35
|
}, [
|
|
37
36
|
t("div", k, [
|
|
38
37
|
t("div", y, [
|
|
@@ -61,6 +60,6 @@ const g = { class: "tw-py-4" }, k = { class: "tw-flex tw-justify-between tw-item
|
|
|
61
60
|
}
|
|
62
61
|
});
|
|
63
62
|
export {
|
|
64
|
-
|
|
63
|
+
q as default
|
|
65
64
|
};
|
|
66
65
|
//# sourceMappingURL=FilterDrawerItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterDrawerItem.js","sources":["../src/components/FilterDrawerItem/FilterDrawerItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, inject } from 'vue';\n\n import { t } from '../../locale';\n import Chip from '../Chip/Chip.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from '../DataViewFilters/DataViewFilters.keys';\n import Icon from '../Icon/Icon.vue';\n\n export interface FilterDrawerItemProps {\n /** The name of a filter group */\n group: string;\n title: string;\n description?: string;\n }\n const props = defineProps<FilterDrawerItemProps>();\n\n export interface FilterDrawerItemEmits {\n (e: 'navigate');\n }\n const emit = defineEmits<FilterDrawerItemEmits>();\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 { activeFiltersCounts } = dataViewFiltersUtils.useFiltersInstance;\n\n const activeCount = computed(() => activeFiltersCounts.value[props.group]);\n</script>\n\n<template>\n <div class=\"tw-py-4\">\n <button\n class=\"tw-w-full tw-outline-none focus:tw-outline-blue-500 tw-border-b tw-border-ice-500\"\n @click=\"emit('navigate')\"\n >\n <div class=\"tw-flex tw-justify-between tw-items-center tw-self-stretch\">\n <div class=\"tw-flex tw-flex-col tw-items-start\">\n <h4>{{ props.title }}</h4>\n <div v-if=\"props.description\" class=\"tw-text-xs\" data-test=\"description\">\n {{ props.description }}\n </div>\n </div>\n <div class=\"tw-inline-flex tw-items-center tw-gap-6\">\n <Chip\n v-if=\"activeCount\"\n color=\"blue\"\n radius=\"pill\"\n shade=\"main\"\n :aria-label=\"t('ll.numberOfActiveFilters')\"\n :title=\"t('ll.numberOfActiveFilters')\"\n >\n {{ activeCount }}\n </Chip>\n <Icon name=\"chevron-right\" />\n </div>\n </div>\n </button>\n </div>\n</template>\n"],"names":["dataViewFiltersUtils","inject","DATA_VIEW_FILTERS_UTILS_INJECTION","activeFiltersCounts","activeCount","computed","props"],"mappings":"
|
|
1
|
+
{"version":3,"file":"FilterDrawerItem.js","sources":["../src/components/FilterDrawerItem/FilterDrawerItem.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, inject } from 'vue';\n\n import { t } from '../../locale';\n import Chip from '../Chip/Chip.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from '../DataViewFilters/DataViewFilters.keys';\n import Icon from '../Icon/Icon.vue';\n\n export interface FilterDrawerItemProps {\n /** The name of a filter group */\n group: string;\n title: string;\n description?: string;\n }\n const props = defineProps<FilterDrawerItemProps>();\n\n export interface FilterDrawerItemEmits {\n (e: 'navigate');\n }\n const emit = defineEmits<FilterDrawerItemEmits>();\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 { activeFiltersCounts } = dataViewFiltersUtils.useFiltersInstance;\n\n const activeCount = computed(() => activeFiltersCounts.value[props.group]);\n</script>\n\n<template>\n <div class=\"tw-py-4\">\n <button\n class=\"tw-w-full tw-outline-none focus:tw-outline-blue-500 tw-border-b tw-border-ice-500\"\n @click=\"emit('navigate')\"\n >\n <div class=\"tw-flex tw-justify-between tw-items-center tw-self-stretch\">\n <div class=\"tw-flex tw-flex-col tw-items-start\">\n <h4>{{ props.title }}</h4>\n <div v-if=\"props.description\" class=\"tw-text-xs\" data-test=\"description\">\n {{ props.description }}\n </div>\n </div>\n <div class=\"tw-inline-flex tw-items-center tw-gap-6\">\n <Chip\n v-if=\"activeCount\"\n color=\"blue\"\n radius=\"pill\"\n shade=\"main\"\n :aria-label=\"t('ll.numberOfActiveFilters')\"\n :title=\"t('ll.numberOfActiveFilters')\"\n >\n {{ activeCount }}\n </Chip>\n <Icon name=\"chevron-right\" />\n </div>\n </div>\n </button>\n </div>\n</template>\n"],"names":["dataViewFiltersUtils","inject","DATA_VIEW_FILTERS_UTILS_INJECTION","activeFiltersCounts","activeCount","computed","props"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;iBAqBQA,IAAuBC,EAAOC,EAAkC,GAAG;AAErE,QAAA,EAACF,KAAA,QAAAA,EAAsB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAIE,UAAA,EAAE,qBAAAG,EAAoB,IAAIH,EAAqB,oBAE/CI,IAAcC,EAAS,MAAMF,EAAoB,MAAMG,EAAM,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/FilterDropdown.js
CHANGED
|
@@ -5,7 +5,7 @@ import D from "./Button.js";
|
|
|
5
5
|
import "lodash-es/cloneDeep";
|
|
6
6
|
import "lodash-es/uniqueId";
|
|
7
7
|
import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
|
|
8
|
-
import "./Paginate.vue_used_vue_type_style_index_0_lang.module-
|
|
8
|
+
import "./Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js";
|
|
9
9
|
import { D as F } from "./DataView.vue_used_vue_type_style_index_0_lang.module-d878ca9a.js";
|
|
10
10
|
import { D as z } from "./DataViewFilters.keys-c80ffabe.js";
|
|
11
11
|
import G from "./Dropdown.js";
|
|
@@ -23,12 +23,11 @@ import "lodash-es/isPlainObject";
|
|
|
23
23
|
import "./Icon.js";
|
|
24
24
|
import "./index-79ce320f.js";
|
|
25
25
|
import "./Chip.js";
|
|
26
|
-
import "./colors-13e95ebf.js";
|
|
27
26
|
import "./utils/colorScheme.js";
|
|
28
27
|
const q = { class: "tw-flex tw-flex-col tw-rounded tw-h-full" }, H = { class: "tw-grow tw-rounded-t tw-relative tw-overflow-hidden" }, K = {
|
|
29
28
|
key: 0,
|
|
30
29
|
class: "tw-absolute tw-bottom-0 tw-left-0 tw-right-0 tw-z-10 tw-h-[20px] tw-bg-scroll-shadow tw-pointer-events-none"
|
|
31
|
-
}, M = { class: "tw-bg-ice-100 tw-border-t-ice-200 tw-border-b-ice-100 tw-border-x-ice-100 tw-border-solid tw-border tw-p-3.5 tw-flex tw-justify-end tw-rounded-b tw-gap-6" },
|
|
30
|
+
}, M = { class: "tw-bg-ice-100 tw-border-t-ice-200 tw-border-b-ice-100 tw-border-x-ice-100 tw-border-solid tw-border tw-p-3.5 tw-flex tw-justify-end tw-rounded-b tw-gap-6" }, bt = /* @__PURE__ */ L({
|
|
32
31
|
__name: "FilterDropdown",
|
|
33
32
|
props: {
|
|
34
33
|
label: {},
|
|
@@ -148,6 +147,6 @@ const q = { class: "tw-flex tw-flex-col tw-rounded tw-h-full" }, H = { class: "t
|
|
|
148
147
|
}
|
|
149
148
|
});
|
|
150
149
|
export {
|
|
151
|
-
|
|
150
|
+
bt as default
|
|
152
151
|
};
|
|
153
152
|
//# sourceMappingURL=FilterDropdown.js.map
|
|
@@ -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 =\n 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-full tw-max-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-flex-col tw-rounded tw-h-full\">\n <div class=\"tw-grow tw-rounded-t tw-relative tw-overflow-hidden\">\n <div class=\"tw-p-3.5 tw-h-full tw-overflow-auto\" @scroll=\"onScroll\" @scrollend=\"onScrollEnd\">\n <slot></slot>\n </div>\n <Transition name=\"fade\">\n <div\n v-if=\"showShadow\"\n class=\"\n tw-absolute\n tw-bottom-0\n tw-left-0\n tw-right-0\n tw-z-10\n tw-h-[20px]\n tw-bg-scroll-shadow\n tw-pointer-events-none\n \"\n ></div>\n </Transition>\n </div>\n\n <footer\n class=\"\n tw-bg-ice-100\n tw-border-t-ice-200\n tw-border-b-ice-100\n tw-border-x-ice-100\n tw-border-solid\n tw-border\n tw-p-3.5\n tw-flex\n tw-justify-end\n tw-rounded-b\n tw-gap-6\n \"\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":["isDataViewLoading","inject","DATA_VIEW_INJECTION","dataViewFiltersUtils","DATA_VIEW_FILTERS_UTILS_INJECTION","applyFilters","resetFilterGroup","activeFiltersCounts","undoWorkingFilters","dropdownRef","ref","isOpen","computed","_a","onToggleButtonClick","wasOpen","emit","handleResetClick","props","handleApplyClick","preventDismiss","_b","onDismiss","showShadow","onScroll","throttle","event","onScrollEnd"],"mappings":"
|
|
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 =\n 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-full tw-max-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-flex-col tw-rounded tw-h-full\">\n <div class=\"tw-grow tw-rounded-t tw-relative tw-overflow-hidden\">\n <div class=\"tw-p-3.5 tw-h-full tw-overflow-auto\" @scroll=\"onScroll\" @scrollend=\"onScrollEnd\">\n <slot></slot>\n </div>\n <Transition name=\"fade\">\n <div\n v-if=\"showShadow\"\n class=\"\n tw-absolute\n tw-bottom-0\n tw-left-0\n tw-right-0\n tw-z-10\n tw-h-[20px]\n tw-bg-scroll-shadow\n tw-pointer-events-none\n \"\n ></div>\n </Transition>\n </div>\n\n <footer\n class=\"\n tw-bg-ice-100\n tw-border-t-ice-200\n tw-border-b-ice-100\n tw-border-x-ice-100\n tw-border-solid\n tw-border\n tw-p-3.5\n tw-flex\n tw-justify-end\n tw-rounded-b\n tw-gap-6\n \"\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":["isDataViewLoading","inject","DATA_VIEW_INJECTION","dataViewFiltersUtils","DATA_VIEW_FILTERS_UTILS_INJECTION","applyFilters","resetFilterGroup","activeFiltersCounts","undoWorkingFilters","dropdownRef","ref","isOpen","computed","_a","onToggleButtonClick","wasOpen","emit","handleResetClick","props","handleApplyClick","preventDismiss","_b","onDismiss","showShadow","onScroll","throttle","event","onScrollEnd"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BQ,EAAE,WAAWA,MAAsBC,EAAOC,EAAoB,KAAKA,EAAoB,QAAQ,GAE/FC,IAAuBF,EAAOG,EAAkC,GAAG;AAErE,QAAA,EAACD,KAAA,QAAAA,EAAsB;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAIJ,UAAM,EAAE,cAAAE,GAAc,kBAAAC,GAAkB,qBAAAC,GAAqB,oBAAAC,MAC3DL,EAAqB,oBAEjBM,IAAcC,KACdC,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,MACiBP,KACnBQ,EAAK,SAAS;AAAA,IAElB;AAEA,aAASC,IAAmB;;AAC1B,MAAAX,EAAiBY,EAAM,KAAK,GAC5BF,EAAK,OAAO,IACZH,IAAAJ,EAAY,UAAZ,QAAAI,EAAmB;AAAA,IACrB;AAEA,mBAAeM,IAAmB;;AAC1B,YAAA,EAAE,gBAAAC,MAAoB,QAAMP,IAAAK,EAAM,YAAN,gBAAAL,EAAA,KAAAK,OAAsBb,EAAa,KAAK;AAE1E,MAAKe,MACHC,IAAAZ,EAAY,UAAZ,QAAAY,EAAmB;AAAA,IAEvB;AAEA,aAASC,IAAY;AACA,MAAAd,KACnBQ,EAAK,SAAS;AAAA,IAChB;AAEM,UAAAO,IAAab,EAAI,EAAK,GACtBc,IAAWC,EAAS,CAACC,MAAiB;AAC1C,MAAKA,EAAM,WAENA,EAAM,OAAuB,YAAY,IAC5CH,EAAW,QAAQ,KAEnBA,EAAW,QAAQ;AAAA,OAEpB,GAAG;AAEN,aAASI,IAAc;AACrB,iBAAW,MAAM;AACf,QAAAJ,EAAW,QAAQ;AAAA,SAClB,GAAI;AAAA,IACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/FilterSelect.js
CHANGED
|
@@ -6,13 +6,12 @@ import "lodash-es/get";
|
|
|
6
6
|
import "lodash-es/uniqueId";
|
|
7
7
|
import "./Label.vue_vue_type_script_setup_true_lang-1d29d98a.js";
|
|
8
8
|
import "./Chip.js";
|
|
9
|
-
import "./colors-13e95ebf.js";
|
|
10
9
|
import "./utils/colorScheme.js";
|
|
11
10
|
import "./Icon.js";
|
|
12
11
|
import "./index-79ce320f.js";
|
|
13
12
|
import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
|
|
14
13
|
import "./_plugin-vue_export-helper-dad06003.js";
|
|
15
|
-
const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, D = ["id"], O = ["for"], U = ["id", "value"], I = ["for"],
|
|
14
|
+
const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, D = ["id"], O = ["for"], U = ["id", "value"], I = ["for"], X = /* @__PURE__ */ S({
|
|
16
15
|
__name: "FilterSelect",
|
|
17
16
|
props: {
|
|
18
17
|
name: {},
|
|
@@ -23,35 +22,35 @@ const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, D = ["id"], O = ["for"],
|
|
|
23
22
|
},
|
|
24
23
|
emits: ["update:modelValue"],
|
|
25
24
|
setup(V, { emit: c }) {
|
|
26
|
-
const e = V,
|
|
25
|
+
const e = V, o = p({
|
|
27
26
|
get() {
|
|
28
27
|
return e.modelValue;
|
|
29
28
|
},
|
|
30
|
-
set(
|
|
31
|
-
c("update:modelValue",
|
|
29
|
+
set(l) {
|
|
30
|
+
c("update:modelValue", l);
|
|
32
31
|
}
|
|
33
32
|
}), n = p({
|
|
34
33
|
get() {
|
|
35
34
|
return e.options.length === e.modelValue.length;
|
|
36
35
|
},
|
|
37
|
-
set(
|
|
38
|
-
c("update:modelValue",
|
|
36
|
+
set(l) {
|
|
37
|
+
c("update:modelValue", l ? e.options.map((a) => a.value) : []);
|
|
39
38
|
}
|
|
40
39
|
});
|
|
41
|
-
function i(
|
|
42
|
-
return `${e.name}--${
|
|
40
|
+
function i(l) {
|
|
41
|
+
return `${e.name}--${l.value}`;
|
|
43
42
|
}
|
|
44
|
-
function g(
|
|
45
|
-
return e.modelValue.includes(
|
|
43
|
+
function g(l) {
|
|
44
|
+
return e.modelValue.includes(l.value);
|
|
46
45
|
}
|
|
47
|
-
function k(
|
|
48
|
-
const
|
|
49
|
-
|
|
46
|
+
function k(l) {
|
|
47
|
+
const a = o.value.filter((t) => t !== l);
|
|
48
|
+
a.length === o.value.length && a.push(l), o.value = a;
|
|
50
49
|
}
|
|
51
50
|
function w() {
|
|
52
51
|
n.value = !n.value;
|
|
53
52
|
}
|
|
54
|
-
return (
|
|
53
|
+
return (l, a) => (r(), $(N, {
|
|
55
54
|
class: "stash-filter-select",
|
|
56
55
|
fieldset: "",
|
|
57
56
|
label: e.label
|
|
@@ -63,7 +62,7 @@ const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, D = ["id"], O = ["for"],
|
|
|
63
62
|
}, [
|
|
64
63
|
f(s("input", {
|
|
65
64
|
id: `${e.name}--all`,
|
|
66
|
-
"onUpdate:modelValue":
|
|
65
|
+
"onUpdate:modelValue": a[0] || (a[0] = (t) => n.value = t),
|
|
67
66
|
class: "sr-only",
|
|
68
67
|
tabindex: "-1",
|
|
69
68
|
type: "checkbox",
|
|
@@ -86,29 +85,29 @@ const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, D = ["id"], O = ["for"],
|
|
|
86
85
|
}, 8, ["is-selected", "onKeypress"])
|
|
87
86
|
], 8, O)
|
|
88
87
|
])) : K("", !0),
|
|
89
|
-
(r(!0), d(A, null, B(e.options, (
|
|
90
|
-
key: i(
|
|
88
|
+
(r(!0), d(A, null, B(e.options, (t) => (r(), d("div", {
|
|
89
|
+
key: i(t)
|
|
91
90
|
}, [
|
|
92
91
|
f(s("input", {
|
|
93
|
-
id: i(
|
|
94
|
-
"onUpdate:modelValue":
|
|
92
|
+
id: i(t),
|
|
93
|
+
"onUpdate:modelValue": a[1] || (a[1] = (m) => o.value = m),
|
|
95
94
|
class: "sr-only",
|
|
96
95
|
tabindex: "-1",
|
|
97
96
|
type: "checkbox",
|
|
98
|
-
value:
|
|
97
|
+
value: t.value
|
|
99
98
|
}, null, 8, U), [
|
|
100
|
-
[v,
|
|
99
|
+
[v, o.value]
|
|
101
100
|
]),
|
|
102
101
|
s("label", {
|
|
103
|
-
for: i(
|
|
102
|
+
for: i(t)
|
|
104
103
|
}, [
|
|
105
104
|
_(y, {
|
|
106
|
-
"is-selected": g(
|
|
105
|
+
"is-selected": g(t),
|
|
107
106
|
tabindex: "0",
|
|
108
|
-
onKeypress: h((m) => k(
|
|
107
|
+
onKeypress: h((m) => k(t.value), ["enter"])
|
|
109
108
|
}, {
|
|
110
109
|
default: u(() => [
|
|
111
|
-
b(x(
|
|
110
|
+
b(x(t.label), 1)
|
|
112
111
|
]),
|
|
113
112
|
_: 2
|
|
114
113
|
}, 1032, ["is-selected", "onKeypress"])
|
|
@@ -121,6 +120,6 @@ const F = { class: "tw-flex tw-flex-wrap tw-gap-1.5" }, D = ["id"], O = ["for"],
|
|
|
121
120
|
}
|
|
122
121
|
});
|
|
123
122
|
export {
|
|
124
|
-
|
|
123
|
+
X as default
|
|
125
124
|
};
|
|
126
125
|
//# 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 Field from '../Field/Field.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import { FilterSelectModelValue, FilterSelectOption } from './FilterSelect.types';\n\n export interface FilterSelectProps {\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 label: 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 =\n 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 class=\"stash-filter-select\" fieldset :label=\"props.label\">\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=\"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=\"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":["selected","computed","props","value","emit","isAllSelected","isChecked","option","getOptionId","isOptionSelected","onEnter","enteredValue","newSelected","onEnterAll"],"mappings":"
|
|
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 Field from '../Field/Field.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import { FilterSelectModelValue, FilterSelectOption } from './FilterSelect.types';\n\n export interface FilterSelectProps {\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 label: 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 =\n 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 class=\"stash-filter-select\" fieldset :label=\"props.label\">\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=\"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=\"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":["selected","computed","props","value","emit","isAllSelected","isChecked","option","getOptionId","isOptionSelected","onEnter","enteredValue","newSelected","onEnterAll"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;iBA0CQA,IAAWC,EAAS;AAAA,MACxB,MAAM;AACJ,eAAOC,EAAM;AAAA,MACf;AAAA,MACA,IAAIC,GAAO;AACT,QAAAC,EAAK,qBAAqBD,CAAK;AAAA,MACjC;AAAA,IAAA,CACD,GAEKE,IAAgBJ,EAAS;AAAA,MAC7B,MAAM;AACJ,eAAOC,EAAM,QAAQ,WAAWA,EAAM,WAAW;AAAA,MACnD;AAAA,MACA,IAAII,GAAW;AACR,QAAAF,EAAA,qBAAqBE,IAAYJ,EAAM,QAAQ,IAAI,CAACK,MAAWA,EAAO,KAAK,IAAI,CAAE,CAAA;AAAA,MACxF;AAAA,IAAA,CACD;AAED,aAASC,EAAYD,GAA4B;AAC/C,aAAO,GAAGL,EAAM,IAAI,KAAKK,EAAO,KAAK;AAAA,IACvC;AAEA,aAASE,EAAiBF,GAA4B;AACpD,aAAOL,EAAM,WAAW,SAASK,EAAO,KAAK;AAAA,IAC/C;AAEA,aAASG,EAAQC,GAA2C;AAC1D,YAAMC,IAAcZ,EAAS,MAAM,OAAO,CAACG,MAAUA,MAAUQ,CAAY;AAE3E,MAAIC,EAAY,WAAWZ,EAAS,MAAM,UACxCY,EAAY,KAAKD,CAAY,GAG/BX,EAAS,QAAQY;AAAA,IACnB;AAEA,aAASC,IAAa;AACN,MAAAR,EAAA,QAAQ,CAACA,EAAc;AAAA,IACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/Filters.js
CHANGED
|
@@ -24,7 +24,7 @@ import "lodash-es/isFinite";
|
|
|
24
24
|
import "lodash-es/isPlainObject";
|
|
25
25
|
import "./Button.vue_used_vue_type_style_index_0_lang.module-b77978d6.js";
|
|
26
26
|
import "lodash-es/uniqueId";
|
|
27
|
-
import "./Checkbox.
|
|
27
|
+
import "./Checkbox.vue_vue_type_style_index_0_scoped_0d7e7fd0_lang-4ed993c7.js";
|
|
28
28
|
import "./utils/createValidDate.js";
|
|
29
29
|
import "./index-5e5945a9.js";
|
|
30
30
|
import "./index-fe8d3765.js";
|
|
@@ -46,7 +46,6 @@ import "./searchFuzzy-74a7de1c.js";
|
|
|
46
46
|
import "./clickoutside.js";
|
|
47
47
|
import "./MenusPlugin-5e93f0a5.js";
|
|
48
48
|
import "./Chip.js";
|
|
49
|
-
import "./colors-13e95ebf.js";
|
|
50
49
|
import "./utils/colorScheme.js";
|
|
51
50
|
const ie = {
|
|
52
51
|
"filter-button-group": "_filter-button-group_1pk5m_177"
|
|
@@ -342,8 +341,8 @@ function ce(l, r, o, i, t, s) {
|
|
|
342
341
|
}
|
|
343
342
|
const de = {
|
|
344
343
|
$style: ie
|
|
345
|
-
},
|
|
344
|
+
}, rt = /* @__PURE__ */ le(oe, [["render", ce], ["__cssModules", de]]);
|
|
346
345
|
export {
|
|
347
|
-
|
|
346
|
+
rt as default
|
|
348
347
|
};
|
|
349
348
|
//# sourceMappingURL=Filters.js.map
|
package/dist/Filters.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Filters.js","sources":["../src/components/Filters/Filters.vue"],"sourcesContent":["<script>\n import cloneDeep from 'lodash-es/cloneDeep';\n import merge from 'lodash-es/merge';\n import { nextTick, ref, toRefs } from 'vue';\n\n import useValidation from '../../composables/useValidation/useValidation';\n import { LLLV_CHANGE_TRIGGERS } from '../../constants';\n import { t } from '../../locale';\n import { persistentStorage } from '../../storage';\n import Button from '../Button/Button.vue';\n import Checkbox from '../Checkbox/Checkbox.vue';\n import DatePicker from '../DatePicker/DatePicker.vue';\n import Input from '../Input/Input.vue';\n import InputOptions from '../InputOptions/InputOptions.vue';\n import Radio from '../Radio/Radio.vue';\n import Select from '../Select/Select.vue';\n\n export default {\n name: 'll-filters',\n\n components: {\n 'll-button': Button,\n 'll-checkbox': Checkbox,\n 'll-input': Input,\n 'll-input-options': InputOptions,\n 'll-radio': Radio,\n 'll-select': Select,\n DatePicker,\n },\n\n props: {\n /**\n * Whether to disable the Apply button\n */\n disableApply: Boolean,\n /**\n * Whether to disable the Clear button\n */\n disableClear: Boolean,\n /**\n * Whether to disable the sticky filters\n * If disabled, a default pre-selected value(s) can be added to\n * the filter component's attributes\n */\n disablePersistency: Boolean,\n /**\n * Filters schema\n */\n schema: {\n type: Array,\n default: () => [],\n },\n /**\n * Validation schema function that returns an object\n */\n validationSchema: {\n type: Function,\n default: () => () => undefined,\n },\n },\n\n emits: ['change', 'submit', 'reset'],\n\n setup(props) {\n const { validationSchema: getValidationSchema } = toRefs(props);\n const validationSchema = getValidationSchema.value();\n const validationValues = ref({});\n\n // Without ref, `this.validation` will always evaluate to its initial value of `undefined` due to lack of reactivity.\n const validation = ref();\n\n function initValidation() {\n if (validationSchema?.toString() !== '[object Object]') {\n return;\n }\n\n validationValues.value = Object.keys(validationSchema).reduce((values, fieldName) => {\n values[fieldName] = undefined;\n\n return values;\n }, {});\n\n const validationRules = Object.entries(validationSchema).reduce((rules, [fieldName, fieldRules]) => {\n rules[fieldName] = fieldRules.map((fieldRule) => {\n return fieldRule(validationValues);\n });\n\n return rules;\n }, {});\n\n validation.value = useValidation({ rules: validationRules, values: validationValues });\n validation.value.validate();\n }\n\n return {\n validation,\n validationValues,\n initValidation,\n };\n },\n\n data() {\n return {\n applyText: t('ll.apply'),\n clearText: t('ll.clear'),\n filters: {},\n filterValues: {},\n forceRenderCount: 0,\n };\n },\n\n watch: {\n filterValues: {\n /**\n * Maps filters to a partcular object structure:\n * @param {IFilterSchemaItem} newFilterValues all selected filters\n * @returns {IFilter}\n */\n handler: function (newFilterValues) {\n const filters = Object.keys(newFilterValues).reduce((acc, i) => {\n const schema = this.schema[i];\n\n if (!schema || !schema.fieldToFilter) {\n return acc;\n }\n\n const item = newFilterValues[i];\n\n // Ignore empty string or undefined/null filter values\n if (item === '' || item == null) {\n return acc;\n }\n\n const trackBy = schema.attributes.trackBy || 'id';\n const isObject = typeof item === 'object';\n const isCustomFilterComponent = typeof schema.type === 'object';\n // TODO: remove handling of schema.attributes.multiple when we remove the vue-multiselect version of Select\n const isMultiple =\n (isCustomFilterComponent && schema.attributes.multiple) ||\n (!isCustomFilterComponent &&\n schema.type.includes('ll-select') &&\n (schema.attributes.multiple || !schema.attributes.single));\n const filterBy = isMultiple\n ? // local storage might have item stored as an object from the old Select\n (Array.isArray(item) ? item : [item]).map((v) => v[trackBy])\n : isObject\n ? [item[trackBy]]\n : [item];\n\n const groupedWith = schema.groupedWith;\n\n if (groupedWith) {\n filterBy[0] = {\n index: groupedWith,\n value: newFilterValues[groupedWith],\n };\n filterBy.push({\n index: Number(i),\n value: newFilterValues[i],\n });\n }\n\n filterBy.length &&\n (acc[schema.fieldToFilter] = {\n // don't add to `filters` if no filterBy\n filterBy,\n filterType: schema.type, // Informs the applied filter count\n isMultiple,\n ...('fn' in schema && { customFilter: schema.fn }),\n });\n\n return acc;\n }, {});\n\n this.filters = filters;\n this.$emit('change', filters);\n },\n\n deep: true,\n immediate: true,\n },\n\n filters() {\n if (this.validation) {\n this.updateValidationValues();\n }\n },\n },\n\n async created() {\n // initFilterValues updates the filterValues so using await nextTick() forces the code\n // after it to wait until nextTick is done, at which point the filterValues will\n // be done initializing. Otherwise, applyFilters sometimes applies the wrong\n // filters because filterValues is not done updating.\n this.initFilterValues();\n await nextTick();\n this.initValidation();\n this.applyFilters({ trigger: LLLV_CHANGE_TRIGGERS.LOAD });\n },\n\n methods: {\n initFilterValues() {\n if (this.disablePersistency) {\n this.filterValues = this.getDefaultFilterValues();\n\n return;\n }\n\n this.filterValues = this.getPersistentFilterValues() || this.getDefaultFilterValues();\n },\n\n /**\n * Apply the selected filters and save them to localStorage.\n * ListView calls this method using a ref to Filters.\n * The trigger option is used in ListView.\n * @param {object} [options] - optional parameters\n * @param {string} [options.trigger] - the action that triggered this function call\n */\n async applyFilters({ trigger = LLLV_CHANGE_TRIGGERS.APPLY } = {}) {\n if (this.validation) {\n await this.validation.validate();\n\n if (this.validation.hasErrors) {\n return;\n }\n }\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n this.$emit('submit', { trigger });\n },\n\n resetFilters() {\n this.filterValues = this.getDefaultFilterValues();\n\n this.forceRenderCount++;\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n // Emit after filters are updated\n this.$nextTick(() => {\n this.$emit('reset');\n });\n },\n\n /**\n * Returns pre-defined filter values to become the default values\n */\n getDefaultFilterValues() {\n return this.schema.reduce((acc, item, filterIndex) => {\n if (item.type === 'll-checkbox') {\n acc[filterIndex] = item.attributes.checked || false;\n } else if (Object.prototype.hasOwnProperty.call(item.attributes, 'modelValue')) {\n acc[filterIndex] = item.attributes.modelValue;\n }\n\n return acc;\n }, {});\n },\n\n /**\n * Intended for external use, when filter values need to be set for the user\n */\n setFilterValues(newValues) {\n this.filterValues = merge({}, this.filterValues, newValues);\n this.forceRenderCount++;\n },\n\n updateValidationValues() {\n const validatable = Object.keys(this.validationSchema());\n\n this.schema.forEach((fieldSchema, filterIndex) => {\n const fieldToFilter = fieldSchema.fieldToFilter;\n const validate = validatable.includes(fieldToFilter);\n\n if (validate) {\n const filter = this.filters[fieldToFilter];\n\n /**\n * Get all validatable fields.\n * Use parsed value of filters that are set,\n * otherwise fall back to `filterValue` value if not set.\n */\n const filterValue = filter\n ? filter.isMultiple\n ? filter.filterBy\n : filter.filterBy[0]\n : this.filterValues[filterIndex];\n\n this.validationValues[fieldToFilter] = filterValue;\n }\n });\n },\n\n /**\n * Change handler for filter fields\n */\n onChange(filter, filterValues, filterIndex) {\n if (filter.on?.change) {\n // Maps to `on.change` handlers in the filter schema.\n filter.on.change(filterValues, filterIndex);\n }\n },\n\n /**\n * Select input event handler for filter fields\n */\n onSelectInput(newValue, filter, filterIndex) {\n if (newValue === undefined) {\n delete this.filterValues[filterIndex]; // prevent undefined filterValues which cause an empty result list\n } else {\n this.filterValues[filterIndex] = newValue;\n }\n\n this.onChange(filter, this.filterValues, filterIndex);\n },\n\n /**\n * Get filter values from local storage.\n * @returns {any}\n */\n getPersistentFilterValues() {\n return persistentStorage.get('filter-values');\n },\n\n /**\n * Clone new filterValues to remove reactivity, and save them to localStorage.\n * @param {object} newValues - the filterValues to be persisted in localStorage\n */\n persistFilterValues(newValues) {\n persistentStorage.set('filter-values', cloneDeep(newValues));\n },\n },\n };\n</script>\n\n<template>\n <div class=\"ll-grid ll-grid-cols-4 md:ll-grid-cols-12\">\n <template v-for=\"(filter, filterIndex) in schema\">\n <div\n v-if=\"!filter.hidden\"\n :key=\"`${filterIndex} ${forceRenderCount}`\"\n class=\"field-wrapper col-span-4 md:col-span-3\"\n :class=\"{ 'hidden-sm-only': !filter.type, 'flex align-bottom': filter.type === 'll-checkbox' }\"\n :data-test=\"`filter|${filter.fieldToFilter}`\"\n >\n <!-- Filter component -->\n <ll-select\n v-if=\"filter.type === 'll-select'\"\n v-bind=\"filter.attributes\"\n :error=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n :model-value=\"filterValues[filterIndex]\"\n @update:model-value=\"(newValue) => onSelectInput(newValue, filter, filterIndex)\"\n />\n <ll-checkbox\n v-else-if=\"filter.type === 'll-checkbox'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <ll-radio\n v-else-if=\"filter.type === 'll-radio'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <component\n v-bind=\"filter.attributes\"\n :is=\"filter.type\"\n v-else-if=\"filter.type\"\n v-model=\"filterValues[filterIndex]\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:model-value=\"onChange(filter, filterValues, filterIndex)\"\n >\n <template v-if=\"filter.slots && filter.slots.selected\" #selected=\"{ option }\">\n <component :is=\"filter.slots.selected\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.option\" #option=\"{ option }\">\n <component :is=\"filter.slots.option\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.prepend\" #prepend>\n <span v-html=\"filter.slots.prepend\"></span>\n </template>\n <template v-if=\"filter.slots && filter.slots.append\" #append>\n <span v-html=\"filter.slots.append\"></span>\n </template>\n </component>\n </div>\n </template>\n <div\n class=\"flex align-right align-bottom button-grid col-span-4 md:col-span-12\"\n :class=\"$style['filter-button-group']\"\n >\n <ll-button secondary data-test=\"button|reset-filters\" :disabled=\"disableClear\" @click=\"resetFilters\">\n {{ clearText }}\n </ll-button>\n <ll-button\n primary\n data-test=\"button|apply-filters\"\n :disabled=\"disableApply || validation?.hasErrors\"\n @click=\"applyFilters\"\n >\n {{ applyText }}\n </ll-button>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" module>\n .filter-button-group {\n @include breakpoint('sm-only') {\n display: flex;\n flex-direction: column-reverse;\n }\n\n button {\n @include breakpoint('sm-only') {\n width: 100% !important;\n }\n\n &:nth-child(2) {\n @include breakpoint('sm-only') {\n margin-bottom: space(2);\n }\n }\n }\n }\n</style>\n"],"names":["_sfc_main","Button","Checkbox","Input","InputOptions","Radio","Select","DatePicker","props","getValidationSchema","toRefs","validationSchema","validationValues","ref","validation","initValidation","values","fieldName","validationRules","rules","fieldRules","fieldRule","useValidation","t","newFilterValues","filters","acc","schema","item","trackBy","isObject","isCustomFilterComponent","isMultiple","filterBy","v","groupedWith","nextTick","LLLV_CHANGE_TRIGGERS","trigger","filterIndex","newValues","merge","validatable","fieldSchema","fieldToFilter","filter","filterValue","filterValues","_a","newValue","persistentStorage","cloneDeep","_hoisted_1","_openBlock","_createElementBlock","_Fragment","_renderList","$props","$data","_normalizeClass","_createBlock","_component_ll_select","_mergeProps","$setup","_b","$options","_component_ll_checkbox","$event","_c","_d","_component_ll_radio","_e","_f","_resolveDynamicComponent","_g","_h","_withCtx","option","_normalizeProps","_guardReactiveProps","_createElementVNode","_ctx","_createVNode","_component_ll_button"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Filters.js","sources":["../src/components/Filters/Filters.vue"],"sourcesContent":["<script>\n import cloneDeep from 'lodash-es/cloneDeep';\n import merge from 'lodash-es/merge';\n import { nextTick, ref, toRefs } from 'vue';\n\n import useValidation from '../../composables/useValidation/useValidation';\n import { LLLV_CHANGE_TRIGGERS } from '../../constants';\n import { t } from '../../locale';\n import { persistentStorage } from '../../storage';\n import Button from '../Button/Button.vue';\n import Checkbox from '../Checkbox/Checkbox.vue';\n import DatePicker from '../DatePicker/DatePicker.vue';\n import Input from '../Input/Input.vue';\n import InputOptions from '../InputOptions/InputOptions.vue';\n import Radio from '../Radio/Radio.vue';\n import Select from '../Select/Select.vue';\n\n export default {\n name: 'll-filters',\n\n components: {\n 'll-button': Button,\n 'll-checkbox': Checkbox,\n 'll-input': Input,\n 'll-input-options': InputOptions,\n 'll-radio': Radio,\n 'll-select': Select,\n DatePicker,\n },\n\n props: {\n /**\n * Whether to disable the Apply button\n */\n disableApply: Boolean,\n /**\n * Whether to disable the Clear button\n */\n disableClear: Boolean,\n /**\n * Whether to disable the sticky filters\n * If disabled, a default pre-selected value(s) can be added to\n * the filter component's attributes\n */\n disablePersistency: Boolean,\n /**\n * Filters schema\n */\n schema: {\n type: Array,\n default: () => [],\n },\n /**\n * Validation schema function that returns an object\n */\n validationSchema: {\n type: Function,\n default: () => () => undefined,\n },\n },\n\n emits: ['change', 'submit', 'reset'],\n\n setup(props) {\n const { validationSchema: getValidationSchema } = toRefs(props);\n const validationSchema = getValidationSchema.value();\n const validationValues = ref({});\n\n // Without ref, `this.validation` will always evaluate to its initial value of `undefined` due to lack of reactivity.\n const validation = ref();\n\n function initValidation() {\n if (validationSchema?.toString() !== '[object Object]') {\n return;\n }\n\n validationValues.value = Object.keys(validationSchema).reduce((values, fieldName) => {\n values[fieldName] = undefined;\n\n return values;\n }, {});\n\n const validationRules = Object.entries(validationSchema).reduce((rules, [fieldName, fieldRules]) => {\n rules[fieldName] = fieldRules.map((fieldRule) => {\n return fieldRule(validationValues);\n });\n\n return rules;\n }, {});\n\n validation.value = useValidation({ rules: validationRules, values: validationValues });\n validation.value.validate();\n }\n\n return {\n validation,\n validationValues,\n initValidation,\n };\n },\n\n data() {\n return {\n applyText: t('ll.apply'),\n clearText: t('ll.clear'),\n filters: {},\n filterValues: {},\n forceRenderCount: 0,\n };\n },\n\n watch: {\n filterValues: {\n /**\n * Maps filters to a partcular object structure:\n * @param {IFilterSchemaItem} newFilterValues all selected filters\n * @returns {IFilter}\n */\n handler: function (newFilterValues) {\n const filters = Object.keys(newFilterValues).reduce((acc, i) => {\n const schema = this.schema[i];\n\n if (!schema || !schema.fieldToFilter) {\n return acc;\n }\n\n const item = newFilterValues[i];\n\n // Ignore empty string or undefined/null filter values\n if (item === '' || item == null) {\n return acc;\n }\n\n const trackBy = schema.attributes.trackBy || 'id';\n const isObject = typeof item === 'object';\n const isCustomFilterComponent = typeof schema.type === 'object';\n // TODO: remove handling of schema.attributes.multiple when we remove the vue-multiselect version of Select\n const isMultiple =\n (isCustomFilterComponent && schema.attributes.multiple) ||\n (!isCustomFilterComponent &&\n schema.type.includes('ll-select') &&\n (schema.attributes.multiple || !schema.attributes.single));\n const filterBy = isMultiple\n ? // local storage might have item stored as an object from the old Select\n (Array.isArray(item) ? item : [item]).map((v) => v[trackBy])\n : isObject\n ? [item[trackBy]]\n : [item];\n\n const groupedWith = schema.groupedWith;\n\n if (groupedWith) {\n filterBy[0] = {\n index: groupedWith,\n value: newFilterValues[groupedWith],\n };\n filterBy.push({\n index: Number(i),\n value: newFilterValues[i],\n });\n }\n\n filterBy.length &&\n (acc[schema.fieldToFilter] = {\n // don't add to `filters` if no filterBy\n filterBy,\n filterType: schema.type, // Informs the applied filter count\n isMultiple,\n ...('fn' in schema && { customFilter: schema.fn }),\n });\n\n return acc;\n }, {});\n\n this.filters = filters;\n this.$emit('change', filters);\n },\n\n deep: true,\n immediate: true,\n },\n\n filters() {\n if (this.validation) {\n this.updateValidationValues();\n }\n },\n },\n\n async created() {\n // initFilterValues updates the filterValues so using await nextTick() forces the code\n // after it to wait until nextTick is done, at which point the filterValues will\n // be done initializing. Otherwise, applyFilters sometimes applies the wrong\n // filters because filterValues is not done updating.\n this.initFilterValues();\n await nextTick();\n this.initValidation();\n this.applyFilters({ trigger: LLLV_CHANGE_TRIGGERS.LOAD });\n },\n\n methods: {\n initFilterValues() {\n if (this.disablePersistency) {\n this.filterValues = this.getDefaultFilterValues();\n\n return;\n }\n\n this.filterValues = this.getPersistentFilterValues() || this.getDefaultFilterValues();\n },\n\n /**\n * Apply the selected filters and save them to localStorage.\n * ListView calls this method using a ref to Filters.\n * The trigger option is used in ListView.\n * @param {object} [options] - optional parameters\n * @param {string} [options.trigger] - the action that triggered this function call\n */\n async applyFilters({ trigger = LLLV_CHANGE_TRIGGERS.APPLY } = {}) {\n if (this.validation) {\n await this.validation.validate();\n\n if (this.validation.hasErrors) {\n return;\n }\n }\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n this.$emit('submit', { trigger });\n },\n\n resetFilters() {\n this.filterValues = this.getDefaultFilterValues();\n\n this.forceRenderCount++;\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n // Emit after filters are updated\n this.$nextTick(() => {\n this.$emit('reset');\n });\n },\n\n /**\n * Returns pre-defined filter values to become the default values\n */\n getDefaultFilterValues() {\n return this.schema.reduce((acc, item, filterIndex) => {\n if (item.type === 'll-checkbox') {\n acc[filterIndex] = item.attributes.checked || false;\n } else if (Object.prototype.hasOwnProperty.call(item.attributes, 'modelValue')) {\n acc[filterIndex] = item.attributes.modelValue;\n }\n\n return acc;\n }, {});\n },\n\n /**\n * Intended for external use, when filter values need to be set for the user\n */\n setFilterValues(newValues) {\n this.filterValues = merge({}, this.filterValues, newValues);\n this.forceRenderCount++;\n },\n\n updateValidationValues() {\n const validatable = Object.keys(this.validationSchema());\n\n this.schema.forEach((fieldSchema, filterIndex) => {\n const fieldToFilter = fieldSchema.fieldToFilter;\n const validate = validatable.includes(fieldToFilter);\n\n if (validate) {\n const filter = this.filters[fieldToFilter];\n\n /**\n * Get all validatable fields.\n * Use parsed value of filters that are set,\n * otherwise fall back to `filterValue` value if not set.\n */\n const filterValue = filter\n ? filter.isMultiple\n ? filter.filterBy\n : filter.filterBy[0]\n : this.filterValues[filterIndex];\n\n this.validationValues[fieldToFilter] = filterValue;\n }\n });\n },\n\n /**\n * Change handler for filter fields\n */\n onChange(filter, filterValues, filterIndex) {\n if (filter.on?.change) {\n // Maps to `on.change` handlers in the filter schema.\n filter.on.change(filterValues, filterIndex);\n }\n },\n\n /**\n * Select input event handler for filter fields\n */\n onSelectInput(newValue, filter, filterIndex) {\n if (newValue === undefined) {\n delete this.filterValues[filterIndex]; // prevent undefined filterValues which cause an empty result list\n } else {\n this.filterValues[filterIndex] = newValue;\n }\n\n this.onChange(filter, this.filterValues, filterIndex);\n },\n\n /**\n * Get filter values from local storage.\n * @returns {any}\n */\n getPersistentFilterValues() {\n return persistentStorage.get('filter-values');\n },\n\n /**\n * Clone new filterValues to remove reactivity, and save them to localStorage.\n * @param {object} newValues - the filterValues to be persisted in localStorage\n */\n persistFilterValues(newValues) {\n persistentStorage.set('filter-values', cloneDeep(newValues));\n },\n },\n };\n</script>\n\n<template>\n <div class=\"ll-grid ll-grid-cols-4 md:ll-grid-cols-12\">\n <template v-for=\"(filter, filterIndex) in schema\">\n <div\n v-if=\"!filter.hidden\"\n :key=\"`${filterIndex} ${forceRenderCount}`\"\n class=\"field-wrapper col-span-4 md:col-span-3\"\n :class=\"{ 'hidden-sm-only': !filter.type, 'flex align-bottom': filter.type === 'll-checkbox' }\"\n :data-test=\"`filter|${filter.fieldToFilter}`\"\n >\n <!-- Filter component -->\n <ll-select\n v-if=\"filter.type === 'll-select'\"\n v-bind=\"filter.attributes\"\n :error=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n :model-value=\"filterValues[filterIndex]\"\n @update:model-value=\"(newValue) => onSelectInput(newValue, filter, filterIndex)\"\n />\n <ll-checkbox\n v-else-if=\"filter.type === 'll-checkbox'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <ll-radio\n v-else-if=\"filter.type === 'll-radio'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <component\n v-bind=\"filter.attributes\"\n :is=\"filter.type\"\n v-else-if=\"filter.type\"\n v-model=\"filterValues[filterIndex]\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:model-value=\"onChange(filter, filterValues, filterIndex)\"\n >\n <template v-if=\"filter.slots && filter.slots.selected\" #selected=\"{ option }\">\n <component :is=\"filter.slots.selected\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.option\" #option=\"{ option }\">\n <component :is=\"filter.slots.option\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.prepend\" #prepend>\n <span v-html=\"filter.slots.prepend\"></span>\n </template>\n <template v-if=\"filter.slots && filter.slots.append\" #append>\n <span v-html=\"filter.slots.append\"></span>\n </template>\n </component>\n </div>\n </template>\n <div\n class=\"flex align-right align-bottom button-grid col-span-4 md:col-span-12\"\n :class=\"$style['filter-button-group']\"\n >\n <ll-button secondary data-test=\"button|reset-filters\" :disabled=\"disableClear\" @click=\"resetFilters\">\n {{ clearText }}\n </ll-button>\n <ll-button\n primary\n data-test=\"button|apply-filters\"\n :disabled=\"disableApply || validation?.hasErrors\"\n @click=\"applyFilters\"\n >\n {{ applyText }}\n </ll-button>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" module>\n .filter-button-group {\n @include breakpoint('sm-only') {\n display: flex;\n flex-direction: column-reverse;\n }\n\n button {\n @include breakpoint('sm-only') {\n width: 100% !important;\n }\n\n &:nth-child(2) {\n @include breakpoint('sm-only') {\n margin-bottom: space(2);\n }\n }\n }\n }\n</style>\n"],"names":["_sfc_main","Button","Checkbox","Input","InputOptions","Radio","Select","DatePicker","props","getValidationSchema","toRefs","validationSchema","validationValues","ref","validation","initValidation","values","fieldName","validationRules","rules","fieldRules","fieldRule","useValidation","t","newFilterValues","filters","acc","schema","item","trackBy","isObject","isCustomFilterComponent","isMultiple","filterBy","v","groupedWith","nextTick","LLLV_CHANGE_TRIGGERS","trigger","filterIndex","newValues","merge","validatable","fieldSchema","fieldToFilter","filter","filterValue","filterValues","_a","newValue","persistentStorage","cloneDeep","_hoisted_1","_openBlock","_createElementBlock","_Fragment","_renderList","$props","$data","_normalizeClass","_createBlock","_component_ll_select","_mergeProps","$setup","_b","$options","_component_ll_checkbox","$event","_c","_d","_component_ll_radio","_e","_f","_resolveDynamicComponent","_g","_h","_withCtx","option","_normalizeProps","_guardReactiveProps","_createElementVNode","_ctx","_createVNode","_component_ll_button"],"mappings":"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"}
|