@wyxos/vibe 1.6.25 → 1.6.27

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.
@@ -8,14 +8,10 @@
8
8
  <h3 class="text-sm font-semibold text-slate-400 uppercase tracking-wider mb-4">Examples</h3>
9
9
  <ul class="space-y-2">
10
10
  <li v-for="example in examples" :key="example.id">
11
- <a
12
- :href="`#${example.id}`"
13
- @click.prevent="scrollTo(example.id)"
14
- class="block px-3 py-2 text-sm rounded-md transition-colors"
15
- :class="activeSection === example.id
16
- ? 'bg-blue-50 text-blue-600 font-medium'
17
- : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'"
18
- >
11
+ <a :href="`#${example.id}`" @click.prevent="scrollTo(example.id)"
12
+ class="block px-3 py-2 text-sm rounded-md transition-colors" :class="activeSection === example.id
13
+ ? 'bg-blue-50 text-blue-600 font-medium'
14
+ : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900'">
19
15
  {{ example.title }}
20
16
  </a>
21
17
  </li>
@@ -33,7 +29,7 @@
33
29
  <h2 class="text-2xl font-bold text-slate-800">Basic Usage</h2>
34
30
  <p class="text-slate-600 mt-1">Simple masonry grid with default MasonryItem component</p>
35
31
  </div>
36
-
32
+
37
33
  <!-- Live Example -->
38
34
  <div class="p-6 bg-slate-50">
39
35
  <div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
@@ -43,14 +39,58 @@
43
39
 
44
40
  <!-- Code Tabs -->
45
41
  <div class="px-6 pb-6">
46
- <CodeTabs
47
- vue='<script setup>
42
+ <CodeTabs vue='<script setup>
43
+ import { ref } from "vue";
44
+ import { Masonry } from "@wyxos/vibe";
45
+
46
+ const items = ref([]);
47
+
48
+ async function getPage(page) {
49
+ const response = await fetch(`/api/items?page=${page}`);
50
+ const data = await response.json();
51
+ return {
52
+ items: data.items,
53
+ nextPage: page + 1
54
+ };
55
+ }
56
+ </script>
57
+
58
+ <template>
59
+ <Masonry
60
+ v-model:items="items"
61
+ :get-page="getPage"
62
+ :load-at-page="1"
63
+ />
64
+ </template>' />
65
+ </div>
66
+ </div>
67
+ </section>
68
+
69
+ <!-- Manual Init Example -->
70
+ <section id="manual-init" ref="manualInitRef" class="scroll-mt-24">
71
+ <div class="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
72
+ <div class="px-6 py-4 border-b border-slate-200 bg-slate-50">
73
+ <h2 class="text-2xl font-bold text-slate-800">Manual Init CTA</h2>
74
+ <p class="text-slate-600 mt-1">Delay initialization until the user clicks a call-to-action</p>
75
+ </div>
76
+
77
+ <!-- Live Example -->
78
+ <div class="p-6 bg-slate-50">
79
+ <div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
80
+ <ManualInitExample />
81
+ </div>
82
+ </div>
83
+
84
+ <!-- Code Tabs -->
85
+ <div class="px-6 pb-6">
86
+ <CodeTabs vue='<script setup>
48
87
  import { ref } from "vue";
49
88
  import { Masonry } from "@wyxos/vibe";
50
89
 
51
90
  const items = ref([]);
91
+ const masonryRef = ref(null);
52
92
 
53
- async function getNextPage(page) {
93
+ async function getPage(page) {
54
94
  const response = await fetch(`/api/items?page=${page}`);
55
95
  const data = await response.json();
56
96
  return {
@@ -58,16 +98,23 @@ async function getNextPage(page) {
58
98
  nextPage: page + 1
59
99
  };
60
100
  }
101
+
102
+ function handleInit() {
103
+ masonryRef.value?.loadPage(1);
104
+ }
61
105
  </script>
62
106
 
63
107
  <template>
108
+ <button @click="handleInit">Load gallery</button>
109
+
64
110
  <Masonry
111
+ ref="masonryRef"
65
112
  v-model:items="items"
66
- :get-next-page="getNextPage"
113
+ :get-page="getPage"
67
114
  :load-at-page="1"
115
+ init="manual"
68
116
  />
69
- </template>'
70
- />
117
+ </template>' />
71
118
  </div>
72
119
  </div>
73
120
  </section>
@@ -79,7 +126,7 @@ async function getNextPage(page) {
79
126
  <h2 class="text-2xl font-bold text-slate-800">Custom Masonry Item</h2>
80
127
  <p class="text-slate-600 mt-1">Customize item rendering with scoped slots</p>
81
128
  </div>
82
-
129
+
83
130
  <!-- Live Example -->
84
131
  <div class="p-6 bg-slate-50">
85
132
  <div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
@@ -89,14 +136,13 @@ async function getNextPage(page) {
89
136
 
90
137
  <!-- Code Tabs -->
91
138
  <div class="px-6 pb-6">
92
- <CodeTabs
93
- vue='<script setup>
139
+ <CodeTabs vue='<script setup>
94
140
  import { ref } from "vue";
95
141
  import { Masonry } from "@wyxos/vibe";
96
142
 
97
143
  const items = ref([]);
98
144
 
99
- async function getNextPage(page) {
145
+ async function getPage(page) {
100
146
  const response = await fetch(`/api/items?page=${page}`);
101
147
  const data = await response.json();
102
148
  return {
@@ -109,7 +155,7 @@ async function getNextPage(page) {
109
155
  <template>
110
156
  <Masonry
111
157
  v-model:items="items"
112
- :get-next-page="getNextPage"
158
+ :get-page="getPage"
113
159
  :load-at-page="1"
114
160
  >
115
161
  <template #item="{ item, remove }">
@@ -122,8 +168,7 @@ async function getNextPage(page) {
122
168
  </div>
123
169
  </template>
124
170
  </Masonry>
125
- </template>'
126
- />
171
+ </template>' />
127
172
  </div>
128
173
  -->
129
174
  </div>
@@ -135,10 +180,11 @@ async function getNextPage(page) {
135
180
  <div class="px-6 py-4 border-b border-slate-200 bg-slate-50">
136
181
  <h2 class="text-2xl font-bold text-slate-800">Header & Footer</h2>
137
182
  <p class="text-slate-600 mt-1">
138
- Use `layout.header` and `layout.footer` with slots to add per-item UI like badges, titles and actions.
183
+ Use `layout.header` and `layout.footer` with slots to add per-item UI like badges, titles and
184
+ actions.
139
185
  </p>
140
186
  </div>
141
-
187
+
142
188
  <!-- Live Example -->
143
189
  <div class="p-6 bg-slate-50">
144
190
  <div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
@@ -158,7 +204,7 @@ async function getNextPage(page) {
158
204
  <h2 class="text-2xl font-bold text-slate-800">Swipe Mode</h2>
159
205
  <p class="text-slate-600 mt-1">Vertical swipe feed for mobile devices</p>
160
206
  </div>
161
-
207
+
162
208
  <!-- Live Example -->
163
209
  <div class="p-6 bg-slate-50">
164
210
  <div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
@@ -168,14 +214,13 @@ async function getNextPage(page) {
168
214
 
169
215
  <!-- Code Tabs -->
170
216
  <div class="px-6 pb-6">
171
- <CodeTabs
172
- vue='<script setup>
217
+ <CodeTabs vue='<script setup>
173
218
  import { ref } from "vue";
174
219
  import { Masonry } from "@wyxos/vibe";
175
220
 
176
221
  const items = ref([]);
177
222
 
178
- async function getNextPage(page) {
223
+ async function getPage(page) {
179
224
  const response = await fetch(`/api/items?page=${page}`);
180
225
  const data = await response.json();
181
226
  return {
@@ -189,7 +234,7 @@ async function getNextPage(page) {
189
234
  <!-- Auto mode: switches to swipe on mobile -->
190
235
  <Masonry
191
236
  v-model:items="items"
192
- :get-next-page="getNextPage"
237
+ :get-page="getPage"
193
238
  layout-mode="auto"
194
239
  :mobile-breakpoint="768"
195
240
  />
@@ -197,11 +242,10 @@ async function getNextPage(page) {
197
242
  <!-- Force swipe mode on all devices -->
198
243
  <Masonry
199
244
  v-model:items="items"
200
- :get-next-page="getNextPage"
245
+ :get-page="getPage"
201
246
  layout-mode="swipe"
202
247
  />
203
- </template>'
204
- />
248
+ </template>' />
205
249
  </div>
206
250
  </div>
207
251
  </section>
@@ -217,12 +261,14 @@ async function getNextPage(page) {
217
261
  import { ref, onMounted, onUnmounted } from 'vue'
218
262
  import CodeTabs from '../components/CodeTabs.vue'
219
263
  import BasicExample from '../components/examples/BasicExample.vue'
264
+ import ManualInitExample from '../components/examples/ManualInitExample.vue'
220
265
  import CustomItemExample from '../components/examples/CustomItemExample.vue'
221
266
  import SwipeModeExample from '../components/examples/SwipeModeExample.vue'
222
267
  import HeaderFooterExample from '../components/examples/HeaderFooterExample.vue'
223
268
 
224
269
  const examples = [
225
270
  { id: 'basic', title: 'Basic Usage' },
271
+ { id: 'manual-init', title: 'Manual Init CTA' },
226
272
  { id: 'custom-item', title: 'Custom Masonry Item' },
227
273
  { id: 'header-footer', title: 'Header & Footer' },
228
274
  { id: 'swipe-mode', title: 'Swipe Mode' }
@@ -230,6 +276,7 @@ const examples = [
230
276
 
231
277
  const activeSection = ref('basic')
232
278
  const basicRef = ref<HTMLElement | null>(null)
279
+ const manualInitRef = ref<HTMLElement | null>(null)
233
280
  const customItemRef = ref<HTMLElement | null>(null)
234
281
  const headerFooterRef = ref<HTMLElement | null>(null)
235
282
  const swipeModeRef = ref<HTMLElement | null>(null)
@@ -245,6 +292,7 @@ function scrollTo(id: string) {
245
292
  function updateActiveSection() {
246
293
  const sections = [
247
294
  { id: 'basic', ref: basicRef },
295
+ { id: 'manual-init', ref: manualInitRef },
248
296
  { id: 'custom-item', ref: customItemRef },
249
297
  { id: 'header-footer', ref: headerFooterRef },
250
298
  { id: 'swipe-mode', ref: swipeModeRef }