@wyxos/vibe 1.2.1 → 1.2.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/package.json +1 -1
- package/src/App.vue +7 -3
- package/src/Masonry.vue +36 -6
- package/src/archive/App.vue +0 -2
- package/src/calculateLayout.js +12 -3
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -5,8 +5,9 @@ import fixture from "./pages.json";
|
|
|
5
5
|
|
|
6
6
|
const items = ref([])
|
|
7
7
|
|
|
8
|
+
const masonry = ref(null)
|
|
9
|
+
|
|
8
10
|
const getPage = async (index) => {
|
|
9
|
-
console.log('index', index)
|
|
10
11
|
return new Promise((resolve) => {
|
|
11
12
|
setTimeout(() => {
|
|
12
13
|
let output = {
|
|
@@ -14,7 +15,6 @@ const getPage = async (index) => {
|
|
|
14
15
|
nextPage: index + 1
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
console.log('output', output)
|
|
18
18
|
resolve(output)
|
|
19
19
|
}, 1000)
|
|
20
20
|
})
|
|
@@ -30,8 +30,12 @@ const getPage = async (index) => {
|
|
|
30
30
|
🚀 Built by <a href="https://wyxos.com" target="_blank" class="underline hover:text-black">wyxos.com</a> •
|
|
31
31
|
💾 <a href="https://github.com/wyxos/vibe" target="_blank" class="underline hover:text-black">Source on GitHub</a>
|
|
32
32
|
</p>
|
|
33
|
+
|
|
34
|
+
<div v-if="masonry">
|
|
35
|
+
<p>Loading: <span class="bg-blue-500 text-white p-2 rounded">{{ masonry.isLoading }}</span></p>
|
|
36
|
+
</div>
|
|
33
37
|
</header>
|
|
34
|
-
<masonry v-model:items="items" :get-next-page="getPage">
|
|
38
|
+
<masonry v-model:items="items" :get-next-page="getPage" ref="masonry">
|
|
35
39
|
<template #item="{item, onRemove}">
|
|
36
40
|
<img :src="item.src" class="w-full"/>
|
|
37
41
|
<button class="absolute bottom-0 right-0 bg-red-500 text-white p-2 rounded cursor-pointer" @click="onRemove(item)">
|
package/src/Masonry.vue
CHANGED
|
@@ -35,7 +35,23 @@ const props = defineProps({
|
|
|
35
35
|
gutterY: {
|
|
36
36
|
type: Number,
|
|
37
37
|
default: 10
|
|
38
|
-
}
|
|
38
|
+
},
|
|
39
|
+
header: {
|
|
40
|
+
type: Number,
|
|
41
|
+
default: 0
|
|
42
|
+
},
|
|
43
|
+
footer: {
|
|
44
|
+
type: Number,
|
|
45
|
+
default: 0
|
|
46
|
+
},
|
|
47
|
+
paddingLeft: {
|
|
48
|
+
type: Number,
|
|
49
|
+
default: 0
|
|
50
|
+
},
|
|
51
|
+
paddingRight: {
|
|
52
|
+
type: Number,
|
|
53
|
+
default: 0
|
|
54
|
+
},
|
|
39
55
|
})
|
|
40
56
|
|
|
41
57
|
const emits = defineEmits(['update:items'])
|
|
@@ -45,7 +61,6 @@ const masonry = computed({
|
|
|
45
61
|
set: (val) => emits('update:items', val)
|
|
46
62
|
})
|
|
47
63
|
|
|
48
|
-
|
|
49
64
|
const columns = ref(7)
|
|
50
65
|
|
|
51
66
|
const container = ref(null)
|
|
@@ -68,6 +83,13 @@ const columnHeights = computed(() => {
|
|
|
68
83
|
return heights
|
|
69
84
|
})
|
|
70
85
|
|
|
86
|
+
defineExpose({
|
|
87
|
+
isLoading,
|
|
88
|
+
refreshLayout,
|
|
89
|
+
containerHeight,
|
|
90
|
+
onRemove,
|
|
91
|
+
})
|
|
92
|
+
|
|
71
93
|
async function onScroll() {
|
|
72
94
|
const {scrollTop, clientHeight} = container.value
|
|
73
95
|
const visibleBottom = scrollTop + clientHeight
|
|
@@ -95,7 +117,7 @@ async function onScroll() {
|
|
|
95
117
|
|
|
96
118
|
// find the last item in that column
|
|
97
119
|
const lastItemInColumn = masonry.value.filter((_, index) => index % columns.value === lowestColumnIndex).pop()
|
|
98
|
-
const lastItemInColumnTop = lastItemInColumn.top
|
|
120
|
+
const lastItemInColumnTop = lastItemInColumn.top + lastItemInColumn.columnHeight
|
|
99
121
|
const lastItemInColumnBottom = lastItemInColumnTop + lastItemInColumn.columnHeight
|
|
100
122
|
const containerTop = container.value.scrollTop
|
|
101
123
|
const containerBottom = containerTop + container.value.clientHeight
|
|
@@ -133,8 +155,15 @@ function calculateHeight(layout) {
|
|
|
133
155
|
}, 0)
|
|
134
156
|
}
|
|
135
157
|
|
|
136
|
-
function refreshLayout(items){
|
|
137
|
-
const layout = calculateLayout(items, container.value, columns.value,
|
|
158
|
+
function refreshLayout(items) {
|
|
159
|
+
const layout = calculateLayout(items, container.value, columns.value, {
|
|
160
|
+
gutterX: props.gutterX,
|
|
161
|
+
gutterY: props.gutterY,
|
|
162
|
+
header: props.header,
|
|
163
|
+
footer: props.footer,
|
|
164
|
+
paddingLeft: props.paddingLeft,
|
|
165
|
+
paddingRight: props.paddingRight,
|
|
166
|
+
});
|
|
138
167
|
|
|
139
168
|
calculateHeight(layout)
|
|
140
169
|
|
|
@@ -251,7 +280,8 @@ onUnmounted(() => {
|
|
|
251
280
|
v-bind="itemAttributes(item)">
|
|
252
281
|
<slot name="item" v-bind="{item, onRemove}">
|
|
253
282
|
<img :src="item.src" class="w-full"/>
|
|
254
|
-
<button class="absolute bottom-0 right-0 bg-red-500 text-white p-2 rounded cursor-pointer"
|
|
283
|
+
<button class="absolute bottom-0 right-0 bg-red-500 text-white p-2 rounded cursor-pointer"
|
|
284
|
+
@click="onRemove(item)">
|
|
255
285
|
<i class="fas fa-trash"></i>
|
|
256
286
|
</button>
|
|
257
287
|
</slot>
|
package/src/archive/App.vue
CHANGED
package/src/calculateLayout.js
CHANGED
|
@@ -23,10 +23,19 @@ function getScrollbarWidth() {
|
|
|
23
23
|
return scrollbarWidth
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export default function calculateLayout(items, container, columnCount,
|
|
26
|
+
export default function calculateLayout(items, container, columnCount, options = {}) {
|
|
27
|
+
const {
|
|
28
|
+
gutterX = 0,
|
|
29
|
+
gutterY = 0,
|
|
30
|
+
header = 0,
|
|
31
|
+
footer = 0,
|
|
32
|
+
paddingLeft = 0,
|
|
33
|
+
paddingRight = 0
|
|
34
|
+
} = options;
|
|
35
|
+
|
|
27
36
|
const measuredScrollbarWidth = container.offsetWidth - container.clientWidth;
|
|
28
37
|
const scrollbarWidth = measuredScrollbarWidth > 0 ? measuredScrollbarWidth + 2 : getScrollbarWidth() + 2;
|
|
29
|
-
const usableWidth = container.offsetWidth - scrollbarWidth;
|
|
38
|
+
const usableWidth = container.offsetWidth - scrollbarWidth - paddingLeft - paddingRight;
|
|
30
39
|
const totalGutterX = gutterX * (columnCount - 1);
|
|
31
40
|
const columnWidth = Math.floor((usableWidth - totalGutterX) / columnCount);
|
|
32
41
|
|
|
@@ -44,7 +53,7 @@ export default function calculateLayout(items, container, columnCount, gutterX =
|
|
|
44
53
|
newItem.columnWidth = columnWidth;
|
|
45
54
|
newItem.left = col * (columnWidth + gutterX);
|
|
46
55
|
newItem.columnHeight = Math.round((columnWidth * originalHeight) / originalWidth);
|
|
47
|
-
newItem.top = columnHeights[col];
|
|
56
|
+
newItem.top = columnHeights[col] + header + footer;
|
|
48
57
|
|
|
49
58
|
columnHeights[col] += newItem.columnHeight + gutterY;
|
|
50
59
|
|