Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆️ React19 & Next15 #64

Merged
merged 10 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/website/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
4 changes: 2 additions & 2 deletions apps/website/next.config.js → apps/website/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// experimental: {
// serverComponentsExternalPackages: ["shiki", "vscode-oniguruma"],
// },
Expand Down
48 changes: 24 additions & 24 deletions apps/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,56 @@
},
"dependencies": {
"@cuicui/ui": "workspace:*",
"@radix-ui/react-dialog": "1.1.1",
"@radix-ui/react-dropdown-menu": "2.1.1",
"@radix-ui/react-scroll-area": "1.1.0",
"@radix-ui/react-select": "2.0.0",
"@radix-ui/react-slot": "1.1.0",
"@radix-ui/react-tabs": "1.1.0",
"@radix-ui/react-dialog": "1.1.3",
"@radix-ui/react-dropdown-menu": "2.1.3",
"@radix-ui/react-scroll-area": "1.2.2",
"@radix-ui/react-select": "2.1.3",
"@radix-ui/react-slot": "1.1.1",
"@radix-ui/react-tabs": "1.1.2",
"class-variance-authority": "0.7.0",
"clsx": "^2.x",
"cmdk": "^1.x",
"date-fns": "^3.x",
"clsx": "^2.1.1",
"cmdk": "^1.0.4",
"date-fns": "^3.6.0",
"dom-to-image-more": "3.4.5",
"fs-extra": "11.2.0",
"lucide-react": "^0.x",
"motion": "^11.x",
"next": "14.2.3",
"lucide-react": "^0.468.0",
"motion": "^11.14.1",
"next": "15.1.0",
"next-mdx-remote": "5.0.0",
"next-themes": "0.3.0",
"next-themes": "0.4.4",
"path": "0.12.7",
"react": "18.2.0",
"react-dom": "18.2.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-frame-component": "5.2.7",
"react-resizable-panels": "2.0.22",
"react-resizable-panels": "2.1.7",
"sharp": "0.33.4",
"sonner": "^1.x",
"sonner": "^1.7.1",
"tailwind-merge": "2.3.0",
"vite-tsconfig-paths": "5.0.1",
"zustand": "^4.x"
"zustand": "^4.5.5"
},
"description": "An open-source all-in-one library for building an advanced SaaS application, a personal website, or anything else with micro-interactions, advanced user experiences, and a focus on performance and code quality.",
"devDependencies": {
"@tailwindcss/forms": "0.5.7",
"@tailwindcss/typography": "0.5.12",
"@testing-library/dom": "10.4.0",
"@testing-library/react": "16.0.0",
"@testing-library/react": "16.1.0",
"@types/dom-to-image": "2.6.7",
"@types/node": "20.12.7",
"@types/react": "18.2.79",
"@types/react-dom": "18.2.25",
"@types/react": "19.0.1",
"@types/react-dom": "19.0.2",
"@vitejs/plugin-react": "4.3.1",
"autoprefixer": "10.4.19",
"eslint": "9.0.0",
"eslint-config-next": "14.2.2",
"eslint-config-next": "15.1.0",
"jsdom": "25.0.0",
"lint-staged": "15.2.2",
"postcss": "8.4.38",
"shiki": "1.18.0",
"tailwindcss": "3.4.3",
"tailwindcss-animate": "1.0.7",
"turbo": "2.2.0",
"typescript": "5.4.5",
"typescript": "5.7.2",
"vitest": "2.0.5"
},
"git": {
Expand All @@ -79,7 +79,7 @@
"scripts": {
"build": "pnpm pre-build && next build",
"pre-build": "pnpm scripts/generate-latest-changelog-date.mjs && pnpm scripts/generate-package-list-check.mjs",
"dev": "next dev --turbo",
"dev": "next dev --turbopack",
"start": "next start",
"generate-package-list-check": "node scripts/generate-package-list-check.js",
"lint": "next lint",
Expand Down
50 changes: 30 additions & 20 deletions apps/website/src/app/(site)/[section]/[category]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { Metadata } from "next";
import Head from "next/head";
import Link from "next/link";
import { notFound } from "next/navigation";
Expand All @@ -7,22 +6,22 @@ import { NEXT_PUBLIC_SITE_URL } from "#/src/lib/site.const";
import { findCategoryBySlug } from "#/src/utils/section-category-components-utils/find-category-by-slug";
import { findSectionBySlug } from "#/src/utils/section-category-components-utils/find-section-by-slug";

type Props = {
children: ReactNode;
params: {
export async function generateMetadata({
params,
}: {
params: Promise<{
section: string;
category: string;
};
};

export function generateMetadata({ params }: Props): Metadata {
const section = findSectionBySlug(params.section);
}>;
}) {
const { section: sectionParam, category: categoryParam } = await params;
const section = findSectionBySlug(sectionParam);
if (!section) {
return {};
}

if (section.type === "page") {
const page = section.pageList.find((page) => page.slug === params.category);
const page = section.pageList.find((page) => page.slug === categoryParam);
if (page) {
return {
title: page.name,
Expand All @@ -40,7 +39,7 @@ export function generateMetadata({ params }: Props): Metadata {
return {};
}

const category = findCategoryBySlug(section, params.category);
const category = findCategoryBySlug(section, categoryParam);
if (category) {
return {
title: `${category.name} React Components`,
Expand All @@ -58,29 +57,40 @@ export function generateMetadata({ params }: Props): Metadata {
return {};
}

export default function CategoryLayout({ children, params }: Props) {
const section = findSectionBySlug(params.section);
if (!section) {
export default async function CategoryLayout({
params,
children,
}: {
children: ReactNode;
params: Promise<{
section: string;
category: string;
}>;
}) {
const { section: sectionParam, category: categoryParam } = await params;

const sectionInList = findSectionBySlug(sectionParam);
if (!sectionInList) {
return notFound();
}
const category = findCategoryBySlug(section, params.category);
if (!category) {
const categoryInList = findCategoryBySlug(sectionInList, categoryParam);
if (!categoryInList) {
return notFound();
}
return (
<>
<div>
<Head>
<Link
href={`${NEXT_PUBLIC_SITE_URL}/${section.slug}/${category.slug}`}
href={`${NEXT_PUBLIC_SITE_URL}/${sectionInList.slug}/${categoryInList.slug}`}
key="canonical"
rel="canonical"
/>
<meta content="all" name="robots" />
</Head>
<h1 className="bg-gradient-to-b from-black to-black/40 dark:from-white dark:to-white/10 bg-clip-text font-medium text-transparent text-3xl sm:text-5xl inline tracking-tighter">
{category.name} components
{categoryInList.name} components
</h1>
{children}
</>
</div>
);
}
67 changes: 39 additions & 28 deletions apps/website/src/app/(site)/[section]/[category]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,74 +8,85 @@ import type {
} from "@cuicui/ui/lib/types/component";
import { findCategoryBySlug } from "#/src/utils/section-category-components-utils/find-category-by-slug";
type Props = {
params: {
params: Promise<{
section: string;
category: string;
};
}>;
};

export async function generateStaticParams() {
const params = sectionList.flatMap((section) => {
export function generateStaticParams() {
const paramsArray = [];
for (const section of sectionList) {
if (
section.type === "multiple-component" ||
section.type === "single-component"
) {
return section.categoriesList.map((category) => ({
section: section.slug,
category: category.slug,
}));
for (const category of section.categoriesList) {
paramsArray.push({
section: section.slug,
category: category.slug,
});
}
}
if (section.type === "page") {
return section.pageList.map((page) => ({
section: section.slug,
category: page.slug,
}));
for (const page of section.pageList) {
paramsArray.push({
section: section.slug,
category: page.slug,
});
}
}
});
}

// Return the generated params array
return params;
return paramsArray;
}

export default async function Page({ params }: Readonly<Props>) {
const section = sectionList.find(
(section) => section.slug === params.section,
export default async function Page({ params }: Props) {
const { section: sectionParam, category: categoryParam } = await params;
const sectionInList = sectionList.find(
(section) => section.slug === sectionParam,
);
if (!section) {
if (!sectionInList) {
return notFound();
}
if (section?.type === "page") {
const page = section.pageList.find((page) => page.slug === params.category);
if (sectionInList?.type === "page") {
const page = sectionInList.pageList.find(
(page) => page.slug === categoryParam,
);
if (!page) {
return notFound();
}
return page.component;
}

if (section?.type === "single-component") {
if (sectionInList?.type === "single-component") {
const category = findCategoryBySlug(
section,
params.category,
sectionInList,
categoryParam,
) as SingleComponentCategoryType | null;
if (!category) {
return notFound();
}
return (
<SingleComponentCategory sectionSlug={section.slug} category={category} />
<SingleComponentCategory
sectionSlug={sectionInList.slug}
category={category}
/>
);
}

if (section?.type === "multiple-component") {
if (sectionInList?.type === "multiple-component") {
const category = findCategoryBySlug(
section,
params.category,
sectionInList,
categoryParam,
) as CategoryType | null;
if (!category) {
return notFound();
}
return (
<MultipleComponentCategory
sectionSlug={section.slug}
sectionSlug={sectionInList.slug}
category={category}
/>
);
Expand Down
29 changes: 16 additions & 13 deletions apps/website/src/app/(site)/[section]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,38 @@ import { findSectionBySlug } from "#/src/utils/section-category-components-utils

type Props = {
children: ReactNode;
params: {
params: Promise<{
section: string;
category: string;
};
}>;
};

export function generateMetadata({ params }: Props): Metadata {
const section = findSectionBySlug(params.section);
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { section: sectionParam } = await params;
const sectionInList = findSectionBySlug(sectionParam);

// optionally access and extend (rather than replace) parent metadata

if (!section) {
if (!sectionInList) {
return {};
}
return {
title: section.name,
description: section.description,
title: sectionInList.name,
description: sectionInList.description,
openGraph: {
title: section.name,
description: section.description,
title: sectionInList.name,
description: sectionInList.description,
},
alternates: {
canonical: `${NEXT_PUBLIC_SITE_URL}/${section.slug}`,
canonical: `${NEXT_PUBLIC_SITE_URL}/${sectionInList.slug}`,
},
};
}

export default function SectionLayout({ children, params }: Props) {
const section = findSectionBySlug(params.section);
export default async function SectionLayout({ params, children }: Props) {
const { section: sectionParam } = await params;

const section = findSectionBySlug(sectionParam);

if (!section) {
return notFound();
}
Expand Down
Loading
Loading