mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-21 23:40:39 +01:00
docs: update
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
24
docs/app/composables/useModule.ts
Normal file
24
docs/app/composables/useModule.ts
Normal 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
|
||||
}
|
||||
}
|
||||
10
docs/app/content/2.components/1.app.md
Normal file
10
docs/app/content/2.components/1.app.md
Normal 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
|
||||
@@ -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"}
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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
12
docs/app/types/index.d.ts
vendored
12
docs/app/types/index.d.ts
vendored
@@ -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[]
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user