mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 12:14:41 +01:00
docs(showcase): update
This commit is contained in:
@@ -165,12 +165,12 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
|
||||
<circle cx="6.53711" cy="37.4551" r="1.5" fill="var(--ui-border-accented)" />
|
||||
<circle cx="38.5957" cy="37.4551" r="1.5" fill="var(--ui-border-accented)" />
|
||||
</svg>
|
||||
<UIcon :name="feature.icon" class="size-5 flex-shrink-0" />
|
||||
<UIcon :name="feature.icon" class="size-5 shrink-0" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<h2 class="font-medium text-(--ui-text-highlighted) inline-flex items-center gap-x-1">
|
||||
{{ feature.title }}
|
||||
<UIcon v-if="feature.to" name="i-lucide-arrow-right" class="size-4 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-all duration-200 -translate-x-1 group-hover:translate-x-0" />
|
||||
<UIcon v-if="feature.to" name="i-lucide-arrow-right" class="size-4 shrink-0 opacity-0 group-hover:opacity-100 transition-all duration-200 -translate-x-1 group-hover:translate-x-0" />
|
||||
</h2>
|
||||
<p class="text-sm text-(--ui-text-muted)">
|
||||
{{ feature.description }}
|
||||
|
||||
@@ -37,12 +37,12 @@ useSeoMeta({
|
||||
|
||||
<div aria-hidden="true" class="hidden lg:block absolute z-[-1] border-x border-(--ui-border) inset-0 mx-4 sm:mx-6 lg:mx-8" />
|
||||
|
||||
<div class="border border-(--ui-border) bg-(--ui-bg)">
|
||||
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 items-start justify-center">
|
||||
<div class="border-l border-t border-(--ui-border)">
|
||||
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 items-start justify-center divide-y divide-x divide-(--ui-border)">
|
||||
<li
|
||||
v-for="item in page.items"
|
||||
:key="item.name"
|
||||
class="relative flex flex-col gap-y-4 justify-start group h-full p-4 hover:bg-(--ui-bg-elevated)/50 border-(--ui-border) border-b max-sm:last:border-b-0 border-r max-sm:border-r-0 sm:even:border-r-0 lg:even:border-r lg:border-r lg:[&:nth-child(4n)]:border-r-0 lg:[&:nth-child(5n)]:border-b-0 lg:[&:nth-child(6n)]:border-b-0"
|
||||
class="group relative flex items-center justify-center flex-1 size-full p-2 last:border-r last:border-b border-(--ui-border) overflow-hidden"
|
||||
>
|
||||
<NuxtLink class="inset-0 absolute" :to="item.url" target="_blank">
|
||||
<span class="sr-only">Go to {{ item.name }}</span>
|
||||
@@ -51,20 +51,34 @@ useSeoMeta({
|
||||
<NuxtImg
|
||||
:src="`/assets/showcase/${item.name.toLowerCase().replace(/\s/g, '-')}.png`"
|
||||
:alt="`Screenshot of ${item.name}`"
|
||||
width="311"
|
||||
height="194"
|
||||
class="rounded-[calc(var(--ui-radius)*1.5)] group-hover:scale-103 duration-200 transition-transform pointer-events-none"
|
||||
width="327"
|
||||
height="184"
|
||||
:modifiers="{
|
||||
position: 'top'
|
||||
}"
|
||||
class="aspect-[16/9] size-full opacity-75 group-hover:opacity-100 group-hover:scale-110 duration-200 transition-[scale,opacity] pointer-events-none"
|
||||
/>
|
||||
|
||||
<div class="flex items-center gap-1 px-1">
|
||||
<span class="font-medium text-(--ui-text-highlighted)">
|
||||
<div class="absolute flex items-center px-2.5 py-0.75 gap-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none bg-black/90 rounded-full">
|
||||
<span class="text-sm text-(--ui-text-highlighted) font-medium">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<UIcon name="i-lucide-arrow-right" class="size-4 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-all duration-200 -translate-x-1 group-hover:translate-x-0 text-(--ui-text-muted)" />
|
||||
<UIcon name="i-lucide-arrow-up-right" class="size-4 shrink-0" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center -mb-[36px]">
|
||||
<UButton
|
||||
label="Submit your project"
|
||||
trailing-icon="i-lucide-plus"
|
||||
color="neutral"
|
||||
size="lg"
|
||||
to="https://github.com/nuxt/ui/edit/v3/docs/content/showcase.yml"
|
||||
target="_blank"
|
||||
/>
|
||||
</div>
|
||||
</UPageHero>
|
||||
</UMain>
|
||||
</template>
|
||||
|
||||
@@ -5,15 +5,27 @@ hero:
|
||||
title: Showcase
|
||||
description: Discover our selection of projects built with Nuxt UI.
|
||||
items:
|
||||
- name: Ovatu
|
||||
url: https://ovatu.com/
|
||||
- name: Shelve
|
||||
url: https://shelve.cloud
|
||||
url: https://shelve.cloud/
|
||||
- name: Uneed
|
||||
url: https://uneed.best
|
||||
url: https://uneed.best/
|
||||
- name: Details
|
||||
url: https://details.team
|
||||
url: https://details.team/
|
||||
- name: Espace Asso by Benevolt
|
||||
url: https://asso.benevolt.fr
|
||||
url: https://asso.benevolt.fr/
|
||||
- name: Directus Docs
|
||||
url: https://docs.directus.io
|
||||
url: https://docs.directus.io/
|
||||
- name: Super SaaS
|
||||
url: https://supersaas.dev/
|
||||
- name: Passionate People
|
||||
url: https://passionatepeople.io/
|
||||
- name: The Companies API
|
||||
url: https://www.thecompaniesapi.com/
|
||||
- name: Thuprai
|
||||
url: https://thuprai.com/
|
||||
- name: Juno.one
|
||||
url: https://www.juno.one/
|
||||
- name: Pallyy
|
||||
url: https://pallyy.com/
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { join } from 'pathe'
|
||||
import captureWebsite from 'capture-website'
|
||||
|
||||
interface ContentFile {
|
||||
id?: string
|
||||
items?: any
|
||||
}
|
||||
|
||||
interface TemplateItem {
|
||||
name: string
|
||||
url?: string
|
||||
screenshotUrl?: string
|
||||
screenshotOptions?: Record<string, any>
|
||||
}
|
||||
|
||||
export default defineNuxtModule((options, nuxt) => {
|
||||
nuxt.hook('content:file:afterParse', async ({ content: file }: { content: ContentFile }) => {
|
||||
if (file.id?.includes('showcase') && file.items) {
|
||||
const itemsArray: TemplateItem[] = Array.isArray(file.items)
|
||||
? file.items
|
||||
: Object.values(file.items)
|
||||
if (itemsArray.length === 0) {
|
||||
console.log('No items to process')
|
||||
return
|
||||
}
|
||||
console.log(`Processing ${itemsArray.length} template items`)
|
||||
for (const template of itemsArray) {
|
||||
const url = template.screenshotUrl || template.url
|
||||
if (!url) {
|
||||
console.error(`Template ${template.name} has no "url" or "screenshotUrl" to take a screenshot from`)
|
||||
continue
|
||||
}
|
||||
const name = template.name.toLowerCase().replace(/\s/g, '-')
|
||||
const filename = join(process.cwd(), 'docs/public/assets/showcase', `${name}.png`)
|
||||
if (existsSync(filename)) {
|
||||
console.log(`Screenshot for ${template.name} already exists, skipping`)
|
||||
continue
|
||||
}
|
||||
console.log(`Generating screenshot for Template ${template.name} hitting ${url}...`)
|
||||
try {
|
||||
await captureWebsite.file(url, filename, {
|
||||
...(template.screenshotOptions || {}),
|
||||
launchOptions: { headless: true }
|
||||
})
|
||||
console.log(`Screenshot for ${template.name} generated successfully`)
|
||||
} catch (error) {
|
||||
console.error(`Error generating screenshot for ${template.name}:`, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
56
docs/modules/showcase.ts
Normal file
56
docs/modules/showcase.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { join } from 'pathe'
|
||||
import captureWebsite from 'capture-website'
|
||||
|
||||
interface ContentFile {
|
||||
id?: string
|
||||
body?: {
|
||||
items: TemplateItem[]
|
||||
}
|
||||
}
|
||||
|
||||
interface TemplateItem {
|
||||
name: string
|
||||
url?: string
|
||||
screenshotUrl?: string
|
||||
screenshotOptions?: Record<string, any>
|
||||
}
|
||||
|
||||
export default defineNuxtModule((_, nuxt) => {
|
||||
nuxt.hook('content:file:afterParse', async ({ content: file }: { content: ContentFile }) => {
|
||||
if (!file.id?.includes('showcase')) {
|
||||
return
|
||||
}
|
||||
if (!file.body?.items?.length) {
|
||||
return
|
||||
}
|
||||
for (const template of file.body.items) {
|
||||
const url = template.screenshotUrl || template.url
|
||||
if (!url) {
|
||||
console.error(`Template ${template.name} has no "url" or "screenshotUrl" to take a screenshot from`)
|
||||
continue
|
||||
}
|
||||
|
||||
const name = template.name.toLowerCase().replace(/\s/g, '-')
|
||||
const filename = join(process.cwd(), 'docs/public/assets/showcase', `${name}.png`)
|
||||
|
||||
if (existsSync(filename)) {
|
||||
continue
|
||||
}
|
||||
|
||||
console.log(`Generating screenshot for Template ${template.name} hitting ${url}...`)
|
||||
|
||||
try {
|
||||
await captureWebsite.file(url, filename, {
|
||||
...(template.screenshotOptions || {}),
|
||||
launchOptions: { headless: true }
|
||||
})
|
||||
|
||||
console.log(`Screenshot for ${template.name} generated successfully`)
|
||||
} catch (error) {
|
||||
console.error(`Error generating screenshot for ${template.name}:`, error)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
BIN
docs/public/assets/showcase/juno.one.png
Normal file
BIN
docs/public/assets/showcase/juno.one.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 422 KiB |
BIN
docs/public/assets/showcase/ovatu.png
Normal file
BIN
docs/public/assets/showcase/ovatu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 MiB |
BIN
docs/public/assets/showcase/pallyy.png
Normal file
BIN
docs/public/assets/showcase/pallyy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 518 KiB |
BIN
docs/public/assets/showcase/passionate-people.png
Normal file
BIN
docs/public/assets/showcase/passionate-people.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 749 KiB |
BIN
docs/public/assets/showcase/the-companies-api.png
Normal file
BIN
docs/public/assets/showcase/the-companies-api.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 575 KiB |
BIN
docs/public/assets/showcase/thuprai.png
Normal file
BIN
docs/public/assets/showcase/thuprai.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Reference in New Issue
Block a user