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.
Files changed (120) hide show
  1. package/README.md +63 -0
  2. package/app/app.config.ts +13 -0
  3. package/app/app.vue +17 -0
  4. package/app/assets/css/main.css +367 -0
  5. package/app/components/Icons.ts +163 -0
  6. package/app/components/app/AppFooter.vue +24 -0
  7. package/app/components/app/AppHeader.vue +58 -0
  8. package/app/components/content/BrowserFrame.vue +21 -0
  9. package/app/components/content/Callout.vue +80 -0
  10. package/app/components/content/Caution.vue +25 -0
  11. package/app/components/content/CodeBlockCommand.vue +92 -0
  12. package/app/components/content/CodeCollapsibleWrapper.vue +50 -0
  13. package/app/components/content/CodeTabs.vue +14 -0
  14. package/app/components/content/ComponentPreview.vue +71 -0
  15. package/app/components/content/ComponentsList.vue +24 -0
  16. package/app/components/content/CopyButton.vue +39 -0
  17. package/app/components/content/FeatureCard.vue +25 -0
  18. package/app/components/content/LinkedCard.vue +19 -0
  19. package/app/components/content/Note.vue +25 -0
  20. package/app/components/content/ProseA.vue +18 -0
  21. package/app/components/content/ProseBlockQuote.vue +8 -0
  22. package/app/components/content/ProseCode.vue +8 -0
  23. package/app/components/content/ProseH1.vue +7 -0
  24. package/app/components/content/ProseH2.vue +8 -0
  25. package/app/components/content/ProseH3.vue +9 -0
  26. package/app/components/content/ProseH4.vue +9 -0
  27. package/app/components/content/ProseH5.vue +7 -0
  28. package/app/components/content/ProseH6.vue +7 -0
  29. package/app/components/content/ProseHr.vue +6 -0
  30. package/app/components/content/ProseIcon.vue +32 -0
  31. package/app/components/content/ProseImg.vue +6 -0
  32. package/app/components/content/ProseLi.vue +8 -0
  33. package/app/components/content/ProseOl.vue +8 -0
  34. package/app/components/content/ProseP.vue +14 -0
  35. package/app/components/content/ProsePre.vue +80 -0
  36. package/app/components/content/ProseStrong.vue +8 -0
  37. package/app/components/content/ProseTable.vue +26 -0
  38. package/app/components/content/ProseTd.vue +8 -0
  39. package/app/components/content/ProseTh.vue +8 -0
  40. package/app/components/content/ProseTr.vue +8 -0
  41. package/app/components/content/ProseUl.vue +8 -0
  42. package/app/components/content/Step.vue +18 -0
  43. package/app/components/content/Steps.vue +18 -0
  44. package/app/components/content/Tabs.vue +129 -0
  45. package/app/components/content/TabsItem.vue +26 -0
  46. package/app/components/content/Tip.vue +25 -0
  47. package/app/components/content/UButton.vue +34 -0
  48. package/app/components/content/UColorModeImage.vue +48 -0
  49. package/app/components/content/UPageCard.vue +83 -0
  50. package/app/components/content/UPageGrid.vue +18 -0
  51. package/app/components/content/UPageHero.vue +92 -0
  52. package/app/components/content/UPageSection.vue +90 -0
  53. package/app/components/content/Warning.vue +25 -0
  54. package/app/components/docs/DocsPageHeader.vue +20 -0
  55. package/app/components/docs/DocsPageNav.vue +31 -0
  56. package/app/components/docs/DocsSidebar.vue +97 -0
  57. package/app/components/docs/DocsTableOfContents.vue +64 -0
  58. package/app/components/ui/accordion/Accordion.vue +22 -0
  59. package/app/components/ui/accordion/AccordionContent.vue +23 -0
  60. package/app/components/ui/accordion/AccordionItem.vue +24 -0
  61. package/app/components/ui/accordion/AccordionTrigger.vue +37 -0
  62. package/app/components/ui/accordion/index.ts +4 -0
  63. package/app/components/ui/alert/Alert.vue +21 -0
  64. package/app/components/ui/alert/AlertDescription.vue +17 -0
  65. package/app/components/ui/alert/AlertTitle.vue +17 -0
  66. package/app/components/ui/alert/index.ts +28 -0
  67. package/app/components/ui/button/Button.vue +29 -0
  68. package/app/components/ui/button/index.ts +38 -0
  69. package/app/components/ui/card/Card.vue +22 -0
  70. package/app/components/ui/card/CardAction.vue +17 -0
  71. package/app/components/ui/card/CardContent.vue +17 -0
  72. package/app/components/ui/card/CardDescription.vue +17 -0
  73. package/app/components/ui/card/CardFooter.vue +17 -0
  74. package/app/components/ui/card/CardHeader.vue +17 -0
  75. package/app/components/ui/card/CardTitle.vue +17 -0
  76. package/app/components/ui/card/index.ts +7 -0
  77. package/app/components/ui/collapsible/Collapsible.vue +19 -0
  78. package/app/components/ui/collapsible/CollapsibleContent.vue +15 -0
  79. package/app/components/ui/collapsible/CollapsibleTrigger.vue +15 -0
  80. package/app/components/ui/collapsible/index.ts +3 -0
  81. package/app/components/ui/separator/Separator.vue +29 -0
  82. package/app/components/ui/separator/index.ts +1 -0
  83. package/app/components/ui/switch/Switch.vue +35 -0
  84. package/app/components/ui/switch/index.ts +1 -0
  85. package/app/components/ui/table/Table.vue +16 -0
  86. package/app/components/ui/table/TableBody.vue +14 -0
  87. package/app/components/ui/table/TableCaption.vue +14 -0
  88. package/app/components/ui/table/TableCell.vue +21 -0
  89. package/app/components/ui/table/TableEmpty.vue +34 -0
  90. package/app/components/ui/table/TableFooter.vue +14 -0
  91. package/app/components/ui/table/TableHead.vue +14 -0
  92. package/app/components/ui/table/TableHeader.vue +14 -0
  93. package/app/components/ui/table/TableRow.vue +14 -0
  94. package/app/components/ui/table/index.ts +9 -0
  95. package/app/components/ui/tabs/Tabs.vue +15 -0
  96. package/app/components/ui/tabs/TabsContent.vue +20 -0
  97. package/app/components/ui/tabs/TabsList.vue +23 -0
  98. package/app/components/ui/tabs/TabsTrigger.vue +27 -0
  99. package/app/components/ui/tabs/index.ts +4 -0
  100. package/app/components/ui/tooltip/Tooltip.vue +19 -0
  101. package/app/components/ui/tooltip/TooltipContent.vue +34 -0
  102. package/app/components/ui/tooltip/TooltipProvider.vue +14 -0
  103. package/app/components/ui/tooltip/TooltipTrigger.vue +15 -0
  104. package/app/components/ui/tooltip/index.ts +4 -0
  105. package/app/composables/useConfig.ts +24 -0
  106. package/app/composables/useNavigation.ts +43 -0
  107. package/app/layouts/default.vue +12 -0
  108. package/app/layouts/docs.vue +27 -0
  109. package/app/lib/utils.ts +7 -0
  110. package/app/pages/[...slug].vue +97 -0
  111. package/app/pages/index.vue +29 -0
  112. package/app/plugins/ssr-width.ts +5 -0
  113. package/content.config.ts +36 -0
  114. package/i18n/locales/en.json +14 -0
  115. package/modules/config.ts +38 -0
  116. package/modules/css.ts +38 -0
  117. package/modules/shadcn.ts +116 -0
  118. package/nuxt.config.ts +125 -0
  119. package/nuxt.schema.ts +68 -0
  120. 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,4 @@
1
+ export { default as Accordion } from './Accordion.vue'
2
+ export { default as AccordionContent } from './AccordionContent.vue'
3
+ export { default as AccordionItem } from './AccordionItem.vue'
4
+ export { default as AccordionTrigger } from './AccordionTrigger.vue'
@@ -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>