@ulu/frontend-vue 0.1.0-beta.15 → 0.1.0-beta.17
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-t2PT-Tjo.js → breakpoints-Cd3pu0Is.js} +1 -1
- package/dist/frontend-vue.js +16 -15
- package/dist/{index-DKFsbs3Z.js → index-Cdy3vpXx.js} +1638 -1586
- package/lib/components/elements/UluCard.vue +1 -1
- package/lib/components/systems/facets/ExampleFacetsWithPagination.vue +119 -0
- package/lib/components/systems/facets/_facets.scss +2 -3
- package/lib/components/systems/index.js +5 -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/composables/index.js +2 -1
- package/lib/composables/usePagination.js +122 -0
- package/lib/plugins/core/index.js +2 -1
- package/package.json +5 -4
- package/types/composables/index.d.ts +1 -0
- package/types/composables/usePagination.d.ts +25 -0
- package/types/composables/usePagination.d.ts.map +1 -0
- package/types/plugins/core/index.d.ts.map +1 -1
- package/lib/components/systems/skeleton/UluSkeletonTextInline.vue +0 -9
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="BibliographyList">
|
|
3
|
+
<LayoutListPage title="Bibliography" icon="type:bibliography">
|
|
4
|
+
<template #intro>
|
|
5
|
+
<AppContent uid="bibliographyIntroduction" />
|
|
6
|
+
</template>
|
|
7
|
+
<template #default>
|
|
8
|
+
<UluFacetsSidebarLayout>
|
|
9
|
+
<template #sidebar>
|
|
10
|
+
<UluFacetsSearch v-model="searchValue" />
|
|
11
|
+
<UluFacetsSort v-model="selectedSort" :sort-types="sortTypes" />
|
|
12
|
+
<UluFacetsFilters :facets="facets" @facet-change="handleFacetChange" />
|
|
13
|
+
</template>
|
|
14
|
+
<template #main>
|
|
15
|
+
<UluFacetsResults :items="paginatedItems">
|
|
16
|
+
<template #item="{ item }">
|
|
17
|
+
<div class="source-item">
|
|
18
|
+
<h3>{{ item.title || "NO TITLE" }}</h3>
|
|
19
|
+
<div>
|
|
20
|
+
<PortableText v-if="item.citation" :value="item.citation" />
|
|
21
|
+
</div>
|
|
22
|
+
<small v-if="item.publicationDate">Published on: {{ item.publicationDate }}</small>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
</UluFacetsResults>
|
|
26
|
+
<UluPager
|
|
27
|
+
v-if="totalPages > 1"
|
|
28
|
+
:items="pagerItems"
|
|
29
|
+
:current="currentPage"
|
|
30
|
+
:ellipses="pagerEllipses"
|
|
31
|
+
class="mt-4"
|
|
32
|
+
/>
|
|
33
|
+
</template>
|
|
34
|
+
</UluFacetsSidebarLayout>
|
|
35
|
+
</template>
|
|
36
|
+
</LayoutListPage>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup>
|
|
41
|
+
import { ref } from "vue";
|
|
42
|
+
import { PortableText } from "@portabletext/vue";
|
|
43
|
+
import sources from "@/api/virtual/sources.js?virtual-module";
|
|
44
|
+
import {
|
|
45
|
+
useFacets,
|
|
46
|
+
usePagination,
|
|
47
|
+
UluFacetsSidebarLayout,
|
|
48
|
+
UluFacetsFilters,
|
|
49
|
+
UluFacetsSort,
|
|
50
|
+
UluFacetsSearch,
|
|
51
|
+
UluFacetsResults
|
|
52
|
+
} from "@ulu/frontend-vue";
|
|
53
|
+
|
|
54
|
+
const sorterDateLatest = (a, b) => new Date(b.publicationDate) - new Date(a.publicationDate);
|
|
55
|
+
|
|
56
|
+
const config = {
|
|
57
|
+
facetFields: [
|
|
58
|
+
{ name: "Chapters", uid: "chapters", open: false, getValue: item => item.chapters?.map(c => c.uuid) },
|
|
59
|
+
{ name: "Types", uid: "types", open: true },
|
|
60
|
+
{ name: "Topics", uid: "topics", open: true },
|
|
61
|
+
{ name: "Citation Type", uid: "citationType", open: true },
|
|
62
|
+
{ name: "Source Type", uid: "sourceType", open: true },
|
|
63
|
+
{ name: "Authors", uid: "authors", open: false },
|
|
64
|
+
{ name: "Source Name", uid: "sourceName", open: false }
|
|
65
|
+
],
|
|
66
|
+
extraSortTypes: {
|
|
67
|
+
newest: {
|
|
68
|
+
text: "Date (Newest)",
|
|
69
|
+
sort: items => [...items].sort(sorterDateLatest)
|
|
70
|
+
},
|
|
71
|
+
oldest: {
|
|
72
|
+
text: "Date (Oldest)",
|
|
73
|
+
sort: items => [...items].sort(sorterDateLatest).reverse()
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
initialSortType: "az",
|
|
77
|
+
// Remove quotes and stuff from beginning when sorting
|
|
78
|
+
getSortValue: item => item.title ? item.title.replace(/^[^A-Za-z0-9]+/, "") : "",
|
|
79
|
+
searchOptions: {
|
|
80
|
+
keys: ["title", "authors", "sourceName", "topics", "types", "citation"]
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const itemsPerPage = 20;
|
|
85
|
+
|
|
86
|
+
const {
|
|
87
|
+
facets,
|
|
88
|
+
searchValue,
|
|
89
|
+
selectedSort,
|
|
90
|
+
sortTypes,
|
|
91
|
+
displayItems,
|
|
92
|
+
handleFacetChange,
|
|
93
|
+
} = useFacets(ref(sources), config);
|
|
94
|
+
|
|
95
|
+
const {
|
|
96
|
+
currentPage,
|
|
97
|
+
totalPages,
|
|
98
|
+
paginatedItems,
|
|
99
|
+
pagerItems,
|
|
100
|
+
pagerEllipses
|
|
101
|
+
} = usePagination(displayItems, itemsPerPage);
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<style lang="scss">
|
|
105
|
+
// Add some basic styling for the item display
|
|
106
|
+
.source-item {
|
|
107
|
+
padding: 1rem;
|
|
108
|
+
border-bottom: 1px solid #eee;
|
|
109
|
+
|
|
110
|
+
h3 {
|
|
111
|
+
margin: 0 0 0.5rem;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
p {
|
|
115
|
+
margin: 0 0 0.5rem;
|
|
116
|
+
font-style: italic;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
</style>
|
|
@@ -5,17 +5,21 @@ export { default as UluFacetsSearch } from './facets/UluFacetsSearch.vue';
|
|
|
5
5
|
export { default as UluFacetsSidebarLayout } from './facets/UluFacetsSidebarLayout.vue';
|
|
6
6
|
export { default as UluFacetsSort } from './facets/UluFacetsSort.vue';
|
|
7
7
|
export { default as UluFacetsList } from './facets/UluFacetsList.vue';
|
|
8
|
+
|
|
8
9
|
export { default as UluScrollAnchors } from './scroll-anchors/UluScrollAnchors.vue';
|
|
9
10
|
export { default as UluScrollAnchorsNav } from './scroll-anchors/UluScrollAnchorsNav.vue';
|
|
10
11
|
export { default as UluScrollAnchorsNavAnimated } from './scroll-anchors/UluScrollAnchorsNavAnimated.vue';
|
|
11
12
|
export { default as UluScrollAnchorsSection } from './scroll-anchors/UluScrollAnchorsSection.vue';
|
|
13
|
+
|
|
12
14
|
export { default as UluShowSkeleton } from './skeleton/UluShowSkeleton.vue';
|
|
13
15
|
export { default as UluSkeletonContent } from './skeleton/UluSkeletonContent.vue';
|
|
14
16
|
export { default as UluSkeletonMedia } from './skeleton/UluSkeletonMedia.vue';
|
|
15
|
-
export { default as
|
|
17
|
+
export { default as UluSkeletonText } from './skeleton/UluSkeletonText.vue';
|
|
18
|
+
|
|
16
19
|
export { default as UluImageSlideShow } from './slider/UluImageSlideShow.vue';
|
|
17
20
|
export { default as UluSlideShow } from './slider/UluSlideShow.vue';
|
|
18
21
|
export { default as UluSlideShowSlide } from './slider/UluSlideShowSlide.vue';
|
|
22
|
+
|
|
19
23
|
export { default as UluTableSticky } from './table-sticky/UluTableSticky.vue';
|
|
20
24
|
export { default as UluTableStickyRows } from './table-sticky/UluTableStickyRows.vue';
|
|
21
25
|
export { default as UluTableStickyTable } from './table-sticky/UluTableStickyTable.vue';
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<slot v-if="!when"/>
|
|
3
|
-
<
|
|
3
|
+
<UluSkeletonText v-else inline/>
|
|
4
4
|
</template>
|
|
5
5
|
|
|
6
|
-
<script>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
<script setup>
|
|
7
|
+
import UluSkeletonText from "./UluSkeletonText.vue";
|
|
8
|
+
defineProps({
|
|
9
|
+
/**
|
|
10
|
+
* If true will show whatever is passed to slot, else skeleton text
|
|
11
|
+
*/
|
|
12
|
+
when: Boolean,
|
|
13
|
+
});
|
|
13
14
|
</script>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div>
|
|
3
3
|
<div v-for="(line, index) in linesWithSegments" :key="index">
|
|
4
4
|
<span
|
|
5
5
|
v-for="segment in line"
|
|
6
6
|
:key="segment"
|
|
7
|
-
class="
|
|
8
|
-
:class="{ '
|
|
7
|
+
class="skeleton skeleton--text skeleton--inline"
|
|
8
|
+
:class="{ 'skeleton--background-alt' : segment.alt }"
|
|
9
9
|
:style="{ width: `${ segment.width }%` }"
|
|
10
10
|
>
|
|
11
11
|
</span>
|
|
@@ -13,48 +13,44 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
16
|
-
<script>
|
|
16
|
+
<script setup>
|
|
17
|
+
import { computed } from "vue";
|
|
17
18
|
import { randomInt } from "@ulu/utils/random.js";
|
|
18
19
|
import { arrayCreate } from "@ulu/utils/array.js";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
methods: {
|
|
28
|
-
randomInt
|
|
20
|
+
|
|
21
|
+
const props = defineProps({
|
|
22
|
+
/**
|
|
23
|
+
* Amount of lines to generate
|
|
24
|
+
*/
|
|
25
|
+
lines: {
|
|
26
|
+
type: Number,
|
|
27
|
+
default: 6
|
|
29
28
|
},
|
|
30
|
-
|
|
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
|
-
return segments.map(width => ({ width, alt: Math.random() < 0.5 }));
|
|
56
|
-
});
|
|
57
|
-
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates the segments (like words) for the given line count
|
|
33
|
+
* - Uses random number of segments and makes sure to fill the line between 70% - 100%
|
|
34
|
+
*/
|
|
35
|
+
const linesWithSegments = computed(() => arrayCreate(props.lines, () => {
|
|
36
|
+
const minWidth = 15;
|
|
37
|
+
const total = randomInt(70, 100);
|
|
38
|
+
let widthCurrent = 0;
|
|
39
|
+
const newWidth = () => {
|
|
40
|
+
const remaining = total - widthCurrent;
|
|
41
|
+
const width = randomInt(minWidth, remaining);
|
|
42
|
+
widthCurrent += width;
|
|
43
|
+
return width;
|
|
44
|
+
};
|
|
45
|
+
const segments = [];
|
|
46
|
+
while (widthCurrent < total - minWidth) {
|
|
47
|
+
segments.push(newWidth());
|
|
48
|
+
}
|
|
49
|
+
const getActualTotal = () => segments.reduce((acc, a) => acc + a, 0);
|
|
50
|
+
while (getActualTotal() >= total) {
|
|
51
|
+
let removed = segments.pop();
|
|
52
|
+
if (!removed) break;
|
|
58
53
|
}
|
|
59
|
-
|
|
54
|
+
return segments.map(width => ({ width, alt: Math.random() < 0.5 }));
|
|
55
|
+
}));
|
|
60
56
|
</script>
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
3
|
-
<
|
|
2
|
+
<div class="skeleton skeleton-block--media">
|
|
3
|
+
<UluIcon icon="type:image"/>
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
|
-
<script>
|
|
8
|
-
|
|
9
|
-
name: "SkeletonMedia",
|
|
10
|
-
};
|
|
7
|
+
<script setup>
|
|
8
|
+
import UluIcon from "../../elements/UluIcon.vue";
|
|
11
9
|
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span
|
|
3
|
+
class="skeleton skeleton--text"
|
|
4
|
+
:class="{
|
|
5
|
+
'skeleton--inline' : inline,
|
|
6
|
+
'skeleton--background-alt' : alt,
|
|
7
|
+
[`skeleton--width-${ width }`] : width
|
|
8
|
+
}"
|
|
9
|
+
></span>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup>
|
|
13
|
+
defineProps({
|
|
14
|
+
/**
|
|
15
|
+
* Inline modifier
|
|
16
|
+
*/
|
|
17
|
+
inline: Boolean,
|
|
18
|
+
/**
|
|
19
|
+
* Use alternate background color
|
|
20
|
+
*/
|
|
21
|
+
alt: Boolean,
|
|
22
|
+
/**
|
|
23
|
+
* Optional size (width) - should correspond with width setup in scss component
|
|
24
|
+
*/
|
|
25
|
+
width: String
|
|
26
|
+
});
|
|
27
|
+
</script>
|
package/lib/composables/index.js
CHANGED
|
@@ -8,4 +8,5 @@ export { useIcon } from './useIcon.js';
|
|
|
8
8
|
export { useModifiers } from './useModifiers.js';
|
|
9
9
|
export { useWindowResize } from './useWindowResize.js';
|
|
10
10
|
export { useRequiredInject } from './useRequiredInject.js';
|
|
11
|
-
export { useBreakpointManager } from './useBreakpointManager.js';
|
|
11
|
+
export { useBreakpointManager } from './useBreakpointManager.js';
|
|
12
|
+
export { usePagination } from './usePagination.js';
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { computed, watch } from "vue";
|
|
2
|
+
import { useRoute, useRouter } from "vue-router";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A Vue composable for handling pagination logic.
|
|
6
|
+
* It interacts with vue-router to keep the current page in the URL query string.
|
|
7
|
+
*
|
|
8
|
+
* @param {import('vue').Ref<Array<any>>} items - A ref containing the full list of items to be paginated.
|
|
9
|
+
* @param {number} itemsPerPage - The number of items to display per page.
|
|
10
|
+
* @returns {{
|
|
11
|
+
* currentPage: import('vue').ComputedRef<number>,
|
|
12
|
+
* totalPages: import('vue').ComputedRef<number>,
|
|
13
|
+
* paginatedItems: import('vue').ComputedRef<Array<any>>,
|
|
14
|
+
* pagerItems: import('vue').ComputedRef<object|null>,
|
|
15
|
+
* pagerEllipses: import('vue').ComputedRef<{previous: boolean, next: boolean}>
|
|
16
|
+
* }} - An object containing reactive properties for pagination.
|
|
17
|
+
*/
|
|
18
|
+
export function usePagination(items, itemsPerPage) {
|
|
19
|
+
const route = useRoute();
|
|
20
|
+
const router = useRouter();
|
|
21
|
+
|
|
22
|
+
const currentPage = computed(() => {
|
|
23
|
+
const page = parseInt(route.query.page || '1', 10);
|
|
24
|
+
return isNaN(page) || page < 1 ? 1 : page;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const totalPages = computed(() => {
|
|
28
|
+
if (!items.value || items.value.length === 0) return 1;
|
|
29
|
+
return Math.ceil(items.value.length / itemsPerPage);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
watch(totalPages, (newTotalPages) => {
|
|
33
|
+
if (currentPage.value > newTotalPages) {
|
|
34
|
+
router.push({ query: { ...route.query, page: newTotalPages } });
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const paginatedItems = computed(() => {
|
|
39
|
+
const start = (currentPage.value - 1) * itemsPerPage;
|
|
40
|
+
const end = start + itemsPerPage;
|
|
41
|
+
return items.value.slice(start, end);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const pagerItems = computed(() => {
|
|
45
|
+
if (totalPages.value <= 1) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const items = {
|
|
50
|
+
pages: {}
|
|
51
|
+
};
|
|
52
|
+
const page = currentPage.value;
|
|
53
|
+
const total = totalPages.value;
|
|
54
|
+
const maxPagesToShow = 5;
|
|
55
|
+
|
|
56
|
+
const createRoute = (p) => {
|
|
57
|
+
return { query: { ...route.query, page: p } };
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (page > 1) {
|
|
61
|
+
items.first = { href: createRoute(1) };
|
|
62
|
+
items.previous = { href: createRoute(page - 1) };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (page < total) {
|
|
66
|
+
items.next = { href: createRoute(page + 1) };
|
|
67
|
+
items.last = { href: createRoute(total) };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let startPage, endPage;
|
|
71
|
+
if (total <= maxPagesToShow) {
|
|
72
|
+
startPage = 1;
|
|
73
|
+
endPage = total;
|
|
74
|
+
} else {
|
|
75
|
+
const maxPagesBeforeCurrent = Math.floor(maxPagesToShow / 2);
|
|
76
|
+
const maxPagesAfterCurrent = Math.ceil(maxPagesToShow / 2) - 1;
|
|
77
|
+
if (page <= maxPagesBeforeCurrent) {
|
|
78
|
+
startPage = 1;
|
|
79
|
+
endPage = maxPagesToShow;
|
|
80
|
+
} else if (page + maxPagesAfterCurrent >= total) {
|
|
81
|
+
startPage = total - maxPagesToShow + 1;
|
|
82
|
+
endPage = total;
|
|
83
|
+
} else {
|
|
84
|
+
startPage = page - maxPagesBeforeCurrent;
|
|
85
|
+
endPage = page + maxPagesAfterCurrent;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
for (let i = startPage; i <= endPage; i++) {
|
|
90
|
+
items.pages[i] = { href: createRoute(i) };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return items;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const pagerEllipses = computed(() => {
|
|
97
|
+
const ellipses = { previous: false, next: false };
|
|
98
|
+
if (!pagerItems.value || !pagerItems.value.pages) return ellipses;
|
|
99
|
+
|
|
100
|
+
const pageKeys = Object.keys(pagerItems.value.pages).map(Number);
|
|
101
|
+
if (pageKeys.length === 0) return ellipses;
|
|
102
|
+
|
|
103
|
+
const firstPageInPager = Math.min(...pageKeys);
|
|
104
|
+
const lastPageInPager = Math.max(...pageKeys);
|
|
105
|
+
|
|
106
|
+
if (firstPageInPager > 1) {
|
|
107
|
+
ellipses.previous = true;
|
|
108
|
+
}
|
|
109
|
+
if (lastPageInPager < totalPages.value) {
|
|
110
|
+
ellipses.next = true;
|
|
111
|
+
}
|
|
112
|
+
return ellipses;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
currentPage,
|
|
117
|
+
totalPages,
|
|
118
|
+
paginatedItems,
|
|
119
|
+
pagerItems,
|
|
120
|
+
pagerEllipses
|
|
121
|
+
};
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulu/frontend-vue",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.17",
|
|
4
4
|
"description": "A modular and tree-shakeable Vue 3 component library for the Ulu frontend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"docs:build": "storybook build -o docs",
|
|
36
36
|
"build": "vite build",
|
|
37
37
|
"types": "npx tsc",
|
|
38
|
-
"deploy": "npm run types && npm run build && npm run docs:build"
|
|
38
|
+
"deploy": "npm run types && npm run build && npm run docs:build",
|
|
39
|
+
"update-contexts": "rm -rf .contexts && mkdir -p .contexts/frontend && cp -R node_modules/@ulu/frontend/scss node_modules/@ulu/frontend/js .contexts/frontend/"
|
|
39
40
|
},
|
|
40
41
|
"keywords": [
|
|
41
42
|
"vue",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"homepage": "https://github.com/Jscherbe/frontend-vue#readme",
|
|
57
58
|
"peerDependencies": {
|
|
58
59
|
"@headlessui/vue": "^1.7.23",
|
|
59
|
-
"@ulu/frontend": "^0.1.0-beta.
|
|
60
|
+
"@ulu/frontend": "^0.1.0-beta.100",
|
|
60
61
|
"vue": "^3.5.17",
|
|
61
62
|
"vue-router": "^4.5.1"
|
|
62
63
|
},
|
|
@@ -78,7 +79,7 @@
|
|
|
78
79
|
"@storybook/addon-links": "^9.1.1",
|
|
79
80
|
"@storybook/addon-essentials": "^9.0.0-alpha.12",
|
|
80
81
|
"@storybook/vue3-vite": "^9.1.1",
|
|
81
|
-
"@ulu/frontend": "^0.1.0-beta.
|
|
82
|
+
"@ulu/frontend": "^0.1.0-beta.100",
|
|
82
83
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
83
84
|
"ollama": "^0.5.16",
|
|
84
85
|
"react": "^19.1.1",
|
|
@@ -3,4 +3,5 @@ export { useModifiers } from "./useModifiers.js";
|
|
|
3
3
|
export { useWindowResize } from "./useWindowResize.js";
|
|
4
4
|
export { useRequiredInject } from "./useRequiredInject.js";
|
|
5
5
|
export { useBreakpointManager } from "./useBreakpointManager.js";
|
|
6
|
+
export { usePagination } from "./usePagination.js";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Vue composable for handling pagination logic.
|
|
3
|
+
* It interacts with vue-router to keep the current page in the URL query string.
|
|
4
|
+
*
|
|
5
|
+
* @param {import('vue').Ref<Array<any>>} items - A ref containing the full list of items to be paginated.
|
|
6
|
+
* @param {number} itemsPerPage - The number of items to display per page.
|
|
7
|
+
* @returns {{
|
|
8
|
+
* currentPage: import('vue').ComputedRef<number>,
|
|
9
|
+
* totalPages: import('vue').ComputedRef<number>,
|
|
10
|
+
* paginatedItems: import('vue').ComputedRef<Array<any>>,
|
|
11
|
+
* pagerItems: import('vue').ComputedRef<object|null>,
|
|
12
|
+
* pagerEllipses: import('vue').ComputedRef<{previous: boolean, next: boolean}>
|
|
13
|
+
* }} - An object containing reactive properties for pagination.
|
|
14
|
+
*/
|
|
15
|
+
export function usePagination(items: import("vue").Ref<Array<any>>, itemsPerPage: number): {
|
|
16
|
+
currentPage: import("vue").ComputedRef<number>;
|
|
17
|
+
totalPages: import("vue").ComputedRef<number>;
|
|
18
|
+
paginatedItems: import("vue").ComputedRef<Array<any>>;
|
|
19
|
+
pagerItems: import("vue").ComputedRef<object | null>;
|
|
20
|
+
pagerEllipses: import("vue").ComputedRef<{
|
|
21
|
+
previous: boolean;
|
|
22
|
+
next: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=usePagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePagination.d.ts","sourceRoot":"","sources":["../../lib/composables/usePagination.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,qCAVW,OAAO,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,gBAC7B,MAAM,GACJ;IACR,WAAW,EAAE,OAAO,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/C,UAAU,EAAE,OAAO,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9C,cAAc,EAAE,OAAO,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,UAAU,EAAE,OAAO,KAAK,EAAE,WAAW,CAAC,MAAM,GAAC,IAAI,CAAC,CAAC;IACnD,aAAa,EAAE,OAAO,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC,CAAC,CAAA;CAC7E,CA0GH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/plugins/core/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/plugins/core/index.js"],"names":[],"mappings":"AA8BA,mEAyDC;AA3DD,gCAA0D"}
|