Skip to content

Commit d97d6a9

Browse files
committed
misc fixes
1 parent f6ddefa commit d97d6a9

18 files changed

Lines changed: 379 additions & 310 deletions

docs/app/(home)/_components/BlockCatalog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const BlockCatalog: React.FC = () => {
4949
🧩
5050
</div>
5151
<h2 className="mb-6 font-serif text-4xl text-stone-900 md:text-6xl">
52-
A universe of blocks.
52+
Build anything, block by block.
5353
</h2>
5454
<p className="mx-auto max-w-2xl text-xl font-light leading-relaxed text-stone-600">
5555
Every BlockNote document is a collection of blocks—headings, lists,

docs/app/(home)/_components/DigitalCommons.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,15 @@ export const DigitalCommons: React.FC = () => {
5252
{/* Short punchy copy */}
5353
<p className="mb-8 text-base leading-relaxed text-stone-400">
5454
France, Germany, and the Netherlands partner to build{" "}
55-
<strong className="text-white">Docs</strong>, a collaborative
56-
writing tool for thousands of public servants.{" "}
55+
<Link
56+
href="https://github.com/suitenumerique/docs"
57+
target="_blank"
58+
rel="noopener noreferrer"
59+
className="font-bold text-white decoration-purple-400 underline-offset-2 transition-colors hover:text-purple-300 hover:underline"
60+
>
61+
Docs
62+
</Link>
63+
, a collaborative writing tool for thousands of public servants.{" "}
5764
<strong className="text-white">BlockNote is the engine.</strong>
5865
</p>
5966

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
1-
"use client";
21
import React, { useState } from "react";
32
import { FeatureSection } from "./FeatureSection";
3+
import { ContentItem, FeatureWindow } from "./ui/FeatureWindow";
44

55
export const FeatureAI: React.FC = () => {
66
const [activeTab, setActiveTab] = useState<"toolbar" | "models" | "human">(
77
"toolbar",
88
);
99

10+
const content: Record<string, ContentItem> = {
11+
toolbar: {
12+
type: "video",
13+
src: "/video/ai-select.mp4",
14+
className: "object-contain px-4",
15+
},
16+
models: {
17+
type: "image",
18+
src: "/img/screenshots/home/any_model.png",
19+
alt: "Bring Any Model",
20+
},
21+
human: {
22+
type: "image",
23+
src: "/img/screenshots/home/human_in_the_loop.png",
24+
alt: "Human in the Loop",
25+
},
26+
};
27+
1028
const tabs = [
1129
{
1230
id: "toolbar",
@@ -38,37 +56,7 @@ export const FeatureAI: React.FC = () => {
3856
onTabChange={(id) => setActiveTab(id as any)}
3957
reverse={true}
4058
>
41-
{activeTab === "models" || activeTab === "human" ? (
42-
<img
43-
src={
44-
activeTab === "models"
45-
? "/img/screenshots/home/any_model.png"
46-
: "/img/screenshots/home/human_in_the_loop.png"
47-
}
48-
alt={activeTab === "models" ? "Bring Any Model" : "Human in the Loop"}
49-
className="h-full w-full object-cover"
50-
/>
51-
) : (
52-
<div className="relative h-[380px] w-full overflow-hidden rounded-xl border border-stone-200 bg-white shadow-sm">
53-
<div className="flex items-center gap-2 border-b border-gray-100 bg-gray-50 px-4 py-3">
54-
<div className="flex gap-1.5">
55-
<div className="h-3 w-3 rounded-full bg-red-400" />
56-
<div className="h-3 w-3 rounded-full bg-amber-400" />
57-
<div className="h-3 w-3 rounded-full bg-green-400" />
58-
</div>
59-
</div>
60-
<div className="relative h-full w-full bg-white">
61-
<video
62-
src="/video/ai-select.mp4"
63-
autoPlay
64-
loop
65-
muted
66-
playsInline
67-
className="h-full w-full object-contain px-4"
68-
/>
69-
</div>
70-
</div>
71-
)}
59+
<FeatureWindow content={content[activeTab]} theme="light" />
7260
</FeatureSection>
7361
);
7462
};
Lines changed: 14 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
1-
"use client";
21
import React, { useState } from "react";
32
import { FeatureSection } from "./FeatureSection";
3+
import { ContentItem, FeatureWindow } from "./ui/FeatureWindow";
44

5-
export const FeatureCollab: React.FC = () => {
5+
export const FeatureCollab: React.FC<{
6+
code: { realtime: string };
7+
}> = ({ code }) => {
68
const [activeTab, setActiveTab] = useState<
79
"realtime" | "comments" | "suggestions"
810
>("realtime");
911

10-
const content = {
12+
const content: Record<string, ContentItem> = {
1113
realtime: {
14+
type: "code",
1215
file: "CollaborativeEditor.tsx",
13-
code: `import * as Y from "yjs";
14-
import { WebsocketProvider } from "y-websocket";
15-
16-
const doc = new Y.Doc();
17-
const provider = new WebsocketProvider(
18-
"ws://localhost:1234", "room-id", doc);
19-
20-
const editor = useCreateBlockNote({
21-
collaboration: {
22-
fragment: doc.getXmlFragment("document"),
23-
user: { name: "Alice", color: "#ff0000" },
24-
provider,
25-
}
26-
});
27-
28-
// Cursors and presence included`,
16+
code: code.realtime,
2917
},
3018
comments: {
31-
file: "Comments.tsx",
32-
code: "", // Using image override
19+
type: "image",
20+
src: "/img/screenshots/home/comments.png",
21+
alt: "Comments",
3322
},
3423
suggestions: {
35-
file: "History.tsx",
36-
code: "", // Using image override
24+
type: "image",
25+
src: "/img/screenshots/home/versioning.png",
26+
alt: "Versioning",
3727
},
3828
};
3929

@@ -68,43 +58,7 @@ const editor = useCreateBlockNote({
6858
onTabChange={(id) => setActiveTab(id as any)}
6959
reverse={false}
7060
>
71-
{/* Window Chrome */}
72-
{activeTab !== "suggestions" && activeTab !== "comments" && (
73-
<div className="flex items-center justify-between border-b border-white/5 bg-[#18181B] px-4 py-3">
74-
<div className="flex gap-1.5">
75-
<div className="h-2.5 w-2.5 rounded-full bg-[#FF5F56]"></div>
76-
<div className="h-2.5 w-2.5 rounded-full bg-[#FFBD2E]"></div>
77-
<div className="h-2.5 w-2.5 rounded-full bg-[#27C93F]"></div>
78-
</div>
79-
<span className="font-mono text-xs text-stone-500">
80-
{content[activeTab].file}
81-
</span>
82-
<div className="w-4"></div>
83-
</div>
84-
)}
85-
86-
{/* Code */}
87-
<div
88-
className={`min-h-[300px] overflow-x-auto bg-[#0F0F11] ${activeTab === "realtime" ? "p-6" : ""}`}
89-
>
90-
{activeTab === "suggestions" ? (
91-
<img
92-
src="/img/screenshots/home/versioning.png"
93-
alt="Versioning"
94-
className="w-full rounded-md"
95-
/>
96-
) : activeTab === "comments" ? (
97-
<img
98-
src="/img/screenshots/home/comments.png"
99-
alt="Comments"
100-
className="w-full rounded-md"
101-
/>
102-
) : (
103-
<pre className="whitespace-pre font-mono text-sm leading-relaxed text-stone-300">
104-
{content[activeTab].code}
105-
</pre>
106-
)}
107-
</div>
61+
<FeatureWindow content={content[activeTab]} theme="dark" />
10862
</FeatureSection>
10963
);
11064
};
Lines changed: 13 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,29 @@
1-
"use client";
21
import React, { useState } from "react";
32
import { FeatureSection } from "./FeatureSection";
3+
import { ContentItem, FeatureWindow } from "./ui/FeatureWindow";
44

5-
export const FeatureDX: React.FC = () => {
5+
export const FeatureDX: React.FC<{
6+
code: { theming: string; extend: string };
7+
}> = ({ code }) => {
68
const [activeTab, setActiveTab] = useState<"types" | "theming" | "extend">(
79
"types",
810
);
911

10-
const content = {
12+
const content: Record<string, ContentItem> = {
1113
types: {
12-
file: "schema.ts",
13-
code: `import { BlockNoteSchema } from "@blocknote/core";
14-
15-
// Define your custom block schema
16-
const schema = BlockNoteSchema.create({
17-
blockSpecs: {
18-
alert: AlertBlock,
19-
callout: CalloutBlock,
20-
},
21-
});
22-
23-
// Full type inference for your blocks
24-
type MyBlock = typeof schema.Block;
25-
// ^? { type: "alert" | "callout" | ... }`,
14+
type: "image",
15+
src: "/img/screenshots/home/code-typescript-support.png",
16+
alt: "Type-Safe Schema",
2617
},
2718
theming: {
19+
type: "code",
2820
file: "Editor.tsx",
29-
code: `import { useCreateBlockNote } from "@blocknote/react";
30-
import { ShadCNComponents } from "@blocknote/shadcn";
31-
32-
const editor = useCreateBlockNote();
33-
34-
return (
35-
<BlockNoteView
36-
editor={editor}
37-
theme="light"
38-
// Use built-in components or your own
39-
components={ShadCNComponents}
40-
/>
41-
);`,
21+
code: code.theming,
4222
},
4323
extend: {
24+
type: "code",
4425
file: "CustomBlock.tsx",
45-
code: `import { createReactBlockSpec } from "@blocknote/react";
46-
47-
// Create custom blocks with React
48-
export const AlertBlock = createReactBlockSpec({
49-
type: "alert",
50-
propSchema: {
51-
type: { default: "warning" },
52-
},
53-
content: "inline",
54-
}, {
55-
render: (props) => (
56-
<div className="alert">
57-
{props.contentRef}
58-
</div>
59-
),
60-
});`,
26+
code: code.extend,
6127
},
6228
};
6329

@@ -91,35 +57,7 @@ export const AlertBlock = createReactBlockSpec({
9157
onTabChange={(id) => setActiveTab(id as any)}
9258
reverse={true}
9359
>
94-
{/* Window Chrome */}
95-
<div className="flex items-center justify-between border-b border-white/5 bg-[#18181B] px-4 py-3">
96-
<div className="flex gap-1.5">
97-
<div className="h-2.5 w-2.5 rounded-full bg-[#FF5F56]"></div>
98-
<div className="h-2.5 w-2.5 rounded-full bg-[#FFBD2E]"></div>
99-
<div className="h-2.5 w-2.5 rounded-full bg-[#27C93F]"></div>
100-
</div>
101-
<span className="font-mono text-xs text-stone-500">
102-
{content[activeTab].file}
103-
</span>
104-
<div className="w-4"></div>
105-
</div>
106-
107-
{/* Code */}
108-
<div className="min-h-[300px] bg-[#0F0F11]">
109-
{activeTab === "types" ? (
110-
<img
111-
src="/img/screenshots/home/code-typescript-support.png"
112-
alt="Type-Safe Schema"
113-
className="w-full"
114-
/>
115-
) : (
116-
<div className="overflow-x-auto p-6">
117-
<pre className="whitespace-pre font-mono text-sm leading-relaxed text-stone-300">
118-
{content[activeTab].code}
119-
</pre>
120-
</div>
121-
)}
122-
</div>
60+
<FeatureWindow content={content[activeTab]} theme="dark" />
12361
</FeatureSection>
12462
);
12563
};

docs/app/(home)/_components/FeatureSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const FeatureSection: React.FC<FeatureSectionProps> = ({
5656
<button
5757
key={tab.id}
5858
onClick={() => onTabChange(tab.id)}
59-
className={`flex w-full items-center gap-4 rounded-xl border p-4 text-left transition-all duration-300 ${
59+
className={`flex w-full cursor-pointer items-center gap-4 rounded-xl border p-4 text-left transition-all duration-300 ${
6060
isActive
6161
? "border-stone-200 bg-stone-50 shadow-sm"
6262
: "border-transparent bg-white hover:bg-stone-50"
Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
1-
"use client";
21
import React, { useState } from "react";
32
import { FeatureSection } from "./FeatureSection";
4-
3+
import { ContentItem, FeatureWindow } from "./ui/FeatureWindow";
54
export const FeatureUX: React.FC = () => {
65
const [activeTab, setActiveTab] = useState<"components" | "ai" | "blocks">(
76
"components",
87
);
98

9+
const content: Record<string, ContentItem> = {
10+
components: {
11+
type: "video",
12+
src: "/video/batteries-included.mp4",
13+
className: "object-cover",
14+
},
15+
ai: {
16+
type: "video",
17+
src: "/video/ai-select.mp4",
18+
className: "object-contain px-4",
19+
},
20+
blocks: {
21+
type: "video",
22+
src: "/video/dragdrop.mp4",
23+
className: "object-cover",
24+
},
25+
};
26+
1027
const tabs = [
1128
{
1229
id: "components",
@@ -29,19 +46,6 @@ export const FeatureUX: React.FC = () => {
2946
},
3047
];
3148

32-
const getVideo = () => {
33-
switch (activeTab) {
34-
case "components":
35-
return "/video/batteries-included.mp4";
36-
case "ai":
37-
return "/video/ai-select.mp4";
38-
case "blocks":
39-
return "/video/dragdrop.mp4";
40-
default:
41-
return "";
42-
}
43-
};
44-
4549
return (
4650
<FeatureSection
4751
title="A modern editor, ready to ship."
@@ -51,26 +55,7 @@ export const FeatureUX: React.FC = () => {
5155
onTabChange={(id) => setActiveTab(id as any)}
5256
reverse={false}
5357
>
54-
<div className="relative h-[380px] w-full overflow-hidden rounded-xl border border-stone-200 bg-white shadow-sm">
55-
<div className="flex items-center gap-2 border-b border-gray-100 bg-gray-50 px-4 py-3">
56-
<div className="flex gap-1.5">
57-
<div className="h-3 w-3 rounded-full bg-red-400" />
58-
<div className="h-3 w-3 rounded-full bg-amber-400" />
59-
<div className="h-3 w-3 rounded-full bg-green-400" />
60-
</div>
61-
</div>
62-
<div className="relative h-full w-full bg-white">
63-
<video
64-
key={activeTab}
65-
src={getVideo()}
66-
autoPlay
67-
loop
68-
muted
69-
playsInline
70-
className={`h-full w-full ${activeTab === "ai" ? "object-contain px-4" : "object-cover"}`}
71-
/>
72-
</div>
73-
</div>
58+
<FeatureWindow content={content[activeTab]} theme="light" />
7459
</FeatureSection>
7560
);
7661
};

0 commit comments

Comments
 (0)