Compare commits
4 Commits
jazz-svelt
...
blacksmith
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
494d902e79 | ||
|
|
44f38f3438 | ||
|
|
33293f3b64 | ||
|
|
e35018a5fa |
6
.github/workflows/build-examples.yaml
vendored
6
.github/workflows/build-examples.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build-examples:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
example: [
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
pnpm --version
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: useblacksmith/setup-node@v5
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: useblacksmith/cache@v5
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
|
||||
6
.github/workflows/build-starters.yaml
vendored
6
.github/workflows/build-starters.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build-starters:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
starter: [
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
pnpm --version
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: useblacksmith/setup-node@v5
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: useblacksmith/cache@v5
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
|
||||
2
.github/workflows/code-quality.yml
vendored
2
.github/workflows/code-quality.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
|
||||
jobs:
|
||||
quality:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
6
.github/workflows/jazz-run.yml
vendored
6
.github/workflows/jazz-run.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
timeout-minutes: 5
|
||||
|
||||
steps:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
pnpm --version
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: useblacksmith/setup-node@v5
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: useblacksmith/cache@v5
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
|
||||
6
.github/workflows/playwright.yml
vendored
6
.github/workflows/playwright.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
pnpm --version
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: useblacksmith/setup-node@v5
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: useblacksmith/cache@v5
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -17,7 +17,7 @@ concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
pnpm --version
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
uses: useblacksmith/setup-node@v5
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: useblacksmith/cache@v5
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
|
||||
6
.github/workflows/unit-test.yml
vendored
6
.github/workflows/unit-test.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
pnpm --version
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: useblacksmith/setup-node@v5
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: useblacksmith/cache@v5
|
||||
name: Setup pnpm cache
|
||||
with:
|
||||
path: ${{ env.STORE_PATH }}
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
MousePointerSquareDashedIcon,
|
||||
PencilLineIcon,
|
||||
ScanFace,
|
||||
ScrollIcon,
|
||||
SunIcon,
|
||||
TrashIcon,
|
||||
UploadCloudIcon,
|
||||
@@ -67,6 +68,7 @@ const icons = {
|
||||
permissions: FileLock2Icon,
|
||||
social: UsersIcon,
|
||||
spatialPresence: MousePointerSquareDashedIcon,
|
||||
tableOfContents: ScrollIcon,
|
||||
touchId: FingerprintIcon,
|
||||
upload: UploadCloudIcon,
|
||||
write: PencilLineIcon,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Icon } from "../atoms/Icon";
|
||||
|
||||
// TODO: add tabs feature, and remove CodeExampleTabs
|
||||
|
||||
function CopyButton({ code, size }: { code: string; size?: "sm" | "md" }) {
|
||||
function CopyButton({ code, size }: { code: string; size: "md" | "lg" }) {
|
||||
let [copyCount, setCopyCount] = useState(0);
|
||||
let copied = copyCount > 0;
|
||||
|
||||
@@ -27,8 +27,8 @@ function CopyButton({ code, size }: { code: string; size?: "sm" | "md" }) {
|
||||
copied
|
||||
? "bg-emerald-400/10 ring-1 ring-inset ring-emerald-400/20"
|
||||
: "bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5",
|
||||
size == "sm"
|
||||
? "right-1.5 top-1.5 py-[2px] pl-1 pr-2"
|
||||
size == "md"
|
||||
? "right-[8px] top-[8px] py-[2px] pl-1 pr-2"
|
||||
: "right-2 top-2 py-1 pl-2 pr-3 ",
|
||||
)}
|
||||
onClick={() => {
|
||||
@@ -48,7 +48,7 @@ function CopyButton({ code, size }: { code: string; size?: "sm" | "md" }) {
|
||||
name="copy"
|
||||
size="xs"
|
||||
className={clsx(
|
||||
size === "sm" ? "size-2" : "size-3",
|
||||
size === "md" ? "size-3" : "size-4",
|
||||
"stroke-stone-500 transition-colors group-hover/button:stroke-stone-600 dark:group-hover/button:stroke-stone-400",
|
||||
)}
|
||||
/>
|
||||
@@ -69,11 +69,11 @@ function CopyButton({ code, size }: { code: string; size?: "sm" | "md" }) {
|
||||
|
||||
export function CodeGroup({
|
||||
children,
|
||||
size,
|
||||
size = "md",
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
size?: "sm" | "md";
|
||||
size?: "md" | "lg";
|
||||
className?: string;
|
||||
}) {
|
||||
const textRef = useRef<HTMLPreElement | null>(null);
|
||||
@@ -86,13 +86,14 @@ export function CodeGroup({
|
||||
}, [children]);
|
||||
|
||||
return (
|
||||
<div className={clsx(className, "group relative")}>
|
||||
<div className={clsx(className, "not-prose group relative")}>
|
||||
<pre
|
||||
className={clsx(
|
||||
"h-full border p-0 bg-stone-50 dark:bg-stone-925",
|
||||
"h-full overflow-x-auto",
|
||||
"border rounded-md p-0 bg-stone-50 dark:bg-stone-925",
|
||||
"text-black dark:text-white",
|
||||
{
|
||||
"text-sm": size === "sm",
|
||||
"text-sm": size === "md",
|
||||
},
|
||||
)}
|
||||
ref={textRef}
|
||||
|
||||
@@ -31,7 +31,7 @@ export function Footer({
|
||||
themeToggle: ThemeToggle,
|
||||
}: FooterProps) {
|
||||
return (
|
||||
<footer className="w-full py-8 mt-12 md:mt-20">
|
||||
<footer className="w-full pt-8 pb-20 mt-12 md:mt-20 md:pb-8">
|
||||
<div className="container grid gap-8 md:gap-12">
|
||||
<div className="grid grid-cols-12 gap-y-3 sm:items-center pb-8 border-b">
|
||||
<div className="col-span-full sm:col-span-6 md:col-span-8">
|
||||
|
||||
@@ -10,14 +10,7 @@ import {
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import {
|
||||
ComponentType,
|
||||
ReactNode,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { ComponentType, ReactNode, useEffect, useState } from "react";
|
||||
import { Icon } from "../atoms/Icon";
|
||||
import { BreadCrumb } from "../molecules/Breadcrumb";
|
||||
import { SocialLinks, SocialLinksProps } from "./SocialLinks";
|
||||
@@ -35,10 +28,16 @@ type NavItemProps = {
|
||||
type NavProps = {
|
||||
mainLogo: ReactNode;
|
||||
items: NavItemProps[];
|
||||
docNav?: ReactNode;
|
||||
cta?: ReactNode;
|
||||
socials?: SocialLinksProps;
|
||||
themeToggle: ComponentType<{ className?: string }>;
|
||||
sections?: NavSection[];
|
||||
};
|
||||
|
||||
export type NavSection = {
|
||||
name: string;
|
||||
content: ReactNode;
|
||||
icon: string;
|
||||
};
|
||||
|
||||
function NavItem({
|
||||
@@ -68,7 +67,7 @@ function NavItem({
|
||||
className,
|
||||
"text-sm px-2 lg:px-4 py-3 ",
|
||||
firstOnRight && "ml-auto",
|
||||
path === href ? "text-black dark:text-white" : "",
|
||||
path === href ? "text-stone-900 dark:text-white" : "",
|
||||
)}
|
||||
{...item}
|
||||
>
|
||||
@@ -81,8 +80,8 @@ function NavItem({
|
||||
<Popover className={clsx("relative", className, firstOnRight && "ml-auto")}>
|
||||
<PopoverButton
|
||||
className={clsx(
|
||||
"flex items-center gap-1.5 text-sm px-2 lg:px-4 py-3 max-sm:w-full text-stone-600 dark:text-stone-400 hover:text-black dark:hover:text-white transition-colors hover:transition-none focus-visible:outline-none",
|
||||
path === href ? "text-black dark:text-white" : "",
|
||||
"flex items-center gap-1.5 text-sm px-2 lg:px-4 py-3 max-sm:w-full hover:text-stone-900 dark:hover:text-white transition-colors hover:transition-none focus-visible:outline-none",
|
||||
path === href ? "text-stone-900 dark:text-white" : "",
|
||||
)}
|
||||
>
|
||||
<span>{title}</span>
|
||||
@@ -128,25 +127,57 @@ function NavItem({
|
||||
export function MobileNav({
|
||||
mainLogo,
|
||||
items,
|
||||
docNav,
|
||||
cta,
|
||||
socials,
|
||||
sections,
|
||||
themeToggle: ThemeToggle,
|
||||
}: NavProps) {
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
const [searchOpen, setSearchOpen] = useState(false);
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
const primarySection = {
|
||||
name: "Menu",
|
||||
icon: "menu",
|
||||
content: (
|
||||
<>
|
||||
<div className="flex items-center justify-between border-b p-3">
|
||||
<Link href="/" className="flex items-center">
|
||||
{mainLogo}
|
||||
</Link>
|
||||
|
||||
useLayoutEffect(() => {
|
||||
searchOpen && searchRef.current?.focus();
|
||||
}, [searchOpen]);
|
||||
<SocialLinks {...socials} className="ml-auto" />
|
||||
|
||||
<ThemeToggle className="ml-4 mr-1" />
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 p-3">
|
||||
{items
|
||||
.filter((item) => !("icon" in item))
|
||||
.map((item, i) => (
|
||||
<NavLink
|
||||
className="p-1"
|
||||
key={i}
|
||||
href={item.href}
|
||||
onClick={() => setActive(null)}
|
||||
newTab={item.newTab}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
const [active, setActive] = useState<string | null>();
|
||||
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
setMenuOpen(false);
|
||||
setActive(null);
|
||||
}, [pathname]);
|
||||
|
||||
const toggle = (type: string) => {
|
||||
setActive(active == type ? null : type);
|
||||
};
|
||||
|
||||
const navSections = [primarySection, ...(sections || [])];
|
||||
return (
|
||||
<>
|
||||
<div className="md:hidden px-4 flex items-center self-stretch dark:text-white">
|
||||
@@ -155,9 +186,8 @@ export function MobileNav({
|
||||
</NavLinkLogo>
|
||||
<button
|
||||
className="flex gap-2 p-3 rounded-xl items-center"
|
||||
onMouseDown={() => {
|
||||
setMenuOpen((o) => !o);
|
||||
setSearchOpen(false);
|
||||
onClick={() => {
|
||||
setActive("Menu");
|
||||
}}
|
||||
aria-label="Open menu"
|
||||
>
|
||||
@@ -165,80 +195,70 @@ export function MobileNav({
|
||||
<BreadCrumb items={items} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
onClick={() => {
|
||||
setMenuOpen(false);
|
||||
setSearchOpen(false);
|
||||
setActive(null);
|
||||
}}
|
||||
className={clsx(
|
||||
menuOpen || searchOpen ? "block" : "hidden",
|
||||
"fixed top-0 bottom-0 left-0 right-0 bg-stone-200/80 dark:bg-black/80 w-full h-full z-20",
|
||||
!!active ? "block" : "hidden",
|
||||
"md:hidden fixed backdrop-blur-sm top-0 bottom-0 left-0 right-0 bg-stone-200/80 dark:bg-black/80 w-full h-full z-20",
|
||||
)}
|
||||
></div>
|
||||
<nav
|
||||
|
||||
<div
|
||||
className={clsx(
|
||||
"md:hidden fixed flex flex-col bottom-4 right-4 z-50",
|
||||
"bg-stone-50 dark:bg-stone-925 border rounded-lg shadow-lg",
|
||||
menuOpen || searchOpen ? "left-4" : "",
|
||||
"md:hidden bg-white border fixed z-50",
|
||||
"dark:bg-stone-925",
|
||||
|
||||
{
|
||||
"rounded-lg right-6 left-6 bottom-6 sm:max-w-lg sm:w-full shadow-md sm:left-1/2 sm:-translate-x-1/2 ":
|
||||
!!active,
|
||||
"rounded-full shadow-sm left-1/2 -translate-x-1/2 bottom-7":
|
||||
!active,
|
||||
},
|
||||
)}
|
||||
>
|
||||
<div className={clsx(menuOpen ? "block" : "hidden", " px-2 pb-2")}>
|
||||
<div className="flex items-center w-full border-b">
|
||||
<NavLinkLogo
|
||||
prominent
|
||||
href="/"
|
||||
className="mr-auto"
|
||||
onClick={() => setMenuOpen(false)}
|
||||
>
|
||||
{mainLogo}
|
||||
</NavLinkLogo>
|
||||
|
||||
<SocialLinks className="px-2 gap-2" {...socials} />
|
||||
</div>
|
||||
|
||||
{pathname.startsWith("/docs") && docNav && (
|
||||
<div className="max-h-[calc(100dvh-15rem)] p-4 border-b overflow-x-auto">
|
||||
{docNav}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-wrap justify-end py-2 gap-x-3 gap-y-1 border-b">
|
||||
{[{ title: "Home", href: "/" }, ...items]
|
||||
.filter((item) => !("icon" in item))
|
||||
.map((item, i) => (
|
||||
<NavLink
|
||||
className="p-1 text-sm"
|
||||
key={i}
|
||||
href={item.href}
|
||||
onClick={() => setMenuOpen(false)}
|
||||
newTab={item.newTab}
|
||||
>
|
||||
{item.title}
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center self-stretch justify-between">
|
||||
{(menuOpen || searchOpen) && <ThemeToggle className="p-3" />}
|
||||
<button
|
||||
className="flex gap-2 p-3 rounded-xl items-center"
|
||||
onMouseDown={() => {
|
||||
setMenuOpen((o) => !o);
|
||||
setSearchOpen(false);
|
||||
}}
|
||||
aria-label="Close menu"
|
||||
>
|
||||
{menuOpen || searchOpen ? (
|
||||
<Icon name="close" />
|
||||
) : (
|
||||
<>
|
||||
<Icon name="menu" />
|
||||
<BreadCrumb items={items} />
|
||||
</>
|
||||
{active && (
|
||||
<div
|
||||
className={clsx(
|
||||
"max-h-[calc(100vh-16rem)] overflow-y-auto",
|
||||
active === "Menu" ? "" : "p-3 pb-10",
|
||||
)}
|
||||
</button>
|
||||
>
|
||||
{navSections.map((section) =>
|
||||
section.name == active ? section.content : null,
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={clsx("flex justify-center py-1 px-1.5", {
|
||||
"border-t py-2": !!active,
|
||||
})}
|
||||
>
|
||||
{navSections.map(
|
||||
(section) =>
|
||||
section.content && (
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
"flex items-center gap-1 px-2 py-1 text-sm rounded-md whitespace-nowrap",
|
||||
"text-stone-900 dark:text-white",
|
||||
{
|
||||
"bg-stone-100 dark:bg-stone-900": active === section.name,
|
||||
},
|
||||
)}
|
||||
onClick={() => toggle(section.name)}
|
||||
key={section.name}
|
||||
>
|
||||
<Icon name={section.icon} size="xs" />
|
||||
{section.name}
|
||||
</button>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -262,7 +282,7 @@ function NavLink({
|
||||
<Link
|
||||
href={href}
|
||||
className={clsx(
|
||||
"text-stone-600 dark:text-stone-400 hover:text-black dark:hover:text-white transition-colors hover:transition-none",
|
||||
"hover:text-stone-900 dark:hover:text-white transition-colors hover:transition-none",
|
||||
className,
|
||||
)}
|
||||
onClick={onClick}
|
||||
@@ -310,7 +330,7 @@ function NavLinkLogo({
|
||||
}
|
||||
|
||||
export function Nav(props: NavProps) {
|
||||
const { mainLogo, items, docNav, cta } = props;
|
||||
const { mainLogo, items, cta } = props;
|
||||
return (
|
||||
<>
|
||||
<div className="w-full border-b py-2 sticky top-0 z-50 bg-white dark:bg-stone-950 hidden md:block">
|
||||
|
||||
@@ -42,7 +42,12 @@ const socials = [
|
||||
|
||||
export function SocialLinks(props: SocialLinksProps & { className?: string }) {
|
||||
return (
|
||||
<div className={clsx(props.className, "inline-flex gap-6 items-center")}>
|
||||
<div
|
||||
className={clsx(
|
||||
props.className,
|
||||
"inline-flex gap-3 items-center sm:gap-6",
|
||||
)}
|
||||
>
|
||||
{socials.map(
|
||||
(social) =>
|
||||
props[social.key as keyof SocialLinksProps] && (
|
||||
|
||||
15
homepage/homepage/app/(docs)/api-reference/layout.tsx
Normal file
15
homepage/homepage/app/(docs)/api-reference/layout.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ApiNav } from "@/components/docs/ApiNav";
|
||||
import DocsLayout from "@/components/docs/DocsLayout";
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<DocsLayout nav={<ApiNav />} navIcon="package" navName="API Ref">
|
||||
<Prose className="overflow-x-hidden lg:flex-1 py-8">{children}</Prose>
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +1,6 @@
|
||||
import DocsLayout from "@/components/docs/DocsLayout";
|
||||
import { DocNav } from "@/components/docs/nav";
|
||||
|
||||
export const metadata = {
|
||||
title: {
|
||||
default: "Documentation",
|
||||
template: "%s | Jazz",
|
||||
},
|
||||
description: "Jazz guide and documentation.",
|
||||
};
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
|
||||
export default function Layout({
|
||||
children,
|
||||
@@ -16,7 +9,7 @@ export default function Layout({
|
||||
}) {
|
||||
return (
|
||||
<DocsLayout nav={<DocNav />}>
|
||||
<div className="flex justify-center lg:gap-5">{children}</div>
|
||||
<Prose className="max-w-3xl mx-auto lg:flex-1 py-8">{children}</Prose>
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import MdxSource from "@/components/docs/docs-intro.mdx";
|
||||
import { frameworks } from "@/lib/framework";
|
||||
import { JazzLogo } from "gcmp-design-system/src/app/components/atoms/logos/JazzLogo";
|
||||
import { HeroHeader } from "gcmp-design-system/src/app/components/molecules/HeroHeader";
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
import MdxSource from "../../../../../components/docs/docs-intro.mdx";
|
||||
import { frameworks } from "../../../../../lib/framework";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
@@ -349,7 +349,7 @@ This works because CoValues
|
||||
|
||||
1. Directly on an instance:
|
||||
|
||||
<CodeGroup size="sm">
|
||||
<CodeGroup>
|
||||
```ts
|
||||
const unsub = issue.subscribe([], (updatedIssue) => console.log(updatedIssue));
|
||||
```
|
||||
@@ -357,7 +357,7 @@ This works because CoValues
|
||||
|
||||
2. If you only have an ID (this will load the issue if needed):
|
||||
|
||||
<CodeGroup size="sm">
|
||||
<CodeGroup>
|
||||
```ts
|
||||
const unsub = Issue.subscribe(issueID, me, [], (updatedIssue) => {
|
||||
console.log(updatedIssue);
|
||||
@@ -373,7 +373,7 @@ This works because CoValues
|
||||
|
||||
|
||||
By the way, `useCoState` is basically just an optimized version of
|
||||
<CodeGroup size="sm">
|
||||
<CodeGroup>
|
||||
```ts
|
||||
function useCoState<V extends CoValue>(Schema: CoValueClass<V>, id?: ID<V>): V | undefined {
|
||||
const [value, setValue] = useState<V>();
|
||||
@@ -1,46 +1,11 @@
|
||||
import DocsLayout from "@/app/docs/[framework]/(others)/layout";
|
||||
import DocsLayout from "@/components/docs/DocsLayout";
|
||||
import { TableOfContents } from "@/components/docs/TableOfContents";
|
||||
import ComingSoonPage from "@/components/docs/coming-soon.mdx";
|
||||
import { DocNav } from "@/components/docs/nav";
|
||||
import { docNavigationItems } from "@/lib/docNavigationItems.js";
|
||||
import { Framework, frameworks } from "@/lib/framework";
|
||||
import type { Toc } from "@stefanprobst/rehype-extract-toc";
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
import { Metadata } from "next";
|
||||
|
||||
async function getMdxSource(slugPath: string, framework: string) {
|
||||
try {
|
||||
return await import(`./${slugPath}.mdx`);
|
||||
} catch (error) {
|
||||
return await import(`./${slugPath}/${framework}.mdx`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params: { slug, framework },
|
||||
}: {
|
||||
params: { slug: string[]; framework: string };
|
||||
}): Promise<Metadata> {
|
||||
const slugPath = slug.join("/");
|
||||
const title = "Coming soon";
|
||||
try {
|
||||
const mdxSource = await getMdxSource(slugPath, framework);
|
||||
const title = mdxSource.metadata.title;
|
||||
|
||||
return {
|
||||
title,
|
||||
openGraph: {
|
||||
title,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
title,
|
||||
openGraph: {
|
||||
title,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default async function Page({
|
||||
params: { slug, framework },
|
||||
@@ -48,24 +13,31 @@ export default async function Page({
|
||||
const slugPath = slug.join("/");
|
||||
|
||||
try {
|
||||
const mdxSource = await getMdxSource(slugPath, framework);
|
||||
let mdxSource;
|
||||
try {
|
||||
mdxSource = await import(`./${slugPath}.mdx`);
|
||||
} catch (error) {
|
||||
mdxSource = await import(`./${slugPath}/${framework}.mdx`);
|
||||
}
|
||||
|
||||
const { default: Content, tableOfContents } = mdxSource;
|
||||
|
||||
// Exclude h1 from table of contents
|
||||
const tocItems = (tableOfContents as Toc)?.[0]?.children;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DocsLayout toc={tocItems} nav={<DocNav />}>
|
||||
<Prose className="overflow-x-hidden lg:flex-1 py-8">
|
||||
<Content />
|
||||
</Prose>
|
||||
{tocItems && <TableOfContents items={tocItems} />}
|
||||
</>
|
||||
</DocsLayout>
|
||||
);
|
||||
} catch (error) {
|
||||
return (
|
||||
<DocsLayout>
|
||||
<ComingSoonPage />
|
||||
<DocsLayout nav={<DocNav />}>
|
||||
<Prose className="overflow-x-hidden lg:flex-1 py-8">
|
||||
<ComingSoonPage className="max-w-3xl mx-auto" />
|
||||
</Prose>
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
@@ -17,12 +17,12 @@ export const metadata = { title: "Upgrade to Jazz 0.9.0" };
|
||||
<CodeGroup>
|
||||
{/* prettier-ignore */}
|
||||
```ts
|
||||
import { useState } from "react";
|
||||
import { Issue } from "./schema";
|
||||
import { IssueComponent } from "./components/Issue.tsx";
|
||||
import { useState } from "react";
|
||||
import { Issue } from "./schema";
|
||||
import { IssueComponent } from "./components/Issue.tsx";
|
||||
function App() {
|
||||
const [issue, setIssue] = useState<Issue>();
|
||||
|
||||
const [issue, setIssue] = useState<Issue>();
|
||||
|
||||
const createIssue = () => {
|
||||
setIssue(Issue.create(
|
||||
{
|
||||
@@ -33,13 +33,13 @@ export const metadata = { title: "Upgrade to Jazz 0.9.0" };
|
||||
}, // The owner defaults now to a group managed by the current user!
|
||||
));
|
||||
};
|
||||
|
||||
|
||||
if (issue) {
|
||||
return <IssueComponent issue={issue} />;
|
||||
} else {
|
||||
return <IssueComponent issue={issue} />;
|
||||
} else {
|
||||
return <button onClick={createIssue}>Create Issue</button>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -71,4 +71,4 @@ export const metadata = { title: "Upgrade to Jazz 0.9.0" };
|
||||
Everything is backward compatible, so no upgrade steps are required.
|
||||
|
||||
With this Jazz API becomes way more lean and more is coming!
|
||||
</div>
|
||||
</div>
|
||||
14
homepage/homepage/app/(others)/layout.tsx
Normal file
14
homepage/homepage/app/(others)/layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { JazzNav } from "@/components/nav";
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex-1 w-full">
|
||||
<JazzNav />
|
||||
<main>{children}</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ApiNav } from "@/components/docs/ApiNav";
|
||||
import DocsLayout from "@/components/docs/DocsLayout";
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
|
||||
export const metadata = {
|
||||
title: "API reference",
|
||||
description:
|
||||
"API references for packages like jazz-tools, jazz-react, and more.",
|
||||
};
|
||||
|
||||
export default function Layout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<DocsLayout nav={<ApiNav />}>
|
||||
<Prose className="py-8 [&_*]:scroll-mt-[8rem]">{children}</Prose>
|
||||
</DocsLayout>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
|
||||
|
||||
export default function DocsLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Prose className="max-w-3xl mx-auto overflow-x-hidden lg:flex-1 py-8">
|
||||
{children}
|
||||
</Prose>
|
||||
);
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import localFont from "next/font/local";
|
||||
|
||||
import { ThemeProvider } from "@/components/ThemeProvider";
|
||||
import { JazzFooter } from "@/components/footer";
|
||||
import { JazzNav } from "@/components/nav";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import { SpeedInsights } from "@vercel/speed-insights/next";
|
||||
|
||||
@@ -98,10 +97,7 @@ export default function RootLayout({
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<div className="flex-1 w-full">
|
||||
<JazzNav />
|
||||
<main>{children}</main>
|
||||
</div>
|
||||
{children}
|
||||
<JazzFooter />
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
|
||||
@@ -1,25 +1,68 @@
|
||||
import { TableOfContents } from "@/components/docs/TableOfContents";
|
||||
import { JazzNav } from "@/components/nav";
|
||||
import { Toc } from "@stefanprobst/rehype-extract-toc";
|
||||
import { clsx } from "clsx";
|
||||
|
||||
export default function DocsLayout({
|
||||
children,
|
||||
nav,
|
||||
navName,
|
||||
navIcon,
|
||||
toc,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
nav?: React.ReactNode;
|
||||
navName?: string;
|
||||
navIcon?: string;
|
||||
toc?: Toc;
|
||||
}) {
|
||||
const navSections = [
|
||||
{
|
||||
name: navName || "Docs",
|
||||
content: nav,
|
||||
icon: navIcon || "docs",
|
||||
},
|
||||
{
|
||||
name: "Outline",
|
||||
content: toc && (
|
||||
<TableOfContents className="text-sm" items={toc as Toc} />
|
||||
),
|
||||
icon: "tableOfContents",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="container relative grid grid-cols-12 gap-5">
|
||||
<div
|
||||
className={clsx(
|
||||
"py-8",
|
||||
"pr-3 md:col-span-4 lg:col-span-3",
|
||||
"sticky align-start top-[65px] h-[calc(100vh-65px)] overflow-y-auto overflow-x-hidden",
|
||||
"hidden md:block",
|
||||
)}
|
||||
>
|
||||
{nav}
|
||||
</div>
|
||||
<div className="col-span-12 md:col-span-8 lg:col-span-9">{children}</div>
|
||||
<div className="flex-1 w-full">
|
||||
<JazzNav sections={navSections} />
|
||||
<main>
|
||||
<div className="container relative grid grid-cols-12 gap-5">
|
||||
<div
|
||||
className={clsx(
|
||||
"py-8",
|
||||
"pr-3 md:col-span-4 lg:col-span-3",
|
||||
"sticky align-start top-[65px] h-[calc(100vh-65px)] overflow-y-auto overflow-x-hidden",
|
||||
"hidden md:block",
|
||||
)}
|
||||
>
|
||||
{nav}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"col-span-12 md:col-span-8 lg:col-span-9 flex gap-3",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
{toc && (
|
||||
<>
|
||||
<TableOfContents
|
||||
className="pl-3 py-6 shrink-0 text-sm sticky align-start top-[65px] w-[16rem] h-[calc(100vh-65px)] overflow-y-auto overflow-x-hidden hidden lg:block"
|
||||
items={toc as Toc}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ import type { Toc, TocEntry } from "@stefanprobst/rehype-extract-toc";
|
||||
import { clsx } from "clsx";
|
||||
import Link from "next/link";
|
||||
|
||||
const TocList = ({ items }: { items: TocEntry[] }) => {
|
||||
const TocList = ({ items, level }: { items: TocEntry[]; level: number }) => {
|
||||
return (
|
||||
<ul className="list-disc pl-4 space-y-2">
|
||||
<ul className="space-y-3" style={{ paddingLeft: `${level * 1}rem` }}>
|
||||
{items.map((item) => (
|
||||
<li key={item.id} className="space-y-2">
|
||||
<li key={item.id} className="space-y-3">
|
||||
<Link href={`#${item.id}`}>{item.value}</Link>
|
||||
{item.children && <TocList items={item.children} />}
|
||||
{item.children && <TocList items={item.children} level={level + 1} />}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
@@ -25,14 +25,11 @@ export function TableOfContents({
|
||||
if (!items.length) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"pl-3 py-6 text-sm sticky align-start top-[65px] w-[16rem] h-[calc(100vh-65px)] overflow-y-auto overflow-x-hidden hidden lg:block",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<p className="mb-3">On this page:</p>
|
||||
<TocList items={items} />
|
||||
<div className={className}>
|
||||
<p className="font-medium text-stone-900 dark:text-white mb-3">
|
||||
On this page
|
||||
</p>
|
||||
<TocList items={items} level={0} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,16 @@ import { ThemeToggle } from "@/components/ThemeToggle";
|
||||
import { socials } from "@/lib/socials";
|
||||
import { useFramework } from "@/lib/use-framework";
|
||||
import { JazzLogo } from "gcmp-design-system/src/app/components/atoms/logos/JazzLogo";
|
||||
import { Nav } from "gcmp-design-system/src/app/components/organisms/Nav";
|
||||
import { DocNav } from "./docs/nav";
|
||||
import {
|
||||
Nav,
|
||||
type NavSection,
|
||||
} from "gcmp-design-system/src/app/components/organisms/Nav";
|
||||
|
||||
export function JazzNav() {
|
||||
export function JazzNav({ sections }: { sections?: NavSection[] }) {
|
||||
return (
|
||||
<Nav
|
||||
mainLogo={<JazzLogo className="w-24" />}
|
||||
sections={sections}
|
||||
mainLogo={<JazzLogo className="w-20 md:w-24" />}
|
||||
themeToggle={ThemeToggle}
|
||||
items={[
|
||||
{ title: "Jazz Cloud", href: "/cloud" },
|
||||
@@ -46,7 +49,6 @@ export function JazzNav() {
|
||||
},
|
||||
]}
|
||||
socials={socials}
|
||||
docNav={<DocNav className="block h-auto" />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user