@wyxos/vibe 1.6.6 → 1.6.8
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 +46 -7
- package/lib/apple-touch-icon-114x114.png +0 -0
- package/lib/apple-touch-icon-120x120.png +0 -0
- package/lib/apple-touch-icon-144x144.png +0 -0
- package/lib/apple-touch-icon-152x152.png +0 -0
- package/lib/apple-touch-icon-180x180.png +0 -0
- package/lib/apple-touch-icon-57x57.png +0 -0
- package/lib/apple-touch-icon-60x60.png +0 -0
- package/lib/apple-touch-icon-72x72.png +0 -0
- package/lib/apple-touch-icon-76x76.png +0 -0
- package/lib/favicon-128x128.png +0 -0
- package/lib/favicon-16x16.png +0 -0
- package/lib/favicon-256x256.png +0 -0
- package/lib/favicon-32x32.png +0 -0
- package/lib/favicon-48x48.png +0 -0
- package/lib/favicon-64x64.png +0 -0
- package/lib/favicon.ico +0 -0
- package/lib/index.js +560 -438
- package/lib/logo-dark.svg +36 -0
- package/lib/logo-light.svg +29 -0
- package/lib/logo.svg +32 -0
- package/lib/manifest.json +41 -0
- package/lib/vibe.css +1 -1
- package/package.json +5 -2
- package/src/App.vue +30 -159
- package/src/Masonry.vue +3 -2
- package/src/components/MasonryItem.vue +239 -41
- package/src/main.ts +2 -1
- package/src/pages.json +36401 -32501
- package/src/router/index.ts +20 -0
- package/src/style.css +31 -31
- package/src/views/Examples.vue +20 -0
- package/src/views/Home.vue +169 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="vibeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
|
|
5
|
+
<stop offset="100%" style="stop-color:#06b6d4;stop-opacity:1" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="vibeGradLight" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
8
|
+
<stop offset="0%" style="stop-color:#60a5fa;stop-opacity:1" />
|
|
9
|
+
<stop offset="100%" style="stop-color:#22d3ee;stop-opacity:1" />
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<!-- Background -->
|
|
14
|
+
<rect width="120" height="120" rx="24" fill="url(#vibeGrad)"/>
|
|
15
|
+
|
|
16
|
+
<!-- Masonry blocks - representing the infinite block engine -->
|
|
17
|
+
<!-- Left column -->
|
|
18
|
+
<rect x="18" y="20" width="24" height="32" rx="5" fill="white" opacity="0.95"/>
|
|
19
|
+
<rect x="18" y="58" width="24" height="20" rx="5" fill="white" opacity="0.85"/>
|
|
20
|
+
<rect x="18" y="84" width="24" height="16" rx="5" fill="white" opacity="0.9"/>
|
|
21
|
+
|
|
22
|
+
<!-- Middle column -->
|
|
23
|
+
<rect x="48" y="28" width="24" height="22" rx="5" fill="white" opacity="0.9"/>
|
|
24
|
+
<rect x="48" y="56" width="24" height="36" rx="5" fill="white" opacity="0.95"/>
|
|
25
|
+
<rect x="48" y="98" width="24" height="14" rx="5" fill="white" opacity="0.8"/>
|
|
26
|
+
|
|
27
|
+
<!-- Right column -->
|
|
28
|
+
<rect x="78" y="22" width="24" height="38" rx="5" fill="white" opacity="0.85"/>
|
|
29
|
+
<rect x="78" y="66" width="24" height="24" rx="5" fill="white" opacity="0.9"/>
|
|
30
|
+
<rect x="78" y="96" width="24" height="16" rx="5" fill="white" opacity="0.85"/>
|
|
31
|
+
|
|
32
|
+
<!-- Infinite loop symbol (subtle overlay) -->
|
|
33
|
+
<path d="M 30 60 Q 40 50, 50 60 Q 60 70, 70 60" stroke="url(#vibeGradLight)" stroke-width="3" fill="none" opacity="0.4" stroke-linecap="round"/>
|
|
34
|
+
<path d="M 30 60 Q 40 70, 50 60 Q 60 50, 70 60" stroke="url(#vibeGradLight)" stroke-width="3" fill="none" opacity="0.4" stroke-linecap="round"/>
|
|
35
|
+
</svg>
|
|
36
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="vibeGradLight" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
|
|
5
|
+
<stop offset="100%" style="stop-color:#06b6d4;stop-opacity:1" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<!-- Masonry blocks - representing the infinite block engine -->
|
|
10
|
+
<!-- Left column -->
|
|
11
|
+
<rect x="18" y="20" width="24" height="32" rx="5" fill="url(#vibeGradLight)" opacity="0.95"/>
|
|
12
|
+
<rect x="18" y="58" width="24" height="20" rx="5" fill="url(#vibeGradLight)" opacity="0.85"/>
|
|
13
|
+
<rect x="18" y="84" width="24" height="16" rx="5" fill="url(#vibeGradLight)" opacity="0.9"/>
|
|
14
|
+
|
|
15
|
+
<!-- Middle column -->
|
|
16
|
+
<rect x="48" y="28" width="24" height="22" rx="5" fill="url(#vibeGradLight)" opacity="0.9"/>
|
|
17
|
+
<rect x="48" y="56" width="24" height="36" rx="5" fill="url(#vibeGradLight)" opacity="0.95"/>
|
|
18
|
+
<rect x="48" y="98" width="24" height="14" rx="5" fill="url(#vibeGradLight)" opacity="0.8"/>
|
|
19
|
+
|
|
20
|
+
<!-- Right column -->
|
|
21
|
+
<rect x="78" y="22" width="24" height="38" rx="5" fill="url(#vibeGradLight)" opacity="0.85"/>
|
|
22
|
+
<rect x="78" y="66" width="24" height="24" rx="5" fill="url(#vibeGradLight)" opacity="0.9"/>
|
|
23
|
+
<rect x="78" y="96" width="24" height="16" rx="5" fill="url(#vibeGradLight)" opacity="0.85"/>
|
|
24
|
+
|
|
25
|
+
<!-- Infinite loop symbol (subtle overlay) -->
|
|
26
|
+
<path d="M 30 60 Q 40 50, 50 60 Q 60 70, 70 60" stroke="url(#vibeGradLight)" stroke-width="3" fill="none" opacity="0.6" stroke-linecap="round"/>
|
|
27
|
+
<path d="M 30 60 Q 40 70, 50 60 Q 60 50, 70 60" stroke="url(#vibeGradLight)" stroke-width="3" fill="none" opacity="0.6" stroke-linecap="round"/>
|
|
28
|
+
</svg>
|
|
29
|
+
|
package/lib/logo.svg
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" style="stop-color:#3b82f6;stop-opacity:1" />
|
|
5
|
+
<stop offset="100%" style="stop-color:#06b6d4;stop-opacity:1" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
|
|
9
|
+
<!-- Background circle -->
|
|
10
|
+
<circle cx="60" cy="60" r="58" fill="url(#grad1)" opacity="0.1"/>
|
|
11
|
+
|
|
12
|
+
<!-- Masonry blocks representing infinite layout -->
|
|
13
|
+
<!-- Column 1 -->
|
|
14
|
+
<rect x="20" y="15" width="22" height="28" rx="4" fill="url(#grad1)" opacity="0.9"/>
|
|
15
|
+
<rect x="20" y="48" width="22" height="18" rx="4" fill="url(#grad1)" opacity="0.7"/>
|
|
16
|
+
<rect x="20" y="71" width="22" height="34" rx="4" fill="url(#grad1)" opacity="0.8"/>
|
|
17
|
+
|
|
18
|
+
<!-- Column 2 -->
|
|
19
|
+
<rect x="49" y="25" width="22" height="20" rx="4" fill="url(#grad1)" opacity="0.8"/>
|
|
20
|
+
<rect x="49" y="50" width="22" height="32" rx="4" fill="url(#grad1)" opacity="0.9"/>
|
|
21
|
+
<rect x="49" y="87" width="22" height="18" rx="4" fill="url(#grad1)" opacity="0.6"/>
|
|
22
|
+
|
|
23
|
+
<!-- Column 3 -->
|
|
24
|
+
<rect x="78" y="18" width="22" height="35" rx="4" fill="url(#grad1)" opacity="0.7"/>
|
|
25
|
+
<rect x="78" y="58" width="22" height="22" rx="4" fill="url(#grad1)" opacity="0.9"/>
|
|
26
|
+
<rect x="78" y="85" width="22" height="20" rx="4" fill="url(#grad1)" opacity="0.8"/>
|
|
27
|
+
|
|
28
|
+
<!-- Infinite symbol overlay (subtle) -->
|
|
29
|
+
<path d="M 35 60 Q 45 50, 55 60 Q 65 70, 75 60" stroke="url(#grad1)" stroke-width="2.5" fill="none" opacity="0.6" stroke-linecap="round"/>
|
|
30
|
+
<path d="M 35 60 Q 45 70, 55 60 Q 65 50, 75 60" stroke="url(#grad1)" stroke-width="2.5" fill="none" opacity="0.6" stroke-linecap="round"/>
|
|
31
|
+
</svg>
|
|
32
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "VIBE - Vue Infinite Block Engine",
|
|
3
|
+
"short_name": "VIBE",
|
|
4
|
+
"description": "A high-performance, responsive masonry layout engine for Vue 3",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#f8fafc",
|
|
8
|
+
"theme_color": "#3b82f6",
|
|
9
|
+
"icons": [
|
|
10
|
+
{
|
|
11
|
+
"src": "favicon-16x16.png",
|
|
12
|
+
"sizes": "16x16",
|
|
13
|
+
"type": "image/png"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"src": "favicon-32x32.png",
|
|
17
|
+
"sizes": "32x32",
|
|
18
|
+
"type": "image/png"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"src": "favicon-48x48.png",
|
|
22
|
+
"sizes": "48x48",
|
|
23
|
+
"type": "image/png"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"src": "favicon-64x64.png",
|
|
27
|
+
"sizes": "64x64",
|
|
28
|
+
"type": "image/png"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"src": "favicon-128x128.png",
|
|
32
|
+
"sizes": "128x128",
|
|
33
|
+
"type": "image/png"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"src": "favicon-256x256.png",
|
|
37
|
+
"sizes": "256x256",
|
|
38
|
+
"type": "image/png"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
package/lib/vibe.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.masonry-container[data-v-
|
|
1
|
+
.masonry-container[data-v-110c3294]{overflow-anchor:none}.masonry-item[data-v-110c3294]{will-change:transform,opacity;contain:layout paint;transition:transform var(--masonry-duration, .45s) var(--masonry-ease, cubic-bezier(.22, .61, .36, 1)),opacity var(--masonry-leave-duration, .16s) ease-out var(--masonry-opacity-delay, 0ms);backface-visibility:hidden}.masonry-move[data-v-110c3294]{transition:transform var(--masonry-duration, .45s) var(--masonry-ease, cubic-bezier(.22, .61, .36, 1))}@media (prefers-reduced-motion: reduce){.masonry-container:not(.force-motion) .masonry-item[data-v-110c3294],.masonry-container:not(.force-motion) .masonry-move[data-v-110c3294]{transition-duration:1ms!important}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wyxos/vibe",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"module": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -38,12 +38,14 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"lodash": "^4.17.21",
|
|
40
40
|
"lodash-es": "^4.17.21",
|
|
41
|
-
"vue": "^3.0.0"
|
|
41
|
+
"vue": "^3.0.0",
|
|
42
|
+
"vue-router": "^4.6.3"
|
|
42
43
|
},
|
|
43
44
|
"peerDependencies": {
|
|
44
45
|
"vue": "^3.0.0"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
48
|
+
"@resvg/resvg-js": "^2.6.2",
|
|
47
49
|
"@tailwindcss/vite": "^4.0.15",
|
|
48
50
|
"@types/lodash-es": "^4.17.12",
|
|
49
51
|
"@types/node": "^24.5.2",
|
|
@@ -52,6 +54,7 @@
|
|
|
52
54
|
"chalk": "^5.3.0",
|
|
53
55
|
"inquirer": "^10.1.8",
|
|
54
56
|
"jsdom": "^26.0.0",
|
|
57
|
+
"sharp": "^0.34.5",
|
|
55
58
|
"simple-git": "^3.27.0",
|
|
56
59
|
"tailwindcss": "^4.0.15",
|
|
57
60
|
"typescript": "^5.9.2",
|
package/src/App.vue
CHANGED
|
@@ -1,164 +1,35 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import Masonry from "./Masonry.vue";
|
|
3
|
-
import { ref, reactive, computed } from "vue";
|
|
4
|
-
import fixture from "./pages.json";
|
|
5
|
-
import type { MasonryItem, GetPageResult } from "./types";
|
|
6
|
-
|
|
7
|
-
const items = ref<MasonryItem[]>([]);
|
|
8
|
-
|
|
9
|
-
const masonry = ref<InstanceType<typeof Masonry> | null>(null);
|
|
10
|
-
|
|
11
|
-
const layoutParams = reactive({
|
|
12
|
-
sizes: {
|
|
13
|
-
base: 1,
|
|
14
|
-
sm: 2,
|
|
15
|
-
md: 3,
|
|
16
|
-
lg: 4,
|
|
17
|
-
xl: 5,
|
|
18
|
-
'2xl': 10
|
|
19
|
-
},
|
|
20
|
-
header: 0,
|
|
21
|
-
footer: 0
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const layout = computed(() => ({
|
|
25
|
-
sizes: { ...layoutParams.sizes },
|
|
26
|
-
header: layoutParams.header,
|
|
27
|
-
footer: layoutParams.footer
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
const showLayoutControls = ref(false);
|
|
31
|
-
|
|
32
|
-
const getPage = async (page: number): Promise<GetPageResult> => {
|
|
33
|
-
return new Promise((resolve) => {
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
// Check if the page exists in the fixture
|
|
36
|
-
const pageData = (fixture as any[])[page - 1] as { items: MasonryItem[] } | undefined;
|
|
37
|
-
|
|
38
|
-
if (!pageData) {
|
|
39
|
-
// Return empty items if page doesn't exist
|
|
40
|
-
resolve({
|
|
41
|
-
items: [],
|
|
42
|
-
nextPage: null // null indicates no more pages
|
|
43
|
-
});
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const output: GetPageResult = {
|
|
48
|
-
items: pageData.items,
|
|
49
|
-
nextPage: page < (fixture as any[]).length ? page + 1 : null
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
resolve(output);
|
|
53
|
-
}, 1000);
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
</script>
|
|
57
1
|
<template>
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
<
|
|
65
|
-
</
|
|
66
|
-
<div>
|
|
67
|
-
<
|
|
68
|
-
|
|
2
|
+
<div id="app">
|
|
3
|
+
<nav class="fixed top-0 left-0 right-0 z-30 bg-white/90 backdrop-blur-md border-b border-slate-200 shadow-sm">
|
|
4
|
+
<div class="max-w-7xl mx-auto px-4 py-3">
|
|
5
|
+
<div class="flex items-center justify-between">
|
|
6
|
+
<router-link to="/" class="flex items-center gap-2 text-lg font-bold text-slate-800 hover:text-blue-600 transition-colors">
|
|
7
|
+
<img src="/logo-light.svg" alt="VIBE" class="w-8 h-8" />
|
|
8
|
+
<span>VIBE</span>
|
|
9
|
+
</router-link>
|
|
10
|
+
<div class="flex items-center gap-4">
|
|
11
|
+
<router-link
|
|
12
|
+
to="/"
|
|
13
|
+
class="text-sm text-slate-600 hover:text-slate-800 transition-colors"
|
|
14
|
+
active-class="text-blue-600 font-medium"
|
|
15
|
+
>
|
|
16
|
+
Demo
|
|
17
|
+
</router-link>
|
|
18
|
+
<router-link
|
|
19
|
+
to="/examples"
|
|
20
|
+
class="text-sm text-slate-600 hover:text-slate-800 transition-colors"
|
|
21
|
+
active-class="text-blue-600 font-medium"
|
|
22
|
+
>
|
|
23
|
+
Examples
|
|
24
|
+
</router-link>
|
|
69
25
|
</div>
|
|
70
26
|
</div>
|
|
71
|
-
|
|
72
|
-
<div class="flex items-center gap-4">
|
|
73
|
-
<div v-if="masonry" class="hidden md:flex items-center gap-3 text-sm font-medium text-slate-600 bg-slate-100/50 px-3 py-1.5 rounded-lg border border-slate-200/50">
|
|
74
|
-
<span class="flex items-center gap-1.5">
|
|
75
|
-
<span class="w-2 h-2 rounded-full" :class="masonry.isLoading ? 'bg-amber-400 animate-pulse' : 'bg-emerald-400'"></span>
|
|
76
|
-
{{ masonry.isLoading ? 'Loading...' : 'Ready' }}
|
|
77
|
-
</span>
|
|
78
|
-
<span class="w-px h-3 bg-slate-300"></span>
|
|
79
|
-
<span>{{ items.length }} items</span>
|
|
80
|
-
</div>
|
|
81
|
-
|
|
82
|
-
<button
|
|
83
|
-
@click="showLayoutControls = !showLayoutControls"
|
|
84
|
-
class="p-2 text-slate-500 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
|
|
85
|
-
:class="{ 'text-blue-600 bg-blue-50': showLayoutControls }"
|
|
86
|
-
title="Layout Controls"
|
|
87
|
-
>
|
|
88
|
-
<i class="fas fa-sliders"></i>
|
|
89
|
-
</button>
|
|
90
|
-
|
|
91
|
-
<a href="https://github.com/wyxos/vibe" target="_blank" class="p-2 text-slate-400 hover:text-slate-800 transition-colors" title="View on GitHub">
|
|
92
|
-
<i class="fab fa-github text-xl"></i>
|
|
93
|
-
</a>
|
|
94
|
-
</div>
|
|
95
27
|
</div>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
enter-active-class="transition duration-200 ease-out"
|
|
100
|
-
enter-from-class="transform -translate-y-2 opacity-0"
|
|
101
|
-
enter-to-class="transform translate-y-0 opacity-100"
|
|
102
|
-
leave-active-class="transition duration-150 ease-in"
|
|
103
|
-
leave-from-class="transform translate-y-0 opacity-100"
|
|
104
|
-
leave-to-class="transform -translate-y-2 opacity-0"
|
|
105
|
-
>
|
|
106
|
-
<div v-if="showLayoutControls" class="mt-2 bg-white/90 backdrop-blur-md border border-white/20 shadow-xl rounded-xl p-6 pointer-events-auto">
|
|
107
|
-
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
108
|
-
<!-- Column Settings -->
|
|
109
|
-
<div>
|
|
110
|
-
<h3 class="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3">Column Configuration</h3>
|
|
111
|
-
<div class="grid grid-cols-3 sm:grid-cols-6 gap-3">
|
|
112
|
-
<div v-for="(val, key) in layoutParams.sizes" :key="key" class="flex flex-col gap-1.5">
|
|
113
|
-
<label class="text-[10px] font-bold text-slate-500 uppercase text-center">{{ key }}</label>
|
|
114
|
-
<input
|
|
115
|
-
v-model.number="layoutParams.sizes[key]"
|
|
116
|
-
type="number"
|
|
117
|
-
min="1"
|
|
118
|
-
class="w-full px-2 py-1.5 bg-slate-50 border border-slate-200 rounded-lg text-center text-sm font-medium text-slate-700 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all"
|
|
119
|
-
/>
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
|
|
124
|
-
<!-- Spacing Settings -->
|
|
125
|
-
<div>
|
|
126
|
-
<h3 class="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3">Spacing</h3>
|
|
127
|
-
<div class="grid grid-cols-2 gap-4">
|
|
128
|
-
<div class="flex flex-col gap-1.5">
|
|
129
|
-
<label class="text-[10px] font-bold text-slate-500 uppercase">Header Offset</label>
|
|
130
|
-
<div class="relative">
|
|
131
|
-
<input
|
|
132
|
-
v-model.number="layoutParams.header"
|
|
133
|
-
type="number"
|
|
134
|
-
min="0"
|
|
135
|
-
class="w-full pl-3 pr-8 py-1.5 bg-slate-50 border border-slate-200 rounded-lg text-sm font-medium text-slate-700 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all"
|
|
136
|
-
/>
|
|
137
|
-
<span class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-400">px</span>
|
|
138
|
-
</div>
|
|
139
|
-
</div>
|
|
140
|
-
<div class="flex flex-col gap-1.5">
|
|
141
|
-
<label class="text-[10px] font-bold text-slate-500 uppercase">Footer Offset</label>
|
|
142
|
-
<div class="relative">
|
|
143
|
-
<input
|
|
144
|
-
v-model.number="layoutParams.footer"
|
|
145
|
-
type="number"
|
|
146
|
-
min="0"
|
|
147
|
-
class="w-full pl-3 pr-8 py-1.5 bg-slate-50 border border-slate-200 rounded-lg text-sm font-medium text-slate-700 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all"
|
|
148
|
-
/>
|
|
149
|
-
<span class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-400">px</span>
|
|
150
|
-
</div>
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
</transition>
|
|
157
|
-
</header>
|
|
158
|
-
|
|
159
|
-
<!-- Main Content -->
|
|
160
|
-
<div class="flex flex-1 overflow-hidden relative pt-24">
|
|
161
|
-
<masonry v-model:items="items" :get-next-page="getPage" :load-at-page="1" :layout="layout" ref="masonry"></masonry>
|
|
162
|
-
</div>
|
|
163
|
-
</main>
|
|
28
|
+
</nav>
|
|
29
|
+
<router-view />
|
|
30
|
+
</div>
|
|
164
31
|
</template>
|
|
32
|
+
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
// Root App component with router
|
|
35
|
+
</script>
|
package/src/Masonry.vue
CHANGED
|
@@ -96,7 +96,7 @@ const props = defineProps({
|
|
|
96
96
|
autoRefreshOnEmpty: {
|
|
97
97
|
type: Boolean,
|
|
98
98
|
default: false
|
|
99
|
-
}
|
|
99
|
+
},
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
const defaultLayout = {
|
|
@@ -753,7 +753,8 @@ onUnmounted(() => {
|
|
|
753
753
|
class="absolute masonry-item"
|
|
754
754
|
v-bind="getItemAttributes(item, i)"
|
|
755
755
|
:style="{ paddingTop: `${layout.header}px`, paddingBottom: `${layout.footer}px` }">
|
|
756
|
-
|
|
756
|
+
<!-- Use default slot if provided, otherwise use MasonryItem -->
|
|
757
|
+
<slot :item="item" :remove="remove">
|
|
757
758
|
<MasonryItem :item="item" :remove="remove" />
|
|
758
759
|
</slot>
|
|
759
760
|
</div>
|