feat: add exmaples layout

This commit is contained in:
zernonia 2023-09-05 14:29:34 +08:00
parent 4701eb16ee
commit 9e977917eb
17 changed files with 315 additions and 41 deletions

View File

@ -1,21 +0,0 @@
<script setup lang="ts">
import { useData } from 'vitepress'
// https://vitepress.dev/reference/runtime-api#usedata
const { site, frontmatter } = useData()
</script>
<template>
<div v-if="frontmatter.home">
<h1>{{ site.title }}</h1>
<p>{{ site.description }}</p>
<ul>
<li><a href="/markdown-examples.html">Markdown Examples</a></li>
<li><a href="/api-examples.html">API Examples</a></li>
</ul>
</div>
<div v-else>
<a href="/">Home</a>
<Content />
</div>
</template>

View File

@ -0,0 +1,81 @@
<script setup lang="ts">
import { useRoute } from 'vitepress'
import { computed, toRefs } from 'vue'
import { cn } from '@/lib/utils'
import { ScrollArea, ScrollBar } from '@/lib/registry/default/ui/scroll-area'
import ArrowRightIcon from '~icons/radix-icons/arrow-right'
const { path } = toRefs(useRoute())
const examples = [
{
name: 'Dashboard',
href: '/examples/dashboard',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/dashboard',
},
{
name: 'Cards',
href: '/examples/cards',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/cards',
},
{
name: 'Tasks',
href: '/examples/tasks',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/tasks',
},
{
name: 'Playground',
href: '/examples/playground',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/playground',
},
{
name: 'Forms',
href: '/examples/forms',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/forms',
},
{
name: 'Music',
href: '/examples/music',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/music',
},
{
name: 'Authentication',
href: '/examples/authentication',
code: 'https://github.com/radix-vue/shadcn-vue/tree/main/apps/www/app/examples/authentication',
},
]
const currentExample = computed(() => examples.find(ex => path.value.startsWith(ex.href)) ?? examples[0])
</script>
<template>
<div class="relative">
<ScrollArea class="max-w-[600px] lg:max-w-none">
<div :class="cn('mb-4 flex items-center', $attrs.class ?? '')">
<a
v-for="example in examples"
:key="example.href"
:href="example.href"
:class="cn(
'flex items-center px-4',
path?.startsWith(example.href) || (path === '/' && example.name === 'Dashboard')
? 'font-bold text-primary'
: 'font-medium text-muted-foreground',
)"
>
{{ example.name }}
</a>
</div>
<ScrollBar orientation="horizontal" class="invisible" />
</ScrollArea>
<a
v-if="currentExample"
:href="currentExample?.code" target="_blank" rel="nofollow"
class="absolute right-0 top-0 hidden items-center rounded-[0.5rem] text-sm font-medium md:flex"
>
View code
<ArrowRightIcon class="ml-1 h-4 w-4" />
</a>
</div>
</template>

View File

@ -0,0 +1,75 @@
<script setup lang="ts">
import PageHeader from '../components/PageHeader.vue'
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
import ExamplesNav from '../components/ExamplesNav.vue'
import ArrowRightIcon from '~icons/radix-icons/arrow-right'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { Separator } from '@/lib/registry/default/ui/separator'
import { cn } from '@/lib/utils'
import DashboardExample from '@/examples/dashboard/Example.vue'
</script>
<template>
<div class="container relative">
<PageHeader class="page-header pb-8">
<a
href="/docs/changelog"
class="inline-flex items-center rounded-lg bg-muted px-3 py-1 text-sm font-medium"
>
🎉 <Separator class="mx-2 h-4" orientation="vertical" />
<span class="sm:hidden">Style, a new CLI and more.</span>
<span class="hidden sm:inline">
Introducing Style, a new CLI and more.
</span>
<ArrowRightIcon class="ml-1 h-4 w-4" />
</a>
<PageHeaderHeading>Build your component library.</PageHeaderHeading>
<PageHeaderDescription>
Beautifully designed components that you can copy and paste into your
apps. Accessible. Customizable. Open Source.
</PageHeaderDescription>
<section class="flex w-full items-center space-x-4 pb-8 pt-4 md:pb-10">
<a
href="/docs"
:class="cn(buttonVariants(), 'rounded-[6px]')"
>
Get Started
</a>
<a
href="/components"
:class="cn(
buttonVariants({ variant: 'outline' }),
'rounded-[6px]',
)"
>
Components
</a>
</section>
</PageHeader>
<ExamplesNav />
<section class="space-y-8 overflow-hidden rounded-lg border-2 border-primary dark:border-muted md:hidden">
<!-- <Image
src="/examples/dashboard-light.png"
width={1280}
height={866}
alt="Dashboard"
className="block dark:hidden"
/>
<Image
src="/examples/dashboard-dark.png"
width={1280}
height={866}
alt="Dashboard"
className="hidden dark:block"
/> -->
</section>
<section class="hidden md:block">
<div class="overflow-hidden rounded-[0.5rem] border bg-background shadow">
<DashboardExample />
</div>
</section>
</div>
</template>

View File

@ -0,0 +1,16 @@
<script setup lang="ts">
import { cn } from '@/lib/utils'
// import WrapBalancer from 'vue-wrap-balancer'
</script>
<template>
<section
:class="cn(
'flex max-w-[980px] flex-col items-start gap-2 px-4 pt-8 md:pt-12',
$attrs.class ?? '',
)"
>
<slot />
</section>
</template>

View File

@ -0,0 +1,10 @@
<script setup lang="ts">
import WrapBalancer from 'vue-wrap-balancer'
import { cn } from '@/lib/utils'
</script>
<template>
<WrapBalancer :class="cn('max-w-[750px] text-lg text-muted-foreground sm:text-xl', $attrs.class ?? '')">
<slot />
</WrapBalancer>
</template>

View File

@ -0,0 +1,14 @@
<script setup lang="ts">
import { cn } from '@/lib/utils'
</script>
<template>
<h1
:class="cn(
'text-3xl font-bold leading-tight tracking-tighter md:text-5xl lg:leading-[1.1]',
$attrs.class ?? '',
)"
>
<slot />
</h1>
</template>

View File

@ -2,6 +2,7 @@
// https://vitepress.dev/guide/custom-theme
import Layout from './layout/MainLayout.vue'
import DocsLayout from './layout/DocsLayout.vue'
import ExamplesLayout from './layout/ExamplesLayout.vue'
import * as components from './components'
import './style.css'
import './styles/vp-doc.css'
@ -12,6 +13,7 @@ export default {
enhanceApp({ app }) {
// ...
app.component('docs', DocsLayout)
app.component('examples', ExamplesLayout)
for (const component of Object.keys(components))
app.component(component, components[component])

View File

@ -0,0 +1,63 @@
<script setup lang="ts">
import PageHeader from '../components/PageHeader.vue'
import PageHeaderHeading from '../components/PageHeaderHeading.vue'
import PageHeaderDescription from '../components/PageHeaderDescription.vue'
import ExamplesNav from '../components/ExamplesNav.vue'
import ArrowRightIcon from '~icons/radix-icons/arrow-right'
import { buttonVariants } from '@/lib/registry/default/ui/button'
import { Separator } from '@/lib/registry/default/ui/separator'
import { cn } from '@/lib/utils'
</script>
<template>
<div class="container relative">
<PageHeader class="page-header pb-8">
<a
href="/docs/changelog"
class="inline-flex items-center rounded-lg bg-muted px-3 py-1 text-sm font-medium"
>
🎉 <Separator class="mx-2 h-4" orientation="vertical" />
<span class="sm:hidden">Style, a new CLI and more.</span>
<span class="hidden sm:inline">
Introducing Style, a new CLI and more.
</span>
<ArrowRightIcon class="ml-1 h-4 w-4" />
</a>
<PageHeaderHeading class="hidden md:block">
Check out some examples.
</PageHeaderHeading>
<PageHeaderHeading class="md:hidden">
Examples
</PageHeaderHeading>
<PageHeaderDescription>
Dashboard, cards, authentication. Some examples built using the
components. Use this as a guide to build your own.
</PageHeaderDescription>
<section class="flex w-full items-center space-x-4 pb-8 pt-4 md:pb-10">
<a
href="/docs"
:class="cn(buttonVariants(), 'rounded-[6px]')"
>
Get Started
</a>
<a
href="/components"
:class="cn(
buttonVariants({ variant: 'outline' }),
'rounded-[6px]',
)"
>
Components
</a>
</section>
</PageHeader>
<section>
<ExamplesNav />
<div class="overflow-hidden rounded-[0.5rem] border bg-background shadow">
<slot />
</div>
</section>
</div>
</template>

View File

@ -109,6 +109,9 @@ const links = [
<component :is="'docs'" v-if="$route.path.includes('docs')">
<Content />
</component>
<component :is="'examples'" v-else-if="$route.path.includes('examples')">
<Content />
</component>
<component :is="frontmatter.layout" v-else-if="frontmatter.layout">
<slot />
</component>

View File

@ -23,7 +23,8 @@
"tailwindcss-animate": "^1.0.6",
"v-calendar": "^3.0.3",
"vitepress": "^1.0.0-rc.10",
"vue": "^3.3.4"
"vue": "^3.3.4",
"vue-wrap-balancer": "^1.1.3"
},
"devDependencies": {
"@iconify-json/radix-icons": "^1.1.11",

View File

@ -1 +0,0 @@
hi

View File

@ -0,0 +1,5 @@
<script setup>
import Dashboard from "@/examples/dashboard/Example.vue"
</script>
<Dashboard />

View File

@ -3,7 +3,7 @@ home: true
---
<script setup>
import Dashboard from "@/examples/dashboard/Example.vue"
import LandingPage from "../../.vitepress/theme/components/LandingPage.vue"
</script>
<Dashboard />
<LandingPage />

View File

@ -1,17 +1,16 @@
<script setup lang="ts">
import {
ScrollAreaCorner,
ScrollAreaRoot,
type ScrollAreaRootProps,
ScrollAreaScrollbar,
type ScrollAreaScrollbarProps,
ScrollAreaThumb,
ScrollAreaViewport,
} from 'radix-vue'
import ScrollBar from './ScrollBar.vue'
import { cn } from '@/lib/utils'
const props = withDefaults(
defineProps<
ScrollAreaRootProps & ScrollAreaScrollbarProps & { class?: string }
ScrollAreaRootProps & { class?: string }
>(),
{
class: '',
@ -22,19 +21,10 @@ const props = withDefaults(
<template>
<ScrollAreaRoot :type="type" :class="cn('relative overflow-hidden', props.class)">
<ScrollAreaViewport class="h-full w-full rounded">
<ScrollAreaViewport class="h-full w-full rounded-[inherit]">
<slot />
</ScrollAreaViewport>
<ScrollAreaScrollbar
:orientation="orientation"
class="flex touch-none select-none transition-colors"
:class="[
props.orientation === 'vertical'
? 'h-full w-2.5 border-l border-l-transparent p-[1px]'
: 'h-2.5 border-t border-t-transparent p-[1px]',
]"
>
<ScrollAreaThumb class="relative flex-1 rounded-full bg-secondary" />
</ScrollAreaScrollbar>
<ScrollBar />
<ScrollAreaCorner />
</ScrollAreaRoot>
</template>

View File

@ -0,0 +1,23 @@
<script setup lang="ts">
import { ScrollAreaScrollbar, type ScrollAreaScrollbarProps, ScrollAreaThumb } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<ScrollAreaScrollbarProps>(), {
orientation: 'vertical',
})
</script>
<template>
<ScrollAreaScrollbar
v-bind="props"
:class="
cn('flex touch-none select-none transition-colors',
orientation === 'vertical'
&& 'h-full w-2.5 border-l border-l-transparent p-[1px]',
orientation === 'horizontal'
&& 'h-2.5 border-t border-t-transparent p-[1px]',
$attrs.class ?? '')"
>
<ScrollAreaThumb class="relative flex-1 rounded-full bg-border" />
</ScrollAreaScrollbar>
</template>

View File

@ -1 +1,2 @@
export { default as ScrollArea } from './ScrollArea.vue'
export { default as ScrollBar } from './ScrollBar.vue'

View File

@ -80,6 +80,9 @@ importers:
vue:
specifier: ^3.3.4
version: 3.3.4
vue-wrap-balancer:
specifier: ^1.1.3
version: 1.1.3(vue@3.3.4)
devDependencies:
'@iconify-json/radix-icons':
specifier: ^1.1.11
@ -7877,6 +7880,15 @@ packages:
typescript: 5.0.2
dev: true
/vue-wrap-balancer@1.1.3(vue@3.3.4):
resolution: {integrity: sha512-9kTRwYIveWxV1FdaCJfRjIIRZOtwgnxypGS5mlAiXnih5+Cfaby9YDh3APMW1jWp0oCvL+gep0XCbcjBb7/ZXQ==}
peerDependencies:
vue: ^3.3.0
dependencies:
nanoid: 3.3.6
vue: 3.3.4
dev: false
/vue@3.3.4:
resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==}
dependencies: