docs-please 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -0
- package/app/app.config.ts +13 -0
- package/app/app.vue +17 -0
- package/app/assets/css/main.css +367 -0
- package/app/components/Icons.ts +163 -0
- package/app/components/app/AppFooter.vue +24 -0
- package/app/components/app/AppHeader.vue +58 -0
- package/app/components/content/BrowserFrame.vue +21 -0
- package/app/components/content/Callout.vue +80 -0
- package/app/components/content/Caution.vue +25 -0
- package/app/components/content/CodeBlockCommand.vue +92 -0
- package/app/components/content/CodeCollapsibleWrapper.vue +50 -0
- package/app/components/content/CodeTabs.vue +14 -0
- package/app/components/content/ComponentPreview.vue +71 -0
- package/app/components/content/ComponentsList.vue +24 -0
- package/app/components/content/CopyButton.vue +39 -0
- package/app/components/content/FeatureCard.vue +25 -0
- package/app/components/content/LinkedCard.vue +19 -0
- package/app/components/content/Note.vue +25 -0
- package/app/components/content/ProseA.vue +18 -0
- package/app/components/content/ProseBlockQuote.vue +8 -0
- package/app/components/content/ProseCode.vue +8 -0
- package/app/components/content/ProseH1.vue +7 -0
- package/app/components/content/ProseH2.vue +8 -0
- package/app/components/content/ProseH3.vue +9 -0
- package/app/components/content/ProseH4.vue +9 -0
- package/app/components/content/ProseH5.vue +7 -0
- package/app/components/content/ProseH6.vue +7 -0
- package/app/components/content/ProseHr.vue +6 -0
- package/app/components/content/ProseIcon.vue +32 -0
- package/app/components/content/ProseImg.vue +6 -0
- package/app/components/content/ProseLi.vue +8 -0
- package/app/components/content/ProseOl.vue +8 -0
- package/app/components/content/ProseP.vue +14 -0
- package/app/components/content/ProsePre.vue +80 -0
- package/app/components/content/ProseStrong.vue +8 -0
- package/app/components/content/ProseTable.vue +26 -0
- package/app/components/content/ProseTd.vue +8 -0
- package/app/components/content/ProseTh.vue +8 -0
- package/app/components/content/ProseTr.vue +8 -0
- package/app/components/content/ProseUl.vue +8 -0
- package/app/components/content/Step.vue +18 -0
- package/app/components/content/Steps.vue +18 -0
- package/app/components/content/Tabs.vue +129 -0
- package/app/components/content/TabsItem.vue +26 -0
- package/app/components/content/Tip.vue +25 -0
- package/app/components/content/UButton.vue +34 -0
- package/app/components/content/UColorModeImage.vue +48 -0
- package/app/components/content/UPageCard.vue +83 -0
- package/app/components/content/UPageGrid.vue +18 -0
- package/app/components/content/UPageHero.vue +92 -0
- package/app/components/content/UPageSection.vue +90 -0
- package/app/components/content/Warning.vue +25 -0
- package/app/components/docs/DocsPageHeader.vue +20 -0
- package/app/components/docs/DocsPageNav.vue +31 -0
- package/app/components/docs/DocsSidebar.vue +97 -0
- package/app/components/docs/DocsTableOfContents.vue +64 -0
- package/app/components/ui/accordion/Accordion.vue +22 -0
- package/app/components/ui/accordion/AccordionContent.vue +23 -0
- package/app/components/ui/accordion/AccordionItem.vue +24 -0
- package/app/components/ui/accordion/AccordionTrigger.vue +37 -0
- package/app/components/ui/accordion/index.ts +4 -0
- package/app/components/ui/alert/Alert.vue +21 -0
- package/app/components/ui/alert/AlertDescription.vue +17 -0
- package/app/components/ui/alert/AlertTitle.vue +17 -0
- package/app/components/ui/alert/index.ts +28 -0
- package/app/components/ui/button/Button.vue +29 -0
- package/app/components/ui/button/index.ts +38 -0
- package/app/components/ui/card/Card.vue +22 -0
- package/app/components/ui/card/CardAction.vue +17 -0
- package/app/components/ui/card/CardContent.vue +17 -0
- package/app/components/ui/card/CardDescription.vue +17 -0
- package/app/components/ui/card/CardFooter.vue +17 -0
- package/app/components/ui/card/CardHeader.vue +17 -0
- package/app/components/ui/card/CardTitle.vue +17 -0
- package/app/components/ui/card/index.ts +7 -0
- package/app/components/ui/collapsible/Collapsible.vue +19 -0
- package/app/components/ui/collapsible/CollapsibleContent.vue +15 -0
- package/app/components/ui/collapsible/CollapsibleTrigger.vue +15 -0
- package/app/components/ui/collapsible/index.ts +3 -0
- package/app/components/ui/separator/Separator.vue +29 -0
- package/app/components/ui/separator/index.ts +1 -0
- package/app/components/ui/switch/Switch.vue +35 -0
- package/app/components/ui/switch/index.ts +1 -0
- package/app/components/ui/table/Table.vue +16 -0
- package/app/components/ui/table/TableBody.vue +14 -0
- package/app/components/ui/table/TableCaption.vue +14 -0
- package/app/components/ui/table/TableCell.vue +21 -0
- package/app/components/ui/table/TableEmpty.vue +34 -0
- package/app/components/ui/table/TableFooter.vue +14 -0
- package/app/components/ui/table/TableHead.vue +14 -0
- package/app/components/ui/table/TableHeader.vue +14 -0
- package/app/components/ui/table/TableRow.vue +14 -0
- package/app/components/ui/table/index.ts +9 -0
- package/app/components/ui/tabs/Tabs.vue +15 -0
- package/app/components/ui/tabs/TabsContent.vue +20 -0
- package/app/components/ui/tabs/TabsList.vue +23 -0
- package/app/components/ui/tabs/TabsTrigger.vue +27 -0
- package/app/components/ui/tabs/index.ts +4 -0
- package/app/components/ui/tooltip/Tooltip.vue +19 -0
- package/app/components/ui/tooltip/TooltipContent.vue +34 -0
- package/app/components/ui/tooltip/TooltipProvider.vue +14 -0
- package/app/components/ui/tooltip/TooltipTrigger.vue +15 -0
- package/app/components/ui/tooltip/index.ts +4 -0
- package/app/composables/useConfig.ts +24 -0
- package/app/composables/useNavigation.ts +43 -0
- package/app/layouts/default.vue +12 -0
- package/app/layouts/docs.vue +27 -0
- package/app/lib/utils.ts +7 -0
- package/app/pages/[...slug].vue +97 -0
- package/app/pages/index.vue +29 -0
- package/app/plugins/ssr-width.ts +5 -0
- package/content.config.ts +36 -0
- package/i18n/locales/en.json +14 -0
- package/modules/config.ts +38 -0
- package/modules/css.ts +38 -0
- package/modules/shadcn.ts +116 -0
- package/nuxt.config.ts +125 -0
- package/nuxt.schema.ts +68 -0
- package/package.json +81 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
title?: string
|
|
6
|
+
description?: string
|
|
7
|
+
headline?: string
|
|
8
|
+
orientation?: 'vertical' | 'horizontal'
|
|
9
|
+
reverse?: boolean
|
|
10
|
+
class?: HTMLAttributes['class']
|
|
11
|
+
}>()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<section
|
|
16
|
+
:class="[
|
|
17
|
+
'py-16 md:py-24',
|
|
18
|
+
props.class,
|
|
19
|
+
]"
|
|
20
|
+
>
|
|
21
|
+
<div class="container">
|
|
22
|
+
<div
|
|
23
|
+
:class="[
|
|
24
|
+
'flex gap-8 lg:gap-12',
|
|
25
|
+
props.orientation === 'horizontal'
|
|
26
|
+
? props.reverse
|
|
27
|
+
? 'flex-col lg:flex-row-reverse items-center'
|
|
28
|
+
: 'flex-col lg:flex-row items-center'
|
|
29
|
+
: 'flex-col items-center text-center',
|
|
30
|
+
]"
|
|
31
|
+
>
|
|
32
|
+
<!-- Header -->
|
|
33
|
+
<div
|
|
34
|
+
:class="[
|
|
35
|
+
'flex flex-col gap-4',
|
|
36
|
+
props.orientation === 'horizontal' ? 'lg:flex-1' : 'max-w-3xl',
|
|
37
|
+
]"
|
|
38
|
+
>
|
|
39
|
+
<!-- Headline slot -->
|
|
40
|
+
<div v-if="$slots.headline || props.headline">
|
|
41
|
+
<slot name="headline">
|
|
42
|
+
<span class="text-sm font-medium text-primary">
|
|
43
|
+
{{ props.headline }}
|
|
44
|
+
</span>
|
|
45
|
+
</slot>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<!-- Title -->
|
|
49
|
+
<h1
|
|
50
|
+
v-if="$slots.title || props.title"
|
|
51
|
+
class="text-4xl font-bold tracking-tight sm:text-5xl lg:text-6xl"
|
|
52
|
+
>
|
|
53
|
+
<slot name="title">
|
|
54
|
+
{{ props.title }}
|
|
55
|
+
</slot>
|
|
56
|
+
</h1>
|
|
57
|
+
|
|
58
|
+
<!-- Description -->
|
|
59
|
+
<p
|
|
60
|
+
v-if="$slots.description || props.description"
|
|
61
|
+
class="text-lg text-muted-foreground sm:text-xl"
|
|
62
|
+
>
|
|
63
|
+
<slot name="description">
|
|
64
|
+
{{ props.description }}
|
|
65
|
+
</slot>
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
<!-- Links slot -->
|
|
69
|
+
<div
|
|
70
|
+
v-if="$slots.links"
|
|
71
|
+
:class="[
|
|
72
|
+
'flex flex-wrap gap-3 mt-4',
|
|
73
|
+
props.orientation !== 'horizontal' && 'justify-center',
|
|
74
|
+
]"
|
|
75
|
+
>
|
|
76
|
+
<slot name="links" />
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<!-- Default slot (illustration) -->
|
|
81
|
+
<div
|
|
82
|
+
v-if="$slots.default"
|
|
83
|
+
:class="[
|
|
84
|
+
props.orientation === 'horizontal' ? 'lg:flex-1' : 'w-full max-w-2xl',
|
|
85
|
+
]"
|
|
86
|
+
>
|
|
87
|
+
<slot />
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</section>
|
|
92
|
+
</template>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
title?: string
|
|
6
|
+
description?: string
|
|
7
|
+
headline?: string
|
|
8
|
+
orientation?: 'vertical' | 'horizontal'
|
|
9
|
+
reverse?: boolean
|
|
10
|
+
class?: HTMLAttributes['class']
|
|
11
|
+
}>()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<section
|
|
16
|
+
:class="[
|
|
17
|
+
'py-12 md:py-16',
|
|
18
|
+
props.class,
|
|
19
|
+
]"
|
|
20
|
+
>
|
|
21
|
+
<div class="container">
|
|
22
|
+
<div
|
|
23
|
+
:class="[
|
|
24
|
+
'flex gap-8 lg:gap-12',
|
|
25
|
+
props.orientation === 'horizontal'
|
|
26
|
+
? props.reverse
|
|
27
|
+
? 'flex-col lg:flex-row-reverse items-center'
|
|
28
|
+
: 'flex-col lg:flex-row items-center'
|
|
29
|
+
: 'flex-col',
|
|
30
|
+
]"
|
|
31
|
+
>
|
|
32
|
+
<!-- Header -->
|
|
33
|
+
<div
|
|
34
|
+
v-if="$slots.title || $slots.description || $slots.headline || props.title || props.description || props.headline"
|
|
35
|
+
:class="[
|
|
36
|
+
'flex flex-col gap-3',
|
|
37
|
+
props.orientation === 'horizontal' ? 'lg:flex-1' : 'max-w-2xl',
|
|
38
|
+
]"
|
|
39
|
+
>
|
|
40
|
+
<!-- Headline -->
|
|
41
|
+
<div v-if="$slots.headline || props.headline">
|
|
42
|
+
<slot name="headline">
|
|
43
|
+
<span class="text-sm font-medium text-primary uppercase tracking-wide">
|
|
44
|
+
{{ props.headline }}
|
|
45
|
+
</span>
|
|
46
|
+
</slot>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Title -->
|
|
50
|
+
<h2
|
|
51
|
+
v-if="$slots.title || props.title"
|
|
52
|
+
class="text-3xl font-bold tracking-tight sm:text-4xl"
|
|
53
|
+
>
|
|
54
|
+
<slot name="title">
|
|
55
|
+
{{ props.title }}
|
|
56
|
+
</slot>
|
|
57
|
+
</h2>
|
|
58
|
+
|
|
59
|
+
<!-- Description -->
|
|
60
|
+
<p
|
|
61
|
+
v-if="$slots.description || props.description"
|
|
62
|
+
class="text-lg text-muted-foreground"
|
|
63
|
+
>
|
|
64
|
+
<slot name="description">
|
|
65
|
+
{{ props.description }}
|
|
66
|
+
</slot>
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
<!-- Links slot -->
|
|
70
|
+
<div
|
|
71
|
+
v-if="$slots.links"
|
|
72
|
+
class="flex flex-wrap gap-3 mt-2"
|
|
73
|
+
>
|
|
74
|
+
<slot name="links" />
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<!-- Default slot (content/illustration) -->
|
|
79
|
+
<div
|
|
80
|
+
v-if="$slots.default"
|
|
81
|
+
:class="[
|
|
82
|
+
props.orientation === 'horizontal' ? 'lg:flex-1' : 'w-full',
|
|
83
|
+
]"
|
|
84
|
+
>
|
|
85
|
+
<slot />
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</section>
|
|
90
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import Callout from './Callout.vue'
|
|
4
|
+
|
|
5
|
+
defineProps<{
|
|
6
|
+
title?: string
|
|
7
|
+
class?: HTMLAttributes['class']
|
|
8
|
+
}>()
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<template>
|
|
12
|
+
<Callout
|
|
13
|
+
type="warning"
|
|
14
|
+
:title
|
|
15
|
+
:class
|
|
16
|
+
>
|
|
17
|
+
<template
|
|
18
|
+
v-if="$slots.title"
|
|
19
|
+
#title
|
|
20
|
+
>
|
|
21
|
+
<slot name="title" />
|
|
22
|
+
</template>
|
|
23
|
+
<slot />
|
|
24
|
+
</Callout>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineProps<{
|
|
3
|
+
title?: string
|
|
4
|
+
description?: string
|
|
5
|
+
}>()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<div class="space-y-2">
|
|
10
|
+
<h1 class="scroll-m-20 text-4xl font-bold tracking-tight">
|
|
11
|
+
{{ title }}
|
|
12
|
+
</h1>
|
|
13
|
+
<p
|
|
14
|
+
v-if="description"
|
|
15
|
+
class="text-lg text-muted-foreground"
|
|
16
|
+
>
|
|
17
|
+
{{ description }}
|
|
18
|
+
</p>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ChevronLeft, ChevronRight } from 'lucide-vue-next'
|
|
3
|
+
|
|
4
|
+
defineProps<{
|
|
5
|
+
prev?: { path: string, title: string } | null
|
|
6
|
+
next?: { path: string, title: string } | null
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div class="flex flex-row items-center justify-between pt-8">
|
|
12
|
+
<NuxtLink
|
|
13
|
+
v-if="prev"
|
|
14
|
+
:to="prev.path"
|
|
15
|
+
class="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
|
|
16
|
+
>
|
|
17
|
+
<ChevronLeft class="size-4" />
|
|
18
|
+
{{ prev.title }}
|
|
19
|
+
</NuxtLink>
|
|
20
|
+
<div v-else />
|
|
21
|
+
|
|
22
|
+
<NuxtLink
|
|
23
|
+
v-if="next"
|
|
24
|
+
:to="next.path"
|
|
25
|
+
class="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
|
|
26
|
+
>
|
|
27
|
+
{{ next.title }}
|
|
28
|
+
<ChevronRight class="size-4" />
|
|
29
|
+
</NuxtLink>
|
|
30
|
+
</div>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ChevronRight } from 'lucide-vue-next'
|
|
3
|
+
|
|
4
|
+
const { data: navigation } = await useNavigation()
|
|
5
|
+
const route = useRoute()
|
|
6
|
+
|
|
7
|
+
function isActive(path: string) {
|
|
8
|
+
return route.path === path || route.path.startsWith(`${path}/`)
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<nav class="sticky top-20 -ml-2 h-[calc(100vh-5rem)] overflow-y-auto pb-10 pr-4">
|
|
14
|
+
<div class="space-y-4">
|
|
15
|
+
<template
|
|
16
|
+
v-for="section in navigation"
|
|
17
|
+
:key="section.path"
|
|
18
|
+
>
|
|
19
|
+
<!-- Section with children (group) -->
|
|
20
|
+
<div
|
|
21
|
+
v-if="section.children?.length"
|
|
22
|
+
class="space-y-2"
|
|
23
|
+
>
|
|
24
|
+
<h4 class="mb-1 rounded-md px-2 py-1 text-sm font-semibold">
|
|
25
|
+
{{ section.title }}
|
|
26
|
+
</h4>
|
|
27
|
+
<div class="space-y-1">
|
|
28
|
+
<template
|
|
29
|
+
v-for="item in section.children"
|
|
30
|
+
:key="item.path"
|
|
31
|
+
>
|
|
32
|
+
<!-- Nested group -->
|
|
33
|
+
<div
|
|
34
|
+
v-if="item.children?.length"
|
|
35
|
+
class="space-y-1"
|
|
36
|
+
>
|
|
37
|
+
<NuxtLink
|
|
38
|
+
:to="item.path"
|
|
39
|
+
class="flex w-full items-center rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground"
|
|
40
|
+
:class="[
|
|
41
|
+
isActive(item.path)
|
|
42
|
+
? 'bg-accent font-medium text-accent-foreground'
|
|
43
|
+
: 'text-muted-foreground',
|
|
44
|
+
]"
|
|
45
|
+
>
|
|
46
|
+
{{ item.title }}
|
|
47
|
+
<ChevronRight class="ml-auto size-4" />
|
|
48
|
+
</NuxtLink>
|
|
49
|
+
<div class="ml-4 space-y-1 border-l pl-2">
|
|
50
|
+
<NuxtLink
|
|
51
|
+
v-for="child in item.children"
|
|
52
|
+
:key="child.path"
|
|
53
|
+
:to="child.path"
|
|
54
|
+
class="block rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground"
|
|
55
|
+
:class="[
|
|
56
|
+
route.path === child.path
|
|
57
|
+
? 'bg-accent font-medium text-accent-foreground'
|
|
58
|
+
: 'text-muted-foreground',
|
|
59
|
+
]"
|
|
60
|
+
>
|
|
61
|
+
{{ child.title }}
|
|
62
|
+
</NuxtLink>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
<!-- Single item -->
|
|
66
|
+
<NuxtLink
|
|
67
|
+
v-else
|
|
68
|
+
:to="item.path"
|
|
69
|
+
class="block rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground"
|
|
70
|
+
:class="[
|
|
71
|
+
route.path === item.path
|
|
72
|
+
? 'bg-accent font-medium text-accent-foreground'
|
|
73
|
+
: 'text-muted-foreground',
|
|
74
|
+
]"
|
|
75
|
+
>
|
|
76
|
+
{{ item.title }}
|
|
77
|
+
</NuxtLink>
|
|
78
|
+
</template>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<!-- Single item without children -->
|
|
82
|
+
<NuxtLink
|
|
83
|
+
v-else
|
|
84
|
+
:to="section.path"
|
|
85
|
+
class="block rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground"
|
|
86
|
+
:class="[
|
|
87
|
+
route.path === section.path
|
|
88
|
+
? 'bg-accent font-medium text-accent-foreground'
|
|
89
|
+
: 'text-muted-foreground',
|
|
90
|
+
]"
|
|
91
|
+
>
|
|
92
|
+
{{ section.title }}
|
|
93
|
+
</NuxtLink>
|
|
94
|
+
</template>
|
|
95
|
+
</div>
|
|
96
|
+
</nav>
|
|
97
|
+
</template>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
interface TocItem {
|
|
3
|
+
id: string
|
|
4
|
+
text: string
|
|
5
|
+
depth: number
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
toc?: TocItem[]
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const activeId = ref('')
|
|
13
|
+
|
|
14
|
+
onMounted(() => {
|
|
15
|
+
const observer = new IntersectionObserver(
|
|
16
|
+
(entries) => {
|
|
17
|
+
entries.forEach((entry) => {
|
|
18
|
+
if (entry.isIntersecting) {
|
|
19
|
+
activeId.value = entry.target.id
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
rootMargin: '-80px 0px -80% 0px',
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
props.toc?.forEach((item) => {
|
|
29
|
+
const el = document.getElementById(item.id)
|
|
30
|
+
if (el)
|
|
31
|
+
observer.observe(el)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
onUnmounted(() => observer.disconnect())
|
|
35
|
+
})
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<nav
|
|
40
|
+
v-if="toc?.length"
|
|
41
|
+
class="sticky top-20 -ml-2 h-[calc(100vh-5rem)] overflow-y-auto pb-10"
|
|
42
|
+
>
|
|
43
|
+
<p class="mb-4 text-sm font-semibold">
|
|
44
|
+
On this page
|
|
45
|
+
</p>
|
|
46
|
+
<ul class="space-y-2 text-sm">
|
|
47
|
+
<li
|
|
48
|
+
v-for="item in toc"
|
|
49
|
+
:key="item.id"
|
|
50
|
+
:style="{ paddingLeft: `${(item.depth - 2) * 12}px` }"
|
|
51
|
+
>
|
|
52
|
+
<a
|
|
53
|
+
:href="`#${item.id}`"
|
|
54
|
+
class="block py-1 text-muted-foreground transition-colors hover:text-foreground"
|
|
55
|
+
:class="[
|
|
56
|
+
activeId === item.id && 'font-medium text-foreground',
|
|
57
|
+
]"
|
|
58
|
+
>
|
|
59
|
+
{{ item.text }}
|
|
60
|
+
</a>
|
|
61
|
+
</li>
|
|
62
|
+
</ul>
|
|
63
|
+
</nav>
|
|
64
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { AccordionRootEmits, AccordionRootProps } from 'reka-ui'
|
|
3
|
+
import {
|
|
4
|
+
AccordionRoot,
|
|
5
|
+
useForwardPropsEmits,
|
|
6
|
+
} from 'reka-ui'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<AccordionRootProps>()
|
|
9
|
+
const emits = defineEmits<AccordionRootEmits>()
|
|
10
|
+
|
|
11
|
+
const forwarded = useForwardPropsEmits(props, emits)
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<AccordionRoot
|
|
16
|
+
v-slot="slotProps"
|
|
17
|
+
data-slot="accordion"
|
|
18
|
+
v-bind="forwarded"
|
|
19
|
+
>
|
|
20
|
+
<slot v-bind="slotProps" />
|
|
21
|
+
</AccordionRoot>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { AccordionContentProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
5
|
+
import { AccordionContent } from 'reka-ui'
|
|
6
|
+
import { cn } from '~/lib/utils'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<AccordionContentProps & { class?: HTMLAttributes['class'] }>()
|
|
9
|
+
|
|
10
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<AccordionContent
|
|
15
|
+
data-slot="accordion-content"
|
|
16
|
+
v-bind="delegatedProps"
|
|
17
|
+
class="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
|
|
18
|
+
>
|
|
19
|
+
<div :class="cn('pt-0 pb-4', props.class)">
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
22
|
+
</AccordionContent>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { AccordionItemProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
5
|
+
import { AccordionItem, useForwardProps } from 'reka-ui'
|
|
6
|
+
import { cn } from '~/lib/utils'
|
|
7
|
+
|
|
8
|
+
const props = defineProps<AccordionItemProps & { class?: HTMLAttributes['class'] }>()
|
|
9
|
+
|
|
10
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
11
|
+
|
|
12
|
+
const forwardedProps = useForwardProps(delegatedProps)
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<AccordionItem
|
|
17
|
+
v-slot="slotProps"
|
|
18
|
+
data-slot="accordion-item"
|
|
19
|
+
v-bind="forwardedProps"
|
|
20
|
+
:class="cn('border-b last:border-b-0', props.class)"
|
|
21
|
+
>
|
|
22
|
+
<slot v-bind="slotProps" />
|
|
23
|
+
</AccordionItem>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { AccordionTriggerProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import { reactiveOmit } from '@vueuse/core'
|
|
5
|
+
import { ChevronDown } from 'lucide-vue-next'
|
|
6
|
+
import {
|
|
7
|
+
AccordionHeader,
|
|
8
|
+
AccordionTrigger,
|
|
9
|
+
} from 'reka-ui'
|
|
10
|
+
import { cn } from '~/lib/utils'
|
|
11
|
+
|
|
12
|
+
const props = defineProps<AccordionTriggerProps & { class?: HTMLAttributes['class'] }>()
|
|
13
|
+
|
|
14
|
+
const delegatedProps = reactiveOmit(props, 'class')
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<AccordionHeader class="flex">
|
|
19
|
+
<AccordionTrigger
|
|
20
|
+
data-slot="accordion-trigger"
|
|
21
|
+
v-bind="delegatedProps"
|
|
22
|
+
:class="
|
|
23
|
+
cn(
|
|
24
|
+
'focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',
|
|
25
|
+
props.class,
|
|
26
|
+
)
|
|
27
|
+
"
|
|
28
|
+
>
|
|
29
|
+
<slot />
|
|
30
|
+
<slot name="icon">
|
|
31
|
+
<ChevronDown
|
|
32
|
+
class="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200"
|
|
33
|
+
/>
|
|
34
|
+
</slot>
|
|
35
|
+
</AccordionTrigger>
|
|
36
|
+
</AccordionHeader>
|
|
37
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import type { AlertVariants } from '.'
|
|
4
|
+
import { cn } from '~/lib/utils'
|
|
5
|
+
import { alertVariants } from '.'
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
class?: HTMLAttributes['class']
|
|
9
|
+
variant?: AlertVariants['variant']
|
|
10
|
+
}>()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div
|
|
15
|
+
data-slot="alert"
|
|
16
|
+
:class="cn(alertVariants({ variant }), props.class)"
|
|
17
|
+
role="alert"
|
|
18
|
+
>
|
|
19
|
+
<slot />
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { cn } from '~/lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class']
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
data-slot="alert-description"
|
|
13
|
+
:class="cn('text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed', props.class)"
|
|
14
|
+
>
|
|
15
|
+
<slot />
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue'
|
|
3
|
+
import { cn } from '~/lib/utils'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class']
|
|
7
|
+
}>()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
data-slot="alert-title"
|
|
13
|
+
:class="cn('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', props.class)"
|
|
14
|
+
>
|
|
15
|
+
<slot />
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { VariantProps } from 'class-variance-authority'
|
|
2
|
+
import { cva } from 'class-variance-authority'
|
|
3
|
+
|
|
4
|
+
export { default as Alert } from './Alert.vue'
|
|
5
|
+
export { default as AlertDescription } from './AlertDescription.vue'
|
|
6
|
+
export { default as AlertTitle } from './AlertTitle.vue'
|
|
7
|
+
|
|
8
|
+
export const alertVariants = cva(
|
|
9
|
+
'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: 'bg-card text-card-foreground',
|
|
14
|
+
destructive:
|
|
15
|
+
'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90',
|
|
16
|
+
info: 'border-blue-500/50 bg-blue-500/10 text-blue-700 dark:text-blue-300 [&>svg]:text-blue-500',
|
|
17
|
+
warning: 'border-amber-500/50 bg-amber-500/10 text-amber-700 dark:text-amber-300 [&>svg]:text-amber-500',
|
|
18
|
+
success: 'border-emerald-500/50 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300 [&>svg]:text-emerald-500',
|
|
19
|
+
error: 'border-red-500/50 bg-red-500/10 text-red-700 dark:text-red-300 [&>svg]:text-red-500',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: 'default',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
export type AlertVariants = VariantProps<typeof alertVariants>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PrimitiveProps } from 'reka-ui'
|
|
3
|
+
import type { HTMLAttributes } from 'vue'
|
|
4
|
+
import type { ButtonVariants } from '.'
|
|
5
|
+
import { Primitive } from 'reka-ui'
|
|
6
|
+
import { cn } from '~/lib/utils'
|
|
7
|
+
import { buttonVariants } from '.'
|
|
8
|
+
|
|
9
|
+
interface Props extends PrimitiveProps {
|
|
10
|
+
variant?: ButtonVariants['variant']
|
|
11
|
+
size?: ButtonVariants['size']
|
|
12
|
+
class?: HTMLAttributes['class']
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
as: 'button',
|
|
17
|
+
})
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<Primitive
|
|
22
|
+
data-slot="button"
|
|
23
|
+
:as="as"
|
|
24
|
+
:as-child="asChild"
|
|
25
|
+
:class="cn(buttonVariants({ variant, size }), props.class)"
|
|
26
|
+
>
|
|
27
|
+
<slot />
|
|
28
|
+
</Primitive>
|
|
29
|
+
</template>
|