@ulu/frontend-vue 0.1.0-beta.9 → 0.1.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{breakpoints-BbkGNxxt.js → breakpoints-DfGETUy5.js} +1 -1
- package/dist/frontend-vue.css +1 -1
- package/dist/frontend-vue.js +79 -68
- package/dist/index-94HkwBnP.js +7595 -0
- package/lib/components/collapsible/UluAccordion.vue +71 -53
- package/lib/components/collapsible/UluAccordionGroup.vue +54 -0
- package/lib/components/collapsible/UluCollapsible.vue +144 -0
- package/lib/components/collapsible/UluDropdown.vue +29 -29
- package/lib/components/collapsible/UluOverflowPopover.vue +1 -1
- package/lib/components/elements/UluBadge.vue +51 -28
- package/lib/components/elements/UluBadgeStack.vue +8 -13
- package/lib/components/elements/UluButtonVerbose.vue +119 -0
- package/lib/components/elements/UluCard.vue +1 -1
- package/lib/components/elements/UluDefinitionList.vue +14 -17
- package/lib/components/elements/UluExternalLink.vue +21 -27
- package/lib/components/elements/UluIcon.vue +11 -1
- package/lib/components/elements/UluList.vue +53 -55
- package/lib/components/elements/UluSpokeSpinner.vue +12 -18
- package/lib/components/elements/UluTag.vue +35 -35
- package/lib/components/forms/UluFileDisplay.vue +49 -31
- package/lib/components/forms/UluFormFile.vue +37 -24
- package/lib/components/forms/UluFormMessage.vue +13 -10
- package/lib/components/forms/UluFormSelect.vue +28 -16
- package/lib/components/forms/UluFormText.vue +24 -15
- package/lib/components/forms/UluSearchForm.vue +11 -10
- package/lib/components/forms/UluSelectableMenu.vue +99 -0
- package/lib/components/index.js +4 -3
- package/lib/components/layout/UluTitleRail.vue +18 -0
- package/lib/components/layout/UluWhenBreakpoint.vue +9 -0
- package/lib/components/navigation/UluBreadcrumb.vue +9 -2
- package/lib/components/navigation/UluMenu.vue +8 -3
- package/lib/components/navigation/UluMenuStack.vue +3 -1
- package/lib/components/navigation/UluPager.vue +102 -0
- package/lib/components/systems/facets/ExampleFacetsWithPagination.vue +119 -0
- package/lib/components/systems/facets/UluFacetsFilterLists.vue +91 -0
- package/lib/components/systems/facets/UluFacetsFilterPopovers.vue +125 -0
- package/lib/components/systems/facets/UluFacetsFilterSelects.vue +71 -0
- package/lib/components/systems/facets/UluFacetsHeaderLayout.vue +24 -0
- package/lib/components/systems/facets/UluFacetsList.vue +62 -34
- package/lib/components/systems/facets/UluFacetsResults.vue +63 -0
- package/lib/components/systems/facets/UluFacetsSearch.vue +27 -50
- package/lib/components/systems/facets/UluFacetsSidebarLayout.vue +70 -0
- package/lib/components/systems/facets/UluFacetsSort.vue +45 -0
- package/lib/components/systems/facets/_facets.scss +2 -3
- package/lib/components/systems/facets/_mock-data.js +40 -0
- package/lib/components/systems/facets/useFacets.js +268 -0
- package/lib/components/systems/index.js +13 -2
- package/lib/components/systems/scroll-anchors/UluScrollAnchors.vue +2 -1
- package/lib/components/systems/skeleton/UluShowSkeleton.vue +9 -8
- package/lib/components/systems/skeleton/UluSkeletonContent.vue +39 -43
- package/lib/components/systems/skeleton/UluSkeletonMedia.vue +4 -6
- package/lib/components/systems/skeleton/UluSkeletonText.vue +27 -0
- package/lib/components/systems/slider/UluImageSlideShow.vue +1 -1
- package/lib/components/systems/slider/UluSlideShow.vue +8 -3
- package/lib/components/systems/table-sticky/UluTableSticky.vue +7 -7
- package/lib/components/systems/table-sticky/UluTableStickyTable.vue +3 -3
- package/lib/components/visualizations/UluAnimateNumber.vue +7 -1
- package/lib/components/visualizations/UluProgressBar.vue +148 -74
- package/lib/components/visualizations/UluProgressCircle.vue +159 -0
- package/lib/composables/index.js +3 -1
- package/lib/composables/useDocumentTitle.js +61 -0
- package/lib/composables/usePagination.js +122 -0
- package/lib/index.js +1 -0
- package/lib/plugins/core/index.js +6 -1
- package/lib/plugins/popovers/UluPopover.vue +8 -3
- package/lib/plugins/toast/UluToast.vue +1 -1
- package/lib/plugins/toast/UluToastDisplay.vue +19 -2
- package/lib/utils/dom.js +12 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/{vue-router.js → router.js} +114 -30
- package/package.json +17 -11
- package/types/components/systems/facets/_mock-data.d.ts +18 -0
- package/types/components/systems/facets/_mock-data.d.ts.map +1 -0
- package/types/components/systems/facets/useFacets.d.ts +39 -0
- package/types/components/systems/facets/useFacets.d.ts.map +1 -0
- package/types/components/systems/index.d.ts +1 -1
- package/types/composables/index.d.ts +2 -0
- package/types/composables/useDocumentTitle.d.ts +22 -0
- package/types/composables/useDocumentTitle.d.ts.map +1 -0
- package/types/composables/usePageTitle.d.ts +19 -0
- package/types/composables/usePageTitle.d.ts.map +1 -0
- package/types/composables/usePagination.d.ts +25 -0
- package/types/composables/usePagination.d.ts.map +1 -0
- package/types/index.d.ts +1 -0
- package/types/plugins/core/index.d.ts.map +1 -1
- package/types/utils/dom.d.ts +1 -0
- package/types/utils/dom.d.ts.map +1 -1
- package/types/utils/index.d.ts +3 -0
- package/types/utils/index.d.ts.map +1 -0
- package/types/utils/router.d.ts +144 -0
- package/types/utils/router.d.ts.map +1 -0
- package/dist/index-D3Uc6T5M.js +0 -6469
- package/lib/components/collapsible/UluCollapsibleRegion.vue +0 -278
- package/lib/components/forms/UluCheckboxMenu.vue +0 -36
- package/lib/components/systems/facets/UluFacets.vue +0 -380
- package/lib/components/systems/skeleton/UluSkeletonTextInline.vue +0 -9
- package/lib/components/visualizations/UluProgressDonut.vue +0 -97
- package/lib/utils/placeholder.js +0 -6
|
@@ -1,82 +1,100 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
>
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
</
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
</slot>
|
|
31
|
-
</DisclosureButton>
|
|
32
|
-
<DisclosurePanel class="accordion__content" :class="classes.content">
|
|
33
|
-
<slot :open="open"/>
|
|
34
|
-
</DisclosurePanel>
|
|
35
|
-
</div>
|
|
36
|
-
</Disclosure>
|
|
2
|
+
<UluCollapsible
|
|
3
|
+
:model-value="modelValue"
|
|
4
|
+
:start-open="startOpen"
|
|
5
|
+
:trigger-text="triggerText"
|
|
6
|
+
:classes="mergedClasses"
|
|
7
|
+
:animate="animate"
|
|
8
|
+
@update:model-value="$emit('update:modelValue', $event)"
|
|
9
|
+
>
|
|
10
|
+
<template #trigger="{ isOpen: open, toggle }">
|
|
11
|
+
<slot name="trigger" :open="open" :toggle="toggle">
|
|
12
|
+
<component :is="triggerTextElement">
|
|
13
|
+
{{ triggerText }}
|
|
14
|
+
</component>
|
|
15
|
+
</slot>
|
|
16
|
+
<slot name="icon" :open="open">
|
|
17
|
+
<span class="accordion__icon" :class="classes.icon">
|
|
18
|
+
<UluIcon
|
|
19
|
+
:icon="open ? 'type:collapse' : 'type:expand'"
|
|
20
|
+
style="display: inline;"
|
|
21
|
+
/>
|
|
22
|
+
</span>
|
|
23
|
+
</slot>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<template #default="{ isOpen: open, toggle }">
|
|
27
|
+
<slot :open="open" :toggle="toggle"/>
|
|
28
|
+
</template>
|
|
29
|
+
</UluCollapsible>
|
|
37
30
|
</template>
|
|
38
31
|
|
|
39
32
|
<script setup>
|
|
33
|
+
import { computed } from 'vue';
|
|
40
34
|
import UluIcon from "../elements/UluIcon.vue";
|
|
35
|
+
import UluCollapsible from "./UluCollapsible.vue";
|
|
41
36
|
import { useModifiers } from "../../composables/useModifiers.js";
|
|
42
|
-
|
|
37
|
+
|
|
43
38
|
const props = defineProps({
|
|
39
|
+
/**
|
|
40
|
+
* v-model for controlling open state (optional)
|
|
41
|
+
*/
|
|
42
|
+
modelValue: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: undefined
|
|
45
|
+
},
|
|
44
46
|
/**
|
|
45
47
|
* Whether the accordion is open by default
|
|
46
48
|
*/
|
|
47
|
-
|
|
49
|
+
startOpen: Boolean,
|
|
50
|
+
/**
|
|
51
|
+
* Enable or configure animations.
|
|
52
|
+
* - `false` (default) to disable all animations.
|
|
53
|
+
* - `true` to enable animations with default settings.
|
|
54
|
+
* - An object to provide custom options to auto-animate (e.g., { duration: 100, easing: 'linear' }).
|
|
55
|
+
*/
|
|
56
|
+
animate: {
|
|
57
|
+
type: [Boolean, Object],
|
|
58
|
+
default: false
|
|
59
|
+
},
|
|
48
60
|
/**
|
|
49
|
-
*
|
|
61
|
+
* Text to use for accordion, alternatively use #trigger slot
|
|
50
62
|
*/
|
|
51
|
-
|
|
63
|
+
triggerText: String,
|
|
52
64
|
/**
|
|
53
65
|
* If using summary text sets the inner element the text is wrapped in, usually a headline or strong
|
|
54
66
|
*/
|
|
55
|
-
|
|
67
|
+
triggerTextElement: {
|
|
56
68
|
type: String,
|
|
57
69
|
default: "strong"
|
|
58
70
|
},
|
|
59
71
|
/**
|
|
60
|
-
* Classes for elements
|
|
72
|
+
* Classes for elements. See UluCollapsible for all available class keys (toggle, content, etc).
|
|
73
|
+
* The 'icon' key is also available for the icon span.
|
|
61
74
|
* - Any valid class binding value per element
|
|
62
75
|
*/
|
|
63
76
|
classes: {
|
|
64
77
|
type: Object,
|
|
65
|
-
default: () => ({
|
|
78
|
+
default: () => ({
|
|
79
|
+
container: 'accordion',
|
|
80
|
+
toggle: 'accordion__summary',
|
|
81
|
+
content: 'accordion__content',
|
|
82
|
+
containerOpen: 'is-active'
|
|
83
|
+
})
|
|
66
84
|
},
|
|
67
85
|
/**
|
|
68
|
-
*
|
|
69
|
-
*/
|
|
70
|
-
activeClass: {
|
|
71
|
-
type: String,
|
|
72
|
-
default: "is-active"
|
|
73
|
-
},
|
|
74
|
-
/**
|
|
75
|
-
* Modifiers for tag class
|
|
86
|
+
* Class modifiers (ie. 'transparent', 'secondary', etc)
|
|
76
87
|
*/
|
|
77
88
|
modifiers: [String, Array]
|
|
78
89
|
});
|
|
79
90
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
const emit = defineEmits(['update:modelValue']);
|
|
92
|
+
|
|
93
|
+
const { resolvedModifiers } = useModifiers({ props, baseClass: "accordion" });
|
|
94
|
+
|
|
95
|
+
const mergedClasses = computed(() => {
|
|
96
|
+
const merged = { ...props.classes };
|
|
97
|
+
merged.container = [merged.container, resolvedModifiers.value];
|
|
98
|
+
return merged;
|
|
99
|
+
});
|
|
100
|
+
</script>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="accordion-group">
|
|
3
|
+
<UluAccordion
|
|
4
|
+
v-for="(item, index) in internalItems"
|
|
5
|
+
:key="index"
|
|
6
|
+
:model-value="item.isOpen"
|
|
7
|
+
@update:modelValue="(newValue) => handleToggle(index, newValue)"
|
|
8
|
+
:trigger-text="item.title"
|
|
9
|
+
:classes="item.classes"
|
|
10
|
+
>
|
|
11
|
+
<slot name="item" :item="item" :index="index">
|
|
12
|
+
{{ item.content }}
|
|
13
|
+
</slot>
|
|
14
|
+
</UluAccordion>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup>
|
|
19
|
+
import { ref, watch } from 'vue';
|
|
20
|
+
import UluAccordion from './UluAccordion.vue';
|
|
21
|
+
|
|
22
|
+
const props = defineProps({
|
|
23
|
+
/**
|
|
24
|
+
* Array of items to render as accordions.
|
|
25
|
+
* Each item can have: title, content, isOpen, classes
|
|
26
|
+
*/
|
|
27
|
+
items: {
|
|
28
|
+
type: Array,
|
|
29
|
+
default: () => []
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const internalItems = ref([]);
|
|
34
|
+
|
|
35
|
+
watch(() => props.items, (newItems) => {
|
|
36
|
+
internalItems.value = newItems.map(item => ({
|
|
37
|
+
...item,
|
|
38
|
+
isOpen: item.isOpen || false
|
|
39
|
+
}));
|
|
40
|
+
}, { immediate: true, deep: true });
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
function handleToggle(selectedIndex, newValue) {
|
|
44
|
+
if (newValue) {
|
|
45
|
+
// if opening, close all others
|
|
46
|
+
internalItems.value.forEach((item, index) => {
|
|
47
|
+
item.isOpen = index === selectedIndex;
|
|
48
|
+
});
|
|
49
|
+
} else {
|
|
50
|
+
// if closing, just close that one
|
|
51
|
+
internalItems.value[selectedIndex].isOpen = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="container"
|
|
4
|
+
@keydown.esc="handleEscape"
|
|
5
|
+
:class="[classes.container, containerStateClasses]"
|
|
6
|
+
>
|
|
7
|
+
<button
|
|
8
|
+
:class="classes.toggle"
|
|
9
|
+
:id="toggleId"
|
|
10
|
+
:aria-controls="contentId"
|
|
11
|
+
:aria-expanded="isOpen"
|
|
12
|
+
@click="toggle"
|
|
13
|
+
>
|
|
14
|
+
<slot name="trigger" :isOpen="isOpen" :toggle="toggle">
|
|
15
|
+
{{ triggerText }}
|
|
16
|
+
</slot>
|
|
17
|
+
</button>
|
|
18
|
+
<div
|
|
19
|
+
v-if="isOpen"
|
|
20
|
+
:class="classes.content"
|
|
21
|
+
tabindex="-1"
|
|
22
|
+
:id="contentId"
|
|
23
|
+
:aria-hidden="!isOpen"
|
|
24
|
+
:aria-labelledby="toggleId"
|
|
25
|
+
>
|
|
26
|
+
<div :class="classes.contentInner">
|
|
27
|
+
<slot :isOpen="isOpen" :toggle="toggle" />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup>
|
|
34
|
+
import { ref, computed, watch, onMounted } from 'vue';
|
|
35
|
+
import { useAutoAnimate } from '@formkit/auto-animate/vue';
|
|
36
|
+
import { newId } from '../../utils/dom.js';
|
|
37
|
+
|
|
38
|
+
const props = defineProps({
|
|
39
|
+
/**
|
|
40
|
+
* v-model for controlling open state
|
|
41
|
+
*/
|
|
42
|
+
modelValue: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: undefined
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* Set text for trigger (instead of using slot)
|
|
48
|
+
*/
|
|
49
|
+
triggerText: String,
|
|
50
|
+
/**
|
|
51
|
+
* Closes with escape key
|
|
52
|
+
*/
|
|
53
|
+
closeOnEscape: Boolean,
|
|
54
|
+
/**
|
|
55
|
+
* When the component is shown it should start visible or hidden
|
|
56
|
+
*/
|
|
57
|
+
startOpen: Boolean,
|
|
58
|
+
/**
|
|
59
|
+
* Enable or configure animations.
|
|
60
|
+
* - `true` to enable animations with default settings (default)
|
|
61
|
+
* - `false` (disable)
|
|
62
|
+
* - An object to provide custom options to auto-animate (e.g., { duration: 100, easing: 'linear' }).
|
|
63
|
+
*/
|
|
64
|
+
animate: {
|
|
65
|
+
type: [Boolean, Object],
|
|
66
|
+
default: true
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* Classes for elements ({ container, toggle, content, contentInner })
|
|
70
|
+
* - Any valid class binding value per element
|
|
71
|
+
*/
|
|
72
|
+
classes: {
|
|
73
|
+
type: Object,
|
|
74
|
+
default: () => ({
|
|
75
|
+
container: 'ulu-collapsible',
|
|
76
|
+
toggle: 'ulu-collapsible__toggle',
|
|
77
|
+
content: 'ulu-collapsible__content',
|
|
78
|
+
contentInner: 'ulu-collapsible__content-inner',
|
|
79
|
+
containerOpen: 'ulu-collapsible--open',
|
|
80
|
+
containerClosed: 'ulu-collapsible--closed'
|
|
81
|
+
})
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const emit = defineEmits(['update:modelValue']);
|
|
86
|
+
|
|
87
|
+
const autoAnimateOptions = computed(() => {
|
|
88
|
+
if (typeof props.animate === 'object') {
|
|
89
|
+
return props.animate;
|
|
90
|
+
}
|
|
91
|
+
return {};
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const [container, enableAnimations] = useAutoAnimate(autoAnimateOptions);
|
|
95
|
+
|
|
96
|
+
// Animation needs to be disabled after the component is mounted
|
|
97
|
+
onMounted(() => { enableAnimations(!!props.animate) });
|
|
98
|
+
// Then we can watch for changes
|
|
99
|
+
watch(() => props.animate, v => { enableAnimations(!!v) });
|
|
100
|
+
|
|
101
|
+
const userControlled = computed(() => props.modelValue !== undefined);
|
|
102
|
+
const internalIsOpen = ref(props.startOpen);
|
|
103
|
+
|
|
104
|
+
const isOpen = computed({
|
|
105
|
+
get() {
|
|
106
|
+
return userControlled.value ? props.modelValue : internalIsOpen.value;
|
|
107
|
+
},
|
|
108
|
+
set(newValue) {
|
|
109
|
+
if (userControlled.value) {
|
|
110
|
+
emit('update:modelValue', newValue);
|
|
111
|
+
} else {
|
|
112
|
+
internalIsOpen.value = newValue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const toggleId = ref(newId('ulu-collapsible-toggle'));
|
|
118
|
+
const contentId = ref(newId('ulu-collapsible-content'));
|
|
119
|
+
|
|
120
|
+
const containerStateClasses = computed(() => {
|
|
121
|
+
const c = props.classes;
|
|
122
|
+
const stateClasses = {};
|
|
123
|
+
if (c.containerOpen && isOpen.value) {
|
|
124
|
+
stateClasses[c.containerOpen] = true;
|
|
125
|
+
}
|
|
126
|
+
if (c.containerClosed && !isOpen.value) {
|
|
127
|
+
stateClasses[c.containerClosed] = true;
|
|
128
|
+
}
|
|
129
|
+
return stateClasses;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Function used to toggle the collapsible
|
|
134
|
+
*/
|
|
135
|
+
function toggle() {
|
|
136
|
+
isOpen.value = !isOpen.value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function handleEscape() {
|
|
140
|
+
if (props.closeOnEscape && isOpen.value) {
|
|
141
|
+
isOpen.value = false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
</script>
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<UluPopover :classes="popoverClasses">
|
|
3
3
|
<template #trigger="{ isOpen }">
|
|
4
|
-
<slot :isOpen="isOpen"
|
|
4
|
+
<slot name="trigger" :isOpen="isOpen">
|
|
5
|
+
<span>{{ triggerText }}</span>
|
|
6
|
+
<UluIcon
|
|
7
|
+
class="button__icon"
|
|
8
|
+
icon="type:dropdownExpand"
|
|
9
|
+
:style="{ transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.2s' }"
|
|
10
|
+
/>
|
|
11
|
+
</slot>
|
|
5
12
|
</template>
|
|
6
|
-
<template #
|
|
13
|
+
<template #default>
|
|
7
14
|
<UluMenuStack :items="items"/>
|
|
8
15
|
</template>
|
|
9
16
|
</UluPopover>
|
|
10
17
|
</template>
|
|
11
18
|
|
|
12
|
-
<script>
|
|
19
|
+
<script setup>
|
|
13
20
|
import UluPopover from "../../plugins/popovers/UluPopover.vue";
|
|
14
21
|
import UluMenuStack from "../navigation/UluMenuStack.vue";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Pass classes object to UluPopover classes prop
|
|
35
|
-
*/
|
|
36
|
-
popoverClasses: {
|
|
37
|
-
type: Object,
|
|
38
|
-
default: () => ({})
|
|
39
|
-
}
|
|
22
|
+
import UluIcon from "../elements/UluIcon.vue";
|
|
23
|
+
defineProps({
|
|
24
|
+
/**
|
|
25
|
+
* Dropdown menu items (to be passed to UluMenu)
|
|
26
|
+
*/
|
|
27
|
+
items: Array,
|
|
28
|
+
/**
|
|
29
|
+
* Optional text if not using slot
|
|
30
|
+
*/
|
|
31
|
+
triggerText: String,
|
|
32
|
+
/**
|
|
33
|
+
* Pass classes object to UluPopover classes prop
|
|
34
|
+
*/
|
|
35
|
+
popoverClasses: {
|
|
36
|
+
type: Object,
|
|
37
|
+
default: () => ({
|
|
38
|
+
trigger: "button"
|
|
39
|
+
})
|
|
40
40
|
}
|
|
41
|
-
};
|
|
41
|
+
});
|
|
42
42
|
</script>
|
|
@@ -26,33 +26,56 @@
|
|
|
26
26
|
</component>
|
|
27
27
|
</template>
|
|
28
28
|
|
|
29
|
-
<script>
|
|
29
|
+
<script setup>
|
|
30
|
+
import { computed } from "vue";
|
|
30
31
|
import { RouterLink } from "vue-router";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
32
|
+
|
|
33
|
+
const props = defineProps({
|
|
34
|
+
/**
|
|
35
|
+
* Whether to display a skeleton loading state.
|
|
36
|
+
*/
|
|
37
|
+
skeleton: Boolean,
|
|
38
|
+
/**
|
|
39
|
+
* The size of the badge (e.g., 'small', 'large').
|
|
40
|
+
*/
|
|
41
|
+
size: String,
|
|
42
|
+
/**
|
|
43
|
+
* The text content of the badge.
|
|
44
|
+
*/
|
|
45
|
+
text: String,
|
|
46
|
+
/**
|
|
47
|
+
* Alt text for the badge, for accessibility.
|
|
48
|
+
*/
|
|
49
|
+
alt: String,
|
|
50
|
+
/**
|
|
51
|
+
* The type or style of the badge (e.g., 'primary', 'secondary').
|
|
52
|
+
*/
|
|
53
|
+
type: String,
|
|
54
|
+
/**
|
|
55
|
+
* A function to call when the badge is clicked. Renders as a <button>.
|
|
56
|
+
*/
|
|
57
|
+
click: Function,
|
|
58
|
+
/**
|
|
59
|
+
* A Vue Router link location. Renders as a <router-link>.
|
|
60
|
+
*/
|
|
61
|
+
to: [Object, String],
|
|
62
|
+
/**
|
|
63
|
+
* A URL. Renders as a standard <a> tag.
|
|
64
|
+
*/
|
|
65
|
+
href: String,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const isInteractive = computed(() => {
|
|
69
|
+
return Boolean(props.to || props.click);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const element = computed(() => {
|
|
73
|
+
const { click, to, href } = props;
|
|
74
|
+
/* eslint-disable */
|
|
75
|
+
return click ? "button" :
|
|
76
|
+
to ? RouterLink :
|
|
77
|
+
href ? "a" :
|
|
78
|
+
"span";
|
|
79
|
+
/* eslint-enable */
|
|
80
|
+
});
|
|
58
81
|
</script>
|
|
@@ -10,18 +10,13 @@
|
|
|
10
10
|
</ul>
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
|
-
<script>
|
|
13
|
+
<script setup>
|
|
14
14
|
import UluBadge from "./UluBadge.vue";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* Array of props for each badge
|
|
23
|
-
*/
|
|
24
|
-
items: Array
|
|
25
|
-
}
|
|
26
|
-
}
|
|
15
|
+
|
|
16
|
+
defineProps({
|
|
17
|
+
/**
|
|
18
|
+
* Array of props for each badge
|
|
19
|
+
*/
|
|
20
|
+
items: Array
|
|
21
|
+
});
|
|
27
22
|
</script>
|
|
@@ -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>
|