Skip to content

Commit

Permalink
Merge branch 'main' into feat_add_preact_to_frameworks
Browse files Browse the repository at this point in the history
  • Loading branch information
jonniebigodes authored Feb 4, 2025
2 parents 454aae5 + 158f837 commit c644d35
Show file tree
Hide file tree
Showing 55 changed files with 2,047 additions and 3,469 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ jobs:
- name: Build packages
run: npm run build:ui

- name: Run Chromatic
- name: Run Chromatic (frontpage)
uses: chromaui/action@latest
with:
workingDir: apps/frontpage
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN_FRONTPAGE }}

- name: Run Chromatic (ui)
uses: chromaui/action@latest
with:
workingDir: packages/ui
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN_UI }}
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![Storybook Web Light](github-light.png#gh-light-mode-only)
![Storybook Web Dark](github-dark.png#gh-dark-mode-only)

Welcome to the new home for Storybook's main website and documentation. This project is still in progress but will soon replace the existing platform. It is mainly built around Next.js, Tailwind, Turborepo and obviously Storybook ✌️
Welcome to the new home for Storybook's main website and documentation. It is mainly built around Next.js, Tailwind, Turborepo and obviously Storybook ✌️

## Monorepo

Expand All @@ -17,15 +17,19 @@ This project is structured around [Turborepo](https://turbo.build/repo). This do

> Install all dependencies
#### `turbo fetch-docs`
#### `npx turbo fetch-docs`

> Fetch docs from the monorepo
#### `turbo dev`
#### `npx turbo generate-redirects`

> Generate redirects file
#### `npx turbo dev`

> Run all apps locally
#### `turbo build`
#### `npx turbo build`

> Build all apps locally
Expand Down
46 changes: 37 additions & 9 deletions apps/addon-catalog/app/(home)/tag/[...name]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
import { type Metadata } from 'next';
import { notFound } from 'next/navigation';
import { Preview } from '../../../../components/preview';
import { fetchTagDetailsData } from '../../../../lib/fetch-tag-details-data';
import type { Tag } from '../../../../types';

// 60*60*24 = 24 hrs
export const revalidate = 86400;

interface Params {
name: string[];
}

type GenerateMetaData = (props: {
params: Promise<Params>;
}) => Promise<Metadata>;

interface TagDetailsProps {
params: {
name: string[];
};
params: Params;
}

async function getTagFromName(
tagName: string[],
): Promise<Tag | { error: string }> {
const name = tagName.join('/');
return (await fetchTagDetailsData(name)) || {};
}

export const generateMetadata: GenerateMetaData = async ({ params }) => {
const tagName = (await params).name.join('/');
const data = (await fetchTagDetailsData(tagName)) || {};

if ('error' in data) return {};

const title = data.displayName ?? data.name;

return {
...(title
? {
title: `${title} tag | Storybook integrations`,
}
: undefined),
};
};

export default async function TagDetails({
params: { name },
}: TagDetailsProps) {
const tagName = name.join('/');

if (!tagName) return notFound();

const data = (await fetchTagDetailsData(tagName)) || {};
const data = await getTagFromName(name);

if ('error' in data) return notFound();
if (!data || 'error' in data) return notFound();

return (
<>
Expand Down
46 changes: 37 additions & 9 deletions apps/addon-catalog/app/[...addonName]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,55 @@
import { type Metadata } from 'next';
import { notFound } from 'next/navigation';
import { SubHeader } from '@repo/ui';
import { cn } from '@repo/utils';
import { fetchAddonDetailsData } from '../../lib/fetch-addon-details-data';
import { AddonHero } from '../../components/addon/addon-hero';
import { AddonSidebar } from '../../components/addon/addon-sidebar';
import { Highlight } from '../../components/highlight';
import type { AddonWithTagLinks } from '../../types';

// 60*60*24 = 24 hrs
export const revalidate = 86400;

interface Params {
addonName: string[];
}

type GenerateMetaData = (props: {
params: Promise<Params>;
}) => Promise<Metadata>;

interface AddonDetailsProps {
params: {
addonName: string[];
};
params: Params;
}

export default async function AddonDetails({ params }: AddonDetailsProps) {
async function getAddonFromName(
addonName: string[],
): Promise<AddonWithTagLinks | undefined> {
// TODO: Better decoding?
const name = params.addonName.join('/').replace('%40', '@');
const addon = await fetchAddonDetailsData(name);
const name = addonName.join('/').replace('%40', '@');
return await fetchAddonDetailsData(name);
}

export const generateMetadata: GenerateMetaData = async ({ params }) => {
const name = (await params).addonName;
const addon = await getAddonFromName(name);

const title = addon?.displayName ?? addon?.name;

return {
...(title
? {
title: `${title} | Storybook integrations`,
}
: undefined),
};
};

export default async function AddonDetails({ params }: AddonDetailsProps) {
const addon = await getAddonFromName(params.addonName);

if (!addon) {
return <div>Not found.</div>;
}
if (!addon) notFound();

return (
<main className="mb-20">
Expand Down
2 changes: 1 addition & 1 deletion apps/addon-catalog/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const fontSans = nunitoSans({

export const metadata: Metadata = {
metadataBase: new URL('https://storybook.js.org/integrations'),
title: 'Integrations | Storybook: Frontend workshop for UI development',
title: 'Storybook integrations',
description:
'Integrations enable advanced functionality and unlock new workflows. Contributed by core maintainers and the amazing developer community.',
openGraph: {
Expand Down
5 changes: 3 additions & 2 deletions apps/addon-catalog/components/addon/addon-hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { StorybookIcon } from '@repo/ui';
import { type Addon } from '../../types';

export function AddonHero({ addon }: { addon: Addon }) {
const installCommand = `npm install -D ${addon.name ?? ''}`;
const [state, setState] = useState(false);

const onClick = () => {
copy(`npx install ${addon.name ?? ''}`);
copy(installCommand);
setState(true);
setTimeout(() => {
setState(false);
Expand Down Expand Up @@ -49,7 +50,7 @@ export function AddonHero({ addon }: { addon: Addon }) {
onClick={onClick}
type="button"
>
npm install {addon.name} <CopyIcon />
{installCommand} <CopyIcon />
<AnimatePresence>
{state ? (
<motion.div
Expand Down
4 changes: 4 additions & 0 deletions apps/frontpage/app/addons/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const categories = await fetchTagsData({ isCategory: true });
const tags = await fetchTagsData();

if (addons.length === 0 || categories.length === 0 || tags.length === 0) {
throw new Error('Failed to fetch addons data');
}

const addonPaths = addons.map((name) => {
if (!name) throw new Error('Addon name is missing');
return { loc: `https://storybook.js.org/addons/${name}` };
Expand Down
4 changes: 4 additions & 0 deletions apps/frontpage/app/blog/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {

if (error) throw new Error(error);

if (sites.length === 0) {
throw new Error('Failed to fetch blog data');
}

return sites;
}
7 changes: 7 additions & 0 deletions apps/frontpage/app/community/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Metadata } from 'next';
import { Header, Footer, Container, NewsletterForm } from '@repo/ui';
import {
fetchDiscordMembers,
Expand All @@ -18,6 +19,12 @@ import { Sponsor } from '../../components/community/sponsor';
import { Testimonials } from '../../components/community/testimonials';
import { CommunityProvider } from './provider';

export function generateMetadata(): Metadata {
return {
title: 'Community | Storybook',
};
}

export default async function Page() {
const { number: githubCount, formattedResult: githubCountFormatted } =
await fetchGithubCount();
Expand Down
65 changes: 38 additions & 27 deletions apps/frontpage/app/docs/[...slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
import { type Metadata } from 'next';
import { notFound, redirect } from 'next/navigation';
import { globalSearchMetaKeys, globalSearchImportance } from '@repo/ui';
import { latestVersion } from '@repo/utils';
import { type Metadata } from 'next';
import { type DocsVersion, latestVersion } from '@repo/utils';
import { getVersion } from '../../../lib/get-version';
import { getPageData } from '../../../lib/get-page';
import { getPageData, type PageDataProps } from '../../../lib/get-page';
import { getAllTrees } from '../../../lib/get-all-trees';
import { getFlatTree } from '../../../lib/get-flat-tree';
import { Content } from '../../../components/docs/content';

interface Params {
slug: string[];
}

type GenerateMetaData = (props: {
params: Promise<Params>;
}) => Promise<Metadata>;

interface PageProps {
params: {
slug?: string[];
};
params: Params;
}

export async function generateMetadata({
params: { slug },
}: PageProps): Promise<Metadata> {
async function getPageFromSlug(
slug: string[],
): Promise<{ activeVersion: DocsVersion; page: PageDataProps | undefined }> {
const activeVersion = getVersion(slug);
const isLatest = activeVersion.id === latestVersion.id;

const slugToFetch = slug ? [...slug] : [];
if (!isLatest) slugToFetch.shift();
slugToFetch.unshift(activeVersion.id);

const page = await getPageData(slugToFetch, activeVersion);
return { activeVersion, page };
}

export const generateMetadata: GenerateMetaData = async ({ params }) => {
const slug = (await params).slug;
const { activeVersion, page } = await getPageFromSlug(slug);

const listofTrees = getAllTrees();
const flatTree = getFlatTree({
tree: listofTrees,
Expand All @@ -29,11 +49,8 @@ export async function generateMetadata({
(node) => node.slug === `/docs/${newSlug.join('/')}`,
);

const slugToFetch = slug ? [...slug] : [];
const page = await getPageData(slugToFetch, activeVersion);

return {
title: `${page?.title ?? 'Docs'} | Storybook`,
title: page?.title ? `${page.title} | Storybook docs` : 'Storybook docs',
alternates: {
canonical: findPage?.canonical,
},
Expand All @@ -42,7 +59,7 @@ export async function generateMetadata({
[globalSearchMetaKeys.importance]: globalSearchImportance.docs,
},
};
}
};

export const generateStaticParams = () => {
const listofTrees = getAllTrees();
Expand All @@ -62,21 +79,15 @@ export const generateStaticParams = () => {
};

export default async function Page({ params: { slug } }: PageProps) {
const activeVersion = getVersion(slug);
const isLatest = activeVersion.id === latestVersion.id;
const slugToFetch = slug ? [...slug] : [];
if (!isLatest) slugToFetch.shift();
slugToFetch.unshift(activeVersion.id);
const newSlug = slug ?? [];

const page = await getPageData(slugToFetch, activeVersion);

const isIndex = slug && slug[slug.length - 1] === 'index';
const pathWithoutIndex = `/docs/${newSlug.slice(0, -1).join('/')}`;

// If the page is an index page, redirect to the parent page
if (isIndex) redirect(pathWithoutIndex);
const isIndex = slug && slug[slug.length - 1] === 'index';
if (isIndex) {
const newSlug = slug ?? [];
const pathWithoutIndex = `/docs/${newSlug.slice(0, -1).join('/')}`;
redirect(pathWithoutIndex);
}

const { page } = await getPageFromSlug(slug);
if (!page) notFound();

return <Content page={page} />;
Expand Down
11 changes: 3 additions & 8 deletions apps/frontpage/app/docs/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Header, Footer, Container } from '@repo/ui';
import Image from 'next/image';
import { fetchGithubCount } from '@repo/utils';
import { type ReactNode, Suspense } from 'react';
import { type Metadata } from 'next';
import { Sidebar } from '../../components/docs/sidebar/sidebar';
import { NavDocs } from '../../components/docs/sidebar/docs-nav';
import { Submenu } from '../../components/docs/submenu';
Expand All @@ -12,12 +11,6 @@ import { getAllTrees } from '../../lib/get-all-trees';
import { DocsProvider } from './provider';
import { RendererCookie } from './renderer-cookie';

export function generateMetadata(): Metadata {
return {
title: 'Docs | Storybook',
};
}

export default async function Layout({ children }: { children: ReactNode }) {
const { number: githubCount } = await fetchGithubCount();
const listofTrees = getAllTrees();
Expand All @@ -38,7 +31,9 @@ export default async function Layout({ children }: { children: ReactNode }) {
/>
<Image
alt="Storybook Docs"
className="absolute top-0 left-0 w-full -z-10"
className="absolute left-0 top-0 -z-10 w-full"
// TODO: 40px is height of eyebrow. Find way to not hard-code this.
// className="absolute left-0 top-[40px] -z-10 w-full"
height={339}
priority
src="/bubbles.png"
Expand Down
5 changes: 4 additions & 1 deletion apps/frontpage/app/docs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import { type Metadata } from 'next';
import { getPageData } from '../../lib/get-page';
import { Content } from '../../components/docs/content';

export function generateMetadata(): Metadata {
export async function generateMetadata(): Promise<Metadata> {
const page = await getPageData([latestVersion.id], latestVersion);

return {
title: page?.title ? `${page.title} | Storybook docs` : 'Storybook docs',
alternates: {
canonical: '/docs',
},
Expand Down
Loading

0 comments on commit c644d35

Please sign in to comment.