Skip to content

Commit 1b79a1b

Browse files
committed
more wip on homepage
1 parent 6fc4d22 commit 1b79a1b

File tree

10 files changed

+641
-254
lines changed

10 files changed

+641
-254
lines changed

packages/docs-site/.eslintrc.cjs

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ module.exports = {
66
extends: ["@dmno/eslint-config/base"],
77
},
88
{
9-
// Define the configuration for `.astro` file.
9+
files: ["**/*.vue"],
10+
extends: ["@dmno/eslint-config/vue"],
11+
},
12+
{
1013
files: ["**/*.astro"],
1114
extends: ["plugin:astro/recommended"],
1215
// Allows Astro components to be parsed.

packages/docs-site/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"astro-robots-txt": "^1.0.0",
3737
"astro-sitemap": "^1.0.0",
3838
"dmno": "workspace:*",
39-
"eslint-plugin-astro": "^1.2.2",
39+
"eslint-plugin-astro": "^1.3.1",
4040
"eslint-plugin-mdx": "^3.1.5",
4141
"less": "^4.2.0",
4242
"nanostores": "^0.10.3",

packages/docs-site/src/components/IconGraph/IconGraph.vue

+131-129
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,23 @@
1-
<script setup lang="ts">
2-
import { ref, onMounted, onUnmounted, computed } from 'vue';
3-
import { Icon } from '@iconify/vue';
4-
import ConnectionLine from './ConnectionLine.vue';
5-
import DMNOLogo from '@dmno/ui-lib/brand-assets/domino-d-gradient-tile.svg';
6-
7-
function shuffleArray(array: any[]) {
8-
for (let i = array.length - 1; i > 0; i--) {
9-
const j = Math.floor(Math.random() * (i + 1));
10-
[array[i], array[j]] = [array[j], array[i]];
11-
}
12-
}
13-
14-
const secretIcons = ref([
15-
{ icon: 'mdi:1password', label: '1Password', docsHref: '/docs/plugins/1password/' },
16-
{ icon: 'simple-icons:bitwarden', label: 'Bitwarden', docsHref: '/docs/plugins/bitwarden/' },
17-
{ icon: 'mdi:lock', label: 'Encrypted Vault', docsHref: '/docs/plugins/encrypted-vault/' },
18-
{ icon: 'mdi:infinity', label: 'Infisical', docsHref: '/docs/plugins/infisical/' },
19-
{ icon: 'mdi:server-outline', label: 'your self-hosted secrets manager', docsHref: '/docs/plugins/overview/' },
20-
]);
21-
22-
const integrationIcons = ref([
23-
{ icon: 'devicon:remix', label: 'Remix', docsHref: '/docs/integrations/remix/' },
24-
{ icon: 'devicon:nextjs', label: 'Next.js', docsHref: '/docs/integrations/nextjs/' },
25-
{ icon: 'devicon:astro', label: 'Astro', docsHref: '/docs/integrations/astro/' },
26-
{ icon: 'logos:vitejs', label: 'Vite', docsHref: '/docs/integrations/vite/' },
27-
{ icon: 'devicon:nodejs', label: 'Node.js', docsHref: '/docs/integrations/node/' }
28-
]);
29-
30-
const platformIcons = ref([
31-
{ icon: 'devicon:netlify', label: 'Netlify', docsHref: '/docs/platforms/netlify/' },
32-
{ icon: 'devicon:vercel', label: 'Vercel', docsHref: '/docs/platforms/vercel/' },
33-
{ icon: 'devicon:cloudflare', label: 'Cloudflare', docsHref: '/docs/platforms/cloudflare/' },
34-
{ icon: 'devicon:docker', label: 'Docker', docsHref: '/docs/platforms/' },
35-
{ icon: 'mdi:server-outline', label: 'Self-hosted infra', docsHref: '/docs/platforms/overview/' },
36-
]);
37-
38-
// Selected icon states
39-
const selectedLeftIndex = ref(0);
40-
const selectedMiddleIndex = ref(0);
41-
const selectedRightIndex = ref(0);
42-
43-
const INTERVAL = 4000;
44-
45-
// Cycle through icons every 2 seconds
46-
onMounted(() => {
47-
shuffleArray(secretIcons.value);
48-
shuffleArray(integrationIcons.value);
49-
shuffleArray(platformIcons.value);
50-
51-
setInterval(() => {
52-
selectedLeftIndex.value = (selectedLeftIndex.value + 1) % secretIcons.value.length;
53-
}, INTERVAL);
54-
55-
setInterval(() => {
56-
selectedMiddleIndex.value = (selectedMiddleIndex.value + 1) % integrationIcons.value.length;
57-
}, INTERVAL);
58-
59-
setInterval(() => {
60-
selectedRightIndex.value = (selectedRightIndex.value + 1) % platformIcons.value.length;
61-
}, INTERVAL);
62-
63-
setInterval(() => {
64-
shuffleArray(secretIcons.value);
65-
shuffleArray(integrationIcons.value);
66-
shuffleArray(platformIcons.value);
67-
}, INTERVAL*platformIcons.value.length);
68-
});
69-
70-
// Adjusted coordinates for better connections
71-
const iconSize = 64 // 16 * 4 (w-16)
72-
const centerIconSize = 80 // 20 * 4 (w-20)
73-
const spacing = 100
74-
const maxWidth = window.innerWidth < 1200 ? window.innerWidth : 1200;
75-
76-
// Column spacing, calculated based on the viewport width
77-
const colSpacing = ref(maxWidth / 4 || 260); // Use SVG viewBox width divided by 4 columns
78-
79-
const leftX = computed(() => 0)
80-
const centerX = computed(() => colSpacing.value)
81-
const middleX = computed(() => colSpacing.value * 2)
82-
const rightX = computed(() => colSpacing.value * 3)
83-
84-
onMounted(() => {
85-
const updateSpacing = () => {
86-
colSpacing.value = maxWidth / 4 || 260;
87-
}
88-
89-
window.addEventListener('resize', updateSpacing)
90-
91-
onUnmounted(() => {
92-
window.removeEventListener('resize', updateSpacing)
93-
})
94-
})
95-
96-
// Calculate vertical positions
97-
const getVerticalPosition = (index: number, total: number) => {
98-
const totalHeight = (total - 1) * spacing
99-
const startY = (600 - totalHeight) / 2
100-
return startY + (index * spacing)
101-
}
102-
103-
// Center Y position - align with middle of all icons
104-
const centerY = 300 - centerIconSize / 2
105-
106-
// Calculate connection points for the right group
107-
const getRightConnectionY = (rightIndex: number, middleTotal: number) => {
108-
const middleSpacing = (middleTotal - 1) * spacing
109-
const middleStartY = (600 - middleSpacing) / 2
110-
const segmentSize = middleSpacing / (platformIcons.value.length - 1)
111-
return middleStartY + (rightIndex * segmentSize)
112-
}
113-
114-
const navigateTo = (href: string) => {
115-
window.location.href = href;
116-
}
117-
</script>
118-
1191
<template>
1202
<div class="container">
1213
<div class="dynamic-text-container">
122-
<h2>Use secrets from
4+
<h2>Use secrets from
1235
<span class="dynamic-text-wrapper">
1246
<transition name="fade" mode="out-in">
1257
<span :key="secretIcons[selectedLeftIndex].label" class="dynamic-text active-secret">
1268
{{ secretIcons[selectedLeftIndex].label }}
1279
</span>
12810
</transition>
129-
</span>
130-
in your
11+
</span>
12+
in your
13113
<span class="dynamic-text-wrapper">
13214
<transition name="fade" mode="out-in">
13315
<span :key="integrationIcons[selectedMiddleIndex].label" class="dynamic-text active-integration">
13416
{{ integrationIcons[selectedMiddleIndex].label }}
13517
</span>
13618
</transition>
137-
</span>
138-
app and deploy to
19+
</span>
20+
app and deploy to
13921
<span class="dynamic-text-wrapper">
14022
<transition name="fade" mode="out-in">
14123
<span :key="platformIcons[selectedRightIndex].label" class="dynamic-text active-platform">
@@ -202,7 +84,7 @@ const navigateTo = (href: string) => {
20284
<!-- Center Node -->
20385
<div
20486
class="center-icon"
205-
:style="{
87+
:style="{
20688
left: centerX + 'px',
20789
top: centerY + 'px'
20890
}"
@@ -250,6 +132,126 @@ const navigateTo = (href: string) => {
250132
</div>
251133
</template>
252134

135+
<script setup lang="ts">
136+
import {
137+
ref, onMounted, onUnmounted, computed,
138+
} from 'vue';
139+
import { Icon } from '@iconify/vue';
140+
import DMNOLogo from '@dmno/ui-lib/brand-assets/domino-d-gradient-tile.svg';
141+
import ConnectionLine from './ConnectionLine.vue';
142+
143+
function shuffleArray(array: Array<any>) {
144+
for (let i = array.length - 1; i > 0; i--) {
145+
const j = Math.floor(Math.random() * (i + 1));
146+
[array[i], array[j]] = [array[j], array[i]];
147+
}
148+
}
149+
150+
const secretIcons = ref([
151+
{ icon: 'mdi:1password', label: '1Password', docsHref: '/docs/plugins/1password/' },
152+
{ icon: 'simple-icons:bitwarden', label: 'Bitwarden', docsHref: '/docs/plugins/bitwarden/' },
153+
{ icon: 'mdi:lock', label: 'Encrypted Vault', docsHref: '/docs/plugins/encrypted-vault/' },
154+
{ icon: 'mdi:infinity', label: 'Infisical', docsHref: '/docs/plugins/infisical/' },
155+
{ icon: 'mdi:server-outline', label: 'your self-hosted secrets manager', docsHref: '/docs/plugins/overview/' },
156+
]);
157+
158+
const integrationIcons = ref([
159+
{ icon: 'devicon:remix', label: 'Remix', docsHref: '/docs/integrations/remix/' },
160+
{ icon: 'devicon:nextjs', label: 'Next.js', docsHref: '/docs/integrations/nextjs/' },
161+
{ icon: 'devicon:astro', label: 'Astro', docsHref: '/docs/integrations/astro/' },
162+
{ icon: 'logos:vitejs', label: 'Vite', docsHref: '/docs/integrations/vite/' },
163+
{ icon: 'devicon:nodejs', label: 'Node.js', docsHref: '/docs/integrations/node/' },
164+
]);
165+
166+
const platformIcons = ref([
167+
{ icon: 'devicon:netlify', label: 'Netlify', docsHref: '/docs/platforms/netlify/' },
168+
{ icon: 'devicon:vercel', label: 'Vercel', docsHref: '/docs/platforms/vercel/' },
169+
{ icon: 'devicon:cloudflare', label: 'Cloudflare', docsHref: '/docs/platforms/cloudflare/' },
170+
{ icon: 'devicon:docker', label: 'Docker', docsHref: '/docs/platforms/' },
171+
{ icon: 'mdi:server-outline', label: 'Self-hosted infra', docsHref: '/docs/platforms/overview/' },
172+
]);
173+
174+
// Selected icon states
175+
const selectedLeftIndex = ref(0);
176+
const selectedMiddleIndex = ref(0);
177+
const selectedRightIndex = ref(0);
178+
179+
const INTERVAL = 4000;
180+
181+
// Cycle through icons every 2 seconds
182+
onMounted(() => {
183+
shuffleArray(secretIcons.value);
184+
shuffleArray(integrationIcons.value);
185+
shuffleArray(platformIcons.value);
186+
187+
setInterval(() => {
188+
selectedLeftIndex.value = (selectedLeftIndex.value + 1) % secretIcons.value.length;
189+
}, INTERVAL);
190+
191+
setInterval(() => {
192+
selectedMiddleIndex.value = (selectedMiddleIndex.value + 1) % integrationIcons.value.length;
193+
}, INTERVAL);
194+
195+
setInterval(() => {
196+
selectedRightIndex.value = (selectedRightIndex.value + 1) % platformIcons.value.length;
197+
}, INTERVAL);
198+
199+
setInterval(() => {
200+
shuffleArray(secretIcons.value);
201+
shuffleArray(integrationIcons.value);
202+
shuffleArray(platformIcons.value);
203+
}, INTERVAL * platformIcons.value.length);
204+
});
205+
206+
// Adjusted coordinates for better connections
207+
const iconSize = 64; // 16 * 4 (w-16)
208+
const centerIconSize = 80; // 20 * 4 (w-20)
209+
const spacing = 100;
210+
const maxWidth = window.innerWidth < 1200 ? window.innerWidth : 1200;
211+
212+
// Column spacing, calculated based on the viewport width
213+
const colSpacing = ref(maxWidth / 4 || 260); // Use SVG viewBox width divided by 4 columns
214+
215+
const leftX = computed(() => 0);
216+
const centerX = computed(() => colSpacing.value);
217+
const middleX = computed(() => colSpacing.value * 2);
218+
const rightX = computed(() => colSpacing.value * 3);
219+
220+
onMounted(() => {
221+
const updateSpacing = () => {
222+
colSpacing.value = maxWidth / 4 || 260;
223+
};
224+
225+
window.addEventListener('resize', updateSpacing);
226+
227+
onUnmounted(() => {
228+
window.removeEventListener('resize', updateSpacing);
229+
});
230+
});
231+
232+
// Calculate vertical positions
233+
const getVerticalPosition = (index: number, total: number) => {
234+
const totalHeight = (total - 1) * spacing;
235+
const startY = (600 - totalHeight) / 2;
236+
return startY + (index * spacing);
237+
};
238+
239+
// Center Y position - align with middle of all icons
240+
const centerY = 300 - centerIconSize / 2;
241+
242+
// Calculate connection points for the right group
243+
const getRightConnectionY = (rightIndex: number, middleTotal: number) => {
244+
const middleSpacing = (middleTotal - 1) * spacing;
245+
const middleStartY = (600 - middleSpacing) / 2;
246+
const segmentSize = middleSpacing / (platformIcons.value.length - 1);
247+
return middleStartY + (rightIndex * segmentSize);
248+
};
249+
250+
const navigateTo = (href: string) => {
251+
window.location.href = href;
252+
};
253+
</script>
254+
253255
<style>
254256
.container {
255257
margin-left: 40px;
@@ -285,14 +287,14 @@ const navigateTo = (href: string) => {
285287
286288
.dynamic-text-container {
287289
margin: 2rem 0;
288-
}
290+
}
289291
290292
.dynamic-text-container > .dynamic-text {
291293
color: rgb(147 51 234); /* text-purple-600 */
292294
&:nth-of-type(1) {
293295
color: rgb(41, 232, 232);
294296
}
295-
297+
296298
&:nth-of-type(2) {
297299
color: rgb(116, 240, 161);
298300
}
@@ -323,7 +325,7 @@ const navigateTo = (href: string) => {
323325
/* todo user brand colors */
324326
325327
.icon-left {
326-
border-color: rgb(156 163 175);
328+
border-color: rgb(156 163 175);
327329
}
328330
329331
.icon-left.icon-selected {
@@ -335,7 +337,7 @@ const navigateTo = (href: string) => {
335337
}
336338
337339
.icon-right.icon-selected {
338-
border: 2px solid rgb(243, 125, 227);
340+
border: 2px solid rgb(243, 125, 227);
339341
}
340342
341343
.center-icon {
@@ -383,7 +385,7 @@ const navigateTo = (href: string) => {
383385
&:nth-of-type(1) {
384386
color: rgb(41, 232, 232);
385387
}
386-
388+
387389
&:nth-of-type(2) {
388390
color: rgb(116, 240, 161);
389391
}

0 commit comments

Comments
 (0)