Skip to content

Commit 821178a

Browse files
committed
docs: add localisation example to demo
1 parent 4498467 commit 821178a

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"use client";
2+
3+
import { Data } from "@/core/types/Config";
4+
import { Puck } from "@/core/components/Puck";
5+
import { Render } from "@/core/components/Render";
6+
import { Button } from "@/core/components/Button";
7+
import headingAnalyzer from "@/plugin-heading-analyzer/src/HeadingAnalyzer";
8+
import config, { UserConfig } from "../../../../config";
9+
import {
10+
LocalisedHeading,
11+
localeContext,
12+
} from "../../../../config/blocks/LocalisedHeading";
13+
import { useDemoData } from "../../../../lib/use-demo-data";
14+
import { useState } from "react";
15+
16+
const localisedConfig: UserConfig = {
17+
...config,
18+
components: {
19+
...config.components,
20+
Heading: LocalisedHeading as any,
21+
},
22+
};
23+
24+
export function Client({
25+
path,
26+
isEdit,
27+
locale,
28+
}: {
29+
path: string;
30+
isEdit: boolean;
31+
locale: string;
32+
}) {
33+
const { data, resolvedData, key } = useDemoData({
34+
path: `locales/${path}`,
35+
isEdit,
36+
});
37+
38+
const [currentLocale, setCurrentLocale] = useState(locale);
39+
40+
if (isEdit) {
41+
return (
42+
<localeContext.Provider value={currentLocale}>
43+
<Puck<UserConfig>
44+
config={localisedConfig}
45+
data={data}
46+
onPublish={async (data: Data) => {
47+
localStorage.setItem(key, JSON.stringify(data));
48+
}}
49+
plugins={[headingAnalyzer]}
50+
headerPath={path}
51+
overrides={{
52+
headerActions: () => (
53+
<>
54+
<select
55+
onChange={(e) => {
56+
setCurrentLocale(e.currentTarget.value);
57+
}}
58+
value={currentLocale}
59+
style={{ fontSize: 18, border: "none" }}
60+
>
61+
<option value="en">en</option>
62+
<option value="de">de</option>
63+
</select>
64+
<div>
65+
<Button
66+
href={`/locales/${currentLocale}${path}`}
67+
newTab
68+
variant="secondary"
69+
>
70+
View page
71+
</Button>
72+
</div>
73+
</>
74+
),
75+
}}
76+
/>
77+
</localeContext.Provider>
78+
);
79+
}
80+
81+
if (data) {
82+
return (
83+
<localeContext.Provider value={currentLocale}>
84+
<Render<UserConfig> config={localisedConfig} data={resolvedData} />
85+
</localeContext.Provider>
86+
);
87+
}
88+
89+
return (
90+
<div
91+
style={{
92+
display: "flex",
93+
height: "100vh",
94+
textAlign: "center",
95+
justifyContent: "center",
96+
alignItems: "center",
97+
}}
98+
>
99+
<div>
100+
<h1>404</h1>
101+
<p>Page does not exist in session storage</p>
102+
</div>
103+
</div>
104+
);
105+
}
106+
107+
export default Client;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import dynamic from "next/dynamic";
2+
import resolvePuckPath from "../../../../lib/resolve-puck-path";
3+
import { Metadata } from "next";
4+
5+
const Client = dynamic(() => import("./client"), {
6+
ssr: false,
7+
});
8+
9+
export async function generateMetadata({
10+
params,
11+
}: {
12+
params: { framework: string; uuid: string; puckPath: string[] };
13+
}): Promise<Metadata> {
14+
const { isEdit, path } = resolvePuckPath(params.puckPath);
15+
16+
if (isEdit) {
17+
return {
18+
title: "Editing: " + path,
19+
};
20+
}
21+
22+
return {
23+
title: "",
24+
};
25+
}
26+
27+
export default async function Page({
28+
params,
29+
}: {
30+
params: { framework: string; uuid: string; locale; puckPath: string[] };
31+
}) {
32+
const { isEdit, path } = resolvePuckPath(params.puckPath);
33+
34+
return <Client isEdit={isEdit} path={path} locale={params.locale} />;
35+
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default } from "./[...puckPath]/page";
2+
export * from "./[...puckPath]/page";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* eslint-disable react-hooks/rules-of-hooks */
2+
import React, { createContext, useContext } from "react";
3+
4+
import { ComponentConfig } from "@/core";
5+
import { Heading as _Heading } from "@/core/components/Heading";
6+
import { Heading } from "../Heading";
7+
import type { HeadingProps as _HeadingProps } from "@/core/components/Heading";
8+
import { HeadingProps } from "../Heading";
9+
10+
export const localeContext = createContext("en");
11+
12+
export type LocalisedHeadingProps = Omit<HeadingProps, "text"> & {
13+
text: {
14+
en: string;
15+
de: string;
16+
};
17+
};
18+
19+
export const LocalisedHeading: ComponentConfig<LocalisedHeadingProps> = {
20+
fields: {
21+
...Heading.fields,
22+
text: {
23+
type: "object",
24+
objectFields: { en: { type: "text" }, de: { type: "text" } },
25+
},
26+
},
27+
defaultProps: {
28+
...Heading.defaultProps,
29+
text: {
30+
en: "Hello, world",
31+
de: "Hallo, Welt",
32+
},
33+
},
34+
render: ({ text, ...props }) => {
35+
const locale = useContext(localeContext);
36+
37+
return <Heading.render {...props} text={text[locale]} />;
38+
},
39+
};

0 commit comments

Comments
 (0)