Skip to content

Commit 4f36dfb

Browse files
committed
more doc improvements
1 parent b3d089e commit 4f36dfb

File tree

6 files changed

+233
-33
lines changed

6 files changed

+233
-33
lines changed
Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import Link from "next/link";
2-
import { Button } from "@/components/ui/button";
3-
import { Code } from "@/components/code";
1+
import { PackageInstall } from "@/components/package-install";
42

53
export const metadata = {
64
title: "Installation | json-render",
@@ -15,19 +13,7 @@ export default function InstallationPage() {
1513
</p>
1614

1715
<h2 className="text-xl font-semibold mt-12 mb-4">Install packages</h2>
18-
<Code lang="bash">npm install @json-render/core @json-render/react</Code>
19-
20-
<p className="text-sm text-muted-foreground mb-4">
21-
Or with other package managers:
22-
</p>
23-
<Code lang="bash">{`# pnpm
24-
pnpm add @json-render/core @json-render/react
25-
26-
# yarn
27-
yarn add @json-render/core @json-render/react
28-
29-
# bun
30-
bun add @json-render/core @json-render/react`}</Code>
16+
<PackageInstall packages="@json-render/core @json-render/react" />
3117

3218
<h2 className="text-xl font-semibold mt-12 mb-4">Peer Dependencies</h2>
3319
<p className="text-sm text-muted-foreground mb-4">
@@ -41,20 +27,14 @@ bun add @json-render/core @json-render/react`}</Code>
4127
<code className="text-foreground">zod</code> ^4.0.0
4228
</li>
4329
</ul>
44-
<Code lang="bash">npm install react zod</Code>
30+
<PackageInstall packages="react zod" />
4531

4632
<h2 className="text-xl font-semibold mt-12 mb-4">For AI Integration</h2>
4733
<p className="text-sm text-muted-foreground mb-4">
4834
To use json-render with AI models, you&apos;ll also need the Vercel AI
4935
SDK:
5036
</p>
51-
<Code lang="bash">npm install ai</Code>
52-
53-
<div className="flex gap-3 mt-12">
54-
<Button size="sm" asChild>
55-
<Link href="/docs/quick-start">Quick Start</Link>
56-
</Button>
57-
</div>
37+
<PackageInstall packages="ai" />
5838
</article>
5939
);
6040
}

apps/web/app/docs/quick-start/page.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Link from "next/link";
2-
import { Button } from "@/components/ui/button";
32
import { Code } from "@/components/code";
43

54
export const metadata = {
@@ -201,12 +200,6 @@ export default function Page() {
201200
</Link>
202201
</li>
203202
</ul>
204-
205-
<div className="flex gap-3 mt-12">
206-
<Button size="sm" asChild>
207-
<Link href="/docs/catalog">Learn about Catalogs</Link>
208-
</Button>
209-
</div>
210203
</article>
211204
);
212205
}

apps/web/components/code-tabs.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"use client";
2+
3+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
4+
import { CopyButton } from "./copy-button";
5+
6+
interface CodeTabsProps {
7+
tabs: {
8+
label: string;
9+
value: string;
10+
code: string;
11+
html: string;
12+
}[];
13+
defaultValue?: string;
14+
}
15+
16+
export function CodeTabs({ tabs, defaultValue }: CodeTabsProps) {
17+
const defaultTab = defaultValue ?? tabs[0]?.value;
18+
19+
return (
20+
<div className="my-6 rounded-lg border border-border bg-neutral-100 dark:bg-[#0a0a0a] text-sm font-mono overflow-hidden">
21+
<Tabs defaultValue={defaultTab} className="gap-0">
22+
<div className="flex items-center justify-between border-b border-border px-4 py-2">
23+
<TabsList className="h-7 bg-transparent p-0 gap-2">
24+
{tabs.map((tab) => (
25+
<TabsTrigger
26+
key={tab.value}
27+
value={tab.value}
28+
className="h-6 px-2 text-xs data-[state=active]:bg-secondary data-[state=active]:shadow-none rounded"
29+
>
30+
{tab.label}
31+
</TabsTrigger>
32+
))}
33+
</TabsList>
34+
</div>
35+
{tabs.map((tab) => (
36+
<TabsContent
37+
key={tab.value}
38+
value={tab.value}
39+
className="relative group mt-0"
40+
>
41+
<div className="absolute top-3 right-3 z-10">
42+
<CopyButton
43+
text={tab.code}
44+
className="opacity-0 group-hover:opacity-100 text-neutral-500 dark:text-neutral-400 bg-neutral-100 dark:bg-[#0a0a0a]"
45+
/>
46+
</div>
47+
<div
48+
className="overflow-x-auto [&_pre]:bg-transparent! [&_pre]:m-0! [&_pre]:p-4! [&_code]:bg-transparent! [&_.shiki]:bg-transparent!"
49+
dangerouslySetInnerHTML={{ __html: tab.html }}
50+
/>
51+
</TabsContent>
52+
))}
53+
</Tabs>
54+
</div>
55+
);
56+
}

apps/web/components/docs-mobile-nav.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export function DocsMobileNav() {
6161

6262
return (
6363
<Sheet open={open} onOpenChange={setOpen}>
64-
<SheetTrigger className="lg:hidden sticky top-[calc(3.5rem+1px)] z-40 w-full px-6 py-3 bg-background/80 backdrop-blur-sm border-b border-border flex items-center justify-between">
64+
<SheetTrigger className="lg:hidden sticky top-[calc(3.5rem+1px)] z-40 w-full px-6 py-3 bg-background/80 backdrop-blur-sm border-b border-border flex items-center justify-between focus:outline-none">
6565
<div className="text-sm font-medium">{currentPage?.title}</div>
6666
<div className="w-8 h-8 flex items-center justify-center">
6767
<List className="h-4 w-4 text-muted-foreground" />
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import { codeToHtml } from "shiki";
2+
import { CodeTabs } from "./code-tabs";
3+
4+
const vercelDarkTheme = {
5+
name: "vercel-dark",
6+
type: "dark" as const,
7+
colors: {
8+
"editor.background": "transparent",
9+
"editor.foreground": "#EDEDED",
10+
},
11+
settings: [
12+
{
13+
scope: ["comment", "punctuation.definition.comment"],
14+
settings: { foreground: "#666666" },
15+
},
16+
{
17+
scope: ["string", "string.quoted", "string.template"],
18+
settings: { foreground: "#50E3C2" },
19+
},
20+
{
21+
scope: [
22+
"constant.numeric",
23+
"constant.language.boolean",
24+
"constant.language.null",
25+
],
26+
settings: { foreground: "#50E3C2" },
27+
},
28+
{
29+
scope: ["keyword", "storage.type", "storage.modifier"],
30+
settings: { foreground: "#FF0080" },
31+
},
32+
{
33+
scope: ["keyword.operator", "keyword.control"],
34+
settings: { foreground: "#FF0080" },
35+
},
36+
{
37+
scope: ["entity.name.function", "support.function", "meta.function-call"],
38+
settings: { foreground: "#7928CA" },
39+
},
40+
{
41+
scope: ["variable", "variable.other", "variable.parameter"],
42+
settings: { foreground: "#EDEDED" },
43+
},
44+
{
45+
scope: ["entity.name.tag", "support.class.component", "entity.name.type"],
46+
settings: { foreground: "#FF0080" },
47+
},
48+
{
49+
scope: ["punctuation", "meta.brace", "meta.bracket"],
50+
settings: { foreground: "#888888" },
51+
},
52+
{
53+
scope: [
54+
"support.type.property-name",
55+
"entity.name.tag.json",
56+
"meta.object-literal.key",
57+
],
58+
settings: { foreground: "#EDEDED" },
59+
},
60+
{
61+
scope: ["entity.other.attribute-name"],
62+
settings: { foreground: "#50E3C2" },
63+
},
64+
{
65+
scope: ["support.type.primitive", "entity.name.type.primitive"],
66+
settings: { foreground: "#50E3C2" },
67+
},
68+
],
69+
};
70+
71+
const vercelLightTheme = {
72+
name: "vercel-light",
73+
type: "light" as const,
74+
colors: {
75+
"editor.background": "transparent",
76+
"editor.foreground": "#171717",
77+
},
78+
settings: [
79+
{
80+
scope: ["comment", "punctuation.definition.comment"],
81+
settings: { foreground: "#6b7280" },
82+
},
83+
{
84+
scope: ["string", "string.quoted", "string.template"],
85+
settings: { foreground: "#067a6e" },
86+
},
87+
{
88+
scope: [
89+
"constant.numeric",
90+
"constant.language.boolean",
91+
"constant.language.null",
92+
],
93+
settings: { foreground: "#067a6e" },
94+
},
95+
{
96+
scope: ["keyword", "storage.type", "storage.modifier"],
97+
settings: { foreground: "#d6409f" },
98+
},
99+
{
100+
scope: ["keyword.operator", "keyword.control"],
101+
settings: { foreground: "#d6409f" },
102+
},
103+
{
104+
scope: ["entity.name.function", "support.function", "meta.function-call"],
105+
settings: { foreground: "#6e56cf" },
106+
},
107+
{
108+
scope: ["variable", "variable.other", "variable.parameter"],
109+
settings: { foreground: "#171717" },
110+
},
111+
{
112+
scope: ["entity.name.tag", "support.class.component", "entity.name.type"],
113+
settings: { foreground: "#d6409f" },
114+
},
115+
{
116+
scope: ["punctuation", "meta.brace", "meta.bracket"],
117+
settings: { foreground: "#6b7280" },
118+
},
119+
{
120+
scope: [
121+
"support.type.property-name",
122+
"entity.name.tag.json",
123+
"meta.object-literal.key",
124+
],
125+
settings: { foreground: "#171717" },
126+
},
127+
{
128+
scope: ["entity.other.attribute-name"],
129+
settings: { foreground: "#067a6e" },
130+
},
131+
{
132+
scope: ["support.type.primitive", "entity.name.type.primitive"],
133+
settings: { foreground: "#067a6e" },
134+
},
135+
],
136+
};
137+
138+
interface PackageInstallProps {
139+
packages: string;
140+
}
141+
142+
const packageManagers = [
143+
{ label: "npm", value: "npm", command: "npm install" },
144+
{ label: "pnpm", value: "pnpm", command: "pnpm add" },
145+
{ label: "yarn", value: "yarn", command: "yarn add" },
146+
{ label: "bun", value: "bun", command: "bun add" },
147+
];
148+
149+
export async function PackageInstall({ packages }: PackageInstallProps) {
150+
const tabs = await Promise.all(
151+
packageManagers.map(async (pm) => {
152+
const code = `${pm.command} ${packages}`;
153+
const html = await codeToHtml(code, {
154+
lang: "bash",
155+
themes: {
156+
light: vercelLightTheme,
157+
dark: vercelDarkTheme,
158+
},
159+
defaultColor: false,
160+
});
161+
return {
162+
label: pm.label,
163+
value: pm.value,
164+
code,
165+
html,
166+
};
167+
}),
168+
);
169+
170+
return <CodeTabs tabs={tabs} />;
171+
}

apps/web/components/ui/sheet.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const SheetContent = React.forwardRef<
3636
<SheetPrimitive.Content
3737
ref={ref}
3838
className={cn(
39-
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
39+
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out focus:outline-none",
4040
"inset-y-0 left-0 h-full w-3/4 max-w-xs border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
4141
className,
4242
)}

0 commit comments

Comments
 (0)