feat: add exmaples layout
This commit is contained in:
parent
4701eb16ee
commit
9e977917eb
|
|
@ -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>
|
||||
81
apps/www/.vitepress/theme/components/ExamplesNav.vue
Normal file
81
apps/www/.vitepress/theme/components/ExamplesNav.vue
Normal 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>
|
||||
75
apps/www/.vitepress/theme/components/LandingPage.vue
Normal file
75
apps/www/.vitepress/theme/components/LandingPage.vue
Normal 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>
|
||||
16
apps/www/.vitepress/theme/components/PageHeader.vue
Normal file
16
apps/www/.vitepress/theme/components/PageHeader.vue
Normal 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>
|
||||
|
|
@ -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>
|
||||
14
apps/www/.vitepress/theme/components/PageHeaderHeading.vue
Normal file
14
apps/www/.vitepress/theme/components/PageHeaderHeading.vue
Normal 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>
|
||||
|
|
@ -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])
|
||||
|
|
|
|||
63
apps/www/.vitepress/theme/layout/ExamplesLayout.vue
Normal file
63
apps/www/.vitepress/theme/layout/ExamplesLayout.vue
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
hi
|
||||
5
apps/www/src/content/examples/dashboard.md
Normal file
5
apps/www/src/content/examples/dashboard.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<script setup>
|
||||
import Dashboard from "@/examples/dashboard/Example.vue"
|
||||
</script>
|
||||
|
||||
<Dashboard />
|
||||
|
|
@ -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 />
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -1 +1,2 @@
|
|||
export { default as ScrollArea } from './ScrollArea.vue'
|
||||
export { default as ScrollBar } from './ScrollBar.vue'
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user