blume 0.0.0 → 0.1.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/bin/blume.mjs +18 -0
- package/dist/cli/index.js +12696 -0
- package/dist/cli/index.js.map +145 -0
- package/dist/types/core/bridge.d.ts +24 -0
- package/dist/types/core/config.d.ts +35 -0
- package/dist/types/core/data.d.ts +129 -0
- package/dist/types/core/define-components.d.ts +27 -0
- package/dist/types/core/define-meta.d.ts +16 -0
- package/dist/types/core/deployment-env.d.ts +9 -0
- package/dist/types/core/diagnostics.d.ts +17 -0
- package/dist/types/core/i18n-ui.d.ts +500 -0
- package/dist/types/core/load-module.d.ts +7 -0
- package/dist/types/core/package-root.d.ts +17 -0
- package/dist/types/core/project.d.ts +9 -0
- package/dist/types/core/schema.d.ts +3451 -0
- package/dist/types/core/sources/types.d.ts +107 -0
- package/dist/types/core/types.d.ts +245 -0
- package/dist/types/core/ui-packs/ar.d.ts +3 -0
- package/dist/types/core/ui-packs/bg.d.ts +3 -0
- package/dist/types/core/ui-packs/bn.d.ts +3 -0
- package/dist/types/core/ui-packs/ca.d.ts +3 -0
- package/dist/types/core/ui-packs/cs.d.ts +3 -0
- package/dist/types/core/ui-packs/da.d.ts +3 -0
- package/dist/types/core/ui-packs/de.d.ts +3 -0
- package/dist/types/core/ui-packs/el.d.ts +3 -0
- package/dist/types/core/ui-packs/es.d.ts +3 -0
- package/dist/types/core/ui-packs/fa.d.ts +3 -0
- package/dist/types/core/ui-packs/fi.d.ts +3 -0
- package/dist/types/core/ui-packs/fr.d.ts +3 -0
- package/dist/types/core/ui-packs/he.d.ts +3 -0
- package/dist/types/core/ui-packs/hi.d.ts +3 -0
- package/dist/types/core/ui-packs/hr.d.ts +3 -0
- package/dist/types/core/ui-packs/hu.d.ts +3 -0
- package/dist/types/core/ui-packs/id.d.ts +3 -0
- package/dist/types/core/ui-packs/index.d.ts +13 -0
- package/dist/types/core/ui-packs/it.d.ts +3 -0
- package/dist/types/core/ui-packs/ja.d.ts +3 -0
- package/dist/types/core/ui-packs/ko.d.ts +3 -0
- package/dist/types/core/ui-packs/nl.d.ts +3 -0
- package/dist/types/core/ui-packs/no.d.ts +3 -0
- package/dist/types/core/ui-packs/pl.d.ts +3 -0
- package/dist/types/core/ui-packs/pt-br.d.ts +3 -0
- package/dist/types/core/ui-packs/pt.d.ts +3 -0
- package/dist/types/core/ui-packs/ro.d.ts +3 -0
- package/dist/types/core/ui-packs/ru.d.ts +3 -0
- package/dist/types/core/ui-packs/sk.d.ts +3 -0
- package/dist/types/core/ui-packs/sr.d.ts +3 -0
- package/dist/types/core/ui-packs/sv.d.ts +3 -0
- package/dist/types/core/ui-packs/th.d.ts +3 -0
- package/dist/types/core/ui-packs/tr.d.ts +3 -0
- package/dist/types/core/ui-packs/uk.d.ts +3 -0
- package/dist/types/core/ui-packs/vi.d.ts +3 -0
- package/dist/types/core/ui-packs/zh-tw.d.ts +3 -0
- package/dist/types/core/ui-packs/zh.d.ts +3 -0
- package/dist/types/core/version.d.ts +8 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/migrate/mintlify/config.d.ts +2 -0
- package/dist/types/migrate/mintlify/i18n.d.ts +7 -0
- package/dist/types/theme/fonts.d.ts +163 -0
- package/docs/01-quickstart.mdx +99 -0
- package/docs/02-deployment.mdx +129 -0
- package/docs/advanced/api-reference.mdx +114 -0
- package/docs/advanced/blog.mdx +121 -0
- package/docs/advanced/changelog.mdx +113 -0
- package/docs/advanced/custom-pages.mdx +268 -0
- package/docs/advanced/meta.ts +7 -0
- package/docs/changelog/v0-1-0.mdx +12 -0
- package/docs/changelog/v0-2-0.mdx +16 -0
- package/docs/configuration/ai.mdx +228 -0
- package/docs/configuration/analytics.mdx +98 -0
- package/docs/configuration/customization.mdx +91 -0
- package/docs/configuration/export.mdx +70 -0
- package/docs/configuration/index.mdx +290 -0
- package/docs/configuration/meta.ts +15 -0
- package/docs/configuration/search.mdx +172 -0
- package/docs/configuration/seo.mdx +196 -0
- package/docs/configuration/theming.mdx +178 -0
- package/docs/content/components.mdx +651 -0
- package/docs/content/i18n.mdx +205 -0
- package/docs/content/index.mdx +161 -0
- package/docs/content/islands.mdx +94 -0
- package/docs/content/meta.mdx +119 -0
- package/docs/content/meta.ts +15 -0
- package/docs/content/navigation.mdx +168 -0
- package/docs/content/sources.mdx +216 -0
- package/docs/content/syntax.mdx +445 -0
- package/docs/index.mdx +112 -0
- package/docs/reference/cli.mdx +43 -0
- package/docs/reference/frontmatter.mdx +74 -0
- package/docs/reference/meta.ts +7 -0
- package/package.json +150 -6
- package/src/ai/ask.ts +93 -0
- package/src/ai/llms.ts +64 -0
- package/src/ai/markdown.ts +31 -0
- package/src/ai/mcp/data.ts +74 -0
- package/src/ai/mcp/discovery.ts +49 -0
- package/src/ai/mcp/server.ts +225 -0
- package/src/ai/mcp/tools.ts +47 -0
- package/src/assets/icon.png +0 -0
- package/src/astro/examples.ts +104 -0
- package/src/astro/generate.ts +1006 -0
- package/src/astro/index.ts +4 -0
- package/src/astro/integration.ts +74 -0
- package/src/astro/islands.ts +131 -0
- package/src/astro/markdown-negotiation.ts +68 -0
- package/src/astro/pages.ts +87 -0
- package/src/astro/templates.ts +1326 -0
- package/src/cli/commands/add.ts +81 -0
- package/src/cli/commands/build.ts +103 -0
- package/src/cli/commands/dev.ts +108 -0
- package/src/cli/commands/doctor.ts +74 -0
- package/src/cli/commands/eject.ts +57 -0
- package/src/cli/commands/init.ts +98 -0
- package/src/cli/commands/migrate.ts +39 -0
- package/src/cli/commands/preview.ts +39 -0
- package/src/cli/commands/sync.ts +52 -0
- package/src/cli/commands/validate.ts +61 -0
- package/src/cli/index.ts +35 -0
- package/src/cli/log.ts +37 -0
- package/src/cli/prepare.ts +80 -0
- package/src/components/Icon.astro +99 -0
- package/src/components/content/Accordion.astro +8 -0
- package/src/components/content/AccordionItem.astro +121 -0
- package/src/components/content/AutoTypeTable.astro +51 -0
- package/src/components/content/Badge.astro +124 -0
- package/src/components/content/Callout.astro +73 -0
- package/src/components/content/Card.astro +104 -0
- package/src/components/content/CardGroup.astro +14 -0
- package/src/components/content/CodeBlock.astro +28 -0
- package/src/components/content/CodeGroup.astro +13 -0
- package/src/components/content/Color.astro +15 -0
- package/src/components/content/ColorItem.astro +87 -0
- package/src/components/content/ColorRow.astro +10 -0
- package/src/components/content/Column.astro +6 -0
- package/src/components/content/Columns.astro +9 -0
- package/src/components/content/Component.astro +65 -0
- package/src/components/content/Diff.astro +44 -0
- package/src/components/content/Expandable.astro +11 -0
- package/src/components/content/FileTree.astro +8 -0
- package/src/components/content/Frame.astro +70 -0
- package/src/components/content/GithubInfo.astro +110 -0
- package/src/components/content/Math.astro +24 -0
- package/src/components/content/Panel.astro +20 -0
- package/src/components/content/Prompt.astro +129 -0
- package/src/components/content/Step.astro +34 -0
- package/src/components/content/Steps.astro +20 -0
- package/src/components/content/Tab.astro +46 -0
- package/src/components/content/Tabs.astro +273 -0
- package/src/components/content/Tile.astro +42 -0
- package/src/components/content/Tooltip.astro +68 -0
- package/src/components/content/Tree.astro +300 -0
- package/src/components/content/TreeFile.astro +15 -0
- package/src/components/content/TreeFolder.astro +62 -0
- package/src/components/content/TypeTable.astro +106 -0
- package/src/components/content/Update.astro +66 -0
- package/src/components/content/Visibility.astro +12 -0
- package/src/components/content/Warning.astro +9 -0
- package/src/components/content/auto-type-table.ts +141 -0
- package/src/components/content/diff.ts +95 -0
- package/src/components/content/github-info.ts +79 -0
- package/src/components/content/mermaid-element.ts +68 -0
- package/src/components/github-mark.ts +9 -0
- package/src/components/index.ts +14 -0
- package/src/components/islands/AskAI.astro +12 -0
- package/src/components/islands/ask-ai.tsx +156 -0
- package/src/components/layout/Analytics.astro +63 -0
- package/src/components/layout/Banner.astro +50 -0
- package/src/components/layout/Breadcrumbs.astro +31 -0
- package/src/components/layout/Favicon.astro +22 -0
- package/src/components/layout/Fonts.astro +14 -0
- package/src/components/layout/Header.astro +188 -0
- package/src/components/layout/LanguageSwitcher.astro +56 -0
- package/src/components/layout/NavTree.astro +462 -0
- package/src/components/layout/PageActions.astro +438 -0
- package/src/components/layout/PageFeedback.astro +58 -0
- package/src/components/layout/PageLayout.astro +173 -0
- package/src/components/layout/Pagination.astro +56 -0
- package/src/components/layout/ReferenceLayout.astro +107 -0
- package/src/components/layout/RootLayout.astro +537 -0
- package/src/components/layout/Search.astro +608 -0
- package/src/components/layout/TableOfContents.astro +68 -0
- package/src/components/layout/analytics-client.ts +38 -0
- package/src/components/layout/head-scripts.ts +19 -0
- package/src/components/layout/nav-utils.ts +87 -0
- package/src/components/layout/overrides.ts +32 -0
- package/src/components/layout/search/algolia.ts +43 -0
- package/src/components/layout/search/endpoint.ts +22 -0
- package/src/components/layout/search/flexsearch.ts +52 -0
- package/src/components/layout/search/orama-cloud.ts +41 -0
- package/src/components/layout/search/orama.ts +26 -0
- package/src/components/layout/search/pagefind.ts +43 -0
- package/src/components/layout/search/types.ts +163 -0
- package/src/components/layout/search/typesense.ts +60 -0
- package/src/components/layout/toc-element.ts +108 -0
- package/src/core/bridge.ts +92 -0
- package/src/core/config.ts +112 -0
- package/src/core/content.ts +50 -0
- package/src/core/data.ts +128 -0
- package/src/core/define-components.ts +34 -0
- package/src/core/define-meta.ts +20 -0
- package/src/core/deployment-env.ts +73 -0
- package/src/core/diagnostics.ts +104 -0
- package/src/core/frontmatter.ts +43 -0
- package/src/core/graph.ts +128 -0
- package/src/core/i18n-ui.ts +171 -0
- package/src/core/i18n.ts +169 -0
- package/src/core/last-modified.ts +88 -0
- package/src/core/links.ts +352 -0
- package/src/core/load-module.ts +15 -0
- package/src/core/manifest.ts +126 -0
- package/src/core/meta.ts +97 -0
- package/src/core/navigation.ts +392 -0
- package/src/core/package-root.ts +37 -0
- package/src/core/project-graph.ts +153 -0
- package/src/core/project.ts +56 -0
- package/src/core/schema.ts +1057 -0
- package/src/core/server-features.ts +23 -0
- package/src/core/sources/assets.ts +77 -0
- package/src/core/sources/cache.ts +122 -0
- package/src/core/sources/filesystem.ts +99 -0
- package/src/core/sources/mdx-remote.ts +215 -0
- package/src/core/sources/mintlify.ts +161 -0
- package/src/core/sources/normalize.ts +243 -0
- package/src/core/sources/notion.ts +440 -0
- package/src/core/sources/portable-text.ts +143 -0
- package/src/core/sources/read.ts +36 -0
- package/src/core/sources/resolve.ts +158 -0
- package/src/core/sources/sanity.ts +218 -0
- package/src/core/sources/types.ts +105 -0
- package/src/core/tsconfig-aliases.ts +201 -0
- package/src/core/types.ts +261 -0
- package/src/core/ui-packs/ar.ts +47 -0
- package/src/core/ui-packs/bg.ts +47 -0
- package/src/core/ui-packs/bn.ts +47 -0
- package/src/core/ui-packs/ca.ts +47 -0
- package/src/core/ui-packs/cs.ts +47 -0
- package/src/core/ui-packs/da.ts +47 -0
- package/src/core/ui-packs/de.ts +47 -0
- package/src/core/ui-packs/el.ts +47 -0
- package/src/core/ui-packs/es.ts +47 -0
- package/src/core/ui-packs/fa.ts +47 -0
- package/src/core/ui-packs/fi.ts +47 -0
- package/src/core/ui-packs/fr.ts +47 -0
- package/src/core/ui-packs/he.ts +47 -0
- package/src/core/ui-packs/hi.ts +47 -0
- package/src/core/ui-packs/hr.ts +47 -0
- package/src/core/ui-packs/hu.ts +47 -0
- package/src/core/ui-packs/id.ts +47 -0
- package/src/core/ui-packs/index.ts +87 -0
- package/src/core/ui-packs/it.ts +47 -0
- package/src/core/ui-packs/ja.ts +47 -0
- package/src/core/ui-packs/ko.ts +47 -0
- package/src/core/ui-packs/nl.ts +47 -0
- package/src/core/ui-packs/no.ts +47 -0
- package/src/core/ui-packs/pl.ts +47 -0
- package/src/core/ui-packs/pt-br.ts +47 -0
- package/src/core/ui-packs/pt.ts +47 -0
- package/src/core/ui-packs/ro.ts +47 -0
- package/src/core/ui-packs/ru.ts +47 -0
- package/src/core/ui-packs/sk.ts +47 -0
- package/src/core/ui-packs/sr.ts +47 -0
- package/src/core/ui-packs/sv.ts +47 -0
- package/src/core/ui-packs/th.ts +47 -0
- package/src/core/ui-packs/tr.ts +47 -0
- package/src/core/ui-packs/uk.ts +47 -0
- package/src/core/ui-packs/vi.ts +47 -0
- package/src/core/ui-packs/zh-tw.ts +47 -0
- package/src/core/ui-packs/zh.ts +47 -0
- package/src/core/version.ts +23 -0
- package/src/deploy/robots.ts +20 -0
- package/src/deploy/rss.ts +128 -0
- package/src/deploy/sitemap.ts +28 -0
- package/src/index.ts +39 -0
- package/src/markdown/code-title.ts +71 -0
- package/src/markdown/directives.ts +83 -0
- package/src/markdown/heading-anchors.ts +137 -0
- package/src/markdown/index.ts +228 -0
- package/src/markdown/inline-code.ts +108 -0
- package/src/markdown/language-icon.ts +172 -0
- package/src/markdown/math.ts +32 -0
- package/src/markdown/mdast.ts +48 -0
- package/src/markdown/mermaid.ts +37 -0
- package/src/markdown/package-commands.ts +159 -0
- package/src/markdown/package-install.ts +40 -0
- package/src/migrate/fumadocs/config.ts +155 -0
- package/src/migrate/fumadocs/content.ts +365 -0
- package/src/migrate/fumadocs/frontmatter.ts +18 -0
- package/src/migrate/fumadocs/groups.ts +230 -0
- package/src/migrate/fumadocs/index.ts +337 -0
- package/src/migrate/fumadocs/meta.ts +244 -0
- package/src/migrate/migrate.ts +53 -0
- package/src/migrate/mintlify/config.ts +1040 -0
- package/src/migrate/mintlify/content.ts +98 -0
- package/src/migrate/mintlify/frontmatter.ts +126 -0
- package/src/migrate/mintlify/i18n.ts +51 -0
- package/src/migrate/mintlify/icons.ts +128 -0
- package/src/migrate/mintlify/index.ts +266 -0
- package/src/migrate/mintlify/snippets.ts +306 -0
- package/src/migrate/mintlify/transform.ts +80 -0
- package/src/migrate/nextra/content.ts +46 -0
- package/src/migrate/nextra/frontmatter.ts +40 -0
- package/src/migrate/nextra/index.ts +374 -0
- package/src/migrate/nextra/meta.ts +266 -0
- package/src/migrate/shared.ts +720 -0
- package/src/migrate/starlight/config.ts +459 -0
- package/src/migrate/starlight/content.ts +78 -0
- package/src/migrate/starlight/frontmatter.ts +111 -0
- package/src/migrate/starlight/i18n.ts +54 -0
- package/src/migrate/starlight/index.ts +131 -0
- package/src/og/card.ts +92 -0
- package/src/og/index.ts +2 -0
- package/src/openapi/scalar.ts +246 -0
- package/src/registry/eject.ts +310 -0
- package/src/registry/registry.ts +100 -0
- package/src/registry/rewrite-imports.ts +39 -0
- package/src/runtime/index.ts +14 -0
- package/src/search/build.ts +23 -0
- package/src/search/documents.ts +164 -0
- package/src/search/orama-index.ts +66 -0
- package/src/search/providers.ts +91 -0
- package/src/search/sync/algolia.ts +30 -0
- package/src/search/sync/index.ts +50 -0
- package/src/search/sync/orama-cloud.ts +40 -0
- package/src/search/sync/typesense.ts +65 -0
- package/src/seo/jsonld.ts +113 -0
- package/src/theme/entry.ts +637 -0
- package/src/theme/fonts.ts +198 -0
- package/src/theme/icons.ts +184 -0
- package/src/theme/palette.ts +143 -0
- package/src/theme/twoslash.ts +81 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Icon from "../Icon.astro";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
title?: string;
|
|
6
|
+
href?: string;
|
|
7
|
+
icon?: string;
|
|
8
|
+
iconType?: string;
|
|
9
|
+
img?: string;
|
|
10
|
+
horizontal?: boolean | string;
|
|
11
|
+
cta?: string;
|
|
12
|
+
arrow?: boolean | string;
|
|
13
|
+
type?: "info" | "warning" | "note" | "tip" | "check" | "danger";
|
|
14
|
+
color?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { arrow, color, cta, horizontal, href, icon, iconType, img, title, type } =
|
|
18
|
+
Astro.props;
|
|
19
|
+
const Tag = href ? "a" : "div";
|
|
20
|
+
const external = href?.startsWith("http");
|
|
21
|
+
const isHorizontal = horizontal === true || horizontal === "true";
|
|
22
|
+
const showArrow =
|
|
23
|
+
href && arrow === undefined ? external : arrow === true || arrow === "true";
|
|
24
|
+
const iconByType = {
|
|
25
|
+
check: "circle-check",
|
|
26
|
+
danger: "circle-x",
|
|
27
|
+
info: "info",
|
|
28
|
+
note: "info",
|
|
29
|
+
tip: "lightbulb",
|
|
30
|
+
warning: "triangle-alert",
|
|
31
|
+
};
|
|
32
|
+
const iconClass = {
|
|
33
|
+
check: "text-green-600 dark:text-green-400",
|
|
34
|
+
danger: "text-red-600 dark:text-red-400",
|
|
35
|
+
info: "text-blue-600 dark:text-blue-400",
|
|
36
|
+
note: "text-muted-foreground/70",
|
|
37
|
+
tip: "text-accent",
|
|
38
|
+
warning: "text-amber-600 dark:text-amber-400",
|
|
39
|
+
};
|
|
40
|
+
const iconName = icon ?? (type ? iconByType[type] : undefined);
|
|
41
|
+
const variantClass = {
|
|
42
|
+
check: "border-green-500/30 bg-green-500/10",
|
|
43
|
+
danger: "border-red-500/30 bg-red-500/10",
|
|
44
|
+
info: "border-blue-500/30 bg-blue-500/10",
|
|
45
|
+
note: "border-border bg-muted/40",
|
|
46
|
+
tip: "border-accent/30 bg-accent/10",
|
|
47
|
+
warning: "border-amber-500/30 bg-amber-500/10",
|
|
48
|
+
}[type ?? "note"];
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
<Tag
|
|
52
|
+
class:list={[
|
|
53
|
+
"not-prose block overflow-hidden rounded-blume border text-inherit no-underline! transition-colors hover:no-underline! hover:[&[href]]:border-accent",
|
|
54
|
+
type ? variantClass : "border-border bg-background",
|
|
55
|
+
isHorizontal ? "sm:flex" : "",
|
|
56
|
+
]}
|
|
57
|
+
data-blume-card
|
|
58
|
+
href={href}
|
|
59
|
+
rel={external ? "noreferrer" : undefined}
|
|
60
|
+
target={external ? "_blank" : undefined}
|
|
61
|
+
>
|
|
62
|
+
{
|
|
63
|
+
img && (
|
|
64
|
+
<img
|
|
65
|
+
alt=""
|
|
66
|
+
class:list={[
|
|
67
|
+
"w-full object-cover",
|
|
68
|
+
isHorizontal ? "sm:w-40 sm:shrink-0" : "max-h-48",
|
|
69
|
+
]}
|
|
70
|
+
src={img}
|
|
71
|
+
/>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
<div class="p-5">
|
|
75
|
+
{
|
|
76
|
+
iconName && (
|
|
77
|
+
<div class:list={["mb-2.5", color ? "" : type ? iconClass[type] : "text-accent"]}>
|
|
78
|
+
<Icon color={color} iconType={iconType} name={iconName} size={20} />
|
|
79
|
+
</div>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
{
|
|
83
|
+
title && (
|
|
84
|
+
<p class="mt-0! mb-1.5! flex items-center gap-1.5 font-medium text-foreground">
|
|
85
|
+
{title}
|
|
86
|
+
{showArrow && (
|
|
87
|
+
<Icon class="text-muted-foreground" name="arrow-right" size={14} />
|
|
88
|
+
)}
|
|
89
|
+
</p>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
<div class="font-normal text-muted-foreground text-sm [&>:first-child]:mt-0! [&>:last-child]:mb-0!">
|
|
93
|
+
<slot />
|
|
94
|
+
</div>
|
|
95
|
+
{
|
|
96
|
+
cta && (
|
|
97
|
+
<p class="mt-4! mb-0! flex items-center gap-1.5 font-medium text-accent text-sm">
|
|
98
|
+
{cta}
|
|
99
|
+
{showArrow && <Icon name="arrow-right" size={14} />}
|
|
100
|
+
</p>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
</div>
|
|
104
|
+
</Tag>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
cols?: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const { cols = 2 } = Astro.props;
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<div
|
|
10
|
+
class="not-prose my-6 grid grid-cols-1 gap-4 sm:grid-cols-[repeat(var(--blume-cols),minmax(0,1fr))]"
|
|
11
|
+
style={`--blume-cols:${cols}`}
|
|
12
|
+
>
|
|
13
|
+
<slot />
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Render a code string highlighted with Blume's Markdown code-block theme — the
|
|
3
|
+
// same Shiki themes, transformers, and dual light/dark swap as fenced code.
|
|
4
|
+
// Use it to show themed code outside the Markdown pipeline (a landing page, a
|
|
5
|
+
// custom component) where there's no fence to write.
|
|
6
|
+
//
|
|
7
|
+
// <CodeBlock lang="ts" code={`export const x = 1;`} />
|
|
8
|
+
//
|
|
9
|
+
// The theme's code styles are scoped to `.prose`, so the output is wrapped in a
|
|
10
|
+
// `.prose` container (`max-w-none` so it fills its own column rather than the
|
|
11
|
+
// prose reading measure); that's what makes the light/dark swap work on a bare
|
|
12
|
+
// page without the manual `[data-theme]` CSS it would otherwise need.
|
|
13
|
+
import { highlightCode } from "../../markdown/index.ts";
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
/** The source to highlight. */
|
|
17
|
+
code: string;
|
|
18
|
+
/** Shiki language id (default `txt`); an unknown one renders plain. */
|
|
19
|
+
lang?: string;
|
|
20
|
+
/** Show the brand language icon in the header (default on, like fences). */
|
|
21
|
+
icons?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { code, lang = "txt", icons } = Astro.props;
|
|
25
|
+
const html = await highlightCode(code.replace(/\n+$/u, ""), lang, { icons });
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
<div class="prose max-w-none"><Fragment set:html={html} /></div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
const { variant = "compact" } = Astro.props;
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<div
|
|
6
|
+
class:list={[
|
|
7
|
+
"not-prose my-6",
|
|
8
|
+
variant === "table"
|
|
9
|
+
? "space-y-4"
|
|
10
|
+
: "grid grid-cols-2 gap-x-5 gap-y-4 sm:grid-cols-4",
|
|
11
|
+
]}
|
|
12
|
+
data-blume-color={variant}
|
|
13
|
+
>
|
|
14
|
+
<slot />
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface ColorValue {
|
|
3
|
+
dark?: string;
|
|
4
|
+
light?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
name: string;
|
|
9
|
+
value: string | ColorValue;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { name, value } = Astro.props;
|
|
13
|
+
|
|
14
|
+
const lightValue = typeof value === "string" ? value : value.light ?? value.dark;
|
|
15
|
+
const darkValue = typeof value === "string" ? value : value.dark ?? value.light;
|
|
16
|
+
const displayValue =
|
|
17
|
+
lightValue && darkValue && lightValue !== darkValue
|
|
18
|
+
? `${lightValue} / ${darkValue}`
|
|
19
|
+
: lightValue;
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<button
|
|
23
|
+
aria-label={`Copy ${name} color ${displayValue}`}
|
|
24
|
+
class="group flex w-full min-w-0 cursor-pointer flex-col gap-2.5 text-center focus:outline-none"
|
|
25
|
+
data-blume-color-copy={displayValue}
|
|
26
|
+
style={`--blume-color-light:${lightValue};--blume-color-dark:${darkValue};`}
|
|
27
|
+
type="button"
|
|
28
|
+
>
|
|
29
|
+
<span
|
|
30
|
+
class="block aspect-square w-full rounded-2xl border border-border/60 shadow-sm transition group-hover:ring-2 group-hover:ring-accent/30 group-focus-visible:ring-2 group-focus-visible:ring-accent/40"
|
|
31
|
+
data-blume-color-swatch
|
|
32
|
+
style="background:var(--blume-color-light)"
|
|
33
|
+
>
|
|
34
|
+
</span>
|
|
35
|
+
<span class="block min-w-0 leading-tight">
|
|
36
|
+
<span class="block truncate font-semibold text-foreground text-sm">
|
|
37
|
+
{name}
|
|
38
|
+
</span>
|
|
39
|
+
<span
|
|
40
|
+
class="mt-0.5 block truncate font-mono text-muted-foreground text-xs uppercase"
|
|
41
|
+
data-blume-color-status
|
|
42
|
+
>
|
|
43
|
+
{displayValue}
|
|
44
|
+
</span>
|
|
45
|
+
</span>
|
|
46
|
+
</button>
|
|
47
|
+
|
|
48
|
+
<style>
|
|
49
|
+
:global(.dark) [data-blume-color-swatch] {
|
|
50
|
+
background: var(--blume-color-dark, var(--blume-color-light));
|
|
51
|
+
}
|
|
52
|
+
</style>
|
|
53
|
+
|
|
54
|
+
<script>
|
|
55
|
+
const state = window as Window & { __blumeColorCopy?: boolean };
|
|
56
|
+
if (!state.__blumeColorCopy) {
|
|
57
|
+
state.__blumeColorCopy = true;
|
|
58
|
+
document.addEventListener("click", async (event) => {
|
|
59
|
+
const target = event.target;
|
|
60
|
+
if (!(target instanceof Element)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const button = target.closest<HTMLButtonElement>("[data-blume-color-copy]");
|
|
65
|
+
if (!button) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
await navigator.clipboard.writeText(button.dataset.blumeColorCopy ?? "");
|
|
71
|
+
} catch {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const status = button.querySelector<HTMLElement>("[data-blume-color-status]");
|
|
76
|
+
if (!status) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const original = status.textContent;
|
|
81
|
+
status.textContent = "Copied";
|
|
82
|
+
window.setTimeout(() => {
|
|
83
|
+
status.textContent = original;
|
|
84
|
+
}, 1500);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
const { title } = Astro.props;
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<div class="rounded-blume border border-border bg-background p-4">
|
|
6
|
+
{title && <p class="mt-0! mb-3! font-medium text-foreground text-sm">{title}</p>}
|
|
7
|
+
<div class="grid grid-cols-2 gap-x-5 gap-y-4 sm:grid-cols-4">
|
|
8
|
+
<slot />
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Render an example file (under the project's `examples/` dir) as a live,
|
|
3
|
+
// hydrated preview alongside its highlighted source, in tabs. `path` is the
|
|
4
|
+
// file's location under `examples/` without its extension, e.g.
|
|
5
|
+
// `<Component path="forms/login" />` for `examples/forms/login.tsx`.
|
|
6
|
+
//
|
|
7
|
+
// Blume discovers `examples/` at build time and generates `blume:examples`: a
|
|
8
|
+
// map of path → { Component (a static hydration wrapper), code, lang }. React,
|
|
9
|
+
// Vue, Svelte, and Astro examples are all supported. The source is highlighted
|
|
10
|
+
// with the same Shiki setup as ordinary code fences.
|
|
11
|
+
import { highlightCode } from "../../markdown/index.ts";
|
|
12
|
+
import Tab from "./Tab.astro";
|
|
13
|
+
import Tabs from "./Tabs.astro";
|
|
14
|
+
// Generated per project; resolves to an empty map when there are no examples.
|
|
15
|
+
import { examples } from "blume:examples";
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
path: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { path } = Astro.props;
|
|
22
|
+
const entry = examples[path];
|
|
23
|
+
const Preview = entry?.Component;
|
|
24
|
+
|
|
25
|
+
// Highlight the source with the shared helper so it matches Markdown fences.
|
|
26
|
+
// `blume-source` makes the inner `<code>` (not the `<pre>`) the scroll/height-
|
|
27
|
+
// capped box — see the theme entry — so the copy button, pinned to the `<pre>`,
|
|
28
|
+
// stays put. This pane already lives inside `.prose`, so the theme styles it.
|
|
29
|
+
const codeHtml = entry
|
|
30
|
+
? await highlightCode(entry.code, entry.lang, { className: "blume-source" })
|
|
31
|
+
: undefined;
|
|
32
|
+
|
|
33
|
+
// Both tabs share one height so toggling them never shifts the layout. Size it
|
|
34
|
+
// to the source (≈21px/line + padding), clamped to a comfortable 18rem floor and
|
|
35
|
+
// a 400px ceiling — taller sources scroll inside the pane.
|
|
36
|
+
const LINE_PX = 21;
|
|
37
|
+
const PADDING_PX = 36;
|
|
38
|
+
const lineCount = entry ? entry.code.replace(/\n+$/u, "").split("\n").length : 0;
|
|
39
|
+
const paneHeight = Math.min(400, Math.max(288, lineCount * LINE_PX + PADDING_PX));
|
|
40
|
+
const paneStyle = `height:${paneHeight}px`;
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
{
|
|
44
|
+
entry ? (
|
|
45
|
+
// `sync={false}`: each preview's Preview/Code tabs are independent — unlike
|
|
46
|
+
// CodeGroup, switching one Component must not switch the others.
|
|
47
|
+
<Tabs hash={false} sync={false}>
|
|
48
|
+
<Tab
|
|
49
|
+
class="flex items-center justify-center overflow-auto"
|
|
50
|
+
style={paneStyle}
|
|
51
|
+
title="Preview"
|
|
52
|
+
>
|
|
53
|
+
<Preview />
|
|
54
|
+
</Tab>
|
|
55
|
+
<Tab class="overflow-hidden" style={paneStyle} title="Code">
|
|
56
|
+
<Fragment set:html={codeHtml} />
|
|
57
|
+
</Tab>
|
|
58
|
+
</Tabs>
|
|
59
|
+
) : (
|
|
60
|
+
<div class="not-prose my-6 rounded-blume border border-border px-3 py-2 text-muted-foreground text-sm">
|
|
61
|
+
No example found at <code class="font-mono">{path}</code>. Add it under{" "}
|
|
62
|
+
<code class="font-mono">examples/</code> in your project.
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Render a git-style diff with `@pierre/diffs`, fully at build time. The library
|
|
3
|
+
// emits a self-contained blob whose styles are scoped to `:host`, so we mount it
|
|
4
|
+
// in a declarative shadow root — no client JS. `--blume-diff-color-scheme`
|
|
5
|
+
// (set in the theme entry from `data-theme`) drives the diff's `light-dark()`.
|
|
6
|
+
//
|
|
7
|
+
// Inputs (one of): `patch`/`src` (unified patch), `before`+`after` (file paths),
|
|
8
|
+
// or `old`+`new` (inline strings, with optional `lang`).
|
|
9
|
+
import { renderDiff } from "./diff.ts";
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
after?: string;
|
|
13
|
+
before?: string;
|
|
14
|
+
lang?: string;
|
|
15
|
+
new?: string;
|
|
16
|
+
old?: string;
|
|
17
|
+
patch?: string;
|
|
18
|
+
src?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let html: string | undefined;
|
|
22
|
+
let error: string | undefined;
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
html = await renderDiff(Astro.props);
|
|
26
|
+
} catch (cause) {
|
|
27
|
+
error = cause instanceof Error ? cause.message : String(cause);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const COLOR_SCHEME =
|
|
31
|
+
"<style>:host{color-scheme:var(--blume-diff-color-scheme, light dark)}</style>";
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
error ? (
|
|
36
|
+
<div class="not-prose my-6 rounded-blume border border-border px-3 py-2 text-muted-foreground text-sm">
|
|
37
|
+
Could not render diff: {error}
|
|
38
|
+
</div>
|
|
39
|
+
) : (
|
|
40
|
+
<blume-diff class="not-prose my-6 block overflow-hidden rounded-blume border border-border">
|
|
41
|
+
<template shadowrootmode="open" set:html={html + COLOR_SCHEME} />
|
|
42
|
+
</blume-diff>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
import AccordionItem from "./AccordionItem.astro";
|
|
3
|
+
|
|
4
|
+
const { defaultOpen = false, title = "Show more" } = Astro.props;
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<div class="not-prose my-4 overflow-hidden rounded-blume border border-border">
|
|
8
|
+
<AccordionItem defaultOpen={defaultOpen} title={title}>
|
|
9
|
+
<slot />
|
|
10
|
+
</AccordionItem>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { createSatteriMarkdownProcessor } from "@astrojs/markdown-satteri";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
caption?: string;
|
|
6
|
+
hint?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { caption, hint } = Astro.props;
|
|
10
|
+
|
|
11
|
+
const escapeRawHtml = (value: string): string =>
|
|
12
|
+
value.replaceAll("<", "<").replaceAll(">", ">");
|
|
13
|
+
|
|
14
|
+
const unwrapParagraph = (html: string): string => {
|
|
15
|
+
const trimmed = html.trim();
|
|
16
|
+
const match = trimmed.match(/^<p>(?<content>[\s\S]*)<\/p>$/u);
|
|
17
|
+
return match?.groups?.content ?? trimmed;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const markdownProcessor = await createSatteriMarkdownProcessor();
|
|
21
|
+
const captionHtml = caption
|
|
22
|
+
? unwrapParagraph((await markdownProcessor.render(escapeRawHtml(caption))).code)
|
|
23
|
+
: undefined;
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<blume-frame class="not-prose my-6 block">
|
|
27
|
+
<figure class="m-0">
|
|
28
|
+
{
|
|
29
|
+
hint && (
|
|
30
|
+
<p class="mb-2 text-muted-foreground text-sm leading-6">
|
|
31
|
+
{hint}
|
|
32
|
+
</p>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
<div
|
|
36
|
+
class="flex justify-center overflow-hidden rounded-blume border border-border bg-muted/30 p-6 [&>:first-child]:m-0! [&_img]:h-auto [&_img]:max-w-full [&_video]:h-auto [&_video]:max-w-full"
|
|
37
|
+
>
|
|
38
|
+
<slot />
|
|
39
|
+
</div>
|
|
40
|
+
{
|
|
41
|
+
captionHtml && (
|
|
42
|
+
<figcaption
|
|
43
|
+
class="mt-2 text-center text-muted-foreground text-xs leading-5 [&_a]:font-medium [&_a]:text-foreground [&_a]:underline [&_strong]:font-semibold [&_strong]:text-foreground"
|
|
44
|
+
set:html={captionHtml}
|
|
45
|
+
/>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
</figure>
|
|
49
|
+
</blume-frame>
|
|
50
|
+
|
|
51
|
+
<script>
|
|
52
|
+
class BlumeFrame extends HTMLElement {
|
|
53
|
+
connectedCallback() {
|
|
54
|
+
for (const video of this.querySelectorAll<HTMLVideoElement>(
|
|
55
|
+
"video[autoplay]"
|
|
56
|
+
)) {
|
|
57
|
+
video.playsInline = true;
|
|
58
|
+
video.loop = true;
|
|
59
|
+
video.muted = true;
|
|
60
|
+
video.setAttribute("playsinline", "");
|
|
61
|
+
video.setAttribute("loop", "");
|
|
62
|
+
video.setAttribute("muted", "");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!customElements.get("blume-frame")) {
|
|
68
|
+
customElements.define("blume-frame", BlumeFrame);
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
// A card linking to a GitHub repository with its star and fork counts, fetched
|
|
3
|
+
// at build time (no client JS). Pass `owner`/`repo`, or omit them to use the
|
|
4
|
+
// repo from blume.config. A `GITHUB_TOKEN` env var lifts the API rate limit.
|
|
5
|
+
// If the API is unreachable the card still renders, just without counts.
|
|
6
|
+
import data from "blume:data";
|
|
7
|
+
import { GITHUB_MARK } from "../github-mark.ts";
|
|
8
|
+
import { fetchRepositoryInfo } from "./github-info.ts";
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
owner?: string;
|
|
12
|
+
repo?: string;
|
|
13
|
+
token?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// The resolved config exposes the repo as `repoUrl`, not `github`; parse the
|
|
17
|
+
// owner/repo back out so <GithubInfo /> can default to the configured repo.
|
|
18
|
+
const repoMatch = data.config.repoUrl?.match(
|
|
19
|
+
/github\.com\/(?<owner>[^/]+)\/(?<repo>[^/]+)/u
|
|
20
|
+
);
|
|
21
|
+
const owner = Astro.props.owner ?? repoMatch?.groups?.owner;
|
|
22
|
+
const repo = Astro.props.repo ?? repoMatch?.groups?.repo;
|
|
23
|
+
const token = Astro.props.token ?? process.env.GITHUB_TOKEN;
|
|
24
|
+
|
|
25
|
+
const info =
|
|
26
|
+
owner && repo ? await fetchRepositoryInfo({ owner, repo, token }) : null;
|
|
27
|
+
|
|
28
|
+
// Compact notation matches GitHub's own counts (e.g. 1.2k, 34.5k).
|
|
29
|
+
const numbers = new Intl.NumberFormat("en", {
|
|
30
|
+
maximumFractionDigits: 1,
|
|
31
|
+
notation: "compact",
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const statIcon =
|
|
35
|
+
"size-3.5 shrink-0 text-muted-foreground"; /* shared classes for stat icons */
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
{
|
|
39
|
+
owner && repo && (
|
|
40
|
+
<a
|
|
41
|
+
class="not-prose my-6 flex flex-col gap-2 rounded-blume border border-border p-4 no-underline! transition-colors hover:border-foreground/30 hover:bg-muted/40"
|
|
42
|
+
href={`https://github.com/${owner}/${repo}`}
|
|
43
|
+
rel="noreferrer"
|
|
44
|
+
target="_blank"
|
|
45
|
+
>
|
|
46
|
+
<span class="flex items-center gap-2 font-medium text-foreground text-sm">
|
|
47
|
+
<svg
|
|
48
|
+
aria-hidden="true"
|
|
49
|
+
class="shrink-0 text-muted-foreground"
|
|
50
|
+
fill="currentColor"
|
|
51
|
+
height="16"
|
|
52
|
+
set:html={GITHUB_MARK}
|
|
53
|
+
viewBox="0 0 16 16"
|
|
54
|
+
width="16"
|
|
55
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
56
|
+
/>
|
|
57
|
+
<span class="truncate">
|
|
58
|
+
{owner}/{repo}
|
|
59
|
+
</span>
|
|
60
|
+
</span>
|
|
61
|
+
|
|
62
|
+
{info?.description && (
|
|
63
|
+
<span class="text-muted-foreground text-sm">{info.description}</span>
|
|
64
|
+
)}
|
|
65
|
+
|
|
66
|
+
{info && (
|
|
67
|
+
<span class="flex items-center gap-4 text-muted-foreground text-xs">
|
|
68
|
+
<span class="flex items-center gap-1.5">
|
|
69
|
+
<svg
|
|
70
|
+
aria-hidden="true"
|
|
71
|
+
class={statIcon}
|
|
72
|
+
fill="none"
|
|
73
|
+
height="14"
|
|
74
|
+
stroke="currentColor"
|
|
75
|
+
stroke-linecap="round"
|
|
76
|
+
stroke-linejoin="round"
|
|
77
|
+
stroke-width="2"
|
|
78
|
+
viewBox="0 0 24 24"
|
|
79
|
+
width="14"
|
|
80
|
+
>
|
|
81
|
+
<path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" />
|
|
82
|
+
</svg>
|
|
83
|
+
<span>{numbers.format(info.stars)}</span>
|
|
84
|
+
</span>
|
|
85
|
+
<span class="flex items-center gap-1.5">
|
|
86
|
+
<svg
|
|
87
|
+
aria-hidden="true"
|
|
88
|
+
class={statIcon}
|
|
89
|
+
fill="none"
|
|
90
|
+
height="14"
|
|
91
|
+
stroke="currentColor"
|
|
92
|
+
stroke-linecap="round"
|
|
93
|
+
stroke-linejoin="round"
|
|
94
|
+
stroke-width="2"
|
|
95
|
+
viewBox="0 0 24 24"
|
|
96
|
+
width="14"
|
|
97
|
+
>
|
|
98
|
+
<circle cx="12" cy="18" r="3" />
|
|
99
|
+
<circle cx="6" cy="6" r="3" />
|
|
100
|
+
<circle cx="18" cy="6" r="3" />
|
|
101
|
+
<path d="M18 9v2c0 .6-.4 1-1 1H7c-.6 0-1-.4-1-1V9" />
|
|
102
|
+
<path d="M12 12v3" />
|
|
103
|
+
</svg>
|
|
104
|
+
<span>{numbers.format(info.forks)}</span>
|
|
105
|
+
</span>
|
|
106
|
+
</span>
|
|
107
|
+
)}
|
|
108
|
+
</a>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
import "katex/dist/katex.min.css";
|
|
3
|
+
import katex from "katex";
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
code: string;
|
|
7
|
+
display?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { code, display = false } = Astro.props;
|
|
11
|
+
|
|
12
|
+
const html = katex.renderToString(code, {
|
|
13
|
+
displayMode: display,
|
|
14
|
+
throwOnError: false,
|
|
15
|
+
});
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
display ? (
|
|
20
|
+
<div class="not-prose my-4 overflow-x-auto" set:html={html} />
|
|
21
|
+
) : (
|
|
22
|
+
<Fragment set:html={html} />
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
const { title } = Astro.props;
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<aside
|
|
6
|
+
class="not-prose my-6 overflow-hidden rounded-blume border border-border/80 bg-background shadow-sm shadow-border/30"
|
|
7
|
+
data-blume-panel
|
|
8
|
+
data-blume-right-rail-item
|
|
9
|
+
>
|
|
10
|
+
{
|
|
11
|
+
title && (
|
|
12
|
+
<p class="m-0! border-border/70 border-b bg-muted/35 px-3.5 py-2 font-medium text-muted-foreground text-xs">
|
|
13
|
+
{title}
|
|
14
|
+
</p>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
<div class="px-3.5 py-3 text-sm leading-6 [&>:first-child]:mt-0! [&>:last-child]:mb-0!">
|
|
18
|
+
<slot />
|
|
19
|
+
</div>
|
|
20
|
+
</aside>
|