@silicajs/components 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backlinks.d.ts +12 -0
- package/dist/backlinks.js +36 -0
- package/dist/backlinks.js.map +1 -0
- package/dist/breadcrumbs.d.ts +10 -0
- package/dist/breadcrumbs.js +37 -0
- package/dist/breadcrumbs.js.map +1 -0
- package/dist/dark-mode-toggle.d.ts +8 -0
- package/dist/dark-mode-toggle.js +107 -0
- package/dist/dark-mode-toggle.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/not-allowed.d.ts +14 -0
- package/dist/not-allowed.js +27 -0
- package/dist/not-allowed.js.map +1 -0
- package/dist/not-found.d.ts +14 -0
- package/dist/not-found.js +27 -0
- package/dist/not-found.js.map +1 -0
- package/dist/page-properties.d.ts +10 -0
- package/dist/page-properties.js +80 -0
- package/dist/page-properties.js.map +1 -0
- package/dist/routing.d.ts +22 -0
- package/dist/routing.js +42 -0
- package/dist/routing.js.map +1 -0
- package/dist/search.d.ts +14 -0
- package/dist/search.js +158 -0
- package/dist/search.js.map +1 -0
- package/dist/slug.d.ts +6 -0
- package/dist/slug.js +20 -0
- package/dist/slug.js.map +1 -0
- package/dist/table-of-contents.d.ts +13 -0
- package/dist/table-of-contents.js +25 -0
- package/dist/table-of-contents.js.map +1 -0
- package/dist/tags-list.d.ts +11 -0
- package/dist/tags-list.js +68 -0
- package/dist/tags-list.js.map +1 -0
- package/dist/user-menu.d.ts +9 -0
- package/dist/user-menu.js +41 -0
- package/dist/user-menu.js.map +1 -0
- package/dist/vault-tree.d.ts +15 -0
- package/dist/vault-tree.js +248 -0
- package/dist/vault-tree.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { Graph, Manifest } from '@silicajs/core/runtime';
|
|
3
|
+
|
|
4
|
+
type BacklinksProps = {
|
|
5
|
+
graph: Graph;
|
|
6
|
+
slug: string;
|
|
7
|
+
manifest: Manifest;
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
declare function Backlinks({ graph, slug, manifest, className, }: BacklinksProps): react_jsx_runtime.JSX.Element | null;
|
|
11
|
+
|
|
12
|
+
export { Backlinks, type BacklinksProps };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import {
|
|
3
|
+
Card,
|
|
4
|
+
CardContent,
|
|
5
|
+
CardHeader,
|
|
6
|
+
CardTitle
|
|
7
|
+
} from "@silicajs/ui/components/card";
|
|
8
|
+
import { SilicaLink } from "./routing.js";
|
|
9
|
+
import { slugToHref } from "./slug.js";
|
|
10
|
+
function Backlinks({
|
|
11
|
+
graph,
|
|
12
|
+
slug,
|
|
13
|
+
manifest,
|
|
14
|
+
className
|
|
15
|
+
}) {
|
|
16
|
+
const backlinks = graph.backlinks[slug] ?? [];
|
|
17
|
+
if (backlinks.length === 0) return null;
|
|
18
|
+
return /* @__PURE__ */ jsxs(Card, { size: "sm", className, "data-slot": "backlinks", children: [
|
|
19
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: "Backlinks" }) }),
|
|
20
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-1.5 text-sm", children: backlinks.map((source) => {
|
|
21
|
+
const entry = manifest.bySlug[source];
|
|
22
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
23
|
+
SilicaLink,
|
|
24
|
+
{
|
|
25
|
+
href: slugToHref(source),
|
|
26
|
+
className: "text-primary hover:underline",
|
|
27
|
+
children: entry?.title ?? source
|
|
28
|
+
}
|
|
29
|
+
) }, source);
|
|
30
|
+
}) }) })
|
|
31
|
+
] });
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
Backlinks
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=backlinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/backlinks.tsx"],"sourcesContent":["import type { Graph, Manifest } from \"@silicajs/core/runtime\";\n\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n} from \"@silicajs/ui/components/card\";\n\nimport { SilicaLink } from \"./routing.js\";\nimport { slugToHref } from \"./slug.js\";\n\nexport type BacklinksProps = {\n graph: Graph;\n slug: string;\n manifest: Manifest;\n className?: string;\n};\n\nexport function Backlinks({\n graph,\n slug,\n manifest,\n className,\n}: BacklinksProps) {\n const backlinks = graph.backlinks[slug] ?? [];\n if (backlinks.length === 0) return null;\n return (\n <Card size=\"sm\" className={className} data-slot=\"backlinks\">\n <CardHeader>\n <CardTitle>Backlinks</CardTitle>\n </CardHeader>\n <CardContent>\n <ul className=\"flex flex-col gap-1.5 text-sm\">\n {backlinks.map((source) => {\n const entry = manifest.bySlug[source];\n return (\n <li key={source}>\n <SilicaLink\n href={slugToHref(source)}\n className=\"text-primary hover:underline\"\n >\n {entry?.title ?? source}\n </SilicaLink>\n </li>\n );\n })}\n </ul>\n </CardContent>\n </Card>\n );\n}\n"],"mappings":"AA4BI,SAEI,KAFJ;AA1BJ;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB;AASpB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,YAAY,MAAM,UAAU,IAAI,KAAK,CAAC;AAC5C,MAAI,UAAU,WAAW,EAAG,QAAO;AACnC,SACE,qBAAC,QAAK,MAAK,MAAK,WAAsB,aAAU,aAC9C;AAAA,wBAAC,cACC,8BAAC,aAAU,uBAAS,GACtB;AAAA,IACA,oBAAC,eACC,8BAAC,QAAG,WAAU,iCACX,oBAAU,IAAI,CAAC,WAAW;AACzB,YAAM,QAAQ,SAAS,OAAO,MAAM;AACpC,aACE,oBAAC,QACC;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,WAAW,MAAM;AAAA,UACvB,WAAU;AAAA,UAET,iBAAO,SAAS;AAAA;AAAA,MACnB,KANO,MAOT;AAAA,IAEJ,CAAC,GACH,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type BreadcrumbsProps = {
|
|
4
|
+
slug: string;
|
|
5
|
+
allSlugs: readonly string[];
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
declare function Breadcrumbs({ slug, allSlugs, className }: BreadcrumbsProps): react_jsx_runtime.JSX.Element;
|
|
9
|
+
|
|
10
|
+
export { Breadcrumbs, type BreadcrumbsProps };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import {
|
|
4
|
+
Breadcrumb,
|
|
5
|
+
BreadcrumbItem,
|
|
6
|
+
BreadcrumbLink,
|
|
7
|
+
BreadcrumbList,
|
|
8
|
+
BreadcrumbPage,
|
|
9
|
+
BreadcrumbSeparator
|
|
10
|
+
} from "@silicajs/ui/components/breadcrumb";
|
|
11
|
+
import { SilicaLink } from "./routing.js";
|
|
12
|
+
import { breadcrumbSegmentHref, prettySegment } from "./slug.js";
|
|
13
|
+
function Breadcrumbs({ slug, allSlugs, className }) {
|
|
14
|
+
const segments = slug === "index" ? [] : slug.split("/").slice(0, -1);
|
|
15
|
+
let acc = "";
|
|
16
|
+
return /* @__PURE__ */ jsx(Breadcrumb, { className, children: /* @__PURE__ */ jsxs(BreadcrumbList, { children: [
|
|
17
|
+
/* @__PURE__ */ jsx(BreadcrumbItem, { children: segments.length === 0 ? /* @__PURE__ */ jsx(BreadcrumbPage, { children: "Home" }) : /* @__PURE__ */ jsx(BreadcrumbLink, { render: /* @__PURE__ */ jsx(SilicaLink, { href: "/", children: "Home" }) }) }),
|
|
18
|
+
segments.map((segment) => {
|
|
19
|
+
acc = acc ? `${acc}/${segment}` : segment;
|
|
20
|
+
const label = prettySegment(segment);
|
|
21
|
+
const href = breadcrumbSegmentHref(acc, allSlugs);
|
|
22
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
23
|
+
/* @__PURE__ */ jsx(BreadcrumbSeparator, {}),
|
|
24
|
+
/* @__PURE__ */ jsx(BreadcrumbItem, { children: href ? /* @__PURE__ */ jsx(
|
|
25
|
+
BreadcrumbLink,
|
|
26
|
+
{
|
|
27
|
+
render: /* @__PURE__ */ jsx(SilicaLink, { href, children: label })
|
|
28
|
+
}
|
|
29
|
+
) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: label }) })
|
|
30
|
+
] }, acc);
|
|
31
|
+
})
|
|
32
|
+
] }) });
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
Breadcrumbs
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=breadcrumbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/breadcrumbs.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@silicajs/ui/components/breadcrumb\";\n\nimport { SilicaLink } from \"./routing.js\";\nimport { breadcrumbSegmentHref, prettySegment } from \"./slug.js\";\n\nexport type BreadcrumbsProps = {\n slug: string;\n allSlugs: readonly string[];\n className?: string;\n};\n\nexport function Breadcrumbs({ slug, allSlugs, className }: BreadcrumbsProps) {\n const segments = slug === \"index\" ? [] : slug.split(\"/\").slice(0, -1);\n let acc = \"\";\n return (\n <Breadcrumb className={className}>\n <BreadcrumbList>\n <BreadcrumbItem>\n {segments.length === 0 ? (\n <BreadcrumbPage>Home</BreadcrumbPage>\n ) : (\n <BreadcrumbLink render={<SilicaLink href=\"/\">Home</SilicaLink>} />\n )}\n </BreadcrumbItem>\n {segments.map((segment) => {\n acc = acc ? `${acc}/${segment}` : segment;\n const label = prettySegment(segment);\n const href = breadcrumbSegmentHref(acc, allSlugs);\n return (\n <React.Fragment key={acc}>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n {href ? (\n <BreadcrumbLink\n render={<SilicaLink href={href}>{label}</SilicaLink>}\n />\n ) : (\n <BreadcrumbPage>{label}</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n </React.Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n"],"mappings":"AA4BY,cAUA,YAVA;AA5BZ,YAAY,WAAW;AAEvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB,qBAAqB;AAQ9C,SAAS,YAAY,EAAE,MAAM,UAAU,UAAU,GAAqB;AAC3E,QAAM,WAAW,SAAS,UAAU,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE;AACpE,MAAI,MAAM;AACV,SACE,oBAAC,cAAW,WACV,+BAAC,kBACC;AAAA,wBAAC,kBACE,mBAAS,WAAW,IACnB,oBAAC,kBAAe,kBAAI,IAEpB,oBAAC,kBAAe,QAAQ,oBAAC,cAAW,MAAK,KAAI,kBAAI,GAAe,GAEpE;AAAA,IACC,SAAS,IAAI,CAAC,YAAY;AACzB,YAAM,MAAM,GAAG,GAAG,IAAI,OAAO,KAAK;AAClC,YAAM,QAAQ,cAAc,OAAO;AACnC,YAAM,OAAO,sBAAsB,KAAK,QAAQ;AAChD,aACE,qBAAC,MAAM,UAAN,EACC;AAAA,4BAAC,uBAAoB;AAAA,QACrB,oBAAC,kBACE,iBACC;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ,oBAAC,cAAW,MAAa,iBAAM;AAAA;AAAA,QACzC,IAEA,oBAAC,kBAAgB,iBAAM,GAE3B;AAAA,WAVmB,GAWrB;AAAA,IAEJ,CAAC;AAAA,KACH,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type DarkModeToggleProps = {
|
|
4
|
+
className?: string;
|
|
5
|
+
};
|
|
6
|
+
declare function DarkModeToggle({ className }: DarkModeToggleProps): react_jsx_runtime.JSX.Element;
|
|
7
|
+
|
|
8
|
+
export { DarkModeToggle, type DarkModeToggleProps };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { MoonIcon, SunIcon } from "lucide-react";
|
|
5
|
+
const STORAGE_KEY = "silica-theme";
|
|
6
|
+
const SYSTEM_THEME_QUERY = "(prefers-color-scheme: dark)";
|
|
7
|
+
function readStoredTheme() {
|
|
8
|
+
try {
|
|
9
|
+
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
10
|
+
return stored === "dark" || stored === "light" ? stored : null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function readSystemTheme() {
|
|
16
|
+
if (!window.matchMedia) return "light";
|
|
17
|
+
return window.matchMedia(SYSTEM_THEME_QUERY).matches ? "dark" : "light";
|
|
18
|
+
}
|
|
19
|
+
function resolveTheme() {
|
|
20
|
+
return readStoredTheme() ?? readSystemTheme();
|
|
21
|
+
}
|
|
22
|
+
function applyTheme(theme) {
|
|
23
|
+
if (typeof document === "undefined") return;
|
|
24
|
+
const root = document.documentElement;
|
|
25
|
+
root.classList.remove("dark", "light");
|
|
26
|
+
root.classList.add(theme);
|
|
27
|
+
}
|
|
28
|
+
function watchThemeChanges(onThemeChange) {
|
|
29
|
+
const media = window.matchMedia(SYSTEM_THEME_QUERY);
|
|
30
|
+
const syncTheme = () => {
|
|
31
|
+
const next = resolveTheme();
|
|
32
|
+
applyTheme(next);
|
|
33
|
+
onThemeChange(next);
|
|
34
|
+
};
|
|
35
|
+
const handleSystemThemeChange = () => {
|
|
36
|
+
if (!readStoredTheme()) syncTheme();
|
|
37
|
+
};
|
|
38
|
+
const handleStorageChange = (event) => {
|
|
39
|
+
if (event.key === STORAGE_KEY || event.key === null) syncTheme();
|
|
40
|
+
};
|
|
41
|
+
media.addEventListener("change", handleSystemThemeChange);
|
|
42
|
+
window.addEventListener("storage", handleStorageChange);
|
|
43
|
+
syncTheme();
|
|
44
|
+
return () => {
|
|
45
|
+
media.removeEventListener("change", handleSystemThemeChange);
|
|
46
|
+
window.removeEventListener("storage", handleStorageChange);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function persistTheme(theme) {
|
|
50
|
+
try {
|
|
51
|
+
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
52
|
+
if (stored !== theme) {
|
|
53
|
+
window.localStorage.setItem(STORAGE_KEY, theme);
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
applyTheme(theme);
|
|
58
|
+
}
|
|
59
|
+
function DarkModeToggle({ className }) {
|
|
60
|
+
const [theme, setTheme] = React.useState("light");
|
|
61
|
+
const [mounted, setMounted] = React.useState(false);
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
const unwatchThemeChanges = watchThemeChanges(setTheme);
|
|
64
|
+
setMounted(true);
|
|
65
|
+
return unwatchThemeChanges;
|
|
66
|
+
}, []);
|
|
67
|
+
const setAndPersist = (next) => {
|
|
68
|
+
setTheme(next);
|
|
69
|
+
persistTheme(next);
|
|
70
|
+
};
|
|
71
|
+
const isLight = mounted && theme === "light";
|
|
72
|
+
const isDark = mounted && theme === "dark";
|
|
73
|
+
const nextTheme = theme === "dark" ? "light" : "dark";
|
|
74
|
+
return /* @__PURE__ */ jsxs(
|
|
75
|
+
"button",
|
|
76
|
+
{
|
|
77
|
+
type: "button",
|
|
78
|
+
role: "switch",
|
|
79
|
+
"aria-checked": isDark,
|
|
80
|
+
"aria-label": `Switch to ${nextTheme} mode`,
|
|
81
|
+
onClick: () => setAndPersist(nextTheme),
|
|
82
|
+
className: `inline-flex items-center rounded-full border border-border bg-muted/50 p-0.5 transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${className ?? ""}`,
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ jsx(
|
|
85
|
+
"span",
|
|
86
|
+
{
|
|
87
|
+
"aria-hidden": "true",
|
|
88
|
+
className: `inline-flex size-6 items-center justify-center rounded-full transition-colors ${isLight ? "bg-background text-foreground shadow-sm" : "text-muted-foreground"}`,
|
|
89
|
+
children: /* @__PURE__ */ jsx(SunIcon, { className: "size-3.5", "aria-hidden": "true" })
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"span",
|
|
94
|
+
{
|
|
95
|
+
"aria-hidden": "true",
|
|
96
|
+
className: `inline-flex size-6 items-center justify-center rounded-full transition-colors ${isDark ? "bg-background text-foreground shadow-sm" : "text-muted-foreground"}`,
|
|
97
|
+
children: /* @__PURE__ */ jsx(MoonIcon, { className: "size-3.5", "aria-hidden": "true" })
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
DarkModeToggle
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=dark-mode-toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/dark-mode-toggle.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { MoonIcon, SunIcon } from \"lucide-react\";\n\nconst STORAGE_KEY = \"silica-theme\";\nconst SYSTEM_THEME_QUERY = \"(prefers-color-scheme: dark)\";\n\ntype Theme = \"light\" | \"dark\";\n\nfunction readStoredTheme(): Theme | null {\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n return stored === \"dark\" || stored === \"light\" ? stored : null;\n } catch {\n return null;\n }\n}\n\nfunction readSystemTheme(): Theme {\n if (!window.matchMedia) return \"light\";\n return window.matchMedia(SYSTEM_THEME_QUERY).matches ? \"dark\" : \"light\";\n}\n\nfunction resolveTheme(): Theme {\n return readStoredTheme() ?? readSystemTheme();\n}\n\nfunction applyTheme(theme: Theme) {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.classList.remove(\"dark\", \"light\");\n root.classList.add(theme);\n}\n\nfunction watchThemeChanges(onThemeChange: (theme: Theme) => void) {\n const media = window.matchMedia(SYSTEM_THEME_QUERY);\n const syncTheme = () => {\n const next = resolveTheme();\n applyTheme(next);\n onThemeChange(next);\n };\n\n const handleSystemThemeChange = () => {\n if (!readStoredTheme()) syncTheme();\n };\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key === STORAGE_KEY || event.key === null) syncTheme();\n };\n\n media.addEventListener(\"change\", handleSystemThemeChange);\n window.addEventListener(\"storage\", handleStorageChange);\n\n syncTheme();\n\n return () => {\n media.removeEventListener(\"change\", handleSystemThemeChange);\n window.removeEventListener(\"storage\", handleStorageChange);\n };\n}\n\nfunction persistTheme(theme: Theme) {\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored !== theme) {\n window.localStorage.setItem(STORAGE_KEY, theme);\n }\n } catch {\n // The visual theme can still update when storage is unavailable.\n }\n applyTheme(theme);\n}\n\nexport type DarkModeToggleProps = {\n className?: string;\n};\n\nexport function DarkModeToggle({ className }: DarkModeToggleProps) {\n const [theme, setTheme] = React.useState<Theme>(\"light\");\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n const unwatchThemeChanges = watchThemeChanges(setTheme);\n setMounted(true);\n return unwatchThemeChanges;\n }, []);\n\n const setAndPersist = (next: Theme) => {\n setTheme(next);\n persistTheme(next);\n };\n\n const isLight = mounted && theme === \"light\";\n const isDark = mounted && theme === \"dark\";\n const nextTheme: Theme = theme === \"dark\" ? \"light\" : \"dark\";\n\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={isDark}\n aria-label={`Switch to ${nextTheme} mode`}\n onClick={() => setAndPersist(nextTheme)}\n className={`inline-flex items-center rounded-full border border-border bg-muted/50 p-0.5 transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${className ?? \"\"}`}\n >\n <span\n aria-hidden=\"true\"\n className={`inline-flex size-6 items-center justify-center rounded-full transition-colors ${\n isLight\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground\"\n }`}\n >\n <SunIcon className=\"size-3.5\" aria-hidden=\"true\" />\n </span>\n <span\n aria-hidden=\"true\"\n className={`inline-flex size-6 items-center justify-center rounded-full transition-colors ${\n isDark\n ? \"bg-background text-foreground shadow-sm\"\n : \"text-muted-foreground\"\n }`}\n >\n <MoonIcon className=\"size-3.5\" aria-hidden=\"true\" />\n </span>\n </button>\n );\n}\n"],"mappings":";AAkGI,SAgBI,KAhBJ;AAhGJ,YAAY,WAAW;AACvB,SAAS,UAAU,eAAe;AAElC,MAAM,cAAc;AACpB,MAAM,qBAAqB;AAI3B,SAAS,kBAAgC;AACvC,MAAI;AACF,UAAM,SAAS,OAAO,aAAa,QAAQ,WAAW;AACtD,WAAO,WAAW,UAAU,WAAW,UAAU,SAAS;AAAA,EAC5D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAyB;AAChC,MAAI,CAAC,OAAO,WAAY,QAAO;AAC/B,SAAO,OAAO,WAAW,kBAAkB,EAAE,UAAU,SAAS;AAClE;AAEA,SAAS,eAAsB;AAC7B,SAAO,gBAAgB,KAAK,gBAAgB;AAC9C;AAEA,SAAS,WAAW,OAAc;AAChC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,OAAO,SAAS;AACtB,OAAK,UAAU,OAAO,QAAQ,OAAO;AACrC,OAAK,UAAU,IAAI,KAAK;AAC1B;AAEA,SAAS,kBAAkB,eAAuC;AAChE,QAAM,QAAQ,OAAO,WAAW,kBAAkB;AAClD,QAAM,YAAY,MAAM;AACtB,UAAM,OAAO,aAAa;AAC1B,eAAW,IAAI;AACf,kBAAc,IAAI;AAAA,EACpB;AAEA,QAAM,0BAA0B,MAAM;AACpC,QAAI,CAAC,gBAAgB,EAAG,WAAU;AAAA,EACpC;AAEA,QAAM,sBAAsB,CAAC,UAAwB;AACnD,QAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,KAAM,WAAU;AAAA,EACjE;AAEA,QAAM,iBAAiB,UAAU,uBAAuB;AACxD,SAAO,iBAAiB,WAAW,mBAAmB;AAEtD,YAAU;AAEV,SAAO,MAAM;AACX,UAAM,oBAAoB,UAAU,uBAAuB;AAC3D,WAAO,oBAAoB,WAAW,mBAAmB;AAAA,EAC3D;AACF;AAEA,SAAS,aAAa,OAAc;AAClC,MAAI;AACF,UAAM,SAAS,OAAO,aAAa,QAAQ,WAAW;AACtD,QAAI,WAAW,OAAO;AACpB,aAAO,aAAa,QAAQ,aAAa,KAAK;AAAA,IAChD;AAAA,EACF,QAAQ;AAAA,EAER;AACA,aAAW,KAAK;AAClB;AAMO,SAAS,eAAe,EAAE,UAAU,GAAwB;AACjE,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAgB,OAAO;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,KAAK;AAElD,QAAM,UAAU,MAAM;AACpB,UAAM,sBAAsB,kBAAkB,QAAQ;AACtD,eAAW,IAAI;AACf,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB,CAAC,SAAgB;AACrC,aAAS,IAAI;AACb,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,UAAU,WAAW,UAAU;AACrC,QAAM,SAAS,WAAW,UAAU;AACpC,QAAM,YAAmB,UAAU,SAAS,UAAU;AAEtD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,cAAY,aAAa,SAAS;AAAA,MAClC,SAAS,MAAM,cAAc,SAAS;AAAA,MACtC,WAAW,qNAAqN,aAAa,EAAE;AAAA,MAE/O;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAW,iFACT,UACI,4CACA,uBACN;AAAA,YAEA,8BAAC,WAAQ,WAAU,YAAW,eAAY,QAAO;AAAA;AAAA,QACnD;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAW,iFACT,SACI,4CACA,uBACN;AAAA,YAEA,8BAAC,YAAS,WAAU,YAAW,eAAY,QAAO;AAAA;AAAA,QACpD;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { Backlinks, BacklinksProps } from './backlinks.js';
|
|
2
|
+
export { Breadcrumbs, BreadcrumbsProps } from './breadcrumbs.js';
|
|
3
|
+
export { DarkModeToggle, DarkModeToggleProps } from './dark-mode-toggle.js';
|
|
4
|
+
export { NotAllowed, NotAllowedProps } from './not-allowed.js';
|
|
5
|
+
export { NotFound, NotFoundProps } from './not-found.js';
|
|
6
|
+
export { PageProperties, PagePropertiesProps } from './page-properties.js';
|
|
7
|
+
export { SearchPalette, SearchPaletteProps, SearchTrigger, SearchTriggerProps } from './search.js';
|
|
8
|
+
export { SilicaLink, SilicaLinkComponent, SilicaLinkProps, SilicaRoutingContextValue, SilicaRoutingProvider, SilicaRoutingProviderProps, useSilicaRouting } from './routing.js';
|
|
9
|
+
export { TableOfContents, TableOfContentsProps } from './table-of-contents.js';
|
|
10
|
+
export { TagsList, TagsListProps } from './tags-list.js';
|
|
11
|
+
export { UserMenu, UserMenuProps } from './user-menu.js';
|
|
12
|
+
export { VaultTree, VaultTreeProps } from './vault-tree.js';
|
|
13
|
+
export { breadcrumbSegmentHref, prettySegment, slugToHref } from './slug.js';
|
|
14
|
+
import 'react/jsx-runtime';
|
|
15
|
+
import '@silicajs/core/runtime';
|
|
16
|
+
import 'react';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Backlinks } from "./backlinks.js";
|
|
2
|
+
import { Breadcrumbs } from "./breadcrumbs.js";
|
|
3
|
+
import {
|
|
4
|
+
DarkModeToggle
|
|
5
|
+
} from "./dark-mode-toggle.js";
|
|
6
|
+
import { NotAllowed } from "./not-allowed.js";
|
|
7
|
+
import { NotFound } from "./not-found.js";
|
|
8
|
+
import { PageProperties } from "./page-properties.js";
|
|
9
|
+
import {
|
|
10
|
+
SearchPalette,
|
|
11
|
+
SearchTrigger
|
|
12
|
+
} from "./search.js";
|
|
13
|
+
import {
|
|
14
|
+
SilicaLink,
|
|
15
|
+
SilicaRoutingProvider,
|
|
16
|
+
useSilicaRouting
|
|
17
|
+
} from "./routing.js";
|
|
18
|
+
import {
|
|
19
|
+
TableOfContents
|
|
20
|
+
} from "./table-of-contents.js";
|
|
21
|
+
import { TagsList } from "./tags-list.js";
|
|
22
|
+
import { UserMenu } from "./user-menu.js";
|
|
23
|
+
import { VaultTree } from "./vault-tree.js";
|
|
24
|
+
import { breadcrumbSegmentHref, prettySegment, slugToHref } from "./slug.js";
|
|
25
|
+
export {
|
|
26
|
+
Backlinks,
|
|
27
|
+
Breadcrumbs,
|
|
28
|
+
DarkModeToggle,
|
|
29
|
+
NotAllowed,
|
|
30
|
+
NotFound,
|
|
31
|
+
PageProperties,
|
|
32
|
+
SearchPalette,
|
|
33
|
+
SearchTrigger,
|
|
34
|
+
SilicaLink,
|
|
35
|
+
SilicaRoutingProvider,
|
|
36
|
+
TableOfContents,
|
|
37
|
+
TagsList,
|
|
38
|
+
UserMenu,
|
|
39
|
+
VaultTree,
|
|
40
|
+
breadcrumbSegmentHref,
|
|
41
|
+
prettySegment,
|
|
42
|
+
slugToHref,
|
|
43
|
+
useSilicaRouting
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Backlinks, type BacklinksProps } from \"./backlinks.js\";\nexport { Breadcrumbs, type BreadcrumbsProps } from \"./breadcrumbs.js\";\nexport {\n DarkModeToggle,\n type DarkModeToggleProps,\n} from \"./dark-mode-toggle.js\";\nexport { NotAllowed, type NotAllowedProps } from \"./not-allowed.js\";\nexport { NotFound, type NotFoundProps } from \"./not-found.js\";\nexport { PageProperties, type PagePropertiesProps } from \"./page-properties.js\";\nexport {\n SearchPalette,\n SearchTrigger,\n type SearchPaletteProps,\n type SearchTriggerProps,\n} from \"./search.js\";\nexport {\n SilicaLink,\n SilicaRoutingProvider,\n useSilicaRouting,\n type SilicaLinkComponent,\n type SilicaLinkProps,\n type SilicaRoutingContextValue,\n type SilicaRoutingProviderProps,\n} from \"./routing.js\";\nexport {\n TableOfContents,\n type TableOfContentsProps,\n} from \"./table-of-contents.js\";\nexport { TagsList, type TagsListProps } from \"./tags-list.js\";\nexport { UserMenu, type UserMenuProps } from \"./user-menu.js\";\nexport { VaultTree, type VaultTreeProps } from \"./vault-tree.js\";\nexport { breadcrumbSegmentHref, prettySegment, slugToHref } from \"./slug.js\";\n"],"mappings":"AAAA,SAAS,iBAAsC;AAC/C,SAAS,mBAA0C;AACnD;AAAA,EACE;AAAA,OAEK;AACP,SAAS,kBAAwC;AACjD,SAAS,gBAAoC;AAC7C,SAAS,sBAAgD;AACzD;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,gBAAoC;AAC7C,SAAS,gBAAoC;AAC7C,SAAS,iBAAsC;AAC/C,SAAS,uBAAuB,eAAe,kBAAkB;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type NotAllowedProps = {
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
cta?: {
|
|
7
|
+
href: string;
|
|
8
|
+
label: string;
|
|
9
|
+
};
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function NotAllowed({ title, description, cta, className, }: NotAllowedProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { NotAllowed, type NotAllowedProps };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@silicajs/ui/components/button";
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle
|
|
9
|
+
} from "@silicajs/ui/components/card";
|
|
10
|
+
function NotAllowed({
|
|
11
|
+
title = "Not allowed",
|
|
12
|
+
description = "Your email is not on this site's allowlist.",
|
|
13
|
+
cta = { href: "/sign-in", label: "Try a different account" },
|
|
14
|
+
className
|
|
15
|
+
}) {
|
|
16
|
+
return /* @__PURE__ */ jsx("main", { className, "data-slot": "not-allowed", children: /* @__PURE__ */ jsxs(Card, { className: "mx-auto max-w-md", children: [
|
|
17
|
+
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
18
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "text-lg", children: title }),
|
|
19
|
+
/* @__PURE__ */ jsx(CardDescription, { children: description })
|
|
20
|
+
] }),
|
|
21
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(Button, { render: /* @__PURE__ */ jsx("a", { href: cta.href, children: cta.label }) }) })
|
|
22
|
+
] }) });
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
NotAllowed
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=not-allowed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/not-allowed.tsx"],"sourcesContent":["import { Button } from \"@silicajs/ui/components/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@silicajs/ui/components/card\";\n\nexport type NotAllowedProps = {\n title?: string;\n description?: string;\n cta?: { href: string; label: string };\n className?: string;\n};\n\nexport function NotAllowed({\n title = \"Not allowed\",\n description = \"Your email is not on this site's allowlist.\",\n cta = { href: \"/sign-in\", label: \"Try a different account\" },\n className,\n}: NotAllowedProps) {\n return (\n <main className={className} data-slot=\"not-allowed\">\n <Card className=\"mx-auto max-w-md\">\n <CardHeader>\n <CardTitle className=\"text-lg\">{title}</CardTitle>\n <CardDescription>{description}</CardDescription>\n </CardHeader>\n <CardContent>\n <Button render={<a href={cta.href}>{cta.label}</a>} />\n </CardContent>\n </Card>\n </main>\n );\n}\n"],"mappings":"AAyBQ,SACE,KADF;AAzBR,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASA,SAAS,WAAW;AAAA,EACzB,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,MAAM,EAAE,MAAM,YAAY,OAAO,0BAA0B;AAAA,EAC3D;AACF,GAAoB;AAClB,SACE,oBAAC,UAAK,WAAsB,aAAU,eACpC,+BAAC,QAAK,WAAU,oBACd;AAAA,yBAAC,cACC;AAAA,0BAAC,aAAU,WAAU,WAAW,iBAAM;AAAA,MACtC,oBAAC,mBAAiB,uBAAY;AAAA,OAChC;AAAA,IACA,oBAAC,eACC,8BAAC,UAAO,QAAQ,oBAAC,OAAE,MAAM,IAAI,MAAO,cAAI,OAAM,GAAM,GACtD;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type NotFoundProps = {
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
cta?: {
|
|
7
|
+
href: string;
|
|
8
|
+
label: string;
|
|
9
|
+
};
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function NotFound({ title, description, cta, className, }: NotFoundProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { NotFound, type NotFoundProps };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from "@silicajs/ui/components/button";
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle
|
|
9
|
+
} from "@silicajs/ui/components/card";
|
|
10
|
+
function NotFound({
|
|
11
|
+
title = "Page not found",
|
|
12
|
+
description = "The requested note does not exist or is not published.",
|
|
13
|
+
cta = { href: "/", label: "Return home" },
|
|
14
|
+
className
|
|
15
|
+
}) {
|
|
16
|
+
return /* @__PURE__ */ jsx("main", { className, "data-slot": "not-found", children: /* @__PURE__ */ jsxs(Card, { className: "mx-auto max-w-md", children: [
|
|
17
|
+
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
18
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "text-lg", children: title }),
|
|
19
|
+
/* @__PURE__ */ jsx(CardDescription, { children: description })
|
|
20
|
+
] }),
|
|
21
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(Button, { variant: "outline", render: /* @__PURE__ */ jsx("a", { href: cta.href, children: cta.label }) }) })
|
|
22
|
+
] }) });
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
NotFound
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=not-found.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/not-found.tsx"],"sourcesContent":["import { Button } from \"@silicajs/ui/components/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@silicajs/ui/components/card\";\n\nexport type NotFoundProps = {\n title?: string;\n description?: string;\n cta?: { href: string; label: string };\n className?: string;\n};\n\nexport function NotFound({\n title = \"Page not found\",\n description = \"The requested note does not exist or is not published.\",\n cta = { href: \"/\", label: \"Return home\" },\n className,\n}: NotFoundProps) {\n return (\n <main className={className} data-slot=\"not-found\">\n <Card className=\"mx-auto max-w-md\">\n <CardHeader>\n <CardTitle className=\"text-lg\">{title}</CardTitle>\n <CardDescription>{description}</CardDescription>\n </CardHeader>\n <CardContent>\n <Button variant=\"outline\" render={<a href={cta.href}>{cta.label}</a>} />\n </CardContent>\n </Card>\n </main>\n );\n}\n"],"mappings":"AAyBQ,SACE,KADF;AAzBR,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASA,SAAS,SAAS;AAAA,EACvB,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,MAAM,EAAE,MAAM,KAAK,OAAO,cAAc;AAAA,EACxC;AACF,GAAkB;AAChB,SACE,oBAAC,UAAK,WAAsB,aAAU,aACpC,+BAAC,QAAK,WAAU,oBACd;AAAA,yBAAC,cACC;AAAA,0BAAC,aAAU,WAAU,WAAW,iBAAM;AAAA,MACtC,oBAAC,mBAAiB,uBAAY;AAAA,OAChC;AAAA,IACA,oBAAC,eACC,8BAAC,UAAO,SAAQ,WAAU,QAAQ,oBAAC,OAAE,MAAM,IAAI,MAAO,cAAI,OAAM,GAAM,GACxE;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type PagePropertiesProps = {
|
|
4
|
+
frontmatter: Record<string, unknown>;
|
|
5
|
+
className?: string;
|
|
6
|
+
defaultOpen?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare function PageProperties({ frontmatter, className, defaultOpen, }: PagePropertiesProps): react_jsx_runtime.JSX.Element | null;
|
|
9
|
+
|
|
10
|
+
export { PageProperties, type PagePropertiesProps };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronRight } from "lucide-react";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { cn } from "@silicajs/ui/lib/utils";
|
|
6
|
+
import {
|
|
7
|
+
Collapsible,
|
|
8
|
+
CollapsibleContent,
|
|
9
|
+
CollapsibleTrigger
|
|
10
|
+
} from "@silicajs/ui/components/collapsible";
|
|
11
|
+
import { getPageProperties } from "@silicajs/core/runtime";
|
|
12
|
+
const STORAGE_KEY = "silica:page-properties:open";
|
|
13
|
+
function PageProperties({
|
|
14
|
+
frontmatter,
|
|
15
|
+
className,
|
|
16
|
+
defaultOpen = false
|
|
17
|
+
}) {
|
|
18
|
+
const properties = getPageProperties(frontmatter);
|
|
19
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
try {
|
|
22
|
+
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
23
|
+
if (stored === "true" || stored === "false") {
|
|
24
|
+
setOpen(stored === "true");
|
|
25
|
+
}
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}, []);
|
|
29
|
+
function handleOpenChange(next) {
|
|
30
|
+
setOpen(next);
|
|
31
|
+
try {
|
|
32
|
+
window.localStorage.setItem(STORAGE_KEY, String(next));
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (properties.length === 0) return null;
|
|
37
|
+
return /* @__PURE__ */ jsxs(
|
|
38
|
+
Collapsible,
|
|
39
|
+
{
|
|
40
|
+
"data-slot": "page-properties",
|
|
41
|
+
open,
|
|
42
|
+
onOpenChange: handleOpenChange,
|
|
43
|
+
className: cn(
|
|
44
|
+
"rounded-lg border border-border bg-card text-sm",
|
|
45
|
+
className
|
|
46
|
+
),
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "flex w-full cursor-pointer items-center gap-2 px-4 py-2.5 text-left font-medium", children: [
|
|
49
|
+
/* @__PURE__ */ jsx(
|
|
50
|
+
ChevronRight,
|
|
51
|
+
{
|
|
52
|
+
className: cn(
|
|
53
|
+
"size-4 shrink-0 text-muted-foreground transition-transform",
|
|
54
|
+
open && "rotate-90"
|
|
55
|
+
),
|
|
56
|
+
"aria-hidden": true
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
/* @__PURE__ */ jsx("span", { className: "text-foreground", children: "Page Properties" }),
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "ml-auto text-xs tabular-nums text-muted-foreground", children: properties.length })
|
|
61
|
+
] }),
|
|
62
|
+
/* @__PURE__ */ jsx(CollapsibleContent, { className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-200 ease-out data-[ending-style]:h-0 data-[starting-style]:h-0 motion-reduce:transition-none", children: /* @__PURE__ */ jsx("dl", { className: "border-t border-border", children: properties.map((property) => /* @__PURE__ */ jsxs(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
className: "grid grid-cols-[10rem_1fr] gap-x-4 border-t border-border first:border-t-0",
|
|
66
|
+
children: [
|
|
67
|
+
/* @__PURE__ */ jsx("dt", { className: "px-4 py-2 text-muted-foreground", children: property.label }),
|
|
68
|
+
/* @__PURE__ */ jsx("dd", { className: "px-4 py-2 text-foreground", children: property.value })
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
property.key
|
|
72
|
+
)) }) })
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
PageProperties
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=page-properties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/page-properties.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\n\nimport { cn } from \"@silicajs/ui/lib/utils\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@silicajs/ui/components/collapsible\";\nimport { getPageProperties } from \"@silicajs/core/runtime\";\n\nconst STORAGE_KEY = \"silica:page-properties:open\";\n\nexport type PagePropertiesProps = {\n frontmatter: Record<string, unknown>;\n className?: string;\n defaultOpen?: boolean;\n};\n\nexport function PageProperties({\n frontmatter,\n className,\n defaultOpen = false,\n}: PagePropertiesProps) {\n const properties = getPageProperties(frontmatter);\n const [open, setOpen] = useState<boolean>(defaultOpen);\n\n useEffect(() => {\n try {\n const stored = window.localStorage.getItem(STORAGE_KEY);\n if (stored === \"true\" || stored === \"false\") {\n setOpen(stored === \"true\");\n }\n } catch {\n // ignore (private mode, disabled storage, etc.)\n }\n }, []);\n\n function handleOpenChange(next: boolean) {\n setOpen(next);\n try {\n window.localStorage.setItem(STORAGE_KEY, String(next));\n } catch {\n // ignore\n }\n }\n\n if (properties.length === 0) return null;\n\n return (\n <Collapsible\n data-slot=\"page-properties\"\n open={open}\n onOpenChange={handleOpenChange}\n className={cn(\n \"rounded-lg border border-border bg-card text-sm\",\n className,\n )}\n >\n <CollapsibleTrigger className=\"flex w-full cursor-pointer items-center gap-2 px-4 py-2.5 text-left font-medium\">\n <ChevronRight\n className={cn(\n \"size-4 shrink-0 text-muted-foreground transition-transform\",\n open && \"rotate-90\",\n )}\n aria-hidden\n />\n <span className=\"text-foreground\">Page Properties</span>\n <span className=\"ml-auto text-xs tabular-nums text-muted-foreground\">\n {properties.length}\n </span>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-200 ease-out data-[ending-style]:h-0 data-[starting-style]:h-0 motion-reduce:transition-none\">\n <dl className=\"border-t border-border\">\n {properties.map((property) => (\n <div\n key={property.key}\n className=\"grid grid-cols-[10rem_1fr] gap-x-4 border-t border-border first:border-t-0\"\n >\n <dt className=\"px-4 py-2 text-muted-foreground\">\n {property.label}\n </dt>\n <dd className=\"px-4 py-2 text-foreground\">{property.value}</dd>\n </div>\n ))}\n </dl>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n"],"mappings":";AA6DM,SACE,KADF;AA3DN,SAAS,oBAAoB;AAC7B,SAAS,WAAW,gBAAgB;AAEpC,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAElC,MAAM,cAAc;AAQb,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,cAAc;AAChB,GAAwB;AACtB,QAAM,aAAa,kBAAkB,WAAW;AAChD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAkB,WAAW;AAErD,YAAU,MAAM;AACd,QAAI;AACF,YAAM,SAAS,OAAO,aAAa,QAAQ,WAAW;AACtD,UAAI,WAAW,UAAU,WAAW,SAAS;AAC3C,gBAAQ,WAAW,MAAM;AAAA,MAC3B;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,WAAS,iBAAiB,MAAe;AACvC,YAAQ,IAAI;AACZ,QAAI;AACF,aAAO,aAAa,QAAQ,aAAa,OAAO,IAAI,CAAC;AAAA,IACvD,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI,WAAW,WAAW,EAAG,QAAO;AAEpC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,cAAc;AAAA,MACd,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,6BAAC,sBAAmB,WAAU,mFAC5B;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,QAAQ;AAAA,cACV;AAAA,cACA,eAAW;AAAA;AAAA,UACb;AAAA,UACA,oBAAC,UAAK,WAAU,mBAAkB,6BAAe;AAAA,UACjD,oBAAC,UAAK,WAAU,sDACb,qBAAW,QACd;AAAA,WACF;AAAA,QACA,oBAAC,sBAAmB,WAAU,iLAC5B,8BAAC,QAAG,WAAU,0BACX,qBAAW,IAAI,CAAC,aACf;AAAA,UAAC;AAAA;AAAA,YAEC,WAAU;AAAA,YAEV;AAAA,kCAAC,QAAG,WAAU,mCACX,mBAAS,OACZ;AAAA,cACA,oBAAC,QAAG,WAAU,6BAA6B,mBAAS,OAAM;AAAA;AAAA;AAAA,UANrD,SAAS;AAAA,QAOhB,CACD,GACH,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type SilicaLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
5
|
+
href: string;
|
|
6
|
+
};
|
|
7
|
+
type SilicaLinkComponent = React.ForwardRefExoticComponent<SilicaLinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
8
|
+
type SilicaRoutingContextValue = {
|
|
9
|
+
Link: SilicaLinkComponent;
|
|
10
|
+
currentSlug?: string;
|
|
11
|
+
navigate: (href: string) => void;
|
|
12
|
+
};
|
|
13
|
+
type SilicaRoutingProviderProps = Partial<SilicaRoutingContextValue> & {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
};
|
|
16
|
+
declare function SilicaRoutingProvider({ children, Link, currentSlug, navigate, }: SilicaRoutingProviderProps): react_jsx_runtime.JSX.Element;
|
|
17
|
+
declare function useSilicaRouting(): SilicaRoutingContextValue;
|
|
18
|
+
declare const SilicaLink: React.ForwardRefExoticComponent<React.AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
19
|
+
href: string;
|
|
20
|
+
} & React.RefAttributes<HTMLAnchorElement>>;
|
|
21
|
+
|
|
22
|
+
export { SilicaLink, type SilicaLinkComponent, type SilicaLinkProps, type SilicaRoutingContextValue, SilicaRoutingProvider, type SilicaRoutingProviderProps, useSilicaRouting };
|
package/dist/routing.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
const DefaultLink = React.forwardRef(
|
|
5
|
+
function DefaultLink2({ href, ...props }, ref) {
|
|
6
|
+
return /* @__PURE__ */ jsx("a", { ref, href, ...props });
|
|
7
|
+
}
|
|
8
|
+
);
|
|
9
|
+
const defaultRouting = {
|
|
10
|
+
Link: DefaultLink,
|
|
11
|
+
navigate: (href) => {
|
|
12
|
+
window.location.href = href;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const SilicaRoutingContext = React.createContext(defaultRouting);
|
|
16
|
+
function SilicaRoutingProvider({
|
|
17
|
+
children,
|
|
18
|
+
Link = DefaultLink,
|
|
19
|
+
currentSlug,
|
|
20
|
+
navigate = defaultRouting.navigate
|
|
21
|
+
}) {
|
|
22
|
+
const value = React.useMemo(
|
|
23
|
+
() => ({ Link, currentSlug, navigate }),
|
|
24
|
+
[Link, currentSlug, navigate]
|
|
25
|
+
);
|
|
26
|
+
return /* @__PURE__ */ jsx(SilicaRoutingContext.Provider, { value, children });
|
|
27
|
+
}
|
|
28
|
+
function useSilicaRouting() {
|
|
29
|
+
return React.useContext(SilicaRoutingContext);
|
|
30
|
+
}
|
|
31
|
+
const SilicaLink = React.forwardRef(
|
|
32
|
+
function SilicaLink2(props, ref) {
|
|
33
|
+
const { Link } = useSilicaRouting();
|
|
34
|
+
return /* @__PURE__ */ jsx(Link, { ref, ...props });
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
export {
|
|
38
|
+
SilicaLink,
|
|
39
|
+
SilicaRoutingProvider,
|
|
40
|
+
useSilicaRouting
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/routing.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nexport type SilicaLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {\n href: string;\n};\n\nexport type SilicaLinkComponent = React.ForwardRefExoticComponent<\n SilicaLinkProps & React.RefAttributes<HTMLAnchorElement>\n>;\n\nexport type SilicaRoutingContextValue = {\n Link: SilicaLinkComponent;\n currentSlug?: string;\n navigate: (href: string) => void;\n};\n\nconst DefaultLink = React.forwardRef<HTMLAnchorElement, SilicaLinkProps>(\n function DefaultLink({ href, ...props }, ref) {\n return <a ref={ref} href={href} {...props} />;\n },\n);\n\nconst defaultRouting: SilicaRoutingContextValue = {\n Link: DefaultLink,\n navigate: (href) => {\n window.location.href = href;\n },\n};\n\nconst SilicaRoutingContext =\n React.createContext<SilicaRoutingContextValue>(defaultRouting);\n\nexport type SilicaRoutingProviderProps = Partial<SilicaRoutingContextValue> & {\n children: React.ReactNode;\n};\n\nexport function SilicaRoutingProvider({\n children,\n Link = DefaultLink,\n currentSlug,\n navigate = defaultRouting.navigate,\n}: SilicaRoutingProviderProps) {\n const value = React.useMemo(\n () => ({ Link, currentSlug, navigate }),\n [Link, currentSlug, navigate],\n );\n\n return (\n <SilicaRoutingContext.Provider value={value}>\n {children}\n </SilicaRoutingContext.Provider>\n );\n}\n\nexport function useSilicaRouting(): SilicaRoutingContextValue {\n return React.useContext(SilicaRoutingContext);\n}\n\nexport const SilicaLink = React.forwardRef<HTMLAnchorElement, SilicaLinkProps>(\n function SilicaLink(props, ref) {\n const { Link } = useSilicaRouting();\n return <Link ref={ref} {...props} />;\n },\n);\n"],"mappings":";AAoBW;AAlBX,YAAY,WAAW;AAgBvB,MAAM,cAAc,MAAM;AAAA,EACxB,SAASA,aAAY,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK;AAC5C,WAAO,oBAAC,OAAE,KAAU,MAAa,GAAG,OAAO;AAAA,EAC7C;AACF;AAEA,MAAM,iBAA4C;AAAA,EAChD,MAAM;AAAA,EACN,UAAU,CAAC,SAAS;AAClB,WAAO,SAAS,OAAO;AAAA,EACzB;AACF;AAEA,MAAM,uBACJ,MAAM,cAAyC,cAAc;AAMxD,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA,WAAW,eAAe;AAC5B,GAA+B;AAC7B,QAAM,QAAQ,MAAM;AAAA,IAClB,OAAO,EAAE,MAAM,aAAa,SAAS;AAAA,IACrC,CAAC,MAAM,aAAa,QAAQ;AAAA,EAC9B;AAEA,SACE,oBAAC,qBAAqB,UAArB,EAA8B,OAC5B,UACH;AAEJ;AAEO,SAAS,mBAA8C;AAC5D,SAAO,MAAM,WAAW,oBAAoB;AAC9C;AAEO,MAAM,aAAa,MAAM;AAAA,EAC9B,SAASC,YAAW,OAAO,KAAK;AAC9B,UAAM,EAAE,KAAK,IAAI,iBAAiB;AAClC,WAAO,oBAAC,QAAK,KAAW,GAAG,OAAO;AAAA,EACpC;AACF;","names":["DefaultLink","SilicaLink"]}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type SearchTriggerProps = {
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
declare function SearchTrigger({ placeholder, className, }: SearchTriggerProps): react_jsx_runtime.JSX.Element;
|
|
8
|
+
type SearchPaletteProps = {
|
|
9
|
+
open: boolean;
|
|
10
|
+
onOpenChange: (next: boolean) => void;
|
|
11
|
+
};
|
|
12
|
+
declare function SearchPalette({ open, onOpenChange }: SearchPaletteProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { SearchPalette, type SearchPaletteProps, SearchTrigger, type SearchTriggerProps };
|