Skip to content

Commit

Permalink
docs: add versioned docs
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvxd committed Dec 13, 2023
1 parent ecb276c commit b68d98f
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 4 deletions.
74 changes: 74 additions & 0 deletions apps/docs/components/ReleaseSwitcher/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useEffect, useState } from "react";

import packageJson from "../../package.json";
import { getClassNameFactory } from "@/core/lib";

import styles from "./styles.module.css";

const { version } = packageJson;

const getClassName = getClassNameFactory("ReleaseSwitcher", styles);

export const ReleaseSwitcher = () => {
const isCanary = process.env.NEXT_PUBLIC_IS_CANARY === "true" || false;
const isLatest = process.env.NEXT_PUBLIC_IS_LATEST === "true" || false;

const currentValue = isCanary ? "canary" : isLatest ? "" : version;

const [options, setOptions] = useState<{ value: string; label: string }[]>([
{
label: "canary",
value: "canary",
},
...(isCanary
? []
: [
{
label: isLatest ? `v${version} (latest)` : `v${version}`,
value: "",
},
]),
]);

useEffect(() => {
fetch("/api/releases").then(async (res) => {
const { releases } = await res.json();

if (releases.length === 0) return;

const releaseOptions = releases.map((release) => ({
label: release.name.split("releases/")[1],
value: release.name.split("releases/v")[1], // remove the leading `v`
}));

releaseOptions[0].label = `${releaseOptions[0].label} (latest)`;
releaseOptions[0].value = "";

setOptions([{ label: "canary", value: "canary" }, ...releaseOptions]);
});
}, []);

return (
<select
className={getClassName()}
value={currentValue}
onChange={(e) => {
const newHref = e.currentTarget.value
? `https://puckeditor.com/v/${e.currentTarget.value}`
: "https://puckeditor.com";

if (window.parent) {
window.parent.location.href = newHref;
} else {
window.location.href = newHref;
}
}}
>
{options.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
);
};
15 changes: 15 additions & 0 deletions apps/docs/components/ReleaseSwitcher/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.ReleaseSwitcher {
appearance: none; /* Safari */
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23c3c3c3'><polygon points='0,0 100,0 50,50'/></svg>")
no-repeat;
background-size: 12px;
background-position: calc(100% - 12px) calc(50% + 3px);
background-repeat: no-repeat;
background-color: var(--puck-color-grey-10);
border-radius: 100px;
color: black;
padding-left: 16px;
padding-right: 16px;
height: 33px; /* Magic number to align with Nextra search */
width: 156px;
}
3 changes: 2 additions & 1 deletion apps/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "1.0.0",
"version": "0.12.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand All @@ -16,6 +16,7 @@
"typescript": "^4.5.3"
},
"dependencies": {
"lru-cache": "^10.1.0",
"next": "^13.5.4",
"nextra": "^2.13.2",
"nextra-theme-docs": "^2.13.2",
Expand Down
35 changes: 33 additions & 2 deletions apps/docs/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
import React from "react";
import React, { useEffect } from "react";

import type { AppProps } from "next/app";
import "../styles.css";
import { useRouter } from "next/router";
import { Message } from "./v/[[...fullPath]]";

export default function DocsApp({ Component, pageProps }: AppProps) {
const router = useRouter();

useEffect(() => {
if (!window.parent) return;

const message: Message = {
type: "routeChange",
title: window.document.title,
};

window.parent.postMessage(message);

const handleRouteChange = (url) => {
const message: Message = {
type: "routeChange",
url,
title: window.document.title,
};

window.parent.postMessage(message);
};

router.events.on("routeChangeComplete", handleRouteChange);

return () => {
router.events.off("routeChangeComplete", handleRouteChange);
};
}, []);

export default function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
41 changes: 41 additions & 0 deletions apps/docs/pages/api/releases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { LRUCache } from "lru-cache";

type ResponseData = {
releases: object;
};

const cache = new LRUCache({
ttl: 1000 * 60 * 2, // 2 minutes
ttlAutopurge: true,
});

/**
* Proxy GitHub and rely on Next.js cache to prevent rate limiting
*/
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
const cached = cache.get("releases");

if (cached) {
res.status(200).json({ releases: cached });

return;
}

const data = [{ name: "releases/v0.12.0", protected: false }];

const releases: { name: string; protected: boolean }[] = data
.filter(
(item) =>
item.name.indexOf("releases") === 0 &&
item.name.indexOf(`v0.11.`) === -1 // Filter out any release branches before v0.12.0
)
.reverse();

res.status(200).json({ releases });

cache.set("releases", releases);
}
56 changes: 56 additions & 0 deletions apps/docs/pages/v/[[...fullPath]].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useEffect, useRef } from "react";

export type Message = {
type: "routeChange";
url?: string;
title: string;
};

export default function Version({ path, version }) {
useEffect(() => {
const handleMessageReceived = (event: MessageEvent) => {
if (event.data.type === "routeChange") {
const routeChange = event.data as Message;

if (routeChange.url) {
window.history.pushState({}, "", `/v/${version}${routeChange.url}`);
}

window.document.title = `${routeChange.title} [${
version !== "canary" ? `v${version}` : version
}]`;
}
};

window.addEventListener("message", handleMessageReceived);

return () => window.removeEventListener("message", handleMessageReceived);
}, []);

const versionSlug = version.replace(/\./g, "");

const src =
version === "canary"
? `https://puck-docs-git-canary-measured.vercel.app`
: `https://puck-docs-git-releases-v${versionSlug}-measured.vercel.app`;

return (
<iframe
src={src}
style={{
top: 0,
left: 0,
height: "100%",
width: "100%",
position: "fixed",
border: 0,
}}
></iframe>
);
}

export function getServerSideProps(ctx) {
const [version, ...path] = ctx.query.fullPath;

return { props: { path: path.join("/"), version } };
}
6 changes: 6 additions & 0 deletions apps/docs/theme.config.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { useRouter } from "next/router";
import { DocsThemeConfig, useConfig } from "nextra-theme-docs";

import { ReleaseSwitcher } from "./components/ReleaseSwitcher";

const Head = () => {
const { asPath, defaultLocale, locale } = useRouter();
const config = useConfig();
Expand Down Expand Up @@ -111,6 +114,9 @@ const theme: DocsThemeConfig = {
},
docsRepositoryBase: "https://github.com/measuredco/puck/tree/main/apps/docs",
primarySaturation: 0,
navbar: {
extraContent: ReleaseSwitcher,
},
};

export default theme;
1 change: 1 addition & 0 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"packages": [
"apps/docs",
"packages/core",
"packages/create-puck-app",
"packages/plugin-heading-analyzer"
Expand Down
6 changes: 5 additions & 1 deletion turbo.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"globalEnv": ["NEXT_PUBLIC_PLAUSIBLE_DATA_DOMAIN"],
"globalEnv": [
"NEXT_PUBLIC_PLAUSIBLE_DATA_DOMAIN",
"NEXT_PUBLIC_IS_LATEST",
"NEXT_PUBLIC_IS_CANARY"
],
"pipeline": {
"build": {
"dependsOn": ["^build"],
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8484,6 +8484,11 @@ lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2:
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==

lru-cache@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==

lru-cache@^4.0.1:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
Expand Down

0 comments on commit b68d98f

Please sign in to comment.