@ulu/frontend-vue 0.1.0-beta.1 → 0.1.0-beta.11
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 +113 -2
- package/dist/{breakpoints-ClT9bfZm.js → breakpoints-DS8rH5b6.js} +1 -1
- package/dist/frontend-vue.js +47 -51
- package/dist/index-C5pNSAJH.js +6579 -0
- package/lib/components/collapsible/UluAccordion.vue +1 -1
- package/lib/components/collapsible/UluModal.vue +4 -5
- package/lib/components/collapsible/UluOverflowPopover.vue +1 -1
- package/lib/components/elements/UluAlert.vue +1 -2
- package/lib/components/elements/UluButton.vue +2 -2
- package/lib/components/elements/UluButtonVerbose.vue +119 -0
- package/lib/components/elements/UluExternalLink.vue +1 -2
- package/lib/components/elements/UluIcon.vue +11 -16
- package/lib/components/elements/UluTag.vue +1 -1
- package/lib/components/index.js +1 -1
- package/lib/components/layout/UluAdaptiveLayout.vue +3 -5
- package/lib/components/layout/UluTitleRail.vue +9 -5
- package/lib/components/layout/UluWhenBreakpoint.vue +71 -77
- package/lib/components/navigation/UluBreadcrumb.vue +1 -2
- package/lib/components/navigation/UluMenu.vue +1 -1
- package/lib/components/systems/facets/UluFacetsFilters.vue +73 -0
- package/lib/components/systems/facets/UluFacetsList.vue +13 -14
- package/lib/components/systems/facets/UluFacetsResults.vue +57 -0
- package/lib/components/systems/facets/UluFacetsSearch.vue +26 -49
- package/lib/components/systems/facets/UluFacetsSidebarLayout.vue +31 -0
- package/lib/components/systems/facets/UluFacetsSort.vue +45 -0
- package/lib/components/systems/facets/_mock-data.js +40 -0
- package/lib/components/systems/facets/useFacets.js +140 -0
- package/lib/components/systems/index.js +4 -1
- package/lib/components/systems/table-sticky/UluTableSticky.vue +1 -1
- package/lib/composables/index.js +1 -0
- package/lib/composables/useRequiredInject.js +26 -0
- package/lib/index.js +0 -1
- package/lib/meta.js +14 -0
- package/lib/plugins/core/index.js +87 -0
- package/lib/plugins/index.js +1 -0
- package/lib/plugins/toast/UluToast.vue +1 -1
- package/package.json +31 -9
- package/types/components/index.d.ts +2 -0
- package/types/components/index.d.ts.map +1 -0
- package/types/components/systems/index.d.ts +2 -0
- package/types/components/systems/index.d.ts.map +1 -0
- package/types/components/systems/scroll-anchors/symbols.d.ts +7 -0
- package/types/components/systems/scroll-anchors/symbols.d.ts.map +1 -0
- package/types/composables/index.d.ts +6 -0
- package/types/composables/index.d.ts.map +1 -0
- package/types/composables/useBreakpointManager.d.ts +8 -0
- package/types/composables/useBreakpointManager.d.ts.map +1 -0
- package/types/composables/useIcon.d.ts +6 -0
- package/types/composables/useIcon.d.ts.map +1 -0
- package/types/composables/useModifiers.d.ts +69 -0
- package/types/composables/useModifiers.d.ts.map +1 -0
- package/types/composables/useRequiredInject.d.ts +8 -0
- package/types/composables/useRequiredInject.d.ts.map +1 -0
- package/types/composables/useWindowResize.d.ts +6 -0
- package/types/composables/useWindowResize.d.ts.map +1 -0
- package/types/index.d.ts +4 -0
- package/types/index.d.ts.map +1 -0
- package/types/meta.d.ts +10 -0
- package/types/meta.d.ts.map +1 -0
- package/types/plugins/breakpoints/index.d.ts +2 -0
- package/types/plugins/breakpoints/index.d.ts.map +1 -0
- package/types/plugins/core/index.d.ts +3 -0
- package/types/plugins/core/index.d.ts.map +1 -0
- package/types/plugins/index.d.ts +6 -0
- package/types/plugins/index.d.ts.map +1 -0
- package/types/plugins/modals/api.d.ts +34 -0
- package/types/plugins/modals/api.d.ts.map +1 -0
- package/types/plugins/modals/index.d.ts +28 -0
- package/types/plugins/modals/index.d.ts.map +1 -0
- package/types/plugins/modals/useModals.d.ts +2 -0
- package/types/plugins/modals/useModals.d.ts.map +1 -0
- package/types/plugins/popovers/defaults.d.ts +14 -0
- package/types/plugins/popovers/defaults.d.ts.map +1 -0
- package/types/plugins/popovers/directive.d.ts +8 -0
- package/types/plugins/popovers/directive.d.ts.map +1 -0
- package/types/plugins/popovers/index.d.ts +7 -0
- package/types/plugins/popovers/index.d.ts.map +1 -0
- package/types/plugins/popovers/manager.d.ts +52 -0
- package/types/plugins/popovers/manager.d.ts.map +1 -0
- package/types/plugins/popovers/useFollow.d.ts +31 -0
- package/types/plugins/popovers/useFollow.d.ts.map +1 -0
- package/types/plugins/popovers/utils.d.ts +2 -0
- package/types/plugins/popovers/utils.d.ts.map +1 -0
- package/types/plugins/toast/defaults.d.ts +15 -0
- package/types/plugins/toast/defaults.d.ts.map +1 -0
- package/types/plugins/toast/index.d.ts +5 -0
- package/types/plugins/toast/index.d.ts.map +1 -0
- package/types/plugins/toast/store.d.ts +22 -0
- package/types/plugins/toast/store.d.ts.map +1 -0
- package/types/plugins/toast/useToast.d.ts +2 -0
- package/types/plugins/toast/useToast.d.ts.map +1 -0
- package/types/utils/dom.d.ts +8 -0
- package/types/utils/dom.d.ts.map +1 -0
- package/types/utils/placeholder.d.ts +8 -0
- package/types/utils/placeholder.d.ts.map +1 -0
- package/types/utils/vue-router.d.ts +122 -0
- package/types/utils/vue-router.d.ts.map +1 -0
- package/dist/frontend-vue.umd.cjs +0 -561
- package/dist/index-P5Rwl_Dl.js +0 -7263
- package/lib/components/forms/UluFormDropzone.vue +0 -62
- package/lib/components/systems/facets/UluFacets.vue +0 -380
- package/lib/settings.js +0 -119
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<UluIcon
|
|
27
27
|
v-if="titleIcon"
|
|
28
28
|
class="modal__title-icon"
|
|
29
|
-
:
|
|
29
|
+
:icon="titleIcon"
|
|
30
30
|
/>
|
|
31
31
|
<span class="modal__title-text">{{ title }}</span>
|
|
32
32
|
</slot>
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
<slot name="closeIcon">
|
|
36
36
|
<UluIcon
|
|
37
37
|
class="modal__close-icon"
|
|
38
|
-
|
|
39
|
-
:definition="closeIcon"
|
|
38
|
+
:icon="closeIcon || 'type:close'"
|
|
40
39
|
/>
|
|
41
40
|
</slot>
|
|
42
41
|
</button>
|
|
@@ -56,7 +55,7 @@
|
|
|
56
55
|
</div>
|
|
57
56
|
<button v-if="resizerEnabled" class="modal__resizer" ref="resizer" type="button">
|
|
58
57
|
<slot name="resizerIcon">
|
|
59
|
-
<UluIcon class="modal__resizer-icon" :
|
|
58
|
+
<UluIcon class="modal__resizer-icon" :icon="resizerIcon || resizerIconType" />
|
|
60
59
|
</slot>
|
|
61
60
|
</button>
|
|
62
61
|
</dialog>
|
|
@@ -213,7 +212,7 @@
|
|
|
213
212
|
});
|
|
214
213
|
|
|
215
214
|
const resizerIconType = computed(() => {
|
|
216
|
-
return props.position === 'center' ? 'resizeBoth' : 'resizeHorizontal';
|
|
215
|
+
return props.position === 'center' ? 'type:resizeBoth' : 'type:resizeHorizontal';
|
|
217
216
|
});
|
|
218
217
|
|
|
219
218
|
// Define the internal modifiers object as a computed property (so it can react to changes)
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<slot name="before"/>
|
|
23
23
|
<UluIcon
|
|
24
24
|
v-if="icon && (iconBefore || iconOnly)"
|
|
25
|
-
:
|
|
25
|
+
:icon="icon"
|
|
26
26
|
class="button__icon"
|
|
27
27
|
/>
|
|
28
28
|
<span v-if="($slots.default || text) && !iconOnly">
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
</span>
|
|
33
33
|
<UluIcon
|
|
34
34
|
v-if="icon && (!iconBefore && !iconOnly)"
|
|
35
|
-
:
|
|
35
|
+
:icon="icon"
|
|
36
36
|
class="button__icon"
|
|
37
37
|
/>
|
|
38
38
|
<slot name="after"/>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component
|
|
3
|
+
:is="element"
|
|
4
|
+
class="button-verbose"
|
|
5
|
+
:class="[
|
|
6
|
+
{
|
|
7
|
+
'button-verbose--inline': inline,
|
|
8
|
+
'button-verbose--full-width': fullWidth,
|
|
9
|
+
},
|
|
10
|
+
resolvedModifiers
|
|
11
|
+
]"
|
|
12
|
+
v-bind="attrs"
|
|
13
|
+
>
|
|
14
|
+
<component
|
|
15
|
+
v-if="$slots.title || title"
|
|
16
|
+
:is="titleElement"
|
|
17
|
+
class="button-verbose__title"
|
|
18
|
+
>
|
|
19
|
+
<slot name="title">
|
|
20
|
+
{{ title }}
|
|
21
|
+
</slot>
|
|
22
|
+
</component>
|
|
23
|
+
<span v-if="$slots.default || body" class="button-verbose__body">
|
|
24
|
+
<slot>
|
|
25
|
+
{{ body }}
|
|
26
|
+
</slot>
|
|
27
|
+
</span>
|
|
28
|
+
<UluIcon
|
|
29
|
+
v-if="icon"
|
|
30
|
+
:icon="icon"
|
|
31
|
+
class="button-verbose__icon"
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
/>
|
|
34
|
+
</component>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script>
|
|
38
|
+
import { RouterLink } from "vue-router";
|
|
39
|
+
import UluIcon from "./UluIcon.vue";
|
|
40
|
+
import { useModifiers } from "../../composables/useModifiers.js";
|
|
41
|
+
|
|
42
|
+
export default {
|
|
43
|
+
name: "UluButtonVerbose",
|
|
44
|
+
components: {
|
|
45
|
+
UluIcon
|
|
46
|
+
},
|
|
47
|
+
props: {
|
|
48
|
+
/**
|
|
49
|
+
* The title of the button. Can also be passed via slot.
|
|
50
|
+
*/
|
|
51
|
+
title: String,
|
|
52
|
+
/**
|
|
53
|
+
* Optional element to use for title
|
|
54
|
+
*/
|
|
55
|
+
titleElement: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: "strong"
|
|
58
|
+
},
|
|
59
|
+
/**
|
|
60
|
+
* The body text of the button. Can also be passed via slot.
|
|
61
|
+
*/
|
|
62
|
+
body: String,
|
|
63
|
+
/**
|
|
64
|
+
* Icon prop, if used will set the icon for the button, will use UluIcon (which uses font-awesome icons conditionally)
|
|
65
|
+
*/
|
|
66
|
+
icon: [String, Array],
|
|
67
|
+
/**
|
|
68
|
+
* If set will use router-link for button component and pass to prop
|
|
69
|
+
*/
|
|
70
|
+
to: [String, Object],
|
|
71
|
+
/**
|
|
72
|
+
* Sets the button to a link with this href
|
|
73
|
+
*/
|
|
74
|
+
href: String,
|
|
75
|
+
/**
|
|
76
|
+
* Set a value for target attribute when button is a link
|
|
77
|
+
*/
|
|
78
|
+
target: String,
|
|
79
|
+
/**
|
|
80
|
+
* Sets the download attribute on the link (passing string [filename] will populate the download attribute, true will just include it as boolean attribute)
|
|
81
|
+
*/
|
|
82
|
+
download: [Boolean, String],
|
|
83
|
+
/**
|
|
84
|
+
* Preset to set inline style
|
|
85
|
+
*/
|
|
86
|
+
inline: Boolean,
|
|
87
|
+
/**
|
|
88
|
+
* Preset to set full-width style
|
|
89
|
+
*/
|
|
90
|
+
fullWidth: Boolean,
|
|
91
|
+
/**
|
|
92
|
+
* Modifiers (to add any modifier classes based on base class [ie. 'tertiary'])
|
|
93
|
+
*/
|
|
94
|
+
modifiers: [String, Array]
|
|
95
|
+
},
|
|
96
|
+
setup(props) {
|
|
97
|
+
const { resolvedModifiers } = useModifiers({ props, baseClass: "button-verbose" });
|
|
98
|
+
return { resolvedModifiers };
|
|
99
|
+
},
|
|
100
|
+
computed: {
|
|
101
|
+
element() {
|
|
102
|
+
return this.to ? RouterLink : this.href ? "a" : "button";
|
|
103
|
+
},
|
|
104
|
+
attrs() {
|
|
105
|
+
const { to, href, download, target } = this;
|
|
106
|
+
const attrs = to ? { to } : href ? { href } : {};
|
|
107
|
+
if (href) {
|
|
108
|
+
if (target) {
|
|
109
|
+
attrs.target = target;
|
|
110
|
+
}
|
|
111
|
+
if (download) {
|
|
112
|
+
attrs.download = typeof download === "string" ? download : true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return attrs;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
</script>
|
|
@@ -17,53 +17,48 @@
|
|
|
17
17
|
</template>
|
|
18
18
|
|
|
19
19
|
<script setup>
|
|
20
|
-
import { ref, defineAsyncComponent, markRaw, watchEffect, computed } from "vue";
|
|
20
|
+
import { ref, defineAsyncComponent, markRaw, watchEffect, computed, inject } from "vue";
|
|
21
21
|
import { useIcon } from "../../composables/useIcon.js";
|
|
22
|
-
import { getSetting, getIconByType } from "../../settings.js";
|
|
23
22
|
|
|
23
|
+
const uluCore = inject('uluCore');
|
|
24
24
|
const faIconComponent = ref(null);
|
|
25
25
|
const { getIconProps, getClassesFromDefinition } = useIcon();
|
|
26
26
|
|
|
27
27
|
let FaModule;
|
|
28
28
|
|
|
29
29
|
const props = defineProps({
|
|
30
|
-
/**
|
|
31
|
-
* Semantic type of icon to use, will be resolved from settings
|
|
32
|
-
*/
|
|
33
|
-
type: String,
|
|
34
30
|
/**
|
|
35
31
|
* Icon definition can be string (fa classes), or array or object (any prop format FaIcon accepts)
|
|
36
32
|
* - This will override the 'type' prop if both are provided
|
|
37
33
|
*/
|
|
38
|
-
|
|
34
|
+
icon: [String, Array, Object, Boolean],
|
|
39
35
|
});
|
|
40
36
|
|
|
41
37
|
const useStaticFa = computed(() => {
|
|
42
|
-
return getSetting("fontAwesomeStatic");
|
|
38
|
+
return uluCore.getSetting("fontAwesomeStatic");
|
|
43
39
|
});
|
|
44
40
|
|
|
45
41
|
const customIconComponent = computed(() => {
|
|
46
|
-
return getSetting("iconComponent");
|
|
42
|
+
return uluCore.getSetting("iconComponent");
|
|
47
43
|
});
|
|
48
44
|
|
|
49
45
|
const iconPropResolver = computed(() => {
|
|
50
|
-
return getSetting("iconPropResolver");
|
|
46
|
+
return uluCore.getSetting("iconPropResolver");
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
// Resolve the final icon definition, giving precedence to the `definition` prop
|
|
54
50
|
const resolvedDefinition = computed(() => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
if (props.type) {
|
|
51
|
+
const { icon } = props;
|
|
52
|
+
if (typeof icon === 'string' && icon.startsWith('type:')) {
|
|
59
53
|
try {
|
|
60
|
-
|
|
54
|
+
const type = icon.substring(5);
|
|
55
|
+
return uluCore.getIcon(type);
|
|
61
56
|
} catch (e) {
|
|
62
57
|
console.warn(e);
|
|
63
58
|
return null;
|
|
64
59
|
}
|
|
65
60
|
}
|
|
66
|
-
return
|
|
61
|
+
return icon;
|
|
67
62
|
});
|
|
68
63
|
|
|
69
64
|
const customIconProps = computed(() => {
|
package/lib/components/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export { default as UluAlert } from './elements/UluAlert.vue';
|
|
|
17
17
|
export { default as UluBadge } from './elements/UluBadge.vue';
|
|
18
18
|
export { default as UluBadgeStack } from './elements/UluBadgeStack.vue';
|
|
19
19
|
export { default as UluButton } from './elements/UluButton.vue';
|
|
20
|
+
export { default as UluButtonVerbose } from './elements/UluButtonVerbose.vue';
|
|
20
21
|
export { default as UluCallout } from './elements/UluCallout.vue';
|
|
21
22
|
export { default as UluCard } from './elements/UluCard.vue';
|
|
22
23
|
export { default as UluDefinitionList } from './elements/UluDefinitionList.vue';
|
|
@@ -28,7 +29,6 @@ export { default as UluSpokeSpinner } from './elements/UluSpokeSpinner.vue';
|
|
|
28
29
|
export { default as UluTag } from './elements/UluTag.vue';
|
|
29
30
|
export { default as UluCheckboxMenu } from './forms/UluCheckboxMenu.vue';
|
|
30
31
|
export { default as UluFileDisplay } from './forms/UluFileDisplay.vue';
|
|
31
|
-
export { default as UluFormDropzone } from './forms/UluFormDropzone.vue';
|
|
32
32
|
export { default as UluFormFile } from './forms/UluFormFile.vue';
|
|
33
33
|
export { default as UluFormMessage } from './forms/UluFormMessage.vue';
|
|
34
34
|
export { default as UluFormSelect } from './forms/UluFormSelect.vue';
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
<slot v-else name="mobile" />
|
|
4
4
|
</template>
|
|
5
5
|
|
|
6
|
-
<script>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
inject: ["uluIsMobile"],
|
|
10
|
-
};
|
|
6
|
+
<script setup>
|
|
7
|
+
import { useRequiredInject } from '../../composables/useRequiredInject.js';
|
|
8
|
+
const uluIsMobile = useRequiredInject('uluIsMobile');
|
|
11
9
|
</script>
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
class="rail rail--title-rail"
|
|
4
|
+
:class="{
|
|
5
|
+
'rail--rule' : rule
|
|
6
|
+
}"
|
|
7
|
+
>
|
|
3
8
|
<div class="rail__item rail__item--title" :class="classes.itemTitle">
|
|
4
9
|
<component
|
|
5
10
|
class="layout-flex type-max-width-small no-margin"
|
|
@@ -8,10 +13,9 @@
|
|
|
8
13
|
:style="{ alignItems: iconAlign }"
|
|
9
14
|
>
|
|
10
15
|
<UluIcon
|
|
11
|
-
v-if="icon
|
|
16
|
+
v-if="icon"
|
|
12
17
|
:class="classes.icon"
|
|
13
|
-
:
|
|
14
|
-
:definition="icon"
|
|
18
|
+
:icon="icon"
|
|
15
19
|
/>
|
|
16
20
|
<slot>
|
|
17
21
|
{{ title }}
|
|
@@ -38,7 +42,6 @@
|
|
|
38
42
|
type: String,
|
|
39
43
|
default: "baseline"
|
|
40
44
|
},
|
|
41
|
-
iconType: String,
|
|
42
45
|
classes: {
|
|
43
46
|
type: Object,
|
|
44
47
|
default: () => ({
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
type: String,
|
|
52
55
|
default: "h2"
|
|
53
56
|
},
|
|
57
|
+
rule: Boolean
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
</script>
|
|
@@ -2,85 +2,79 @@
|
|
|
2
2
|
<slot v-if="shouldShow" />
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
|
-
<script>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
data() {
|
|
15
|
-
return {
|
|
16
|
-
conditions: {},
|
|
17
|
-
handlers: [],
|
|
18
|
-
handlersSetup: false,
|
|
19
|
-
};
|
|
20
|
-
},
|
|
21
|
-
computed: {
|
|
22
|
-
shouldShow() {
|
|
23
|
-
if (!this.handlersSetup) return false;
|
|
24
|
-
const props = ['max', 'min', 'only'].filter(p => this[p]);
|
|
25
|
-
if (props.length === 0) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
return Object.values(this.conditions).every(c => c);
|
|
29
|
-
},
|
|
30
|
-
propsIdentifier() {
|
|
31
|
-
return `${this.max || ''}-${this.min || ''}-${this.only || ''}`;
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
watch: {
|
|
35
|
-
uluBreakpointManager: {
|
|
36
|
-
handler(manager) {
|
|
37
|
-
if (manager && !this.handlersSetup) {
|
|
38
|
-
this.setupHandlers(manager);
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
immediate: true
|
|
42
|
-
},
|
|
43
|
-
propsIdentifier() {
|
|
44
|
-
if (this.uluBreakpointManager && this.handlersSetup) {
|
|
45
|
-
this.tearDownHandlers();
|
|
46
|
-
this.setupHandlers(this.uluBreakpointManager);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
methods: {
|
|
51
|
-
setupHandlers(manager) {
|
|
52
|
-
const setupCondition = (direction) => {
|
|
53
|
-
const breakpointName = this[direction];
|
|
54
|
-
if (breakpointName) {
|
|
55
|
-
this.conditions[direction] = false;
|
|
56
|
-
const handler = {
|
|
57
|
-
on: () => { this.conditions[direction] = true; },
|
|
58
|
-
off: () => { this.conditions[direction] = false; },
|
|
59
|
-
};
|
|
60
|
-
manager.at(breakpointName)[direction](handler);
|
|
61
|
-
this.handlers.push({ name: breakpointName, direction, handler });
|
|
62
|
-
}
|
|
63
|
-
};
|
|
5
|
+
<script setup>
|
|
6
|
+
import { ref, computed, watch, onBeforeUnmount } from 'vue';
|
|
7
|
+
import { useRequiredInject } from '../../composables/useRequiredInject.js';
|
|
8
|
+
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
max: String,
|
|
11
|
+
min: String,
|
|
12
|
+
only: String,
|
|
13
|
+
});
|
|
64
14
|
|
|
65
|
-
|
|
66
|
-
setupCondition('min');
|
|
67
|
-
setupCondition('only');
|
|
15
|
+
const uluBreakpointManager = useRequiredInject('uluBreakpointManager');
|
|
68
16
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
17
|
+
const conditions = ref({});
|
|
18
|
+
const handlers = ref([]);
|
|
19
|
+
const handlersSetup = ref(false);
|
|
20
|
+
|
|
21
|
+
const shouldShow = computed(() => {
|
|
22
|
+
if (!handlersSetup.value) return false;
|
|
23
|
+
const activeProps = ['max', 'min', 'only'].filter(p => props[p]);
|
|
24
|
+
if (activeProps.length === 0) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return Object.values(conditions.value).every(c => c);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const setupHandlers = (manager) => {
|
|
31
|
+
const setupCondition = (direction) => {
|
|
32
|
+
const breakpointName = props[direction];
|
|
33
|
+
if (breakpointName) {
|
|
34
|
+
conditions.value[direction] = false;
|
|
35
|
+
const handler = {
|
|
36
|
+
on: () => { conditions.value[direction] = true; },
|
|
37
|
+
off: () => { conditions.value[direction] = false; },
|
|
38
|
+
};
|
|
39
|
+
manager.at(breakpointName)[direction](handler);
|
|
40
|
+
handlers.value.push({ name: breakpointName, direction, handler });
|
|
80
41
|
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
setupCondition('max');
|
|
45
|
+
setupCondition('min');
|
|
46
|
+
setupCondition('only');
|
|
47
|
+
|
|
48
|
+
handlersSetup.value = true;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const tearDownHandlers = () => {
|
|
52
|
+
if (uluBreakpointManager) {
|
|
53
|
+
handlers.value.forEach(({ name, direction, handler }) => {
|
|
54
|
+
uluBreakpointManager.at(name).remove(handler, direction);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
handlers.value = [];
|
|
58
|
+
conditions.value = {};
|
|
59
|
+
handlersSetup.value = false;
|
|
85
60
|
};
|
|
61
|
+
|
|
62
|
+
watch(uluBreakpointManager, (manager) => {
|
|
63
|
+
if (manager && !handlersSetup.value) {
|
|
64
|
+
setupHandlers(manager);
|
|
65
|
+
}
|
|
66
|
+
}, { immediate: true });
|
|
67
|
+
|
|
68
|
+
// Watch all the props and update if they change
|
|
69
|
+
// - Using array syntax to avoid "deep" flag
|
|
70
|
+
watch([() => props.max, () => props.min, () => props.only], () => {
|
|
71
|
+
if (uluBreakpointManager && handlersSetup.value) {
|
|
72
|
+
tearDownHandlers();
|
|
73
|
+
setupHandlers(uluBreakpointManager);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
onBeforeUnmount(() => {
|
|
78
|
+
tearDownHandlers();
|
|
79
|
+
});
|
|
86
80
|
</script>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<slot :item="item" :index="index">
|
|
27
27
|
<UluIcon
|
|
28
28
|
v-if="item.icon"
|
|
29
|
-
:
|
|
29
|
+
:icon="item.icon"
|
|
30
30
|
:class="[classes.linkIcon, item?.classes?.linkIcon]"
|
|
31
31
|
/>
|
|
32
32
|
<span :class="[classes.linkText, item?.classes?.linkText]">{{ item.title }}</span>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="UluFacetsFilters">
|
|
3
|
+
<UluCollapsibleRegion
|
|
4
|
+
class="UluFacets__group"
|
|
5
|
+
:class="classes.group"
|
|
6
|
+
:classToggle="['UluFacets__group-toggle', classes.groupToggle]"
|
|
7
|
+
:classContent="['UluFacets__group-content', classes.groupContent]"
|
|
8
|
+
v-for="group in facets"
|
|
9
|
+
:key="group.uid"
|
|
10
|
+
:group="group"
|
|
11
|
+
:startOpen="group.open"
|
|
12
|
+
:clickOutsideCloses="false"
|
|
13
|
+
:closeOnEscape="false"
|
|
14
|
+
:transitionHeight="true"
|
|
15
|
+
>
|
|
16
|
+
<template #toggle="{ isOpen }">
|
|
17
|
+
<slot name="groupToggle" :group="group" :isOpen="isOpen">
|
|
18
|
+
{{ group.name }}
|
|
19
|
+
</slot>
|
|
20
|
+
</template>
|
|
21
|
+
<template #default>
|
|
22
|
+
<UluFacetsList
|
|
23
|
+
:children="group.children.slice(0, maxVisible)"
|
|
24
|
+
:groupUid="group.uid"
|
|
25
|
+
:classFacet="classes.facet"
|
|
26
|
+
@facet-change="emit('facet-change', $event)"
|
|
27
|
+
/>
|
|
28
|
+
<UluCollapsibleRegion
|
|
29
|
+
v-if="group.children.length > maxVisible"
|
|
30
|
+
class="UluFacets__more-facets"
|
|
31
|
+
:class="classes.moreFacets"
|
|
32
|
+
:clickOutsideCloses="false"
|
|
33
|
+
:closeOnEscape="false"
|
|
34
|
+
:transitionHeight="true"
|
|
35
|
+
>
|
|
36
|
+
<template #toggle="{ isOpen }">
|
|
37
|
+
{{ isOpen ? "- Less" : "+ More" }}
|
|
38
|
+
</template>
|
|
39
|
+
<template #default>
|
|
40
|
+
<UluFacetsList
|
|
41
|
+
:children="group.children.slice(maxVisible)"
|
|
42
|
+
:groupUid="group.uid"
|
|
43
|
+
:classFacet="classes.facet"
|
|
44
|
+
@facet-change="emit('facet-change', $event)"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
</UluCollapsibleRegion>
|
|
48
|
+
</template>
|
|
49
|
+
</UluCollapsibleRegion>
|
|
50
|
+
</div>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script setup>
|
|
54
|
+
import UluFacetsList from "./UluFacetsList.vue";
|
|
55
|
+
import UluCollapsibleRegion from "../../collapsible/UluCollapsibleRegion.vue";
|
|
56
|
+
|
|
57
|
+
defineProps({
|
|
58
|
+
classes: {
|
|
59
|
+
type: Object,
|
|
60
|
+
default: () => ({})
|
|
61
|
+
},
|
|
62
|
+
maxVisible: {
|
|
63
|
+
type: Number,
|
|
64
|
+
default: 5
|
|
65
|
+
},
|
|
66
|
+
facets: {
|
|
67
|
+
type: Array,
|
|
68
|
+
default: () => []
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const emit = defineEmits(['facet-change']);
|
|
73
|
+
</script>
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
class="UluFacets__facet-checkbox"
|
|
11
11
|
:id="facetCheckboxId(facet)"
|
|
12
12
|
type="checkbox"
|
|
13
|
-
|
|
13
|
+
:checked="facet.selected"
|
|
14
|
+
@change="emit('facet-change', { groupUid, facetUid: facet.uid, selected: $event.target.checked })"
|
|
14
15
|
>
|
|
15
16
|
<label
|
|
16
17
|
class="UluFacets__facet-label"
|
|
@@ -22,18 +23,16 @@
|
|
|
22
23
|
</ul>
|
|
23
24
|
</template>
|
|
24
25
|
|
|
25
|
-
<script>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
}
|
|
26
|
+
<script setup>
|
|
27
|
+
const props = defineProps({
|
|
28
|
+
groupUid: String,
|
|
29
|
+
children: Array,
|
|
30
|
+
classFacet: String
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const emit = defineEmits(['facet-change']);
|
|
34
|
+
|
|
35
|
+
function facetCheckboxId(facet) {
|
|
36
|
+
return `facet-${props.groupUid}-${facet.uid}`;
|
|
38
37
|
}
|
|
39
38
|
</script>
|