livemark 0.23.0 → 0.24.1
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/.agents/skills/change-review/SKILL.md +47 -0
- package/{skills/configuration → .agents/skills/livemark-configuration}/SKILL.md +2 -4
- package/build/actions/changelog/build.d.ts +21 -9
- package/build/actions/changelog/build.js +31 -23
- package/build/actions/changelog/build.unit.js +156 -2
- package/build/actions/config/load.js +1 -1
- package/build/actions/config/load.unit.js +1 -1
- package/build/actions/target/build.js +2 -5
- package/build/commands/build.js +1 -1
- package/build/commands/escape.js +1 -1
- package/build/commands/preview.js +1 -1
- package/build/commands/start.js +1 -1
- package/build/components/Abbr.js +2 -2
- package/build/components/Article.js +2 -2
- package/build/components/BlogIndex.js +2 -4
- package/build/components/Callout.js +2 -2
- package/build/components/ChangelogIndex.js +1 -1
- package/build/components/CodeBlock.js +3 -5
- package/build/components/CodeTabs.js +1 -1
- package/build/components/Columns.js +2 -4
- package/build/components/Content.js +2 -2
- package/build/components/ContentTab.js +1 -1
- package/build/components/ContentTabs.js +1 -1
- package/build/components/DefinitionList.js +1 -1
- package/build/components/FileTree.js +1 -1
- package/build/components/FootnoteRef.js +2 -2
- package/build/components/InlineToc.js +1 -1
- package/build/components/Layout.js +1 -1
- package/build/components/LinkButton.js +2 -2
- package/build/components/Mermaid.js +1 -1
- package/build/components/PackageTabs.js +2 -2
- package/build/components/PageToolbar.js +2 -2
- package/build/components/PrevNext.js +3 -7
- package/build/components/SearchDialog.js +1 -1
- package/build/components/Section.js +2 -2
- package/build/components/SectionHeader.js +2 -2
- package/build/components/Sidebar.js +2 -2
- package/build/components/SidebarArticles.js +2 -2
- package/build/components/SidebarLinks.js +2 -2
- package/build/components/TagIndex.js +2 -4
- package/build/components/Toc.js +1 -1
- package/build/content/article.js +1 -1
- package/build/content-collections.js +6 -7
- package/build/elements/accordion.js +2 -2
- package/build/elements/alert-dialog.js +5 -5
- package/build/elements/alert.js +2 -2
- package/build/elements/aspect-ratio.js +2 -2
- package/build/elements/avatar.d.ts +1 -1
- package/build/elements/avatar.js +3 -3
- package/build/elements/badge.js +2 -2
- package/build/elements/breadcrumb.js +2 -2
- package/build/elements/button-group.d.ts +1 -1
- package/build/elements/button-group.js +3 -3
- package/build/elements/button.js +2 -2
- package/build/elements/calendar.js +5 -5
- package/build/elements/card.js +2 -2
- package/build/elements/carousel.js +2 -2
- package/build/elements/chart.js +5 -15
- package/build/elements/checkbox.js +2 -2
- package/build/elements/collapsible.js +3 -3
- package/build/elements/command.js +2 -2
- package/build/elements/context-menu.js +5 -5
- package/build/elements/dialog.js +2 -2
- package/build/elements/direction.d.ts +1 -1
- package/build/elements/direction.js +2 -2
- package/build/elements/drawer.js +2 -2
- package/build/elements/dropdown-menu.js +3 -3
- package/build/elements/empty.d.ts +1 -1
- package/build/elements/empty.js +3 -3
- package/build/elements/field.js +2 -2
- package/build/elements/hover-card.js +3 -3
- package/build/elements/input-group.js +2 -2
- package/build/elements/input-otp.js +2 -2
- package/build/elements/input.js +2 -2
- package/build/elements/item.js +2 -2
- package/build/elements/kbd.js +2 -2
- package/build/elements/label.js +2 -2
- package/build/elements/menubar.js +2 -2
- package/build/elements/native-select.js +2 -2
- package/build/elements/navigation-menu.js +2 -2
- package/build/elements/pagination.js +3 -3
- package/build/elements/popover.js +2 -2
- package/build/elements/progress.d.ts +1 -1
- package/build/elements/progress.js +3 -3
- package/build/elements/radio-group.js +2 -2
- package/build/elements/resizable.js +3 -3
- package/build/elements/scroll-area.js +2 -2
- package/build/elements/select.js +2 -2
- package/build/elements/separator.js +2 -2
- package/build/elements/sheet.js +2 -2
- package/build/elements/sidebar.js +3 -4
- package/build/elements/skeleton.js +2 -2
- package/build/elements/slider.js +2 -2
- package/build/elements/spinner.js +2 -2
- package/build/elements/switch.js +2 -2
- package/build/elements/table.js +2 -2
- package/build/elements/tabs.js +2 -2
- package/build/elements/textarea.js +2 -2
- package/build/elements/toggle-group.js +2 -2
- package/build/elements/toggle.js +2 -2
- package/build/elements/tooltip.js +2 -2
- package/build/helpers/changelog-source.js +1 -1
- package/build/helpers/dynamic-icon-resolver.js +1 -1
- package/build/helpers/resolve-asset-path.unit.js +1 -1
- package/build/helpers/resolve-base.unit.js +2 -2
- package/build/helpers/resolve-includes.js +2 -2
- package/build/helpers/resolve-includes.unit.js +1 -1
- package/build/helpers/rss.js +2 -4
- package/build/helpers/rss.unit.js +1 -1
- package/build/helpers/section.js +2 -3
- package/build/helpers/section.unit.js +4 -13
- package/build/helpers/toc.unit.js +2 -4
- package/build/plugins/rehype-inline-code.js +2 -2
- package/build/plugins/rehype-task-list-a11y.js +1 -1
- package/build/plugins/remark-abbr.js +2 -4
- package/build/plugins/remark-ansi.js +2 -4
- package/build/plugins/remark-ansi.unit.js +1 -1
- package/build/plugins/remark-badge.js +2 -4
- package/build/plugins/remark-button.unit.js +1 -1
- package/build/plugins/remark-callout.js +1 -1
- package/build/plugins/remark-card.js +1 -1
- package/build/plugins/remark-code-tabs.js +4 -8
- package/build/plugins/remark-columns.js +1 -1
- package/build/plugins/remark-custom-heading-id.unit.js +1 -1
- package/build/plugins/remark-deflist.js +1 -1
- package/build/plugins/remark-details.js +2 -4
- package/build/plugins/remark-filetree.js +1 -1
- package/build/plugins/remark-filetree.unit.js +1 -1
- package/build/plugins/remark-media.js +3 -7
- package/build/plugins/remark-media.unit.js +1 -1
- package/build/plugins/remark-steps.unit.js +1 -1
- package/build/plugins/remark-tab.js +4 -2
- package/build/plugins/remark-tab.unit.js +3 -7
- package/build/plugins/remark-toc.unit.js +1 -1
- package/build/plugins/shiki-icon.js +1 -1
- package/build/plugins/shiki-line-highlight.js +1 -1
- package/build/plugins/vite-livemark.js +1 -1
- package/build/plugins/vite-robots.js +1 -1
- package/build/plugins/vite-robots.unit.js +1 -1
- package/build/routes/$.js +1 -1
- package/build/vite.config.js +3 -8
- package/package.json +17 -19
- package/source/actions/changelog/build.ts +32 -35
- package/source/actions/changelog/build.unit.ts +191 -1
- package/source/actions/config/load.ts +1 -3
- package/source/actions/config/load.unit.ts +2 -7
- package/source/actions/target/build.ts +1 -4
- package/source/commands/build.ts +1 -7
- package/source/commands/escape.ts +3 -8
- package/source/commands/preview.ts +1 -7
- package/source/commands/start.ts +1 -7
- package/source/components/Abbr.tsx +1 -5
- package/source/components/Article.tsx +1 -5
- package/source/components/BlogIndex.tsx +3 -9
- package/source/components/Callout.tsx +2 -7
- package/source/components/ChangelogIndex.tsx +1 -3
- package/source/components/CodeBlock.tsx +4 -14
- package/source/components/CodeTabs.tsx +1 -3
- package/source/components/Columns.tsx +1 -3
- package/source/components/Content.tsx +1 -5
- package/source/components/ContentTab.tsx +1 -4
- package/source/components/ContentTabs.tsx +3 -10
- package/source/components/DefinitionList.tsx +1 -4
- package/source/components/FileTree.tsx +1 -5
- package/source/components/FootnoteRef.tsx +1 -5
- package/source/components/InlineToc.tsx +1 -4
- package/source/components/Layout.tsx +3 -10
- package/source/components/LinkButton.tsx +2 -8
- package/source/components/Mermaid.tsx +1 -3
- package/source/components/PackageTabs.tsx +1 -5
- package/source/components/PageToolbar.tsx +1 -5
- package/source/components/PrevNext.tsx +2 -6
- package/source/components/SearchDialog.tsx +2 -6
- package/source/components/Section.tsx +1 -1
- package/source/components/SectionHeader.tsx +2 -8
- package/source/components/Sidebar.tsx +2 -7
- package/source/components/SidebarArticles.tsx +4 -20
- package/source/components/SidebarLinks.tsx +2 -6
- package/source/components/TagIndex.tsx +3 -9
- package/source/components/Toc.tsx +2 -7
- package/source/content/article.ts +1 -2
- package/source/content-collections.ts +6 -8
- package/source/elements/accordion.tsx +1 -1
- package/source/elements/alert-dialog.tsx +8 -30
- package/source/elements/alert.tsx +2 -5
- package/source/elements/aspect-ratio.tsx +1 -1
- package/source/elements/avatar.tsx +5 -21
- package/source/elements/badge.tsx +3 -5
- package/source/elements/breadcrumb.tsx +4 -14
- package/source/elements/button-group.tsx +2 -7
- package/source/elements/button.tsx +1 -1
- package/source/elements/calendar.tsx +7 -24
- package/source/elements/card.tsx +1 -1
- package/source/elements/carousel.tsx +4 -11
- package/source/elements/chart.tsx +9 -34
- package/source/elements/checkbox.tsx +1 -1
- package/source/elements/collapsible.tsx +2 -6
- package/source/elements/command.tsx +4 -13
- package/source/elements/context-menu.tsx +8 -25
- package/source/elements/dialog.tsx +4 -14
- package/source/elements/direction.tsx +1 -4
- package/source/elements/drawer.tsx +4 -10
- package/source/elements/dropdown-menu.tsx +5 -19
- package/source/elements/empty.tsx +3 -13
- package/source/elements/field.tsx +3 -7
- package/source/elements/hover-card.tsx +2 -4
- package/source/elements/input-group.tsx +15 -28
- package/source/elements/input-otp.tsx +1 -1
- package/source/elements/input.tsx +1 -1
- package/source/elements/item.tsx +4 -13
- package/source/elements/kbd.tsx +1 -1
- package/source/elements/label.tsx +1 -1
- package/source/elements/menubar.tsx +5 -14
- package/source/elements/native-select.tsx +4 -15
- package/source/elements/navigation-menu.tsx +2 -5
- package/source/elements/pagination.tsx +4 -14
- package/source/elements/popover.tsx +2 -5
- package/source/elements/progress.tsx +4 -16
- package/source/elements/radio-group.tsx +1 -1
- package/source/elements/resizable.tsx +4 -12
- package/source/elements/scroll-area.tsx +2 -6
- package/source/elements/select.tsx +4 -14
- package/source/elements/separator.tsx +1 -1
- package/source/elements/sheet.tsx +3 -10
- package/source/elements/sidebar.tsx +7 -25
- package/source/elements/skeleton.tsx +1 -1
- package/source/elements/slider.tsx +1 -1
- package/source/elements/spinner.tsx +1 -1
- package/source/elements/switch.tsx +1 -1
- package/source/elements/table.tsx +4 -13
- package/source/elements/tabs.tsx +1 -1
- package/source/elements/textarea.tsx +1 -1
- package/source/elements/toggle-group.tsx +2 -4
- package/source/elements/toggle.tsx +1 -1
- package/source/elements/tooltip.tsx +3 -10
- package/source/helpers/changelog-source.ts +1 -3
- package/source/helpers/dynamic-icon-resolver.tsx +1 -4
- package/source/helpers/resolve-asset-path.unit.ts +6 -12
- package/source/helpers/resolve-base.unit.ts +1 -2
- package/source/helpers/resolve-includes.ts +2 -8
- package/source/helpers/resolve-includes.unit.ts +9 -36
- package/source/helpers/rss.ts +3 -9
- package/source/helpers/rss.unit.ts +1 -3
- package/source/helpers/section.ts +1 -4
- package/source/helpers/section.unit.ts +5 -18
- package/source/helpers/toc.unit.ts +1 -3
- package/source/plugins/rehype-inline-code.ts +5 -21
- package/source/plugins/rehype-task-list-a11y.ts +1 -2
- package/source/plugins/remark-abbr.ts +1 -3
- package/source/plugins/remark-ansi.ts +2 -5
- package/source/plugins/remark-ansi.unit.ts +6 -18
- package/source/plugins/remark-badge.ts +1 -3
- package/source/plugins/remark-button.unit.ts +3 -9
- package/source/plugins/remark-callout.ts +35 -40
- package/source/plugins/remark-card.ts +25 -29
- package/source/plugins/remark-code-tabs.ts +3 -7
- package/source/plugins/remark-columns.ts +13 -17
- package/source/plugins/remark-custom-heading-id.unit.ts +2 -6
- package/source/plugins/remark-deflist.ts +1 -2
- package/source/plugins/remark-details.ts +28 -34
- package/source/plugins/remark-filetree.ts +28 -34
- package/source/plugins/remark-filetree.unit.ts +1 -4
- package/source/plugins/remark-media.ts +2 -6
- package/source/plugins/remark-media.unit.ts +2 -6
- package/source/plugins/remark-steps.unit.ts +2 -7
- package/source/plugins/remark-tab.ts +26 -30
- package/source/plugins/remark-tab.unit.ts +2 -6
- package/source/plugins/remark-toc.unit.ts +1 -3
- package/source/plugins/shiki-icon.ts +1 -4
- package/source/plugins/shiki-line-highlight.ts +4 -11
- package/source/plugins/vite-livemark.ts +3 -10
- package/source/plugins/vite-robots.ts +1 -6
- package/source/plugins/vite-robots.unit.ts +1 -3
- package/source/routes/$.tsx +1 -3
- package/source/styles/general.css +1 -5
- package/source/vite.config.ts +2 -7
- package/build/utils/style.d.ts +0 -2
- package/build/utils/style.js +0 -6
- package/source/utils/style.ts +0 -6
- /package/{skills/authoring → .agents/skills/livemark-authoring}/SKILL.md +0 -0
- /package/{skills/customization → .agents/skills/livemark-customization}/SKILL.md +0 -0
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { Check, ChevronDown, Clipboard, WrapText } from "lucide-react"
|
|
2
2
|
import { useRef, useState } from "react"
|
|
3
|
-
import {
|
|
4
|
-
Tooltip,
|
|
5
|
-
TooltipContent,
|
|
6
|
-
TooltipTrigger,
|
|
7
|
-
} from "../elements/tooltip.tsx"
|
|
3
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../elements/tooltip.tsx"
|
|
8
4
|
|
|
9
5
|
export function CodeBlock(props: React.ComponentProps<"pre">) {
|
|
10
6
|
const [copied, setCopied] = useState(false)
|
|
@@ -17,9 +13,7 @@ export function CodeBlock(props: React.ComponentProps<"pre">) {
|
|
|
17
13
|
const maxLines = meta?.match(/maxLines=(\d+)/)?.[1]
|
|
18
14
|
const icon = extra.icon as string | undefined
|
|
19
15
|
const style = props.style as Record<string, string> | undefined
|
|
20
|
-
const collapsedHeight = maxLines
|
|
21
|
-
? `${Number(maxLines) * 1.5 + 1.75}rem`
|
|
22
|
-
: undefined
|
|
16
|
+
const collapsedHeight = maxLines ? `${Number(maxLines) * 1.5 + 1.75}rem` : undefined
|
|
23
17
|
|
|
24
18
|
const handleCopy = () => {
|
|
25
19
|
const text = preRef.current?.textContent ?? ""
|
|
@@ -54,9 +48,7 @@ export function CodeBlock(props: React.ComponentProps<"pre">) {
|
|
|
54
48
|
>
|
|
55
49
|
<WrapText className="size-3.5" />
|
|
56
50
|
</TooltipTrigger>
|
|
57
|
-
<TooltipContent>
|
|
58
|
-
{wrap ? "Disable wrap" : "Enable wrap"}
|
|
59
|
-
</TooltipContent>
|
|
51
|
+
<TooltipContent>{wrap ? "Disable wrap" : "Enable wrap"}</TooltipContent>
|
|
60
52
|
</Tooltip>
|
|
61
53
|
<Tooltip>
|
|
62
54
|
<TooltipTrigger
|
|
@@ -83,9 +75,7 @@ export function CodeBlock(props: React.ComponentProps<"pre">) {
|
|
|
83
75
|
>
|
|
84
76
|
<WrapText className="size-3.5" />
|
|
85
77
|
</TooltipTrigger>
|
|
86
|
-
<TooltipContent>
|
|
87
|
-
{wrap ? "Disable wrap" : "Enable wrap"}
|
|
88
|
-
</TooltipContent>
|
|
78
|
+
<TooltipContent>{wrap ? "Disable wrap" : "Enable wrap"}</TooltipContent>
|
|
89
79
|
</Tooltip>
|
|
90
80
|
<Tooltip>
|
|
91
81
|
<TooltipTrigger
|
|
@@ -37,9 +37,7 @@ export function CodeTabs(props: {
|
|
|
37
37
|
useEffect(() => {
|
|
38
38
|
if (!props.sync) return
|
|
39
39
|
const handler = (e: Event) => {
|
|
40
|
-
const { sync, title } = (
|
|
41
|
-
e as CustomEvent<{ sync: string; title: string }>
|
|
42
|
-
).detail
|
|
40
|
+
const { sync, title } = (e as CustomEvent<{ sync: string; title: string }>).detail
|
|
43
41
|
if (sync !== props.sync) return
|
|
44
42
|
const idx = names.indexOf(title)
|
|
45
43
|
if (idx >= 0) setActive(idx)
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/** Grid layout for arranging content side by side */
|
|
2
2
|
export function Columns(props: { cols?: string; children: React.ReactNode }) {
|
|
3
3
|
const cols = props.cols ? parseInt(props.cols, 10) : undefined
|
|
4
|
-
const style = cols
|
|
5
|
-
? { gridTemplateColumns: `repeat(${cols}, 1fr)` }
|
|
6
|
-
: undefined
|
|
4
|
+
const style = cols ? { gridTemplateColumns: `repeat(${cols}, 1fr)` } : undefined
|
|
7
5
|
return (
|
|
8
6
|
<div className="grid gap-6 my-4 sm:grid-cols-2" style={style}>
|
|
9
7
|
{props.children}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
/** Simple wrapper that provides a title prop for ContentTabs to read */
|
|
2
|
-
export function ContentTab(props: {
|
|
3
|
-
title: string
|
|
4
|
-
children: React.ReactNode
|
|
5
|
-
}) {
|
|
2
|
+
export function ContentTab(props: { title: string; children: React.ReactNode }) {
|
|
6
3
|
return <div>{props.children}</div>
|
|
7
4
|
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import { Children, isValidElement, useEffect, useState } from "react"
|
|
2
2
|
|
|
3
3
|
/** Tabbed container component for grouping content tabs with optional sync across groups */
|
|
4
|
-
export function ContentTabs(props: {
|
|
5
|
-
sync?: string
|
|
6
|
-
children: React.ReactNode
|
|
7
|
-
}) {
|
|
4
|
+
export function ContentTabs(props: { sync?: string; children: React.ReactNode }) {
|
|
8
5
|
const children = Children.toArray(props.children)
|
|
9
6
|
const titles = children.map(child =>
|
|
10
7
|
isValidElement<{ title: string }>(child) ? child.props.title : "",
|
|
@@ -38,9 +35,7 @@ export function ContentTabs(props: {
|
|
|
38
35
|
useEffect(() => {
|
|
39
36
|
if (!props.sync) return
|
|
40
37
|
const handler = (e: Event) => {
|
|
41
|
-
const { sync, title } = (
|
|
42
|
-
e as CustomEvent<{ sync: string; title: string }>
|
|
43
|
-
).detail
|
|
38
|
+
const { sync, title } = (e as CustomEvent<{ sync: string; title: string }>).detail
|
|
44
39
|
if (sync !== props.sync) return
|
|
45
40
|
const idx = titles.indexOf(title)
|
|
46
41
|
if (idx >= 0) setActive(idx)
|
|
@@ -70,9 +65,7 @@ export function ContentTabs(props: {
|
|
|
70
65
|
{children.map((child, i) => (
|
|
71
66
|
<div
|
|
72
67
|
key={titles[i]}
|
|
73
|
-
className={
|
|
74
|
-
i === active ? "p-4 prose dark:prose-invert max-w-none" : "hidden"
|
|
75
|
-
}
|
|
68
|
+
className={i === active ? "p-4 prose dark:prose-invert max-w-none" : "hidden"}
|
|
76
69
|
>
|
|
77
70
|
{child}
|
|
78
71
|
</div>
|
|
@@ -13,9 +13,6 @@ export function DefinitionTerm(props: ComponentProps<"dt">) {
|
|
|
13
13
|
/** Styled definition detail with a left border accent */
|
|
14
14
|
export function DefinitionDetail(props: ComponentProps<"dd">) {
|
|
15
15
|
return (
|
|
16
|
-
<dd
|
|
17
|
-
{...props}
|
|
18
|
-
className="ml-0 pl-4 border-l-2 border-border text-muted-foreground"
|
|
19
|
-
/>
|
|
16
|
+
<dd {...props} className="ml-0 pl-4 border-l-2 border-border text-muted-foreground" />
|
|
20
17
|
)
|
|
21
18
|
}
|
|
@@ -21,11 +21,7 @@ function TreeItems(props: { items: TreeItem[]; depth: number }) {
|
|
|
21
21
|
return (
|
|
22
22
|
<ul className={props.depth > 0 ? "ml-4 border-l border-border pl-2" : ""}>
|
|
23
23
|
{props.items.map((item, index) => (
|
|
24
|
-
<TreeNode
|
|
25
|
-
key={`${item.name}-${index}`}
|
|
26
|
-
item={item}
|
|
27
|
-
depth={props.depth}
|
|
28
|
-
/>
|
|
24
|
+
<TreeNode key={`${item.name}-${index}`} item={item} depth={props.depth} />
|
|
29
25
|
))}
|
|
30
26
|
</ul>
|
|
31
27
|
)
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { type ComponentProps, useEffect, useState } from "react"
|
|
2
|
-
import {
|
|
3
|
-
HoverCard,
|
|
4
|
-
HoverCardContent,
|
|
5
|
-
HoverCardTrigger,
|
|
6
|
-
} from "../elements/hover-card.tsx"
|
|
2
|
+
import { HoverCard, HoverCardContent, HoverCardTrigger } from "../elements/hover-card.tsx"
|
|
7
3
|
|
|
8
4
|
const FOOTNOTE_PREFIX = "#user-content-fn-"
|
|
9
5
|
|
|
@@ -13,10 +13,7 @@ export function InlineToc(props: { maxLevel?: string }) {
|
|
|
13
13
|
<p className="text-base font-semibold mb-4">Table of Contents</p>
|
|
14
14
|
<ul className="text-base space-y-2.5">
|
|
15
15
|
{items.map(item => (
|
|
16
|
-
<li
|
|
17
|
-
key={item.url}
|
|
18
|
-
style={{ paddingLeft: `${(item.depth - 2) * 1.25}rem` }}
|
|
19
|
-
>
|
|
16
|
+
<li key={item.url} style={{ paddingLeft: `${(item.depth - 2) * 1.25}rem` }}>
|
|
20
17
|
<a
|
|
21
18
|
href={item.url}
|
|
22
19
|
className="text-muted-foreground hover:text-primary transition-colors"
|
|
@@ -26,10 +26,7 @@ function splatFor(pathname: string) {
|
|
|
26
26
|
return { _splat: pathname.replace(/^\/|\/$/g, "") }
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export function Layout(props: {
|
|
30
|
-
withSidebar?: boolean
|
|
31
|
-
children?: React.ReactNode
|
|
32
|
-
}) {
|
|
29
|
+
export function Layout(props: { withSidebar?: boolean; children?: React.ReactNode }) {
|
|
33
30
|
const pathname = useLocation({ select: l => l.pathname })
|
|
34
31
|
const articleRoute = useMatch({ from: "/$", shouldThrow: false })
|
|
35
32
|
const activeSection = articleRoute
|
|
@@ -56,10 +53,7 @@ export function Layout(props: {
|
|
|
56
53
|
<div className="hidden lg:flex">
|
|
57
54
|
<SidebarTrigger />
|
|
58
55
|
</div>
|
|
59
|
-
<SiteLink
|
|
60
|
-
to={siteLinkTarget}
|
|
61
|
-
className="lg:hidden flex items-center gap-2"
|
|
62
|
-
>
|
|
56
|
+
<SiteLink to={siteLinkTarget} className="lg:hidden flex items-center gap-2">
|
|
63
57
|
<SiteTitle />
|
|
64
58
|
</SiteLink>
|
|
65
59
|
</>
|
|
@@ -100,8 +94,7 @@ export function Layout(props: {
|
|
|
100
94
|
const latestVersion =
|
|
101
95
|
section.type === "changelog" && section.version
|
|
102
96
|
? sortedArticles.find(
|
|
103
|
-
a =>
|
|
104
|
-
a.path === sectionFlatArticles.get(section.prefix)?.[0],
|
|
97
|
+
a => a.path === sectionFlatArticles.get(section.prefix)?.[0],
|
|
105
98
|
)?.title
|
|
106
99
|
: undefined
|
|
107
100
|
return (
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { buttonVariants } from "../elements/button.tsx"
|
|
2
|
-
import { cn } from "
|
|
2
|
+
import { cn } from "cn"
|
|
3
3
|
|
|
4
4
|
/** Styled link button rendered from ::button leaf directives */
|
|
5
5
|
export function LinkButton(props: {
|
|
6
6
|
href: string
|
|
7
7
|
label: string
|
|
8
|
-
variant?:
|
|
9
|
-
| "default"
|
|
10
|
-
| "outline"
|
|
11
|
-
| "secondary"
|
|
12
|
-
| "ghost"
|
|
13
|
-
| "destructive"
|
|
14
|
-
| "link"
|
|
8
|
+
variant?: "default" | "outline" | "secondary" | "ghost" | "destructive" | "link"
|
|
15
9
|
size?: "default" | "sm" | "lg"
|
|
16
10
|
}) {
|
|
17
11
|
return (
|
|
@@ -7,9 +7,7 @@ export function Mermaid(props: { children: string }) {
|
|
|
7
7
|
return (
|
|
8
8
|
<Suspense
|
|
9
9
|
fallback={
|
|
10
|
-
<div className="not-prose mermaid flex justify-center">
|
|
11
|
-
Loading diagram…
|
|
12
|
-
</div>
|
|
10
|
+
<div className="not-prose mermaid flex justify-center">Loading diagram…</div>
|
|
13
11
|
}
|
|
14
12
|
>
|
|
15
13
|
<MermaidRenderer>{props.children}</MermaidRenderer>
|
|
@@ -55,11 +55,7 @@ export function PackageTabs(props: PackageTabsProps) {
|
|
|
55
55
|
className="me-2 p-1 rounded-md text-muted-foreground hover:text-foreground transition-colors"
|
|
56
56
|
aria-label="Copy code"
|
|
57
57
|
>
|
|
58
|
-
{copied ?
|
|
59
|
-
<Check className="size-3.5" />
|
|
60
|
-
) : (
|
|
61
|
-
<Clipboard className="size-3.5" />
|
|
62
|
-
)}
|
|
58
|
+
{copied ? <Check className="size-3.5" /> : <Clipboard className="size-3.5" />}
|
|
63
59
|
</button>
|
|
64
60
|
</div>
|
|
65
61
|
<div className="text-[0.8125rem] py-3.5 overflow-auto max-h-[600px]">
|
|
@@ -59,11 +59,7 @@ export function PageToolbar(props: {
|
|
|
59
59
|
</span>
|
|
60
60
|
)}
|
|
61
61
|
<button type="button" onClick={handleCopy} className={buttonClass}>
|
|
62
|
-
{copied ?
|
|
63
|
-
<Check className="size-3.5" />
|
|
64
|
-
) : (
|
|
65
|
-
<Copy className="size-3.5" />
|
|
66
|
-
)}
|
|
62
|
+
{copied ? <Check className="size-3.5" /> : <Copy className="size-3.5" />}
|
|
67
63
|
Copy Markdown
|
|
68
64
|
</button>
|
|
69
65
|
<button
|
|
@@ -18,12 +18,8 @@ export function PrevNext(props: { path: string }) {
|
|
|
18
18
|
|
|
19
19
|
const prevPath = index > 0 ? flat[index - 1] : undefined
|
|
20
20
|
const nextPath = index < flat.length - 1 ? flat[index + 1] : undefined
|
|
21
|
-
const prev = prevPath
|
|
22
|
-
|
|
23
|
-
: undefined
|
|
24
|
-
const next = nextPath
|
|
25
|
-
? sortedArticles.find(a => a.path === nextPath)
|
|
26
|
-
: undefined
|
|
21
|
+
const prev = prevPath ? sortedArticles.find(a => a.path === prevPath) : undefined
|
|
22
|
+
const next = nextPath ? sortedArticles.find(a => a.path === nextPath) : undefined
|
|
27
23
|
|
|
28
24
|
if (!prev && !next) return null
|
|
29
25
|
|
|
@@ -80,9 +80,7 @@ export function SearchDialog(props: {
|
|
|
80
80
|
})
|
|
81
81
|
setResults(
|
|
82
82
|
hits.hits.map(hit => {
|
|
83
|
-
const article = sortedArticles.find(
|
|
84
|
-
a => a.title === hit.document.title,
|
|
85
|
-
)
|
|
83
|
+
const article = sortedArticles.find(a => a.title === hit.document.title)
|
|
86
84
|
if (!article)
|
|
87
85
|
return toResult(
|
|
88
86
|
{
|
|
@@ -161,9 +159,7 @@ export function SearchDialog(props: {
|
|
|
161
159
|
<Icon className="size-5 shrink-0 mt-0.5 self-start opacity-60" />
|
|
162
160
|
)}
|
|
163
161
|
<div className="flex flex-col gap-0.5 min-w-0">
|
|
164
|
-
<span className="text-base font-medium">
|
|
165
|
-
{result.title}
|
|
166
|
-
</span>
|
|
162
|
+
<span className="text-base font-medium">{result.title}</span>
|
|
167
163
|
{result.snippet && (
|
|
168
164
|
<span className="text-sm text-muted-foreground line-clamp-1">
|
|
169
165
|
<HighlightedText text={result.snippet} term={query} />
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from "
|
|
1
|
+
import { cn } from "cn"
|
|
2
2
|
|
|
3
3
|
export function SectionHeader(props: {
|
|
4
4
|
label?: string
|
|
@@ -10,13 +10,7 @@ export function SectionHeader(props: {
|
|
|
10
10
|
const align = props.align ?? "center"
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
|
-
<div
|
|
14
|
-
className={cn(
|
|
15
|
-
align === "center" && "text-center",
|
|
16
|
-
"mb-12",
|
|
17
|
-
props.className,
|
|
18
|
-
)}
|
|
19
|
-
>
|
|
13
|
+
<div className={cn(align === "center" && "text-center", "mb-12", props.className)}>
|
|
20
14
|
{props.label && (
|
|
21
15
|
<p className="text-primary text-xs uppercase tracking-[0.2em] font-medium mb-3">
|
|
22
16
|
{props.label}
|
|
@@ -44,10 +44,7 @@ export function Sidebar(props: { withSidebar?: boolean }) {
|
|
|
44
44
|
<SidebarHeader>
|
|
45
45
|
<SidebarMenu>
|
|
46
46
|
<SidebarMenuItem>
|
|
47
|
-
<SidebarMenuButton
|
|
48
|
-
size="lg"
|
|
49
|
-
render={<SiteLink to={siteLinkTarget} />}
|
|
50
|
-
>
|
|
47
|
+
<SidebarMenuButton size="lg" render={<SiteLink to={siteLinkTarget} />}>
|
|
51
48
|
<SiteTitle />
|
|
52
49
|
</SidebarMenuButton>
|
|
53
50
|
</SidebarMenuItem>
|
|
@@ -56,9 +53,7 @@ export function Sidebar(props: { withSidebar?: boolean }) {
|
|
|
56
53
|
<SidebarContent>
|
|
57
54
|
<SidebarSections />
|
|
58
55
|
{props.withSidebar && section?.type === "blog" && <SidebarPosts />}
|
|
59
|
-
{props.withSidebar && section?.type === "changelog" &&
|
|
60
|
-
<SidebarReleases />
|
|
61
|
-
)}
|
|
56
|
+
{props.withSidebar && section?.type === "changelog" && <SidebarReleases />}
|
|
62
57
|
{props.withSidebar &&
|
|
63
58
|
section?.type !== "blog" &&
|
|
64
59
|
section?.type !== "changelog" && <SidebarArticles />}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { config } from "livemark:virtual"
|
|
2
2
|
import { Link, useLocation } from "@tanstack/react-router"
|
|
3
3
|
import { ChevronRight } from "lucide-react"
|
|
4
|
-
import {
|
|
5
|
-
articleTree,
|
|
6
|
-
currentSection,
|
|
7
|
-
sectionArticleTrees,
|
|
8
|
-
} from "../content/article.ts"
|
|
4
|
+
import { articleTree, currentSection, sectionArticleTrees } from "../content/article.ts"
|
|
9
5
|
import {
|
|
10
6
|
Collapsible,
|
|
11
7
|
CollapsibleContent,
|
|
@@ -61,11 +57,7 @@ function isActive(articlePathname: string, currentPath: string) {
|
|
|
61
57
|
return articlePathname === normalized
|
|
62
58
|
}
|
|
63
59
|
|
|
64
|
-
function NavNode(props: {
|
|
65
|
-
node: ArticleNode
|
|
66
|
-
currentPath: string
|
|
67
|
-
depth?: number
|
|
68
|
-
}) {
|
|
60
|
+
function NavNode(props: { node: ArticleNode; currentPath: string; depth?: number }) {
|
|
69
61
|
const { node, currentPath, depth = 0 } = props
|
|
70
62
|
const Icon = resolveArticleIcon(node.icon)
|
|
71
63
|
const active = isActive(node.path, currentPath)
|
|
@@ -79,11 +71,7 @@ function NavNode(props: {
|
|
|
79
71
|
if (node.children.length === 0) {
|
|
80
72
|
return (
|
|
81
73
|
<Item>
|
|
82
|
-
<Button
|
|
83
|
-
isActive={active}
|
|
84
|
-
className={active ? "" : "opacity-75"}
|
|
85
|
-
render={link}
|
|
86
|
-
>
|
|
74
|
+
<Button isActive={active} className={active ? "" : "opacity-75"} render={link}>
|
|
87
75
|
{!isSub && Icon && <Icon className="size-4" />}
|
|
88
76
|
{label}
|
|
89
77
|
</Button>
|
|
@@ -94,11 +82,7 @@ function NavNode(props: {
|
|
|
94
82
|
return (
|
|
95
83
|
<Item>
|
|
96
84
|
<Collapsible defaultOpen className="group/collapsible">
|
|
97
|
-
<Button
|
|
98
|
-
isActive={active}
|
|
99
|
-
className={active ? "" : "opacity-75"}
|
|
100
|
-
render={link}
|
|
101
|
-
>
|
|
85
|
+
<Button isActive={active} className={active ? "" : "opacity-75"} render={link}>
|
|
102
86
|
{!isSub && Icon && <Icon className="size-4" />}
|
|
103
87
|
{label}
|
|
104
88
|
</Button>
|
|
@@ -19,9 +19,7 @@ export function SidebarLinks() {
|
|
|
19
19
|
const pathname = useLocation({ select: l => l.pathname })
|
|
20
20
|
const section = currentSection(`/${pathname.replace(/^\/|\/$/g, "")}/`)
|
|
21
21
|
const links =
|
|
22
|
-
config.links?.filter(
|
|
23
|
-
link => !link.prefix || link.prefix === section?.prefix,
|
|
24
|
-
) ?? []
|
|
22
|
+
config.links?.filter(link => !link.prefix || link.prefix === section?.prefix) ?? []
|
|
25
23
|
|
|
26
24
|
if (!links.length) return null
|
|
27
25
|
const hasDesktopItems = links.some(l => l.position === "sidebar")
|
|
@@ -44,9 +42,7 @@ export function SidebarLinks() {
|
|
|
44
42
|
className="text-muted-foreground"
|
|
45
43
|
render={<a href={prefixUrl(link.url, config.base)} />}
|
|
46
44
|
>
|
|
47
|
-
{link.icon &&
|
|
48
|
-
<DynamicIcon name={link.icon} className="size-4" />
|
|
49
|
-
)}
|
|
45
|
+
{link.icon && <DynamicIcon name={link.icon} className="size-4" />}
|
|
50
46
|
<span>{link.title}</span>
|
|
51
47
|
</SidebarMenuButton>
|
|
52
48
|
</SidebarMenuItem>
|
|
@@ -30,9 +30,7 @@ export function TagIndex(props: { sectionPrefix: string; tag: string }) {
|
|
|
30
30
|
const parts = [`## ${post.title}`]
|
|
31
31
|
if (post.date) parts.push(formatDate(post.date))
|
|
32
32
|
if (post.author) {
|
|
33
|
-
parts.push(
|
|
34
|
-
Array.isArray(post.author) ? post.author.join(", ") : post.author,
|
|
35
|
-
)
|
|
33
|
+
parts.push(Array.isArray(post.author) ? post.author.join(", ") : post.author)
|
|
36
34
|
}
|
|
37
35
|
if (post.description) parts.push("", post.description)
|
|
38
36
|
return parts.join("\n")
|
|
@@ -76,16 +74,12 @@ export function TagIndex(props: { sectionPrefix: string; tag: string }) {
|
|
|
76
74
|
{post.date && <span>{formatDate(post.date)}</span>}
|
|
77
75
|
{post.author && (
|
|
78
76
|
<span>
|
|
79
|
-
{Array.isArray(post.author)
|
|
80
|
-
? post.author.join(", ")
|
|
81
|
-
: post.author}
|
|
77
|
+
{Array.isArray(post.author) ? post.author.join(", ") : post.author}
|
|
82
78
|
</span>
|
|
83
79
|
)}
|
|
84
80
|
</p>
|
|
85
81
|
{post.description && (
|
|
86
|
-
<p className="text-muted-foreground mt-2">
|
|
87
|
-
{post.description}
|
|
88
|
-
</p>
|
|
82
|
+
<p className="text-muted-foreground mt-2">{post.description}</p>
|
|
89
83
|
)}
|
|
90
84
|
</article>
|
|
91
85
|
))}
|
|
@@ -63,10 +63,7 @@ export function MobileToc(props: { items: TocItem[]; children?: ReactNode }) {
|
|
|
63
63
|
const title = active?.title ?? props.items[0]?.title ?? "Contents"
|
|
64
64
|
|
|
65
65
|
return (
|
|
66
|
-
<div
|
|
67
|
-
ref={wrapperRef}
|
|
68
|
-
className="xl:hidden sticky top-16 z-20 border-b bg-background"
|
|
69
|
-
>
|
|
66
|
+
<div ref={wrapperRef} className="xl:hidden sticky top-16 z-20 border-b bg-background">
|
|
70
67
|
<button
|
|
71
68
|
type="button"
|
|
72
69
|
onClick={() => setOpen(v => !v)}
|
|
@@ -91,9 +88,7 @@ export function MobileToc(props: { items: TocItem[]; children?: ReactNode }) {
|
|
|
91
88
|
<li key={item.url}>
|
|
92
89
|
<a
|
|
93
90
|
href={item.url}
|
|
94
|
-
data-active={
|
|
95
|
-
activeId === item.url.slice(1) || undefined
|
|
96
|
-
}
|
|
91
|
+
data-active={activeId === item.url.slice(1) || undefined}
|
|
97
92
|
onClick={() => setOpen(false)}
|
|
98
93
|
className={`-ms-px block border-l border-transparent py-1.5 text-muted-foreground transition-colors hover:text-foreground data-[active]:border-primary data-[active]:font-medium data-[active]:text-primary ${item.depth <= 2 ? "ps-3" : item.depth === 3 ? "ps-6" : "ps-8"}`}
|
|
99
94
|
>
|
|
@@ -54,8 +54,7 @@ if (routedSections.length) {
|
|
|
54
54
|
const sorted =
|
|
55
55
|
section?.type === "blog" || section?.type === "changelog"
|
|
56
56
|
? [...bucket].sort(
|
|
57
|
-
(a, b) =>
|
|
58
|
-
new Date(b.date ?? 0).getTime() - new Date(a.date ?? 0).getTime(),
|
|
57
|
+
(a, b) => new Date(b.date ?? 0).getTime() - new Date(a.date ?? 0).getTime(),
|
|
59
58
|
)
|
|
60
59
|
: bucket
|
|
61
60
|
const tree = buildArticleTree(sorted)
|
|
@@ -53,18 +53,16 @@ import { extractToc } from "./helpers/toc.ts"
|
|
|
53
53
|
|
|
54
54
|
const config = await loadConfig()
|
|
55
55
|
|
|
56
|
-
const changelogSections =
|
|
57
|
-
config.sections?.filter(s => s.type === "changelog") ?? []
|
|
56
|
+
const changelogSections = config.sections?.filter(s => s.type === "changelog") ?? []
|
|
58
57
|
for (const section of changelogSections) {
|
|
59
58
|
await buildChangelog(section, config)
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
const configInclude = Array.isArray(config.include)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
: configInclude
|
|
61
|
+
const configInclude = Array.isArray(config.include) ? config.include : [config.include]
|
|
62
|
+
const include = [
|
|
63
|
+
...configInclude,
|
|
64
|
+
...changelogSections.map(section => cacheIncludeGlob(section, config)),
|
|
65
|
+
]
|
|
68
66
|
|
|
69
67
|
const userExclude = config.exclude
|
|
70
68
|
? Array.isArray(config.exclude)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion"
|
|
2
2
|
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react"
|
|
3
3
|
|
|
4
|
-
import { cn } from "
|
|
4
|
+
import { cn } from "cn"
|
|
5
5
|
|
|
6
6
|
function Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {
|
|
7
7
|
return (
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
2
|
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog"
|
|
3
3
|
|
|
4
|
-
import { cn } from "
|
|
4
|
+
import { cn } from "cn"
|
|
5
5
|
import { Button } from "./button.tsx"
|
|
6
6
|
|
|
7
7
|
function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
|
|
@@ -9,15 +9,11 @@ function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {
|
|
12
|
-
return
|
|
13
|
-
<AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
|
|
14
|
-
)
|
|
12
|
+
return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
|
|
15
13
|
}
|
|
16
14
|
|
|
17
15
|
function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {
|
|
18
|
-
return
|
|
19
|
-
<AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
|
|
20
|
-
)
|
|
16
|
+
return <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
|
|
21
17
|
}
|
|
22
18
|
|
|
23
19
|
function AlertDialogOverlay({
|
|
@@ -59,10 +55,7 @@ function AlertDialogContent({
|
|
|
59
55
|
)
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
function AlertDialogHeader({
|
|
63
|
-
className,
|
|
64
|
-
...props
|
|
65
|
-
}: React.ComponentProps<"div">) {
|
|
58
|
+
function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
66
59
|
return (
|
|
67
60
|
<div
|
|
68
61
|
data-slot="alert-dialog-header"
|
|
@@ -75,10 +68,7 @@ function AlertDialogHeader({
|
|
|
75
68
|
)
|
|
76
69
|
}
|
|
77
70
|
|
|
78
|
-
function AlertDialogFooter({
|
|
79
|
-
className,
|
|
80
|
-
...props
|
|
81
|
-
}: React.ComponentProps<"div">) {
|
|
71
|
+
function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
82
72
|
return (
|
|
83
73
|
<div
|
|
84
74
|
data-slot="alert-dialog-footer"
|
|
@@ -91,10 +81,7 @@ function AlertDialogFooter({
|
|
|
91
81
|
)
|
|
92
82
|
}
|
|
93
83
|
|
|
94
|
-
function AlertDialogMedia({
|
|
95
|
-
className,
|
|
96
|
-
...props
|
|
97
|
-
}: React.ComponentProps<"div">) {
|
|
84
|
+
function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">) {
|
|
98
85
|
return (
|
|
99
86
|
<div
|
|
100
87
|
data-slot="alert-dialog-media"
|
|
@@ -139,17 +126,8 @@ function AlertDialogDescription({
|
|
|
139
126
|
)
|
|
140
127
|
}
|
|
141
128
|
|
|
142
|
-
function AlertDialogAction({
|
|
143
|
-
className
|
|
144
|
-
...props
|
|
145
|
-
}: React.ComponentProps<typeof Button>) {
|
|
146
|
-
return (
|
|
147
|
-
<Button
|
|
148
|
-
data-slot="alert-dialog-action"
|
|
149
|
-
className={cn(className)}
|
|
150
|
-
{...props}
|
|
151
|
-
/>
|
|
152
|
-
)
|
|
129
|
+
function AlertDialogAction({ className, ...props }: React.ComponentProps<typeof Button>) {
|
|
130
|
+
return <Button data-slot="alert-dialog-action" className={cn(className)} {...props} />
|
|
153
131
|
}
|
|
154
132
|
|
|
155
133
|
function AlertDialogCancel({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
2
|
-
import { cn } from "
|
|
2
|
+
import { cn } from "cn"
|
|
3
3
|
|
|
4
4
|
const alertVariants = cva(
|
|
5
5
|
"grid gap-0.5 rounded-lg border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert",
|
|
@@ -45,10 +45,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
45
45
|
)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function AlertDescription({
|
|
49
|
-
className,
|
|
50
|
-
...props
|
|
51
|
-
}: React.ComponentProps<"div">) {
|
|
48
|
+
function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
|
|
52
49
|
return (
|
|
53
50
|
<div
|
|
54
51
|
data-slot="alert-description"
|