@wyxos/vibe 1.2.1 → 1.2.3

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 CHANGED
@@ -32,36 +32,42 @@ npm install @wyxos/vibe
32
32
 
33
33
  ```vue
34
34
  <script setup>
35
- import Vibe from '@wyxos/vibe'
36
- import { ref } from 'vue'
37
- import fixture from './pages.json'
38
-
39
- const items = ref([])
40
-
41
- const getNextPage = async (page) => {
42
- return new Promise((resolve) => {
43
- setTimeout(() => {
44
- resolve({
45
- items: fixture[page - 1].items,
46
- nextPage: page + 1
47
- })
48
- }, 1000)
49
- })
50
- }
35
+ import { ref } from 'vue'
36
+ import { Masonry } from '@wyxos/vibe' // named export
37
+ // or if globally registered via `app.use()`, you can skip this import
38
+
39
+ const items = ref([])
40
+
41
+ async function getNextPage(page) {
42
+ const response = await fetch(`/api/items?page=${page}`)
43
+ const data = await response.json()
44
+ return {
45
+ items: data.items,
46
+ nextPage: page + 1
47
+ }
48
+ }
51
49
  </script>
52
50
 
53
51
  <template>
54
- <Vibe v-model:items="items" :get-next-page="getNextPage">
52
+ <WyxosMasonry
53
+ v-model:items="items"
54
+ :get-next-page="getNextPage"
55
+ :gutter-x="12"
56
+ :gutter-y="12"
57
+ :sizes="{ base: 1, sm: 2, md: 3, lg: 4 }"
58
+ >
55
59
  <template #item="{ item, onRemove }">
56
- <img :src="item.src" class="w-full" />
57
- <button
58
- class="absolute bottom-0 right-0 bg-red-500 text-white p-2 rounded cursor-pointer"
59
- @click="onRemove(item)"
60
- >
61
- <i class="fas fa-trash"></i>
62
- </button>
60
+ <div class="relative">
61
+ <img :src="item.src" class="w-full" />
62
+ <button
63
+ class="absolute bottom-2 right-2 bg-red-600 text-white text-xs p-1 rounded"
64
+ @click="onRemove(item)"
65
+ >
66
+ Remove
67
+ </button>
68
+ </div>
63
69
  </template>
64
- </Vibe>
70
+ </WyxosMasonry>
65
71
  </template>
66
72
  ```
67
73
 
package/index.js CHANGED
@@ -1,9 +1,10 @@
1
- import InfiniteMasonry from './src/archive/InfiniteMasonry.vue';
1
+ import Masonry from './src/Masonry.vue';
2
2
 
3
3
  export default {
4
4
  install(app) {
5
- app.component('InfiniteMasonry', InfiniteMasonry);
5
+ app.component('WyxosMasonry', Masonry);
6
+ app.component('WMasonry', Masonry);
6
7
  }
7
8
  };
8
9
 
9
- export { InfiniteMasonry };
10
+ export { Masonry };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wyxos/vibe",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "main": "index.js",
5
5
  "module": "index.js",
6
6
  "type": "module",
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, props.gutterX, props.gutterY);
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" @click="onRemove(item)">
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>
@@ -33,8 +33,6 @@
33
33
 
34
34
  <!-- pageIndex.value = pageIndex.value + 1;-->
35
35
 
36
- <!-- console.log(pageIndex.value)-->
37
-
38
36
  <!-- await nextTick()-->
39
37
 
40
38
  <!-- isLoading.value = false;-->
@@ -23,10 +23,19 @@ function getScrollbarWidth() {
23
23
  return scrollbarWidth
24
24
  }
25
25
 
26
- export default function calculateLayout(items, container, columnCount, gutterX = 0, gutterY = 0, header = 0, footer = 0) {
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