docs: update

This commit is contained in:
Benjamin Canac
2024-06-18 11:01:00 +02:00
parent cd7888cac7
commit 06e041c374
27 changed files with 173 additions and 2045 deletions

View File

@@ -3,48 +3,16 @@ import { withoutTrailingSlash } from 'ufo'
// import { debounce } from 'perfect-debounce'
import type { ContentSearchFile } from '#ui-pro/types'
const searchTerm = ref('')
const route = useRoute()
// const colorMode = useColorMode()
// const { branch } = useContentSource()
const runtimeConfig = useRuntimeConfig()
const { integrity, api } = runtimeConfig.public.content
const { data: navigation } = await useAsyncData('navigation', () => fetchContentNavigation(), { default: () => [] })
const { data: files } = await useLazyFetch<ContentSearchFile[]>(`${api.baseURL}/search${integrity ? '.' + integrity : ''}`, { default: () => [] })
// Computed
// const color = computed(() => colorMode.value === 'dark' ? '#18181b' : 'white')
const links = computed(() => {
return [{
label: 'Docs',
icon: 'i-heroicons-book-open',
to: '/getting-started',
active: route.path.startsWith('/getting-started') || route.path.startsWith('/components')
}, ...(navigation.value.find(item => item._path === '/pro') ? [{
label: 'Pro',
icon: 'i-heroicons-square-3-stack-3d',
to: '/pro',
active: route.path.startsWith('/pro/getting-started') || route.path.startsWith('/pro/components') || route.path.startsWith('/pro/prose')
}, {
label: 'Pricing',
icon: 'i-heroicons-credit-card',
to: '/pro/pricing'
}, {
label: 'Templates',
icon: 'i-heroicons-computer-desktop',
to: '/pro/templates'
}] : []), {
label: 'Releases',
icon: 'i-heroicons-rocket-launch',
to: '/releases'
}].filter(Boolean)
})
// Watch
const open = ref(false)
const searchTerm = ref('')
// watch(searchTerm, debounce((query: string) => {
// if (!query) {
@@ -54,7 +22,19 @@ const links = computed(() => {
// useTrackEvent('Search', { props: { query: `${query} - ${searchTerm.value?.commandPaletteRef.results.length} results` } })
// }, 500))
// Head
const links = computed(() => [{
label: 'Docs',
icon: 'i-heroicons-book-open',
to: '/getting-started',
active: route.path.startsWith('/getting-started')
}, {
label: 'Components',
icon: 'i-heroicons-cube-transparent',
to: '/components',
active: route.path.startsWith('/components')
}].filter(Boolean))
// const color = computed(() => colorMode.value === 'dark' ? '#18181b' : 'white')
useHead({
meta: [
@@ -75,8 +55,7 @@ useServerSeoMeta({
twitterCard: 'summary_large_image'
})
// Provide
provide('open', open)
provide('navigation', navigation)
provide('files', files)
</script>
@@ -85,16 +64,16 @@ provide('files', files)
<UApp>
<NuxtLoadingIndicator />
<Banner v-if="!$route.path.startsWith('/examples')" />
<Banner v-if="!route.path.startsWith('/examples')" />
<Header v-if="!$route.path.startsWith('/examples')" :links="links" />
<Header v-if="!route.path.startsWith('/examples')" :links="links" />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<Footer v-if="!$route.path.startsWith('/examples')" />
<Footer v-if="!route.path.startsWith('/examples')" />
<LazyUContentSearch v-model:search-term="searchTerm" :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 42 }" />
<LazyUContentSearch v-model:open="open" v-model:search-term="searchTerm" :files="files" :navigation="navigation" :links="links" :fuse="{ resultLimit: 42 }" />
</UApp>
</template>

View File

@@ -1,58 +1,11 @@
<script setup lang="ts">
const id = 'nuxt-ui-banner-1'
const to = '/pro/pricing'
const hideBanner = () => {
localStorage.setItem(id, 'true')
document.querySelector('html')?.classList.add('hide-banner')
}
if (import.meta.server) {
useHead({
script: [{
key: 'prehydrate-template-banner',
innerHTML: `
if (localStorage.getItem('${id}') === 'true') {
document.querySelector('html').classList.add('hide-banner')
}`.replace(/\s+/g, ' '),
type: 'text/javascript'
}]
})
}
const config = useRuntimeConfig().public
</script>
<template>
<div class="relative bg-primary hover:bg-primary/90 transition-[background] backdrop-blur z-50 app-banner">
<UContainer class="py-2">
<NuxtLink v-if="to" :to="to" class="focus:outline-none" aria-label="Nuxt UI Pro pricing" tabindex="-1">
<span class="absolute inset-0 " aria-hidden="true" />
</NuxtLink>
<div class="flex items-center justify-between gap-2">
<div class="lg:flex-1 hidden lg:flex items-center" />
<p class="text-sm font-medium text-white dark:text-gray-900">
<UIcon name="i-heroicons-rocket-launch" class="w-5 h-5 align-top flex-shrink-0 pointer-events-none mr-2" />
<span class="font-semibold">Nuxt UI Pro v1.0</span> is out with dashboard components!
</p>
<div class="flex items-center justify-end lg:flex-1">
<button
class="p-1.5 rounded-md inline-flex hover:bg-primary/90"
aria-label="Close banner"
@click.prevent="hideBanner"
>
<UIcon name="i-heroicons-x-mark-20-solid" class="w-5 h-5 text-white dark:text-gray-900" />
</button>
</div>
</div>
</UContainer>
</div>
<UBanner icon="i-heroicons-light-bulb" :actions="[{ label: 'Go to Nuxt UI v2', to: 'https://ui.nuxt.com', trailingIcon: 'i-heroicons-arrow-right-20-solid', color: 'white', class: 'rounded-full' }]" :close="false">
<template #title>
You're looking at the documentation for <span class="font-semibold">Nuxt UI v{{ config.version }}</span>!
</template>
</UBanner>
</template>
<style scoped>
.hide-banner .app-banner {
display: none;
}
</style>

View File

@@ -1,21 +1,19 @@
<script setup lang="ts">
const links = [{
icon: 'i-simple-icons-figma',
const route = useRoute()
const items = [{
label: 'Figma Kit',
to: 'https://www.figma.com/community/file/1288455405058138934',
target: '_blank'
}, {
label: 'Playground',
icon: 'i-simple-icons-stackblitz',
to: 'https://stackblitz.com/edit/nuxt-ui',
target: '_blank'
}, {
label: 'Roadmap',
icon: 'i-heroicons-map',
to: '/roadmap'
}, {
label: 'Releases',
icon: 'i-heroicons-rocket-launch',
to: '/releases'
}]
</script>
@@ -23,9 +21,9 @@ const links = [{
<template>
<USeparator icon="i-simple-icons-nuxtdotjs" class="h-px" />
<UFooter :links="links">
<UFooter>
<template #left>
<NuxtLink v-if="$route.path.startsWith('/pro')" to="https://ui.nuxt.com/pro/purchase" target="_blank" class="text-sm text-gray-500 dark:text-gray-400">
<NuxtLink v-if="route.path.startsWith('/pro')" to="https://ui.nuxt.com/pro/purchase" target="_blank" class="text-sm text-gray-500 dark:text-gray-400">
Purchase <span class="text-gray-900 dark:text-white">Nuxt UI Pro</span>
</NuxtLink>
<NuxtLink v-else to="https://github.com/nuxt/ui" target="_blank" class="text-sm text-gray-500 dark:text-gray-400">
@@ -33,6 +31,8 @@ const links = [{
</NuxtLink>
</template>
<UNavigationMenu :items="items" variant="link" color="black" />
<template #right>
<UButton aria-label="Nuxt Website" icon="i-simple-icons-nuxtdotjs" to="https://nuxt.com" target="_blank" color="gray" variant="ghost" />
<UButton aria-label="Nuxt UI on Discord" icon="i-simple-icons-discord" to="https://chat.nuxt.dev" target="_blank" color="gray" variant="ghost" />

View File

@@ -1,26 +1,43 @@
<script setup lang="ts">
import type { NavItem } from '@nuxt/content/dist/runtime/types'
import type { NavigationMenuItem } from '#ui/types'
const props = defineProps<{
links: NavigationMenuItem[]
}>()
const route = useRoute()
const config = useRuntimeConfig().public
const open = inject<Ref<boolean>>('open')
const navigation = inject<Ref<NavItem[]>>('navigation')
const items = computed(() => props.links.map(({ icon, ...link }) => link))
</script>
<template>
<UHeader
:links="links"
:class="{
'border-primary-200/75 dark:border-primary-900/50': $route.path === '/',
'border-gray-200 dark:border-gray-800': $route.path !== '/'
'border-primary-200/75 dark:border-primary-900/50': route.path === '/',
'border-gray-200 dark:border-gray-800': route.path !== '/'
}"
>
<template #left>
<NuxtLink to="/" class="flex items-end gap-2 font-bold text-xl text-gray-900 dark:text-white" aria-label="Nuxt UI">
<Logo class="w-auto h-6" />
<UBadge v-if="$route.path.startsWith('/pro')" label="Pro" variant="subtle" size="sm" class="-mb-[2px] rounded font-semibold" />
<UBadge v-if="$route.path.startsWith('/dev')" label="Edge" variant="subtle" size="sm" class="-mb-[2px] rounded font-semibold" />
<UBadge :label="`v${config.version}`" variant="subtle" size="sm" class="-mb-[2px] rounded font-semibold" />
</NuxtLink>
</template>
<UNavigationMenu :items="items" variant="link" />
<template #right>
<!-- <ColorPicker /> -->
<!-- <UTooltip text="Search" :shortcuts="[metaSymbol, 'K']" :popper="{ strategy: 'absolute' }">
<UContentSearchButton :label="null" />
</UTooltip> -->
<UTooltip text="Search" :kbds="['meta', 'K']">
<UButton aria-label="Search" icon="i-heroicons-magnifying-glass-20-solid" color="gray" variant="ghost" @click="open = true" />
</UTooltip>
<!-- <UColorModeButton /> -->
@@ -34,35 +51,12 @@
/>
</template>
<template #panel>
<!-- <UAsideLinks :links="links" /> -->
<template #content>
<UNavigationMenu orientation="vertical" :items="items" class="-ml-2.5" />
<!-- <UDivider type="dashed" class="my-4" /> -->
<USeparator type="dashed" class="my-4" />
<!-- <BranchSelect /> -->
<!-- <UNavigationTree :links="mapContentNavigation(navigation)" :multiple="false" default-open /> -->
<UContentNavigation :navigation="navigation" />
</template>
</UHeader>
</template>
<script setup lang="ts">
import type { NavItem } from '@nuxt/content/dist/runtime/types'
import type { HeaderLink } from '#ui-pro/types'
defineProps<{
links: HeaderLink[]
}>()
const route = useRoute()
const nav = inject<Ref<NavItem[]>>('navigation')
const navigation = computed(() => {
if (route.path.startsWith('/pro')) {
return nav.value.find(item => item._path === '/pro')?.children
}
return nav.value.filter(item => !item._path.startsWith('/pro'))
})
</script>

View File

@@ -1,5 +0,0 @@
<template>
<svg width="264" height="264" viewBox="0 0 264 264" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M146.496 211.2H234.822C237.627 211.2 240.383 210.468 242.813 209.078C245.242 207.688 247.259 205.688 248.662 203.279C250.064 200.871 250.801 198.139 250.8 195.359C250.799 192.579 250.059 189.847 248.655 187.44L189.337 85.612C187.935 83.2043 185.918 81.2049 183.489 79.8147C181.06 78.4246 178.305 77.6927 175.5 77.6927C172.695 77.6927 169.94 78.4246 167.511 79.8147C165.082 81.2049 163.065 83.2043 161.663 85.612L146.496 111.666L116.841 60.7179C115.438 58.3104 113.42 56.3113 110.991 54.9214C108.561 53.5315 105.805 52.7998 103 52.7998C100.195 52.7998 97.4386 53.5315 95.0089 54.9214C92.5793 56.3113 90.5615 58.3104 89.1583 60.7179L15.3453 187.44C13.9411 189.847 13.2012 192.579 13.2 195.359C13.1987 198.139 13.9363 200.871 15.3384 203.279C16.7405 205.688 18.7578 207.688 21.1873 209.078C23.6168 210.468 26.3728 211.2 29.1783 211.2H84.6219C106.589 211.2 122.789 201.636 133.937 182.979L161 136.526L175.496 111.666L219 186.34H161L146.496 211.2ZM83.7181 186.314L45.0255 186.306L103.026 86.7466L131.966 136.526L112.589 169.798C105.186 181.904 96.7763 186.314 83.7181 186.314Z" fill="currentColor" />
</svg>
</template>

View File

@@ -1,45 +0,0 @@
<template>
<div ref="carbonads" class="carbon" />
</template>
<script setup lang="ts">
const carbonads = ref(null)
onMounted(() => {
if (carbonads.value) {
const script = document.createElement('script')
script.setAttribute('type', 'text/javascript')
script.setAttribute('src', 'https://cdn.carbonads.com/carbon.js?serve=CWYIVK3E&placement=uinuxtcom')
script.setAttribute('id', '_carbonads_js')
carbonads.value.appendChild(script)
}
})
</script>
<style lang="postcss">
.carbon > #carbonads {
@apply relative border border-gray-200 dark:border-gray-800 rounded-lg bg-white dark:bg-gray-800/50 hover:border-gray-300 dark:hover:border-gray-700 w-full transition-colors min-h-[220px];
&:hover {
.carbon-text {
@apply text-gray-700 dark:text-gray-200;
}
}
.carbon-img {
@apply flex justify-center p-2 w-full;
& > img {
@apply !max-w-full w-full rounded;
}
}
.carbon-text {
@apply flex px-2 text-sm text-gray-500 dark:text-gray-400 transition-colors text-center w-full;
}
.carbon-poweredby {
@apply block text-xs text-center text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400 pt-1 pb-2 px-2 transition-colors;
}
}
</style>

View File

@@ -1,27 +0,0 @@
<template>
<div class="relative group/ad border border-gray-200 dark:border-gray-800 rounded-lg bg-white dark:bg-gray-800/50 hover:border-gray-300 dark:hover:border-gray-700 p-2 w-full transition-colors">
<NuxtLink to="/pro" class="focus:outline-none" tabindex="-1">
<span class="absolute inset-0" aria-hidden="true" />
</NuxtLink>
<UColorModeImage
light="/illustrations/pro-light.svg"
dark="/illustrations/pro-dark.svg"
alt="Nuxt UI Pro"
loading="lazy"
class="w-full"
/>
<div class="flex flex-col items-center mt-2 text-center">
<div class="inline-flex gap-1.5">
<Logo class="h-4 w-auto" />
<UBadge variant="subtle" size="xs" label="Pro" class="font-semibold rounded" />
</div>
<p class="text-sm text-gray-500 dark:text-gray-400 group-hover/ad:text-gray-700 dark:group-hover/ad:text-gray-200 mt-1 transition-colors">
The Building Blocks for Modern Web Apps.
</p>
</div>
</div>
</template>

View File

@@ -1,206 +0,0 @@
<script setup lang="ts">
const refs = ref([])
const section = ref()
const { stop } = useIntersectionObserver(
section,
([{ isIntersecting }]) => {
if (!isIntersecting) {
return
}
refs.value.forEach(element => element.style.animationPlayState = 'running')
stop()
},
{ threshold: 0.3 }
)
onMounted(() => {
refs.value.forEach((element) => {
if (!element) {
return
}
element.style.animationFillMode = 'forwards'
element.style.transformOrigin = 'center'
element.style.animationPlayState = 'paused'
element.style.animationDuration = '1s'
})
})
</script>
<template>
<ULandingGrid ref="section" class="lg:grid-cols-10 lg:gap-8">
<div :ref="(el) => (refs[1] = el)" class="col-span-8 flex items-center animate-top">
<RangeExample />
</div>
<div :ref="(el) => (refs[2] = el)" class="col-span-2 row-span-2 flex items-center animate-right">
<RadioExample />
</div>
<div :ref="(el) => (refs[4] = el)" class="col-span-2 animate-left z-10">
<DropdownExampleBasic :popper="{ placement: 'bottom-start', strategy: 'absolute' }" />
</div>
<div
:ref="(el) => (refs[3] = el)"
class="col-span-6 flex flex-wrap items-center justify-between gap-1 animate-bottom"
>
<UAvatarGroup :max="2">
<UAvatar
src="https://ipx.nuxt.com/s_32x32/gh_avatar/benjamincanac"
srcset="https://ipx.nuxt.com/s_64x64/gh_avatar/benjamincanac 2x"
alt="benjamincanac"
width="40"
height="40"
loading="lazy"
/>
<UAvatar
src="https://ipx.nuxt.com/s_32x32/gh_avatar/Atinux"
srcset="https://ipx.nuxt.com/s_64x64/gh_avatar/Atinux 2x"
alt="Atinux"
width="40"
height="40"
loading="lazy"
/>
<UAvatar
src="https://ipx.nuxt.com/s_32x32/gh_avatar/smarroufin"
srcset="https://ipx.nuxt.com/s_64x64/gh_avatar/smarroufin 2x"
alt="smarroufin"
width="40"
height="40"
loading="lazy"
/>
</UAvatarGroup>
<UButton label="Button" loading />
<UBadge label="Badge" />
<UColorModeToggle />
<PaginationExampleBasic />
</div>
<div :ref="(el) => (refs[5] = el)" class="col-span-3 row-span-8 gap-6 flex flex-col justify-between animate-left">
<UNotification
:id="1"
title="Notification"
description="This is a notification!"
icon="i-heroicons-command-line"
:ui="{ shadow: 'shadow' }"
:close-button="null"
:timeout="30000"
/>
<TabsExampleItemCustomSlot />
<UCard class="flex-shrink-0">
<div class="flex items-center gap-4 justify-center">
<USkeleton class="h-14 w-14 flex-shrink-0" :ui="{ rounded: 'rounded-full' }" />
<div class="space-y-3 flex-1">
<USkeleton class="h-4 w-full" />
<USkeleton class="h-4 w-2/3" />
</div>
</div>
</UCard>
</div>
<div :ref="(el) => (refs[6] = el)" class="col-span-5 row-span-2 flex flex-col animate-bottom">
<UCard
:ui="{ body: { base: 'flex-1 flex flex-col overflow-y-auto', padding: '' } }"
class="col-span-4 row-span-6 flex-1 flex flex-col"
>
<CommandPaletteExampleGroups />
</UCard>
</div>
<div :ref="(el) => (refs[7] = el)" class="col-span-2 row-span-2 gap-6 flex flex-col animate-right z-10">
<CheckboxExample />
<InputExampleClearable />
<UFormGroup label="Labels">
<SelectMenuExampleCreatable />
</UFormGroup>
<UCard :ui="{ body: { padding: '!p-1' } }">
<VerticalNavigationExampleAvatarSlot />
</UCard>
</div>
<div :ref="(el) => (refs[8] = el)" class="col-span-7 row-span-6 animate-bottom">
<UCard :ui="{ body: { padding: '' } }">
<TableExampleClickable :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }" />
</UCard>
</div>
</ULandingGrid>
</template>
<style scoped lang="postcss">
.animate-top {
animation: translateDown;
}
.animate-bottom {
animation: translateUp;
}
.animate-left {
animation: translateLeft;
}
.animate-right {
animation-name: translateRight;
}
@keyframes translateDown {
0% {
transform: translate3D(0, -100px, 0);
opacity: 0;
}
100% {
transform: translateY(0, 0, 0);
opacity: 1;
}
}
@keyframes translateUp {
0% {
transform: translate3D(0, 100px, 0);
opacity: 0;
}
100% {
transform: translateY(0, 0, 0);
opacity: 1;
}
}
@keyframes translateLeft {
0% {
transform: translate3D(-100px, 0, 0);
opacity: 0;
}
100% {
transform: translate3D(0, 0, 0);
opacity: 1;
}
}
@keyframes translateRight {
0% {
transform: translate3D(100px, 0, 0);
opacity: 0;
}
100% {
transform: translate3D(0, 0, 0);
opacity: 1;
}
}
</style>

View File

@@ -1,31 +0,0 @@
<template>
<div class="rounded-xl border border-gray-800/10 dark:border-gray-200/10 bg-gray-200/20 dark:bg-gray-700/20 p-4 flex-1 w-full">
<div class="relative h-full">
<TransitionGroup name="fade">
<HomeProDemoBlock v-for="(block, index) in blocks" :key="index" :block="block">
<template v-for="(_, name) in $slots" #[name]="slotData">
<slot :name="name" v-bind="slotData" />
</template>
</HomeProDemoBlock>
</TransitionGroup>
</div>
</div>
</template>
<script setup lang="ts">
import type { HomeProBlock } from '~/types'
defineProps<{ blocks: HomeProBlock[] }>()
</script>
<style scoped lang="postcss">
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@@ -1,59 +0,0 @@
<template>
<div
:id="block.id"
:class="twMerge(
'absolute rounded-lg flex items-center justify-center',
block.class,
!block.slot && (block.inactive || block.inactive === undefined ? 'border border-gray-800/10 dark:border-gray-200/10 bg-gray-200/20 dark:bg-gray-700/20 transition-[background,text] duration-500' : 'bg-primary transition-[background,text] duration-500'),
block.name?.startsWith('#') && 'border-dashed'
)"
:style="block.style"
>
<NuxtLink v-if="block.to && !block.inactive" :to="block.to" class="focus:outline-none" tabindex="-1">
<span class="absolute inset-0" aria-hidden="true" />
</NuxtLink>
<template v-if="block.inactive">
<TransitionGroup name="fade">
<HomeProDemoBlock v-for="(subComponent, subIndex) in block.children" :key="subIndex" :block="subComponent">
<template v-for="(_, name) in $slots" #[name]="slotData: any">
<slot :name="name" v-bind="slotData" />
</template>
</HomeProDemoBlock>
</TransitionGroup>
</template>
<template v-else-if="block.slot">
<slot :name="block.slot" />
</template>
<p
v-else
class="font-semibold flex flex-col gap-1 text-center"
:class="[
!block.slot && (block.inactive || block.inactive === undefined ? 'text-gray-900 dark:text-white' : 'text-white dark:text-gray-900'),
]"
>
{{ block.name }}
<span v-if="block.description" class="font-normal">{{ block.description }}</span>
</p>
</div>
</template>
<script setup lang="ts">
import { twMerge } from 'tailwind-merge'
import type { HomeProBlock } from '~/types'
defineProps<{ block: HomeProBlock }>()
</script>
<style scoped lang="postcss">
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@@ -1,108 +0,0 @@
<template>
<Transition appear name="fade">
<div
:style="{
'--cell': `${width / cols}px`,
'--rows': rows - 1
}"
>
<div
ref="el"
class="absolute inset-0 grid justify-center auto-rows-[--cell] -space-y-px"
>
<div v-for="(row, rowIndex) in grid" :key="rowIndex" class="grid grid-flow-col auto-cols-[--cell] flex-1 -space-x-px">
<div
v-for="(cell, cellIndex) in row"
:key="cellIndex"
class="relative border border-primary-200/50 dark:border-primary-900/25"
>
<div class="absolute inset-0 bg-primary-500/10 hover:bg-primary-500/20 dark:bg-primary-400/5 dark:hover:bg-primary-400/10 opacity-0 transition-opacity will-change-[opacity] duration-1000" :class="[cell && 'opacity-100 cursor-pointer']" @click="cell && removeCell(rowIndex, cellIndex)" />
</div>
</div>
<div class="absolute top-[calc((var(--cell)*var(--rows))+1px)] inset-x-0 h-[calc(var(--cell)*2)] bg-gradient-to-t from-white dark:from-gray-900 pointer-events-none" />
</div>
</div>
</Transition>
</template>
<script setup lang="ts">
import { useElementSize } from '@vueuse/core'
const el = ref(null)
const grid = ref([])
const rows = ref(0)
const cols = ref(0)
const { width, height } = useElementSize(el)
function createGrid () {
grid.value = []
for (let i = 0; i <= rows.value; i++) {
grid.value.push(new Array(cols.value).fill(null))
}
}
function createNewCell () {
const x = Math.floor(Math.random() * cols.value)
grid.value[0][x] = true
}
function moveCellsDown () {
for (let row = rows.value - 1; row >= 0; row--) {
for (let col = 0; col < cols.value; col++) {
if (grid.value[row][col] !== null && grid.value[row + 1][col] === null) {
grid.value[row + 1][col] = grid.value[row][col]
grid.value[row][col] = null
}
}
}
setTimeout(() => {
if (grid.value[rows.value].every(cell => cell !== null)) {
for (let col = 0; col < cols.value; col++) {
grid.value[rows.value][col] = null
}
}
}, 500)
}
function removeCell (row, col) {
grid.value[row][col] = null
}
function calcGrid () {
const base = Math.ceil(width.value / 60)
const cell = width.value / base
rows.value = Math.ceil(height.value / cell)
cols.value = width.value / cell
createGrid()
}
watch(width, calcGrid)
onMounted(() => {
setTimeout(calcGrid, 50)
setInterval(() => {
moveCellsDown()
createNewCell()
}, 1000)
})
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@@ -1,54 +0,0 @@
<script setup lang="ts">
import { useIntersectionObserver } from '@vueuse/core'
defineProps<{
date: {
day: Date
release?: {
name: string
}
pulls?: {
id: number
number: number
title: string
html_url: string
user: {
login: string
}
}[]
}
}>()
const target = ref(null)
const targetIsVisible = ref(false)
useIntersectionObserver(target, ([{ isIntersecting }]) => {
targetIsVisible.value = isIntersecting
}, {
rootMargin: '-68px 0px -68px 0px'
})
</script>
<template>
<div ref="target" class="flex flex-col transition-opacity duration-500" :class="targetIsVisible ? 'opacity-100' : 'opacity-25'">
<time :datetime="date.day.toISOString()" class="flex-shrink-0 text-sm/6 font-semibold text-gray-500 dark:text-gray-400">{{ date.day.toLocaleString('en-us', { year: 'numeric', month: 'short', day: 'numeric' })
}}</time>
<NuxtLink v-if="date.release" :to="`https://github.com/nuxt/ui/releases/tag/${date.release.name}`" target="_blank" class="text-gray-900 dark:text-white font-bold text-3xl mt-2 group hover:text-primary-500 dark:hover:text-primary-400 transition-[color]">
{{ date.release.name }}
</NuxtLink>
<ul v-if="date.pulls?.length" class="mt-2 space-y-1 text-gray-600 dark:text-gray-300">
<li v-for="pull in date.pulls" :key="pull.id" class="text-sm/6 break-all">
<NuxtLink :to="`https://github.com/${pull.user.login}`" target="_blank" class="text-gray-900 dark:text-white transition-colors inline-flex items-center gap-1 rounded-full bg-gray-100/50 dark:bg-gray-800/50 dark:hover:bg-gray-800 p-0.5 pr-1 ring-1 ring-gray-300 dark:ring-gray-700 text-xs font-medium flex-shrink-0 align-middle">
<UAvatar :src="`https://github.com/${pull.user.login}.png`" size="3xs" />
{{ pull.user.login }}
</NuxtLink>
pushed <NuxtLink :to="pull.html_url" target="_blank" class="font-medium text-gray-700 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-[color]">
#{{ pull.number }} {{ pull.title }}
</NuxtLink>
</li>
</ul>
</div>
</template>

View File

@@ -0,0 +1,24 @@
import pkg from '../../ui-pro2/package.json'
export function useModule() {
const config = useRuntimeConfig().public
const modules = [{
label: 'nuxt/ui',
icon: 'i-heroicons-cube-transparent',
suffix: `v${config.version}`,
value: 'ui'
}, {
label: 'nuxt/ui-pro',
icon: 'i-heroicons-cube-transparent',
suffix: `v${pkg.version.split('-')[0]}`,
value: 'ui-pro'
}]
const module = useCookie<string>('module', { default: () => modules[0].value })
return {
module,
modules
}
}

View File

@@ -0,0 +1,10 @@
---
title: App
description: Starting point for your Nuxt UI app.
links:
- label: GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Accordion.vue
---
## Usage

View File

@@ -1,112 +0,0 @@
---
title: DatePicker
description: 'An example of a date picker component built with v-calendar.'
---
## Installation
This example is a composition of a [Popover](/components/popover) and [v-calendar](https://github.com/nathanreyes/v-calendar). We also use [date-fns](https://date-fns.org/) to format dates.
::callout{icon="i-heroicons-light-bulb"}
Note that you can use any calendar library you want.
::
Let's start by installing the `v-calendar` and `date-fns` dependency:
::code-group
```bash [pnpm]
pnpm add v-calendar@next date-fns
```
```bash [yarn]
yarn add v-calendar@next date-fns
```
```bash [npm]
npm install v-calendar@next date-fns
```
::
## Usage
You can create a `DatePicker.vue` component based on the `DatePicker` from `v-calendar`.
The following example is styled based on the `primary` and `gray` colors and supports the `dark` mode. It also supports a `v-model` or `v-model.range` depending on the type of date you want to use.
```vue [components/DatePicker.vue]
<script setup lang="ts">
import { DatePicker as VCalendarDatePicker } from 'v-calendar'
import type { DatePickerDate, DatePickerRangeObject } from 'v-calendar/dist/types/src/use/datePicker'
import 'v-calendar/dist/style.css'
const props = defineProps({
modelValue: {
type: [Date, Object] as PropType<DatePickerDate | DatePickerRangeObject | null>,
default: null
}
})
const emit = defineEmits(['update:model-value', 'close'])
const date = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:model-value', value)
emit('close')
}
})
const attrs = {
transparent: true,
borderless: true,
color: 'primary',
'is-dark': { selector: 'html', darkClass: 'dark' },
'first-day-of-week': 2,
}
</script>
<template>
<VCalendarDatePicker v-if="date && (typeof date === 'object')" v-model.range="date" :columns="2" v-bind="{ ...attrs, ...$attrs }" />
<VCalendarDatePicker v-else v-model="date" v-bind="{ ...attrs, ...$attrs }" />
</template>
<style>
:root {
--vc-gray-50: rgb(var(--color-gray-50));
--vc-gray-100: rgb(var(--color-gray-100));
--vc-gray-200: rgb(var(--color-gray-200));
--vc-gray-300: rgb(var(--color-gray-300));
--vc-gray-400: rgb(var(--color-gray-400));
--vc-gray-500: rgb(var(--color-gray-500));
--vc-gray-600: rgb(var(--color-gray-600));
--vc-gray-700: rgb(var(--color-gray-700));
--vc-gray-800: rgb(var(--color-gray-800));
--vc-gray-900: rgb(var(--color-gray-900));
}
.vc-primary {
--vc-accent-50: rgb(var(--color-primary-50));
--vc-accent-100: rgb(var(--color-primary-100));
--vc-accent-200: rgb(var(--color-primary-200));
--vc-accent-300: rgb(var(--color-primary-300));
--vc-accent-400: rgb(var(--color-primary-400));
--vc-accent-500: rgb(var(--color-primary-500));
--vc-accent-600: rgb(var(--color-primary-600));
--vc-accent-700: rgb(var(--color-primary-700));
--vc-accent-800: rgb(var(--color-primary-800));
--vc-accent-900: rgb(var(--color-primary-900));
}
</style>
```
## Examples
### DatePicker
:component-example{component="date-picker-example"}
### DateRangePicker
:component-example{component="date-picker-range-example"}

View File

@@ -1,191 +0,0 @@
navigation: false
title: 'Nuxt UI: A UI Library for Modern Web Apps'
description: 'It provides everything related to UI when building your Nuxt app. This includes components, icons, colors, dark mode but also keyboard shortcuts. Built with Headless UI and Tailwind CSS, published under MIT License.'
hero:
title: 'A <span class="text-primary">UI Library</span> for<br class="hidden lg:block"> Modern Web Apps'
description: 'Nuxt UI simplifies the creation of stunning and responsive web applications with its<br class="hidden lg:block"> comprehensive collection of fully styled and customizable UI components designed for Nuxt.'
sections:
- slot: demo
class: 'hidden lg:block dark:bg-gradient-to-b from-gray-900 to-gray-950/50 !pt-12'
- title: Everything you expect from a<br class="hidden lg:block"> <span class="text-primary">UI component library</span>
slot: features
class: 'dark:bg-gradient-to-b from-gray-900 to-gray-950/50 dark:lg:bg-none dark:lg:bg-gray-950/50'
cards:
- title: Color Palette
description: 'Choose a primary and a gray color from your Tailwind CSS color palette. Components will be styled accordingly.'
icon: i-heroicons-swatch
to: /getting-started/theming#colors
class: 'col-span-7 row-span-3'
image:
path: /illustrations/color-palette
width: 363
height: 152
orientation: 'horizontal'
- title: Fully Customizable
description: 'Change the style of any component in your App Config or customize them specifically through the ui prop.'
icon: i-heroicons-wrench-screwdriver
to: /getting-started/theming#components
image:
path: /illustrations/fully-customizable
width: 444
height: 160
class: 'col-span-5 row-span-5 lg:mb-10'
orientation: 'vertical'
- title: Icons
description: 'Choose any of the 100k+ icons from the most popular icon libraries with the Icon component or the icon prop.'
icon: i-heroicons-face-smile
to: /getting-started/theming#icons
image:
path: /illustrations/icon-library
width: 362
height: 184
class: 'col-span-7 row-span-3'
orientation: 'horizontal'
- title: Light & Dark
description: 'Every component is designed with dark mode in mind. Works out of the box with @nuxtjs/color-mode.'
to: /getting-started/theming#dark-mode
icon: i-heroicons-moon
image:
path: /illustrations/dark-mode
width: 444
height: 160
class: 'col-span-5 row-span-5 lg:-mt-10 lg:mb-20'
orientation: 'vertical'
- title: Keyboard Shortcuts
description: 'Nuxt UI comes with a set of Vue composables to easily handle keyboard shortcuts in your app.'
icon: i-heroicons-computer-desktop
to: /getting-started/shortcuts
class: 'col-span-7 row-span-3'
image:
path: /illustrations/keyboard-shortcuts
width: 444
height: 160
orientation: 'horizontal'
links:
- label: Explore 40+ components
to: /components
color: black
size: lg
icon: i-heroicons-cube
- label: Star on GitHub
to: https://github.com/nuxt/ui
target: _blank
color: white
size: lg
icon: i-simple-icons-github
cta:
title: Trusted and supported by our<br class="hidden lg:block"> amazing community
pro:
title: Upgrade to <span class="text-primary">Nuxt UI Pro</span>
description: 'Nuxt UI Pro is a collection of premium Vue components built on top of Nuxt UI to create beautiful & responsive Nuxt applications in minutes.<br>It includes all primitives to build landing pages, documentations, blogs, dashboards or entire SaaS products.'
links:
- label: Buy now
to: /pro/pricing
color: black
trailingIcon: i-heroicons-arrow-right-20-solid
size: lg
- label: Explore templates
to: /pro/templates
color: gray
icon: i-heroicons-computer-desktop
size: lg
sections:
- title: The freedom to build anything
description: Nuxt UI Pro ships with an extensive set of advanced components that cover a wide range of use-cases. Carefully crafted to reduce boilerplate code without sacrificing flexibility.
id: features
align: left
features:
- name: Fully customizable
description: Like Nuxt UI, change the style of any component from your App Config or customize them specifically through the ui prop.
icon: i-heroicons-wrench-screwdriver
- name: Slots for everything
description: Each component leverages the power of Vue's slots to give you the flexibility to build anything.
icon: i-heroicons-square-3-stack-3d
- name: Responsive by design
description: Nuxt UI Pro components aims to structure your content, they are responsive by design and will adapt to any screen size.
icon: i-heroicons-device-phone-mobile
links:
- label: Explore components
to: /pro/components
color: gray
icon: i-heroicons-arrow-right-20-solid
trailing: true
size: md
class: ml-8
code: |
```vue [app.vue]
<script setup lang="ts">
const links = [
{ to: '/', label: 'Home' },
{ to: '/about', label: 'About' },
{ to: '/contact', label: 'Contact' }
]
</script>
<template>
<UHeader :links="links" />
<UMain>
<ULandingHero title="Hello World" />
<ULandingSection title="Features">
<UPageGrid>
<ULandingCard title="First Card" />
<ULandingCard title="Second Card" />
<ULandingCard title="Third Card" />
</UPageGrid>
</ULandingSection>
</UMain>
<UFooter />
</template>
```
- title: The flexibility to control your data
description: Although you can use any data source you want, Nuxt UI Pro is fully integrated with Nuxt Content and provides additional features when the module is detected.
align: right
features:
- name: 'Write Markdown with ease'
description: Nuxt UI Pro overrides Nuxt Content prose components to make them awesome but also adds new ones like Callout, CodeGroup, Field, etc.
icon: i-simple-icons-markdown
- name: 'Beautiful Typography styles'
description: Tailwind CSS typography plugin is pre-configured and styled to match Nuxt UI components and colors.
icon: i-heroicons-paint-brush
- name: Full-Text Search out of the box
description: 'Nuxt UI Pro ships with a ready to use command palette component. No need to setup Algolia DocSearch anymore.'
icon: i-heroicons-magnifying-glass
links:
- label: Nuxt Content integration
to: /pro/getting-started/content
color: gray
icon: i-heroicons-arrow-right-20-solid
trailing: true
size: md
class: ml-8
code: |
```vue [pages/\[...slug\\].vue]
<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => queryContent(route.path).findOne())
</script>
<template>
<UPage>
<UPageHeader :title="page.title" :description="page.description" :links="page.links" />
<UPageBody prose>
<ContentRenderer v-if="page.body" :value="page" />
</UPageBody>
<template #right>
<UContentToc :links="page.body.toc.links" />
</template>
</UPage>
</template>
```
landing:
title: Start with a landing page
description: Stop wasting time building another landing page, Nuxt UI Pro flexible components will allow you to focus on your content.
docs:
title: Build your docs in seconds
description: Whether you're creating documentation for your open source project or explaining your product, Nuxt UI Pro has you covered.

View File

@@ -1,16 +0,0 @@
navigation: false
title: '<span class="text-primary">Nuxt UI</span> Releases'
head.title: Releases
description: Follow the latest releases and updates happening on the nuxt/ui repository.
links:
- label: Get Started
trailingIcon: i-heroicons-arrow-right-20-solid
to: /getting-started
size: md
color: black
- label: View on GitHub
icon: i-simple-icons-github
to: https://github.com/nuxt/ui/releases
target: _blank
size: md
color: white

View File

@@ -1,10 +1,20 @@
<script setup lang="ts">
import type { NavItem } from '@nuxt/content/dist/runtime/types'
const nav = inject<Ref<NavItem[]>>('navigation')
const navigation = computed(() => nav.value.filter(item => !item._path.startsWith('/pro')))
const { module, modules } = useModule()
</script>
<template>
<UMain>
<UContainer>
<UPage>
<template #left>
<UPageAside>
<!-- <BranchSelect /> -->
<USelect v-model="module" :items="modules" icon="i-heroicons-cube" class="w-full mb-3 lg:mb-6" />
<UContentNavigation :navigation="navigation" />
</UPageAside>
@@ -15,11 +25,3 @@
</UContainer>
</UMain>
</template>
<script setup lang="ts">
import type { NavItem } from '@nuxt/content/dist/runtime/types'
const nav = inject<Ref<NavItem[]>>('navigation')
const navigation = computed(() => nav.value.filter(item => !item._path.startsWith('/pro')))
</script>

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import { withoutTrailingSlash } from 'ufo'
import { findPageHeadline } from '#ui-pro/utils/content'
const route = useRoute()
// const { branch } = useContentSource()
definePageMeta({
layout: 'docs'
@@ -13,22 +13,19 @@ if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
}
// const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
// return queryContent()
// .where({
// _extension: 'md',
// _path: {
// [branch.value?.name === 'dev' ? '$eq' : '$ne']: new RegExp('^/dev')
// },
// navigation: {
// $ne: false
// }
// })
// .only(['title', 'description', '_path'])
// .findSurround(withoutTrailingSlash(route.path))
// })
const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
return queryContent()
.where({
_extension: 'md',
navigation: {
$ne: false
}
})
.only(['title', 'description', '_path'])
.findSurround(withoutTrailingSlash(route.path))
}, { default: () => [] })
// const headline = computed(() => findPageHeadline(page.value))
const headline = computed(() => findPageHeadline(page.value))
useSeoMeta({
titleTemplate: '%s - Nuxt UI',
@@ -42,13 +39,13 @@ defineOgImage({
component: 'Docs',
title: page.value.title,
description: page.value.description,
// headline: headline.value
headline: headline.value
})
const communityLinks = computed(() => [{
icon: 'i-heroicons-pencil-square',
label: 'Edit this page',
to: `https://github.com/nuxt/ui/edit/dev/docs/content/${branch.value?.name === 'dev' ? page?.value?._file.split('/').slice(1).join('/') : page?.value?._file}`,
to: `https://github.com/nuxt/ui/edit/dev/docs/content/${page?.value?._file}`,
target: '_blank'
}, {
icon: 'i-heroicons-star',
@@ -84,13 +81,13 @@ const resourcesLinks = [{
</script>
<template>
<UPage>
<!-- <UPageHeader :title="page.title" :description="page.description" :links="page.links" :headline="headline" />
<UPage v-if="page">
<UPageHeader :title="page.title" :description="page.description" :links="page.links" :headline="headline" />
<UPageBody prose>
<UPageBody>
<ContentRenderer v-if="page.body" :value="page" />
<hr v-if="surround?.length">
<USeparator />
<UContentSurround :surround="surround" />
</UPageBody>
@@ -98,24 +95,20 @@ const resourcesLinks = [{
<template v-if="page?.body?.toc?.links?.length" #right>
<UContentToc :links="page.body.toc.links">
<template #bottom>
<div class="hidden lg:block space-y-6 !mt-6">
<UDivider v-if="page.body?.toc?.links?.length" type="dashed" />
<USeparator v-if="page.body?.toc?.links?.length" type="dashed" />
<UPageLinks title="Community" :links="communityLinks" />
<UPageLinks title="Community" :links="communityLinks" />
<UDivider type="dashed" />
<USeparator type="dashed" />
<UPageLinks title="Resources" :links="resourcesLinks" />
<UPageLinks title="Resources" :links="resourcesLinks" />
<UDivider type="dashed" />
<!-- <USeparator type="dashed" />
<div class="space-y-3">
<AdsPro />
<AdsCarbon />
</div>
</div>
<AdsPro />
<AdsCarbon /> -->
</template>
</UContentToc>
</template> -->
</template>
</UPage>
</template>

View File

@@ -1,837 +0,0 @@
<script setup lang="ts">
import type { ParsedContent, NavItem } from '@nuxt/content/dist/runtime/types'
import { useElementBounding, useWindowScroll, useElementSize, breakpointsTailwind, useBreakpoints } from '@vueuse/core'
import type { HomeProBlock } from '~/types'
const { data: page } = await useAsyncData('index', () => queryContent('/dev').findOne())
const { data: module } = await useFetch<{
stats: {
downloads: number
stars: number
}
contributors: {
username: string
}[]
}>('https://api.nuxt.com/modules/ui', {
transform: ({ stats, contributors }) => ({ stats, contributors })
})
const navigation = inject<Ref<NavItem[]>>('navigation')
useSeoMeta({
titleTemplate: '',
title: page.value.title,
ogTitle: page.value.title,
description: page.value.description,
ogDescription: page.value.description,
ogImage: 'https://ui.nuxt.com/social-card.png',
twitterImage: 'https://ui.nuxt.com/social-card.png'
})
const source = ref('npm i @nuxt/ui')
const sectionRef = ref()
const demoRef = ref()
const start = ref(0)
const { height } = useElementSize(demoRef)
const { top } = useElementBounding(sectionRef)
const { y } = useWindowScroll()
const config = useRuntimeConfig().public
const { copy, copied } = useClipboard({ source })
const breakpoints = useBreakpoints(breakpointsTailwind)
const mdAndLarger = breakpoints.greaterOrEqual('md')
const lgAndLarger = breakpoints.greaterOrEqual('lg')
const xlAndLarger = breakpoints.greaterOrEqual('xl')
const { format } = Intl.NumberFormat('en', { notation: 'compact' })
const steps = {
header: 0,
footer: 5,
landing: 10,
docs: 27
}
// Computed
const inc = computed(() => (height.value - 32 - 64 - 32 - 32) / 4)
const landingBlocks = computed(() => isAfterStep(steps.landing) && isBeforeStep(steps.docs) ? [{
class: 'inset-x-0 top-20 bottom-20 overflow-hidden',
inactive: true,
children: [{
name: 'ULandingHero',
to: '/pro/components/landing-hero',
class: [
'inset-4',
isAfterStep(steps.landing + 2) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
].filter(Boolean).join(' '),
style: {
'--step-y': `${getStepY(steps.landing + 2)}px`
},
inactive: isAfterStep(steps.landing + 1),
children: [{
slot: 'landing-hero',
class: 'inset-4'
}]
}, isAfterStep(steps.landing + 2) && {
name: 'ULandingSection',
to: '/pro/components/landing-section',
class: [
'inset-4',
isBeforeStep(steps.landing + 6) && '-top-[calc(var(--y)-var(--prev-step-y)-var(--height)-1rem)] bottom-[calc(var(--y)-var(--prev-step-y)-var(--height)+1rem)]',
isAfterStep(steps.landing + 10) && '-top-[calc(var(--y)-var(--step-y)-1rem)] bottom-[calc(var(--y)-var(--step-y)+1rem)]'
].filter(Boolean).join(' '),
style: {
'--height': (inc.value * 4) + 'px',
'--step-y': `${getStepY(steps.landing + 10)}px`,
'--prev-step-y': `${getStepY(steps.landing + 2)}px`
},
inactive: isAfterStep(steps.landing + 7),
children: [{
slot: 'landing-section',
class: 'inset-x-4 top-16'
}, {
name: 'ULandingGrid',
to: '/pro/components/landing-grid',
class: ['inset-x-4 bottom-4 top-48', isAfterStep(steps.landing + 8) && 'grid grid-cols-4 gap-4 p-4'].filter(Boolean).join(' '),
inactive: isAfterStep(steps.landing + 8),
children: [isAfterStep(steps.landing + 9) ? {
slot: 'landing-card-1',
class: '!relative'
} : {
name: 'ULandingCard',
to: '/pro/components/landing-card',
class: '!relative h-full',
inactive: false
}, isAfterStep(steps.landing + 9) ? {
slot: 'landing-card-2',
class: '!relative h-full'
} : {
name: 'ULandingCard',
to: '/pro/components/landing-card',
class: '!relative h-full',
inactive: false
}, isAfterStep(steps.landing + 9) ? {
slot: 'landing-card-3',
class: '!relative h-full'
} : {
name: 'ULandingCard',
to: '/pro/components/landing-card',
class: '!relative h-full',
inactive: false
}, isAfterStep(steps.landing + 9) ? {
slot: 'landing-card-4',
class: '!relative h-full'
} : {
name: 'ULandingCard',
to: '/pro/components/landing-card',
class: '!relative h-full',
inactive: false
}]
}]
}, isAfterStep(steps.landing + 10) && {
name: 'ULandingSection',
to: '/pro/components/landing-section',
class: [
'inset-4',
isBeforeStep(steps.landing + 14) && '-top-[calc(var(--y)-var(--prev-step-y)-var(--height)-1rem)] bottom-[calc(var(--y)-var(--prev-step-y)-var(--height)+1rem)]'
].filter(Boolean).join(' '),
style: {
'--height': (inc.value * 4) + 'px',
'--step-y': `${getStepY(steps.landing + 18)}px`,
'--prev-step-y': `${getStepY(steps.landing + 10)}px`
},
inactive: isAfterStep(steps.landing + 15),
children: [{
name: 'ULandingCTA',
class: 'inset-4',
inactive: isAfterStep(steps.landing + 16),
children: [{
slot: 'landing-cta',
class: 'inset-0'
}]
}]
}].filter(Boolean)
}] : [])
const docsBlocks = computed(() => [isAfterStep(steps.docs) && {
name: 'UPage',
to: '/pro/components/page',
class: 'inset-x-0 top-20 bottom-20',
inactive: isAfterStep(steps.docs + 1),
children: [isAfterStep(steps.docs + 2) ? {
name: 'UAside',
to: '/pro/components/aside',
class: 'left-4 inset-y-4 w-64',
inactive: isAfterStep(steps.docs + 3),
children: [isAfterStep(steps.docs + 4) ? {
slot: 'aside-top',
class: 'inset-x-4 top-4'
} : {
name: '#top',
class: 'inset-x-4 top-4 h-9'
}, isAfterStep(steps.docs + 5) ? {
name: 'UNavigationTree',
to: '/pro/components/navigation-tree',
class: ['inset-x-4 top-[4.25rem] bottom-4', isAfterStep(steps.docs + 6) && '!bg-transparent !border-0'].join(' '),
inactive: isAfterStep(steps.docs + 6),
children: [{
slot: 'aside-default',
class: 'inset-0'
}]
} : {
name: '#default',
class: 'inset-x-4 top-[4.25rem] bottom-4'
}]
} : {
name: '#left',
class: 'left-4 inset-y-4 w-64'
}, isAfterStep(steps.docs + 7) ? {
name: 'UPage',
to: '/pro/components/page',
class: 'left-72 right-4 inset-y-4',
inactive: isAfterStep(steps.docs + 8),
children: [...(isAfterStep(steps.docs + 9) ? [{
name: 'UPageHeader',
to: '/pro/components/page-header',
class: 'top-4 left-4 right-72 h-32',
inactive: isAfterStep(steps.docs + 10),
children: [{
slot: 'page-header',
class: 'inset-4 justify-start'
}]
}, {
name: 'UPageBody',
to: '/pro/components/page-body',
class: 'top-40 left-4 right-72 bottom-4 overflow-y-auto',
inactive: isAfterStep(steps.docs + 11),
children: [{
slot: 'page-body',
class: 'inset-x-4 top-4 justify-start'
}, isAfterStep(steps.docs + 12) ? {
slot: 'content-surround',
class: 'bottom-4 inset-x-4 h-28'
} : {
name: 'UContentSurround',
to: '/pro/components/content-surround',
class: 'bottom-4 inset-x-4 h-28',
inactive: false
}]
}] : [{
name: '#default',
class: 'left-4 right-72 inset-y-4'
}]), isAfterStep(steps.docs + 13) ? {
name: 'UContentToc',
to: '/pro/components/content-toc',
class: 'right-4 inset-y-4 w-64',
inactive: isAfterStep(steps.docs + 14),
children: [{
slot: 'content-toc',
class: 'inset-4 overflow-y-auto'
}]
} : {
name: '#right',
class: 'right-4 inset-y-4 w-64'
}]
} : {
name: '#default',
class: 'left-72 right-4 inset-y-4'
}]
}].filter(Boolean))
const blocks = computed(() => [isAfterStep(steps.header) && {
name: 'UHeader',
to: '/pro/components/header',
class: 'h-16 inset-x-0 top-0',
inactive: isAfterStep(steps.header + 1),
children: [isAfterStep(steps.header + 2) ? {
slot: 'header-left',
class: 'left-4 top-4'
} : {
name: '#left',
class: 'left-4 inset-y-4 w-64'
}, isAfterStep(steps.header + 3) ? {
slot: 'header-center',
class: 'inset-x-72 top-5'
} : {
name: '#center',
class: 'inset-x-72 inset-y-4'
}, isAfterStep(steps.header + 4) ? {
slot: 'header-right',
class: 'right-4 top-4'
} : {
name: '#right',
class: 'right-4 inset-y-4 w-64'
}]
}, isAfterStep(steps.footer) && {
name: 'UFooter',
to: '/pro/components/footer',
class: 'h-16 inset-x-0 bottom-0',
inactive: isAfterStep(steps.footer + 1),
children: [isAfterStep(steps.footer + 2) ? {
slot: 'footer-left',
class: 'left-4 bottom-5'
} : {
name: '#left',
class: 'left-4 inset-y-4 w-64'
}, isAfterStep(steps.footer + 3) ? {
slot: 'footer-center',
class: 'inset-x-72 bottom-5'
} : {
name: '#center',
class: 'inset-x-72 inset-y-4'
}, isAfterStep(steps.footer + 4) ? {
slot: 'footer-right',
class: 'right-4 bottom-4'
} : {
name: '#right',
class: 'right-4 inset-y-4 w-64'
}]
}, ...landingBlocks.value, ...docsBlocks.value].filter(Boolean))
// Methods
function isBeforeStep (i = 0) {
return y.value < (start.value + (i * inc.value))
}
function isAfterStep (i = 0) {
return y.value >= (start.value + (i * inc.value))
}
function getStepY (step: number) {
return start.value + (step * inc.value)
}
// Hooks
onMounted(() => {
setTimeout(() => {
start.value = top.value + y.value
}, 100)
})
// Slots Data
const headerLinks = [{
label: 'Documentation',
active: true
}, {
label: 'Playground'
}, {
label: 'Roadmap'
}, {
label: 'Pro'
}]
const navigationLinks = [{
label: 'Getting Started',
children: [{
label: 'Introduction'
}, {
label: 'Installation',
active: true
}, {
label: 'Theming'
}, {
label: 'Shortcuts'
}, {
label: 'Examples'
}, {
label: 'Roadmap'
}]
}, {
label: 'Elements',
children: [{
label: 'Alert'
}, {
label: 'Avatar'
}, {
label: 'Badge'
}, {
label: 'Button'
}]
}]
const surround = [{
title: 'Introduction',
description: 'Fully styled and customizable components for Nuxt.',
_path: '/'
}, {
title: 'Theming',
description: 'Learn how to customize the look and feel of the components.',
_path: '/'
}]
const md = `
## Edge
To use the latest updates pushed on the [\`dev\`](https://github.com/nuxt/ui/tree/dev) branch, you can use \`@nuxt/ui-edge\`.
`
const toc = [{
id: 'quick-start',
depth: 2,
text: 'Quick Start'
}, {
id: 'intellisense',
depth: 2,
text: 'IntelliSense'
}, {
id: 'options',
depth: 2,
text: 'Options'
}, {
id: 'edge',
depth: 2,
text: 'Edge'
}]
const communityLinks = [{
icon: 'i-heroicons-pencil-square',
label: 'Edit this page'
}, {
icon: 'i-heroicons-star',
label: 'Star on GitHub',
to: 'https://github.com/nuxt/ui',
target: '_blank'
}, {
icon: 'i-heroicons-book-open',
label: 'Nuxt documentation',
to: 'https://nuxt.com',
target: '_blank'
}]
</script>
<!-- eslint-disable vue/no-v-html -->
<template>
<div>
<ULandingHero :ui="{ base: 'relative z-[1]', container: 'max-w-4xl' }" class="mb-[calc(var(--header-height)*2)]">
<template #headline>
<UBadge variant="subtle" size="md" class="hover:bg-primary-100 dark:bg-primary-950/100 dark:hover:bg-primary-900 transition-color relative font-medium rounded-full shadow-none">
<NuxtLink :to="`https://github.com/nuxt/ui/releases/tag/v${config.version.split('.').slice(0, -1).join('.')}.0`" target="_blank" class="focus:outline-none" aria-label="Go to last relase" tabindex="-1">
<span class="absolute inset-0" aria-hidden="true" />
</NuxtLink>
<span class="flex items-center gap-1">
Nuxt UI v{{ config.version.split('.').slice(0, -1).join('.') }} is out!
</span>
</UBadge>
</template>
<template #title>
<span v-html="page.hero?.title" />
</template>
<template #description>
<span v-html="page.hero?.description" />
</template>
<template #links>
<UButton label="Get Started" trailing-icon="i-heroicons-arrow-right-20-solid" size="lg" to="/getting-started/installation" />
<UInput
v-model="source"
color="gray"
readonly
autocomplete="off"
icon="i-heroicons-command-line"
input-class="select-none"
aria-label="Install @nuxt/ui"
size="lg"
:ui="{ base: 'disabled:cursor-default', icon: { trailing: { pointer: '' } } }"
>
<template #trailing>
<UButton
aria-label="Copy Code"
:color="copied ? 'primary' : 'gray'"
variant="link"
size="2xs"
:icon="copied ? 'i-heroicons-clipboard-document-check' : 'i-heroicons-clipboard-document'"
@click="copy(source)"
/>
</template>
</UInput>
</template>
<ClientOnly>
<HomeTetris />
</ClientOnly>
</ULandingHero>
<ULandingSection v-for="(section, index) of page.sections" :key="index" v-bind="section">
<template v-if="section.title" #title>
<span v-html="section?.title" />
</template>
<template v-if="section.description" #description>
<span v-html="section.description" />
</template>
<template #demo>
<ClientOnly>
<HomeDemo v-if="lgAndLarger" />
</ClientOnly>
</template>
<template #features>
<ULandingGrid class="lg:-mb-20 lg:auto-rows-[3rem]">
<ULandingCard
v-for="(card, subIndex) of section.cards"
:key="subIndex"
v-bind="card"
:ui="{
background: 'dark:bg-gray-900/50 dark:lg:bg-gradient-to-b from-gray-700/50 to-gray-950/50',
body: {
base: 'flex-1',
background: 'dark:bg-gray-800/50 dark:lg:bg-gray-900/50 backdrop-blur-lg'
}
}"
class="flex flex-col"
>
<UColorModeImage
:light="`${card.image.path}-light.svg`"
:dark="`${card.image.path}-dark.svg`"
:width="card.image.width"
:height="card.image.height"
:alt="card.title"
loading="lazy"
class="object-cover w-full"
/>
</ULandingCard>
</ULandingGrid>
</template>
</ULandingSection>
<ULandingSection class="!pt-0 dark:bg-gradient-to-b from-gray-950/50 to-gray-900">
<ULandingCTA
align="left"
card
:ui="{
background: 'dark:bg-gradient-to-b from-gray-800 to-gray-900',
shadow: 'dark:shadow-2xl',
body: {
background: 'bg-gray-50/50 dark:bg-gray-900/50'
},
title: 'text-center lg:text-left',
links: 'justify-center lg:justify-start'
}"
>
<template #title>
<span v-html="page.cta.title" />
</template>
<template #links>
<ClientOnly>
<UAvatarGroup :max="xlAndLarger ? 13 : lgAndLarger ? 10 : mdAndLarger ? 16 : 8" size="md" class="flex-wrap-reverse [&_span:first-child]:text-xs justify-center">
<UTooltip
v-for="(contributor, index) of module.contributors"
:key="index"
:text="contributor.username"
class="rounded-full"
:ui="{ background: 'bg-gray-50 dark:bg-gray-800/50' }"
:popper="{ offsetDistance: 16 }"
>
<UAvatar
:alt="contributor.username"
:src="`https://ipx.nuxt.com/s_40x40/gh_avatar/${contributor.username}`"
:srcset="`https://ipx.nuxt.com/s_80x80/gh_avatar/${contributor.username} 2x`"
class="lg:hover:scale-125 lg:hover:ring-2 lg:hover:ring-primary-500 dark:lg:hover:ring-primary-400 transition-transform"
width="40"
height="40"
size="md"
loading="lazy"
>
<NuxtLink :to="`https://github.com/${contributor.username}`" :aria-label="contributor.username" target="_blank" class="focus:outline-none" tabindex="-1">
<span class="absolute inset-0" aria-hidden="true" />
</NuxtLink>
</UAvatar>
</UTooltip>
</UAvatarGroup>
</ClientOnly>
</template>
<div class="flex flex-col sm:flex-row items-center justify-center gap-8 lg:gap-16">
<NuxtLink class="text-center group" to="https://npmjs.org/package/@nuxt/ui" target="_blank">
<p class="text-6xl font-semibold text-gray-900 dark:text-white group-hover:text-primary-500 dark:group-hover:text-primary-400">
{{ format(module.stats.downloads) }}+
</p>
<p>monthly downloads</p>
</NuxtLink>
<NuxtLink class="text-center group" to="https://github.com/nuxt/ui" target="_blank">
<p class="text-6xl font-semibold text-gray-900 dark:text-white group-hover:text-primary-500 dark:group-hover:text-primary-400">
{{ format(module.stats.stars) }}+
</p>
<p>stars</p>
</NuxtLink>
</div>
</ULandingCTA>
</ULandingSection>
<template v-if="navigation.find(item => item._path === '/pro')">
<div class="relative">
<UDivider class="absolute inset-x-0" />
<div class="w-full relative overflow-hidden h-px bg-gradient-to-r from-gray-800 via-primary-400 to-gray-800 max-w-5xl mx-auto" />
</div>
<ULandingHero id="pro" :links="page.pro.links" :ui="{ title: 'sm:text-6xl' }" class="bg-gradient-to-b from-gray-50 dark:from-gray-950/50 to-white dark:to-gray-900 relative">
<template #title>
<span v-html="page.pro.title" />
</template>
<template #description>
<span v-html="page.pro.description" />
</template>
<div class="bg-gray-900/5 dark:bg-white/5 ring-1 ring-inset ring-gray-900/10 dark:ring-white/10 rounded-xl lg:-m-4 p-4">
<video preload="none" poster="https://res.cloudinary.com/nuxt/video/upload/so_3.3/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.jpg" controls class="rounded-lg">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.webm" type="video/webm">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.mp4" type="video/mp4">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1708511800/ui-pro/video-nuxt-ui-pro_kwfbdh.ogg" type="video/ogg">
</video>
</div>
</ULandingHero>
<ULandingSection v-for="(section, index) in page.pro.sections" :key="index" v-bind="section" class="!pt-0">
<MDC
v-if="section.code"
:value="section.code"
tag="pre"
class="prose prose-primary dark:prose-invert max-w-none"
/>
</ULandingSection>
<div ref="sectionRef" :style="{ '--y': `${y}px`, '--inc': `${inc}px` }" class="_screen_xl">
<ULandingSection class="sticky h-screen top-0 flex !pb-16" :ui="{ container: 'flex-1 sm:gap-y-12' }">
<template #title>
<Transition name="fade" mode="out-in">
<span v-if="isAfterStep(steps.docs)" v-html="page.pro.docs?.title" />
<span v-else v-html="page.pro.landing?.title" />
</Transition>
</template>
<template #description>
<Transition name="fade" mode="out-in">
<span v-if="isAfterStep(steps.docs)" v-html="page.pro.docs?.description" />
<span v-else v-html="page.pro.landing?.description" />
</Transition>
</template>
<HomeProDemo ref="demoRef" :blocks="(blocks as HomeProBlock[])">
<template #header-left>
<Logo class="w-auto h-6" />
</template>
<template #header-center>
<UHeaderLinks :links="headerLinks" />
</template>
<template #header-right>
<div class="flex items-center gap-1.5">
<UColorModeButton />
<UButton
to="https://github.com/nuxt/ui"
target="_blank"
icon="i-simple-icons-github"
aria-label="GitHub"
class="hidden lg:inline-flex"
color="gray" variant="ghost"
/>
</div>
</template>
<template #footer-left>
<span class="text-sm text-gray-500 dark:text-gray-400">
Published under <NuxtLink to="https://github.com/nuxt/ui" target="_blank" class="text-gray-900 dark:text-white">
MIT License
</NuxtLink>
</span>
</template>
<template #footer-right>
<div class="flex items-center gap-1.5">
<UButton aria-label="Nuxt on X" icon="i-simple-icons-x" to="https://x.com/nuxt_js" target="_blank" color="gray" variant="ghost" />
<UButton aria-label="Nuxt UI on Discord" icon="i-simple-icons-discord" to="https://discord.com/channels/473401852243869706/1153996761426300948" target="_blank" color="gray" variant="ghost" />
<UButton aria-label="Nuxt UI on GitHub" icon="i-simple-icons-github" to="https://github.com/nuxt/ui" target="_blank" color="gray" variant="ghost" />
</div>
</template>
<template #aside-top>
<UContentSearchButton size="md" class="w-full" />
</template>
<template #aside-default>
<UNavigationTree
class="w-full h-full [&>div>div>div>nav]:border-gray-800/10 dark:[&>div>div>div>nav]:border-gray-200/10 overflow-y-auto"
:links="navigationLinks"
/>
</template>
<template #page-header>
<UPageHeader
title="Installation"
description="Learn how to install and configure the module in your Nuxt app."
headline="Getting Started"
class="!p-0 !border-0"
:ui="{ headline: 'mb-1 text-xs', title: '!text-2xl', description: 'mt-1 text-sm' }"
/>
</template>
<template #page-body>
<div class="-mt-8 prose prose-primary prose-sm dark:prose-invert max-w-none">
<MDC :value="md" tag="div" />
<!-- <hr class="border-gray-800/10 dark:border-gray-200/10 !mt-5"> -->
</div>
</template>
<template #content-surround>
<UContentSurround
:surround="(surround as unknown as ParsedContent[])"
class="w-full gap-4"
:ui="{
link: {
wrapper: 'px-4 py-2.5 border-gray-800/10 dark:border-gray-200/10 cursor-pointer',
icon: {
wrapper: 'mb-2 p-1',
base: 'h-4 w-4',
},
title: 'text-sm',
description: 'text-xs'
}
}"
/>
</template>
<template #content-toc>
<div class="absolute top-0 left-0 right-0 space-y-3">
<UContentToc :links="toc" class="bg-transparent relative max-h-full overflow-hidden top-0" :ui="({ container: { base: '!pt-0 !pb-4' } } as any)" />
<UDivider type="dashed" :ui="{ border: { base: 'border-gray-800/10 dark:border-gray-200/10' } }" />
<UPageLinks title="Community" :links="communityLinks" class="mt-4" />
</div>
</template>
<template #landing-hero>
<ULandingHero class="!p-0" :ui="{ title: '!text-5xl', description: 'text-base' }">
<template #title>
A <span class="text-primary">UI Library</span> for<br> Modern Web Apps
</template>
<template #description>
Nuxt UI simplifies the creation of stunning and responsive web applications with its<br> comprehensive collection of fully styled and customizable UI components designed for Nuxt.
</template>
<template #links>
<UButton label="Get Started" icon="i-heroicons-rocket-launch" size="md" />
<UInput
model-value="npm i @nuxt/ui"
color="gray"
readonly
autocomplete="off"
icon="i-heroicons-command-line"
input-class="select-none"
aria-label="Install @nuxt/ui"
size="md"
:ui="{ base: 'disabled:cursor-default', icon: { trailing: { pointer: '' } } }"
/>
</template>
</ULandingHero>
</template>
<template #landing-section>
<ULandingSection :ui="{ title: '!text-3xl', description: 'text-base' }" class="!p-0">
<template #title>
Everything you expect from a<br> <span class="text-primary">UI component library</span>
</template>
</ULandingSection>
</template>
<template #landing-card-1>
<ULandingCard icon="i-heroicons-swatch" title="Color Palette" description="Choose a primary and a gray color from your Tailwind CSS color palette." />
</template>
<template #landing-card-2>
<ULandingCard icon="i-heroicons-wrench-screwdriver" title="Fully Customizable" description="Change the style of any component in your App Config or with ui prop." />
</template>
<template #landing-card-3>
<ULandingCard icon="i-heroicons-face-smile" title="Icons" description="Choose any of the 100k+ icons from the most popular icon libraries." />
</template>
<template #landing-card-4>
<ULandingCard icon="i-heroicons-computer-desktop" title="Keyboard Shortcuts" description="Nuxt UI comes with a set of Vue composables to easily handle shortcuts." />
</template>
<template #landing-cta>
<ULandingCTA card :links="[{ label: 'Get started', color: 'black', size: 'md' }, { label: 'Learn more', color: 'black', variant: 'link', size: 'md', trailingIcon: 'i-heroicons-arrow-right-20-solid' }]" :ui="{ title: '!text-3xl', description: 'text-base' }" class="w-full h-full rounded-md">
<template #title>
Trusted and supported by our<br> amazing community
</template>
</ULandingCTA>
</template>
</HomeProDemo>
</ULandingSection>
<div class="h-[calc(var(--inc)*42)]" />
</div>
<div class="_not_screen_xl">
<ULandingSection>
<template #title>
<span v-html="page.pro.landing?.title" />
</template>
<template #description>
<span v-html="page.pro.landing?.description" />
</template>
<video preload="none" poster="https://res.cloudinary.com/nuxt/video/upload/so_14.4/v1698923423/ui-pro/nuxt-ui-pro-landing-demo_yrh6nr.jpg" controls>
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923423/ui-pro/nuxt-ui-pro-landing-demo_yrh6nr.webm" type="video/webm">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923423/ui-pro/nuxt-ui-pro-landing-demo_yrh6nr.mp4" type="video/mp4">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923423/ui-pro/nuxt-ui-pro-landing-demo_yrh6nr.ogg" type="video/ogg">
</video>
</ULandingSection>
<ULandingSection>
<template #title>
<span v-html="page.pro.docs?.title" />
</template>
<template #description>
<span v-html="page.pro.docs?.description" />
</template>
<video preload="none" poster="https://res.cloudinary.com/nuxt/video/upload/v1698923398/ui-pro/nuxt-ui-pro-docs-demo_jm6ubr.jpg" controls>
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923398/ui-pro/nuxt-ui-pro-docs-demo_jm6ubr.webm" type="video/webm">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923398/ui-pro/nuxt-ui-pro-docs-demo_jm6ubr.mp4" type="video/mp4">
<source src="https://res.cloudinary.com/nuxt/video/upload/v1698923398/ui-pro/nuxt-ui-pro-docs-demo_jm6ubr.ogg" type="video/ogg">
</video>
</ULandingSection>
</div>
</template>
</div>
</template>
<style scoped lang="postcss">
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.2s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
._screen_xl {
display: none;
}
@media (min-width: 1280px) and (min-height: 955px) {
._screen_xl {
display: block;
}
._not_screen_xl {
display: none;
}
}
</style>

View File

@@ -14,12 +14,14 @@ defineOgImage({
title,
description
})
const colorMode = useColorMode()
</script>
<template>
<div class="h-[calc(100vh-var(--header-height)-var(--header-height)-1px)]">
<ClientOnly>
<iframe :src="`https://stackblitz.com/edit/nuxt-ui?embed=1&file=app.config.ts,app.vue&theme=${$colorMode.preference}`" width="100%" height="100%" />
<iframe :src="`https://stackblitz.com/edit/nuxt-ui?embed=1&file=app.config.ts,app.vue&theme=${colorMode.preference}`" width="100%" height="100%" />
</ClientOnly>
</div>
</template>

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +0,0 @@
export interface HomeProBlock {
id?: string
to?: string
name?: string
description?: string
slot?: string
class: string
style?: any
inactive?: boolean
transparent?: boolean
children?: ProBlock[]
}

View File

@@ -12,19 +12,19 @@ export default defineNuxtConfig({
}
}
},
extends: [
process.env.NUXT_UI_PRO_PATH ? resolve(process.env.NUXT_UI_PRO_PATH, 'docs') : process.env.NUXT_GITHUB_TOKEN && ['github:nuxt/ui-pro/docs#dev', { giget: { auth: process.env.NUXT_GITHUB_TOKEN } }]
],
// extends: [
// process.env.NUXT_UI_PRO_PATH ? resolve(process.env.NUXT_UI_PRO_PATH, 'docs') : process.env.NUXT_GITHUB_TOKEN && ['github:nuxt/ui-pro/docs#dev', { giget: { auth: process.env.NUXT_GITHUB_TOKEN } }]
// ],
modules: [
module,
'@nuxt/ui-pro',
'@nuxt/content',
'@nuxt/fonts',
'@nuxt/image',
module,
'@nuxt/ui-pro',
'@nuxtjs/plausible',
// '@nuxtjs/plausible',
'@vueuse/nuxt',
'nuxt-og-image',
// 'modules/content-examples-code'
'nuxt-og-image'
],
future: {
compatibilityVersion: 4
@@ -39,18 +39,22 @@ export default defineNuxtConfig({
// },
content: {
sources: {
pro: process.env.NUXT_UI_PRO_PATH ? {
prefix: '/pro',
driver: 'fs',
base: resolve(process.env.NUXT_UI_PRO_PATH, 'docs/content/pro')
} : process.env.NUXT_GITHUB_TOKEN ? {
prefix: '/pro',
driver: 'github',
repo: 'nuxt/ui-pro',
branch: 'dev',
dir: 'docs/content/pro',
token: process.env.NUXT_GITHUB_TOKEN || ''
} : undefined
pro: process.env.NUXT_UI_PRO_PATH
? {
prefix: '/pro',
driver: 'fs',
base: resolve(process.env.NUXT_UI_PRO_PATH, 'docs/app/content/pro')
}
: process.env.NUXT_GITHUB_TOKEN
? {
prefix: '/pro',
driver: 'github',
repo: 'nuxt/ui-pro',
branch: 'dev',
dir: 'docs/app/content/pro',
token: process.env.NUXT_GITHUB_TOKEN || ''
}
: undefined
}
},
image: {
@@ -69,6 +73,7 @@ export default defineNuxtConfig({
}
},
routeRules: {
'/': { redirect: '/getting-started', prerender: false },
'/components': { redirect: '/components/app', prerender: false },
'/dev/components': { redirect: '/dev/components/app', prerender: false }
},
@@ -104,9 +109,12 @@ export default defineNuxtConfig({
// })
// }
},
vite: {
optimizeDeps: {
include: ['date-fns']
}
// vite: {
// optimizeDeps: {
// include: ['date-fns']
// }
// },
typescript: {
strict: false
}
})

View File

@@ -4,7 +4,7 @@
"type": "module",
"dependencies": {
"@iconify-json/heroicons": "^1.1.21",
"@iconify-json/simple-icons": "^1.1.105",
"@iconify-json/simple-icons": "^1.1.106",
"@iconify-json/vscode-icons": "^1.1.35",
"@nuxt/content": "npm:@nuxt/content-edge@2.12.1-28635002.f66778a",
"@nuxt/fonts": "^0.7.0",
@@ -13,16 +13,13 @@
"@nuxt/ui-pro": "file:../../ui-pro2",
"@nuxtjs/plausible": "^1.0.0",
"@octokit/rest": "^20.1.1",
"@vueuse/nuxt": "^10.10.0",
"date-fns": "^3.6.0",
"@vueuse/nuxt": "^10.11.0",
"joi": "^17.13.1",
"nuxt": "^3.12.1",
"nuxt": "^3.12.2",
"nuxt-component-meta": "^0.6.4",
"nuxt-og-image": "^2.2.4",
"nuxt-og-image": "^3.0.0-rc.53",
"prettier": "^3.3.2",
"typescript": "^5.4.5",
"ufo": "^1.5.3",
"v-calendar": "^3.1.2",
"valibot": "^0.30.0",
"yup": "^1.4.0",
"zod": "^3.23.8"