@wyxos/vibe 1.6.12 → 1.6.13
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/lib/index.js +483 -501
- package/lib/vibe.css +1 -1
- package/package.json +93 -67
- package/src/Masonry.vue +3 -21
- package/src/components/CodeTabs.vue +158 -0
- package/src/components/examples/BasicExample.vue +45 -0
- package/src/components/examples/CustomItemExample.vue +86 -0
- package/src/components/examples/SwipeModeExample.vue +39 -0
- package/src/pages.json +36401 -36401
- package/src/views/Examples.vue +247 -20
- package/toggle-link.mjs +92 -92
package/src/views/Examples.vue
CHANGED
|
@@ -1,20 +1,247 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="min-h-screen bg-slate-50
|
|
3
|
-
<div class="max-w-
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div class="min-h-screen bg-slate-50 pt-20">
|
|
3
|
+
<div class="max-w-7xl mx-auto px-4 py-8">
|
|
4
|
+
<div class="flex gap-8">
|
|
5
|
+
<!-- Side Menu -->
|
|
6
|
+
<aside class="hidden lg:block w-64 flex-shrink-0 sticky top-24 h-fit">
|
|
7
|
+
<nav class="bg-white rounded-lg shadow-sm p-4 border border-slate-200">
|
|
8
|
+
<h3 class="text-sm font-semibold text-slate-400 uppercase tracking-wider mb-4">Examples</h3>
|
|
9
|
+
<ul class="space-y-2">
|
|
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
|
+
>
|
|
19
|
+
{{ example.title }}
|
|
20
|
+
</a>
|
|
21
|
+
</li>
|
|
22
|
+
</ul>
|
|
23
|
+
</nav>
|
|
24
|
+
</aside>
|
|
25
|
+
|
|
26
|
+
<!-- Main Content -->
|
|
27
|
+
<main class="flex-1 min-w-0">
|
|
28
|
+
<div class="space-y-16">
|
|
29
|
+
<!-- Basic Example -->
|
|
30
|
+
<section id="basic" ref="basicRef" class="scroll-mt-24">
|
|
31
|
+
<div class="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
|
|
32
|
+
<div class="px-6 py-4 border-b border-slate-200 bg-slate-50">
|
|
33
|
+
<h2 class="text-2xl font-bold text-slate-800">Basic Usage</h2>
|
|
34
|
+
<p class="text-slate-600 mt-1">Simple masonry grid with default MasonryItem component</p>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<!-- Live Example -->
|
|
38
|
+
<div class="p-6 bg-slate-50">
|
|
39
|
+
<div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
|
|
40
|
+
<BasicExample />
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<!-- Code Tabs -->
|
|
45
|
+
<div class="px-6 pb-6">
|
|
46
|
+
<CodeTabs
|
|
47
|
+
vue='<script setup>
|
|
48
|
+
import { ref } from "vue";
|
|
49
|
+
import { Masonry } from "@wyxos/vibe";
|
|
50
|
+
|
|
51
|
+
const items = ref([]);
|
|
52
|
+
|
|
53
|
+
async function getNextPage(page) {
|
|
54
|
+
const response = await fetch(`/api/items?page=${page}`);
|
|
55
|
+
const data = await response.json();
|
|
56
|
+
return {
|
|
57
|
+
items: data.items,
|
|
58
|
+
nextPage: page + 1
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<template>
|
|
64
|
+
<Masonry
|
|
65
|
+
v-model:items="items"
|
|
66
|
+
:get-next-page="getNextPage"
|
|
67
|
+
:load-at-page="1"
|
|
68
|
+
/>
|
|
69
|
+
</template>'
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</section>
|
|
74
|
+
|
|
75
|
+
<!-- Custom Masonry Item Example -->
|
|
76
|
+
<section id="custom-item" ref="customItemRef" class="scroll-mt-24">
|
|
77
|
+
<div class="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
|
|
78
|
+
<div class="px-6 py-4 border-b border-slate-200 bg-slate-50">
|
|
79
|
+
<h2 class="text-2xl font-bold text-slate-800">Custom Masonry Item</h2>
|
|
80
|
+
<p class="text-slate-600 mt-1">Customize item rendering with scoped slots</p>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<!-- Live Example -->
|
|
84
|
+
<div class="p-6 bg-slate-50">
|
|
85
|
+
<div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
|
|
86
|
+
<CustomItemExample />
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<!-- Code Tabs -->
|
|
91
|
+
<div class="px-6 pb-6">
|
|
92
|
+
<CodeTabs
|
|
93
|
+
vue='<script setup>
|
|
94
|
+
import { ref } from "vue";
|
|
95
|
+
import { Masonry } from "@wyxos/vibe";
|
|
96
|
+
|
|
97
|
+
const items = ref([]);
|
|
98
|
+
|
|
99
|
+
async function getNextPage(page) {
|
|
100
|
+
const response = await fetch(`/api/items?page=${page}`);
|
|
101
|
+
const data = await response.json();
|
|
102
|
+
return {
|
|
103
|
+
items: data.items,
|
|
104
|
+
nextPage: page + 1
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<template>
|
|
110
|
+
<Masonry
|
|
111
|
+
v-model:items="items"
|
|
112
|
+
:get-next-page="getNextPage"
|
|
113
|
+
:load-at-page="1"
|
|
114
|
+
>
|
|
115
|
+
<template #item="{ item, remove }">
|
|
116
|
+
<div class="custom-card">
|
|
117
|
+
<img :src="item.src" :alt="item.title" />
|
|
118
|
+
<div class="overlay">
|
|
119
|
+
<h3>{{ item.title }}</h3>
|
|
120
|
+
<button @click="remove">Remove</button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</template>
|
|
124
|
+
</Masonry>
|
|
125
|
+
</template>'
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</section>
|
|
130
|
+
|
|
131
|
+
<!-- Swipe Mode Example -->
|
|
132
|
+
<section id="swipe-mode" ref="swipeModeRef" class="scroll-mt-24">
|
|
133
|
+
<div class="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
|
|
134
|
+
<div class="px-6 py-4 border-b border-slate-200 bg-slate-50">
|
|
135
|
+
<h2 class="text-2xl font-bold text-slate-800">Swipe Mode</h2>
|
|
136
|
+
<p class="text-slate-600 mt-1">Vertical swipe feed for mobile devices</p>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<!-- Live Example -->
|
|
140
|
+
<div class="p-6 bg-slate-50">
|
|
141
|
+
<div class="bg-white rounded-lg border border-slate-200 p-4" style="height: 500px;">
|
|
142
|
+
<SwipeModeExample />
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<!-- Code Tabs -->
|
|
147
|
+
<div class="px-6 pb-6">
|
|
148
|
+
<CodeTabs
|
|
149
|
+
vue='<script setup>
|
|
150
|
+
import { ref } from "vue";
|
|
151
|
+
import { Masonry } from "@wyxos/vibe";
|
|
152
|
+
|
|
153
|
+
const items = ref([]);
|
|
154
|
+
|
|
155
|
+
async function getNextPage(page) {
|
|
156
|
+
const response = await fetch(`/api/items?page=${page}`);
|
|
157
|
+
const data = await response.json();
|
|
158
|
+
return {
|
|
159
|
+
items: data.items,
|
|
160
|
+
nextPage: page + 1
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
</script>
|
|
164
|
+
|
|
165
|
+
<template>
|
|
166
|
+
<!-- Auto mode: switches to swipe on mobile -->
|
|
167
|
+
<Masonry
|
|
168
|
+
v-model:items="items"
|
|
169
|
+
:get-next-page="getNextPage"
|
|
170
|
+
layout-mode="auto"
|
|
171
|
+
:mobile-breakpoint="768"
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
<!-- Force swipe mode on all devices -->
|
|
175
|
+
<Masonry
|
|
176
|
+
v-model:items="items"
|
|
177
|
+
:get-next-page="getNextPage"
|
|
178
|
+
layout-mode="swipe"
|
|
179
|
+
/>
|
|
180
|
+
</template>'
|
|
181
|
+
/>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</section>
|
|
185
|
+
</div>
|
|
186
|
+
</main>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</template>
|
|
191
|
+
|
|
192
|
+
<script setup lang="ts">
|
|
193
|
+
import { ref, onMounted, onUnmounted } from 'vue'
|
|
194
|
+
import CodeTabs from '../components/CodeTabs.vue'
|
|
195
|
+
import BasicExample from '../components/examples/BasicExample.vue'
|
|
196
|
+
import CustomItemExample from '../components/examples/CustomItemExample.vue'
|
|
197
|
+
import SwipeModeExample from '../components/examples/SwipeModeExample.vue'
|
|
198
|
+
|
|
199
|
+
const examples = [
|
|
200
|
+
{ id: 'basic', title: 'Basic Usage' },
|
|
201
|
+
{ id: 'custom-item', title: 'Custom Masonry Item' },
|
|
202
|
+
{ id: 'swipe-mode', title: 'Swipe Mode' }
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
const activeSection = ref('basic')
|
|
206
|
+
const basicRef = ref<HTMLElement | null>(null)
|
|
207
|
+
const customItemRef = ref<HTMLElement | null>(null)
|
|
208
|
+
const swipeModeRef = ref<HTMLElement | null>(null)
|
|
209
|
+
|
|
210
|
+
function scrollTo(id: string) {
|
|
211
|
+
const element = document.getElementById(id)
|
|
212
|
+
if (element) {
|
|
213
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
214
|
+
activeSection.value = id
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function updateActiveSection() {
|
|
219
|
+
const sections = [
|
|
220
|
+
{ id: 'basic', ref: basicRef },
|
|
221
|
+
{ id: 'custom-item', ref: customItemRef },
|
|
222
|
+
{ id: 'swipe-mode', ref: swipeModeRef }
|
|
223
|
+
]
|
|
224
|
+
|
|
225
|
+
const scrollPosition = window.scrollY + 100
|
|
226
|
+
|
|
227
|
+
for (let i = sections.length - 1; i >= 0; i--) {
|
|
228
|
+
const section = sections[i]
|
|
229
|
+
if (section.ref.value) {
|
|
230
|
+
const top = section.ref.value.offsetTop
|
|
231
|
+
if (scrollPosition >= top) {
|
|
232
|
+
activeSection.value = section.id
|
|
233
|
+
break
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
onMounted(() => {
|
|
240
|
+
window.addEventListener('scroll', updateActiveSection)
|
|
241
|
+
updateActiveSection()
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
onUnmounted(() => {
|
|
245
|
+
window.removeEventListener('scroll', updateActiveSection)
|
|
246
|
+
})
|
|
247
|
+
</script>
|
package/toggle-link.mjs
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { readFileSync, writeFileSync } from 'fs';
|
|
4
|
-
import { resolve, dirname, relative } from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { execSync } from 'child_process';
|
|
7
|
-
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = dirname(__filename);
|
|
10
|
-
|
|
11
|
-
// Get the vibe package directory
|
|
12
|
-
const vibeDir = resolve(__dirname);
|
|
13
|
-
const vibePackageJson = JSON.parse(readFileSync(resolve(vibeDir, 'package.json'), 'utf-8'));
|
|
14
|
-
const vibeVersion = vibePackageJson.version;
|
|
15
|
-
|
|
16
|
-
// Get the current working directory (where the script is run from)
|
|
17
|
-
const cwd = process.cwd();
|
|
18
|
-
const targetPackageJsonPath = resolve(cwd, 'package.json');
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
const targetPackageJson = JSON.parse(readFileSync(targetPackageJsonPath, 'utf-8'));
|
|
22
|
-
|
|
23
|
-
// Check if @wyxos/vibe exists in dependencies or devDependencies
|
|
24
|
-
const deps = { ...targetPackageJson.dependencies, ...targetPackageJson.devDependencies };
|
|
25
|
-
const currentVibeRef = deps['@wyxos/vibe'];
|
|
26
|
-
|
|
27
|
-
if (!currentVibeRef) {
|
|
28
|
-
console.error('❌ @wyxos/vibe not found in package.json dependencies or devDependencies');
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Determine if it's a local path or version reference
|
|
33
|
-
const isLocalPath = currentVibeRef.startsWith('file:') || currentVibeRef.startsWith('../') || currentVibeRef.startsWith('./');
|
|
34
|
-
|
|
35
|
-
let newRef;
|
|
36
|
-
let action;
|
|
37
|
-
|
|
38
|
-
if (isLocalPath) {
|
|
39
|
-
// Switch to published version
|
|
40
|
-
newRef = `^${vibeVersion}`;
|
|
41
|
-
action = 'published version';
|
|
42
|
-
} else {
|
|
43
|
-
// Switch to local path
|
|
44
|
-
// Calculate relative path from target to vibe
|
|
45
|
-
const relativePath = relative(cwd, vibeDir).replace(/\\/g, '/');
|
|
46
|
-
newRef = `file:${relativePath}`;
|
|
47
|
-
action = 'local path';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Update package.json
|
|
51
|
-
if (targetPackageJson.dependencies && targetPackageJson.dependencies['@wyxos/vibe']) {
|
|
52
|
-
targetPackageJson.dependencies['@wyxos/vibe'] = newRef;
|
|
53
|
-
}
|
|
54
|
-
if (targetPackageJson.devDependencies && targetPackageJson.devDependencies['@wyxos/vibe']) {
|
|
55
|
-
targetPackageJson.devDependencies['@wyxos/vibe'] = newRef;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Write updated package.json
|
|
59
|
-
writeFileSync(
|
|
60
|
-
targetPackageJsonPath,
|
|
61
|
-
JSON.stringify(targetPackageJson, null, 2) + '\n',
|
|
62
|
-
'utf-8'
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
console.log(`✅ Switched @wyxos/vibe to ${action}: ${newRef}`);
|
|
66
|
-
|
|
67
|
-
// If switching to local path, ensure the library is built before installation
|
|
68
|
-
if (action === 'local path') {
|
|
69
|
-
try {
|
|
70
|
-
console.log('🔧 Building local @wyxos/vibe (build:lib)...');
|
|
71
|
-
execSync('npm run build:lib', { cwd: vibeDir, stdio: 'inherit' });
|
|
72
|
-
} catch (e) {
|
|
73
|
-
console.warn('⚠️ Failed to build local @wyxos/vibe. Attempting install anyway.');
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Run npm install
|
|
78
|
-
console.log('📦 Running npm install...');
|
|
79
|
-
execSync('npm install', { cwd, stdio: 'inherit' });
|
|
80
|
-
|
|
81
|
-
console.log('✨ Done!');
|
|
82
|
-
|
|
83
|
-
} catch (error) {
|
|
84
|
-
if (error.code === 'ENOENT') {
|
|
85
|
-
console.error(`❌ package.json not found in ${cwd}`);
|
|
86
|
-
console.error(' Make sure you run this script from a project directory that uses @wyxos/vibe');
|
|
87
|
-
} else {
|
|
88
|
-
console.error('❌ Error:', error.message);
|
|
89
|
-
}
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
4
|
+
import { resolve, dirname, relative } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Get the vibe package directory
|
|
12
|
+
const vibeDir = resolve(__dirname);
|
|
13
|
+
const vibePackageJson = JSON.parse(readFileSync(resolve(vibeDir, 'package.json'), 'utf-8'));
|
|
14
|
+
const vibeVersion = vibePackageJson.version;
|
|
15
|
+
|
|
16
|
+
// Get the current working directory (where the script is run from)
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const targetPackageJsonPath = resolve(cwd, 'package.json');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const targetPackageJson = JSON.parse(readFileSync(targetPackageJsonPath, 'utf-8'));
|
|
22
|
+
|
|
23
|
+
// Check if @wyxos/vibe exists in dependencies or devDependencies
|
|
24
|
+
const deps = { ...targetPackageJson.dependencies, ...targetPackageJson.devDependencies };
|
|
25
|
+
const currentVibeRef = deps['@wyxos/vibe'];
|
|
26
|
+
|
|
27
|
+
if (!currentVibeRef) {
|
|
28
|
+
console.error('❌ @wyxos/vibe not found in package.json dependencies or devDependencies');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Determine if it's a local path or version reference
|
|
33
|
+
const isLocalPath = currentVibeRef.startsWith('file:') || currentVibeRef.startsWith('../') || currentVibeRef.startsWith('./');
|
|
34
|
+
|
|
35
|
+
let newRef;
|
|
36
|
+
let action;
|
|
37
|
+
|
|
38
|
+
if (isLocalPath) {
|
|
39
|
+
// Switch to published version
|
|
40
|
+
newRef = `^${vibeVersion}`;
|
|
41
|
+
action = 'published version';
|
|
42
|
+
} else {
|
|
43
|
+
// Switch to local path
|
|
44
|
+
// Calculate relative path from target to vibe
|
|
45
|
+
const relativePath = relative(cwd, vibeDir).replace(/\\/g, '/');
|
|
46
|
+
newRef = `file:${relativePath}`;
|
|
47
|
+
action = 'local path';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Update package.json
|
|
51
|
+
if (targetPackageJson.dependencies && targetPackageJson.dependencies['@wyxos/vibe']) {
|
|
52
|
+
targetPackageJson.dependencies['@wyxos/vibe'] = newRef;
|
|
53
|
+
}
|
|
54
|
+
if (targetPackageJson.devDependencies && targetPackageJson.devDependencies['@wyxos/vibe']) {
|
|
55
|
+
targetPackageJson.devDependencies['@wyxos/vibe'] = newRef;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Write updated package.json
|
|
59
|
+
writeFileSync(
|
|
60
|
+
targetPackageJsonPath,
|
|
61
|
+
JSON.stringify(targetPackageJson, null, 2) + '\n',
|
|
62
|
+
'utf-8'
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
console.log(`✅ Switched @wyxos/vibe to ${action}: ${newRef}`);
|
|
66
|
+
|
|
67
|
+
// If switching to local path, ensure the library is built before installation
|
|
68
|
+
if (action === 'local path') {
|
|
69
|
+
try {
|
|
70
|
+
console.log('🔧 Building local @wyxos/vibe (build:lib)...');
|
|
71
|
+
execSync('npm run build:lib', { cwd: vibeDir, stdio: 'inherit' });
|
|
72
|
+
} catch (e) {
|
|
73
|
+
console.warn('⚠️ Failed to build local @wyxos/vibe. Attempting install anyway.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Run npm install
|
|
78
|
+
console.log('📦 Running npm install...');
|
|
79
|
+
execSync('npm install', { cwd, stdio: 'inherit' });
|
|
80
|
+
|
|
81
|
+
console.log('✨ Done!');
|
|
82
|
+
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error.code === 'ENOENT') {
|
|
85
|
+
console.error(`❌ package.json not found in ${cwd}`);
|
|
86
|
+
console.error(' Make sure you run this script from a project directory that uses @wyxos/vibe');
|
|
87
|
+
} else {
|
|
88
|
+
console.error('❌ Error:', error.message);
|
|
89
|
+
}
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|