feat(chapter3): replicate styled Next.js app setup
Add the App Router page group, nested layouts, Tailwind and shadcn styling, shared header components, local fonts and backgrounds, Ant Design demo support, and compatible lint scripts and dependencies.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
"css": "src/app/styles/tailwind.css",
|
||||
"baseColor": "neutral",
|
||||
"cssVariables": true,
|
||||
"prefix": "tw"
|
||||
"prefix": ""
|
||||
},
|
||||
"iconLibrary": "lucide",
|
||||
"rtl": false,
|
||||
|
||||
+22
-7
@@ -3,20 +3,32 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"dev": "rimraf .next && next dev --turbopack",
|
||||
"build": "rimraf .next && next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint"
|
||||
"lint": "pnpm lint:es && pnpm lint:style",
|
||||
"lint:es": "eslint . --fix",
|
||||
"lint:style": "stylelint \"**/*.css\" --fix --cache --cache-location node_modules/.cache/stylelint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
||||
"@ant-design/cssinjs": "^2.1.2",
|
||||
"@ant-design/nextjs-registry": "^1.3.0",
|
||||
"antd": "^6.6.2",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"immer": "^11.1.18",
|
||||
"lucide-react": "^1.37.0",
|
||||
"lodash": "^4.18.1",
|
||||
"next": "16.3.3",
|
||||
"radix-ui": "^1.6.7",
|
||||
"react": "19.2.8",
|
||||
"react-dom": "19.2.8"
|
||||
"react-dom": "19.2.8",
|
||||
"shadcn": "^4.19.0",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"tw-animate-css": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^9.3.0",
|
||||
"@eslint-react/eslint-plugin": "^5.18.6",
|
||||
"@eslint/eslintrc": "^3.3.6",
|
||||
"@next/eslint-plugin-next": "^16.3.3",
|
||||
@@ -26,7 +38,7 @@
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"eslint": "^9",
|
||||
"eslint": "^9.39.5",
|
||||
"eslint-config-next": "16.3.3",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
@@ -46,5 +58,8 @@
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"packageManager": "pnpm@10.34.5"
|
||||
"packageManager": "pnpm@10.34.5",
|
||||
"imports": {
|
||||
"#tailwind.css": "./src/app/styles/tailwind.css"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+4011
-1732
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
/* src/app/(pages)/layout.module.css */
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.layout {
|
||||
@apply min-h-full w-full flex flex-col bg-background bg-cover bg-fixed bg-center bg-no-repeat bg-[url('../styles/images/bg-light.png')] p-0 m-0;
|
||||
|
||||
html.dark &,
|
||||
html[data-theme='dark'] & {
|
||||
background-image: url('../styles/images/bg-dark.png');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// src/app/(pages)/layout.tsx
|
||||
import type { Metadata } from 'next';
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
|
||||
import { Header } from '../_components/header';
|
||||
import $styles from './layout.module.css';
|
||||
export const metadata: Metadata = {
|
||||
title: 'pincman的博客',
|
||||
description:
|
||||
'pincman的个人博客,提供一些ts、react、node.js、php、golang相关的技术文档以及分享一些生活琐事',
|
||||
};
|
||||
|
||||
const AppLayout: FC<PropsWithChildren> = ({ children }) => (
|
||||
<div className={$styles.layout}>
|
||||
<Header />
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
export default AppLayout;
|
||||
@@ -0,0 +1,9 @@
|
||||
/* src/app/(pages)/page.module.css */
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.block {
|
||||
@apply page-container flex flex-col flex-none! w-full space-y-4 p-5 items-center justify-center
|
||||
rounded-sm backdrop-blur-sm shadow-nysm shadow-neutral-800 duration-300
|
||||
text-lg text-center text-white bg-black/30
|
||||
hover:shadow-nylg font-lxgw;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// src/app/(pages)/page.tsx
|
||||
import { FC } from 'react';
|
||||
|
||||
import { ArrowBigRight } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
import $styles from './page.module.css';
|
||||
import { Button } from '../_components/shadcn/ui/button';
|
||||
|
||||
const App: FC = () => (
|
||||
<main className={$styles.container}>
|
||||
<div className={$styles.block}>
|
||||
欢迎来到3R教室,这是Nextjs课程的开始
|
||||
<Button asChild>
|
||||
<Link href="https://3rcd.com" target="_blank">
|
||||
<ArrowBigRight /> 查看官网
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
export default App;
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 801 802"><defs><style>.cls-1{fill:#fff;}.cls-1,.cls-2{stroke:#000;stroke-miterlimit:10;}.cls-2{fill:#224740;}</style></defs><rect class="cls-1" x="0.5" y="0.5" width="800" height="801"/><path class="cls-2" d="M255.61,517.24,182.5,569.53c-16.57,13.4-68.15,8.09-74.37-.12-8.7-11.49-23.82-26.39-14-35.29s37.18-8.36,37.18-8.36l30.06-.58s19.51-4,27.92-4.89c11.23-1.23,13-3.43,10.56-5.93-.67.24-.48-.48-.48-.48-5.6-4.86-25.35-10.58-22.23-12.31l62-52.44c-1.87,1.12-163.29,65.48-163.29,65.48L62.67,526.27s-2.17-1.48-20.75,27.34c-2.5,3.88,37.87,28.51,37.87,28.51C209.06,671.81,328.12,475,353.3,420.12l-.24-2.29,5.15-5.58c18.53,15.86,32.57,37.32,45.87,45.14,20.4,12-.15-8.39,38.94,24.3s39.47,148.93,36.6,175.53-29.74,29.64-29.74,29.64,9.93-28.87,7.36-78.72c-2.57-49.16-81.43-51.44-83.41-51.51C471,602.21,394,738.52,394,738.52s35,4.34,93.39-56.92-25.93-226.14-20.1-253.09c2.69-12.37,95.24-19.54,95.24-19.54s117.86,1.61,120.76,5.78c5.4,7.7,9.11,22.5,4.08,46.84-5,23.83-78.09,90.15-81.16,93,2.29-.59,39.63-11.61,96.61-69.39,58.81-59.69-1.66-127.51-58.34-103.49S528,381.27,528,381.27c-7.7-8.51-11.89-18.92-13.46-30.47h0l-27.48-5.14,27.46-18.19h0c7.21-63.27,66.28-143.75,74.05-152.62,10.38-11.8,15.63-11.29,7.31-23-6.65-9.35-3-12.33-.71-13.37l.64-.2c-9.26,2.67-52.44,13.88-116.82,11.24-72-2.92-111-84.78-112-87.12l-2.21-2.86s-38.57,66-12.6,108.84c20.18,33.3,153.43,44.76,153.43,44.76s.82,14.78-9.7,21.19-32.69-2.77-72.55-15.43l-8.88-1.7c-11.23-1.51-36.36-13.58-64-40.62l-26.19,218,5.65,18-67.34,97.66c-2.6,2.47-2.6,2.47-6.91,7m68.6-122.67M407,285.14s13.38-5.44,25.85.58,19.25,21.2,19.25,21.2-13.37,5.47-25.84-.55S407,285.14,407,285.14Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,11 @@
|
||||
// src/app/_components/header/index.tsx
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { HeaderLogo } from './logo';
|
||||
import $styles from './styles.module.css';
|
||||
|
||||
export const Header: FC = () => (
|
||||
<header className={$styles.header}>
|
||||
<HeaderLogo />
|
||||
</header>
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
/* src/app/_components/header/logo.module.css */
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.link {
|
||||
@apply w-20 h-20 block rounded-full shadow-nymd p-1 bg-white;
|
||||
transition-duration: 300ms;
|
||||
animation: breathe-light 4s ease-in-out infinite;
|
||||
|
||||
&:hover {
|
||||
@apply shadow-nylg shadow-amber-400;
|
||||
transform: scale(1.2) rotate(360deg);
|
||||
}
|
||||
|
||||
& > img {
|
||||
@apply rounded-full;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// src/app/_components/header/logo.tsx
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
import Avatar from './avatar.svg';
|
||||
import $styles from './logo.module.css';
|
||||
|
||||
export const HeaderLogo = () => (
|
||||
<Link href="/" className={$styles.link}>
|
||||
<Image
|
||||
src={Avatar}
|
||||
alt="avatar logo"
|
||||
sizes="100vw"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
}}
|
||||
/>
|
||||
</Link>
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
/* src/app/_components/header/styles.module.css */
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.header {
|
||||
@apply flex justify-center items-center pt-6 max-h-24 flex-auto;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
@@ -5,33 +5,33 @@ import { Slot } from "radix-ui"
|
||||
import { cn } from "@/app/_components/shadcn/libs/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"tw:group/button tw:inline-flex tw:shrink-0 tw:items-center tw:justify-center tw:rounded-lg tw:border tw:border-transparent tw:bg-clip-padding tw:text-sm tw:font-medium tw:whitespace-nowrap tw:transition-all tw:outline-none tw:select-none tw:focus-visible:border-ring tw:focus-visible:ring-3 tw:focus-visible:ring-ring/50 tw:active:not-aria-[haspopup]:translate-y-px tw:disabled:pointer-events-none tw:disabled:opacity-50 tw:aria-invalid:border-destructive tw:aria-invalid:ring-3 tw:aria-invalid:ring-destructive/20 tw:dark:aria-invalid:border-destructive/50 tw:dark:aria-invalid:ring-destructive/40 tw:[&_svg]:pointer-events-none tw:[&_svg]:shrink-0 tw:[&_svg:not([class*=size-])]:size-4",
|
||||
"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "tw:bg-primary tw:text-primary-foreground tw:hover:bg-primary/80",
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
||||
outline:
|
||||
"tw:border-border tw:bg-background tw:hover:bg-muted tw:hover:text-foreground tw:aria-expanded:bg-muted tw:aria-expanded:text-foreground tw:dark:border-input tw:dark:bg-input/30 tw:dark:hover:bg-input/50",
|
||||
"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
||||
secondary:
|
||||
"tw:bg-secondary tw:text-secondary-foreground tw:hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] tw:aria-expanded:bg-secondary tw:aria-expanded:text-secondary-foreground",
|
||||
"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
||||
ghost:
|
||||
"tw:hover:bg-muted tw:hover:text-foreground tw:aria-expanded:bg-muted tw:aria-expanded:text-foreground tw:dark:hover:bg-muted/50",
|
||||
"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
||||
destructive:
|
||||
"tw:bg-destructive/10 tw:text-destructive tw:hover:bg-destructive/20 tw:focus-visible:border-destructive/40 tw:focus-visible:ring-destructive/20 tw:dark:bg-destructive/20 tw:dark:hover:bg-destructive/30 tw:dark:focus-visible:ring-destructive/40",
|
||||
link: "tw:text-primary tw:underline-offset-4 tw:hover:underline",
|
||||
"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default:
|
||||
"tw:h-8 tw:gap-1.5 tw:px-2.5 tw:has-data-[icon=inline-end]:pr-2 tw:has-data-[icon=inline-start]:pl-2",
|
||||
xs: "tw:h-6 tw:gap-1 tw:rounded-[min(var(--radius-md),10px)] tw:px-2 tw:text-xs tw:in-data-[slot=button-group]:rounded-lg tw:has-data-[icon=inline-end]:pr-1.5 tw:has-data-[icon=inline-start]:pl-1.5 tw:[&_svg:not([class*=size-])]:size-3",
|
||||
sm: "tw:h-7 tw:gap-1 tw:rounded-[min(var(--radius-md),12px)] tw:px-2.5 tw:text-[0.8rem] tw:in-data-[slot=button-group]:rounded-lg tw:has-data-[icon=inline-end]:pr-1.5 tw:has-data-[icon=inline-start]:pl-1.5 tw:[&_svg:not([class*=size-])]:size-3.5",
|
||||
lg: "tw:h-9 tw:gap-1.5 tw:px-2.5 tw:has-data-[icon=inline-end]:pr-2 tw:has-data-[icon=inline-start]:pl-2",
|
||||
icon: "tw:size-8",
|
||||
"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
||||
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
||||
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
||||
icon: "size-8",
|
||||
"icon-xs":
|
||||
"tw:size-6 tw:rounded-[min(var(--radius-md),10px)] tw:in-data-[slot=button-group]:rounded-lg tw:[&_svg:not([class*=size-])]:size-3",
|
||||
"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
||||
"icon-sm":
|
||||
"tw:size-7 tw:rounded-[min(var(--radius-md),12px)] tw:in-data-[slot=button-group]:rounded-lg",
|
||||
"icon-lg": "tw:size-9",
|
||||
"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
||||
"icon-lg": "size-9",
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
@@ -12,7 +12,7 @@ function Card({
|
||||
data-slot="card"
|
||||
data-size={size}
|
||||
className={cn(
|
||||
"tw:group/card tw:flex tw:flex-col tw:gap-(--card-spacing) tw:overflow-hidden tw:rounded-xl tw:bg-card tw:py-(--card-spacing) tw:text-sm tw:text-card-foreground tw:ring-1 tw:ring-foreground/10 tw:[--card-spacing:--spacing(4)] tw:has-data-[slot=card-footer]:pb-0 tw:has-[>img:first-child]:pt-0 tw:data-[size=sm]:[--card-spacing:--spacing(3)] tw:data-[size=sm]:has-data-[slot=card-footer]:pb-0 tw:*:[img:first-child]:rounded-t-xl tw:*:[img:last-child]:rounded-b-xl",
|
||||
"group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -25,7 +25,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
|
||||
<div
|
||||
data-slot="card-header"
|
||||
className={cn(
|
||||
"tw:group/card-header tw:@container/card-header tw:grid tw:auto-rows-min tw:items-start tw:gap-1 tw:rounded-t-xl tw:px-(--card-spacing) tw:has-data-[slot=card-action]:grid-cols-[1fr_auto] tw:has-data-[slot=card-description]:grid-rows-[auto_auto] tw:[.border-b]:pb-(--card-spacing)",
|
||||
"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -38,7 +38,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
|
||||
<div
|
||||
data-slot="card-title"
|
||||
className={cn(
|
||||
"tw: tw:text-base tw:leading-snug tw:font-medium tw:group-data-[size=sm]/card:text-sm",
|
||||
"font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -50,7 +50,7 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="card-description"
|
||||
className={cn("tw:text-sm tw:text-muted-foreground", className)}
|
||||
className={cn("text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
@@ -61,7 +61,7 @@ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
|
||||
<div
|
||||
data-slot="card-action"
|
||||
className={cn(
|
||||
"tw:col-start-2 tw:row-span-2 tw:row-start-1 tw:self-start tw:justify-self-end",
|
||||
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -73,7 +73,7 @@ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
|
||||
return (
|
||||
<div
|
||||
data-slot="card-content"
|
||||
className={cn("tw:px-(--card-spacing)", className)}
|
||||
className={cn("px-(--card-spacing)", className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
@@ -84,7 +84,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||
<div
|
||||
data-slot="card-footer"
|
||||
className={cn(
|
||||
"tw:flex tw:items-center tw:rounded-b-xl tw:border-t tw:bg-muted/50 tw:p-(--card-spacing)",
|
||||
"flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.container {
|
||||
@apply bg-neutral-100/40 shadow-black/20 backdrop-blur-sm shadow-md rounded-md p-5 m-5 min-w-[20rem];
|
||||
}
|
||||
|
||||
html.dark {
|
||||
.container {
|
||||
@apply bg-neutral-800/40 shadow-slate-100/30;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/* src/app/(pages)/layout.module.css */
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.layout {
|
||||
@apply min-h-full w-full flex flex-col bg-background bg-cover bg-fixed bg-center bg-no-repeat bg-[url('../styles/images/bg-light.png')] p-0 m-0;
|
||||
|
||||
html.dark &,
|
||||
html[data-theme='dark'] & {
|
||||
background-image: url('../styles/images/bg-dark.png');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// src/app/demo/layout.tsx
|
||||
'use client';
|
||||
import { FC, PropsWithChildren } from 'react';
|
||||
|
||||
// src/app/demo/layout.tsx
|
||||
import { px2remTransformer, StyleProvider } from '@ant-design/cssinjs';
|
||||
import { AntdRegistry } from '@ant-design/nextjs-registry';
|
||||
import { App as AntdApp, ConfigProvider, theme } from 'antd';
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
|
||||
import $styles from './layout.module.css';
|
||||
|
||||
const px2rem = px2remTransformer();
|
||||
const DemoLayout: FC<PropsWithChildren> = ({ children }) => (
|
||||
<AntdRegistry>
|
||||
<ConfigProvider
|
||||
locale={zhCN}
|
||||
theme={{
|
||||
algorithm: theme.defaultAlgorithm,
|
||||
// 启用css变量
|
||||
cssVar: {},
|
||||
hashed: false,
|
||||
token: {},
|
||||
}}
|
||||
>
|
||||
<AntdApp>
|
||||
<StyleProvider transformers={[px2rem]}>
|
||||
<div className={$styles.layout}>{children}</div>
|
||||
</StyleProvider>
|
||||
</AntdApp>
|
||||
</ConfigProvider>
|
||||
</AntdRegistry>
|
||||
);
|
||||
export default DemoLayout;
|
||||
@@ -0,0 +1,9 @@
|
||||
@reference "#tailwind.css";
|
||||
|
||||
.demo {
|
||||
@apply flex flex-auto flex-wrap items-center justify-center;
|
||||
|
||||
& > .container {
|
||||
@apply bg-neutral-100/40 shadow-black/20 backdrop-blur-sm shadow-md rounded-md p-5 m-5 min-w-[20rem];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// src/app/demo/page.tsx
|
||||
// ...
|
||||
import { FC } from 'react';
|
||||
import { Button } from 'antd';
|
||||
|
||||
import $styles from './page.module.css';
|
||||
|
||||
const DemoPage: FC = () => (
|
||||
<div className={$styles.demo}>
|
||||
<div className={$styles.container}>
|
||||
<h2 className="text-center">First React App</h2>
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="my-5 flex-auto">
|
||||
<Button variant="solid" href="https://3rcd.com" target="_blank">
|
||||
3R教室
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default DemoPage;
|
||||
@@ -1,26 +0,0 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
+11
-21
@@ -1,29 +1,19 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
// src/app/layout.tsx
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
import './styles/index.css';
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: 'nextapp',
|
||||
description: '3r教室Next.js全栈开发课程',
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: LayoutProps<"/">) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col">{children}</body>
|
||||
const RootLayout: FC<PropsWithChildren> = ({ children }) => (
|
||||
<html lang="en">
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
export default RootLayout;
|
||||
@@ -1,69 +0,0 @@
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="flex flex-col flex-1 items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
||||
<main className="flex flex-1 w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
|
||||
<Image
|
||||
className="dark:invert h-5 w-[100px]"
|
||||
src="/next.svg"
|
||||
alt="Next.js logo"
|
||||
width={100}
|
||||
height={20}
|
||||
priority
|
||||
/>
|
||||
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
|
||||
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
|
||||
To get started, edit the{" "}
|
||||
<code className="rounded bg-black/[.06] px-1.5 py-0.5 font-mono text-[0.9em] dark:bg-white/[.08]">
|
||||
page.tsx
|
||||
</code>{" "}
|
||||
file.
|
||||
</h1>
|
||||
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
|
||||
Looking for a starting point or more instructions? Head over to{" "}
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
||||
>
|
||||
Templates
|
||||
</a>{" "}
|
||||
or the{" "}
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="font-medium text-zinc-950 dark:text-zinc-50"
|
||||
>
|
||||
Learning
|
||||
</a>{" "}
|
||||
center.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
|
||||
<a
|
||||
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Image
|
||||
className="dark:invert h-[14px] w-4"
|
||||
src="/vercel.svg"
|
||||
alt="Vercel logomark"
|
||||
width={16}
|
||||
height={14}
|
||||
/>
|
||||
Deploy Now
|
||||
</a>
|
||||
<a
|
||||
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/* src/app/styles/app.css */
|
||||
.lucide {
|
||||
@apply w-4 h-4 stroke-[1px];
|
||||
}
|
||||
|
||||
.ant-app {
|
||||
@apply h-[100vh] w-full p-0 m-0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src:
|
||||
url('/fonts/firacode/woff2/FiraCode-Light.woff2') format('woff2'),
|
||||
url('/fonts/firacode/woff/FiraCode-Light.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src:
|
||||
url('/fonts/firacode/woff2/FiraCode-Regular.woff2') format('woff2'),
|
||||
url('/fonts/firacode/woff/FiraCode-Regular.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src:
|
||||
url('/fonts/firacode/woff2/FiraCode-Medium.woff2') format('woff2'),
|
||||
url('/fonts/firacode/woff/FiraCode-Medium.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src:
|
||||
url('/fonts/firacode/woff2/FiraCode-SemiBold.woff2') format('woff2'),
|
||||
url('/fonts/firacode/woff/FiraCode-SemiBold.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fira Code';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src:
|
||||
url('/fonts/firacode/woff2/FiraCode-Bold.woff2') format('woff2'),
|
||||
url('/fonts/firacode/woff/FiraCode-Bold.woff') format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Fira Code VF';
|
||||
font-style: normal;
|
||||
|
||||
/* font-weight requires a range: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide#Using_a_variable_font_font-face_changes */
|
||||
font-weight: 300 700;
|
||||
src:
|
||||
url('/fonts/firacode/woff2/FiraCode-VF.woff2') format('woff2-variations'),
|
||||
url('/fonts/firacode/woff/FiraCode-VF.woff') format('woff-variations');
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 923 KiB |
@@ -0,0 +1,5 @@
|
||||
@import './fonts/fira-code.css';
|
||||
@import './fonts/lxgwwenkai-regular.css';
|
||||
@import './fonts/lxgwwenkaimono-regular.css';
|
||||
@import './tailwind.css';
|
||||
@import './app.css';
|
||||
@@ -0,0 +1,118 @@
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(100% 0 0deg);
|
||||
--foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--card: oklch(100% 0 0deg);
|
||||
--card-foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--popover: oklch(100% 0 0deg);
|
||||
--popover-foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--primary: oklch(21% 0.006 285.885deg);
|
||||
--primary-foreground: oklch(98.5% 0 0deg);
|
||||
--secondary: oklch(96.7% 0.001 286.375deg);
|
||||
--secondary-foreground: oklch(21% 0.006 285.885deg);
|
||||
--muted: oklch(96.7% 0.001 286.375deg);
|
||||
--muted-foreground: oklch(55.2% 0.016 285.938deg);
|
||||
--accent: oklch(96.7% 0.001 286.375deg);
|
||||
--accent-foreground: oklch(21% 0.006 285.885deg);
|
||||
--destructive: oklch(57.7% 0.245 27.325deg);
|
||||
--border: oklch(92% 0.004 286.32deg);
|
||||
--input: oklch(92% 0.004 286.32deg);
|
||||
--ring: oklch(70.5% 0.015 286.067deg);
|
||||
--chart-1: oklch(64.6% 0.222 41.116deg);
|
||||
--chart-2: oklch(60% 0.118 184.704deg);
|
||||
--chart-3: oklch(39.8% 0.07 227.392deg);
|
||||
--chart-4: oklch(82.8% 0.189 84.429deg);
|
||||
--chart-5: oklch(76.9% 0.188 70.08deg);
|
||||
--sidebar: oklch(98.5% 0 0deg);
|
||||
--sidebar-foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--sidebar-primary: oklch(21% 0.006 285.885deg);
|
||||
--sidebar-primary-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-accent: oklch(96.7% 0.001 286.375deg);
|
||||
--sidebar-accent-foreground: oklch(21% 0.006 285.885deg);
|
||||
--sidebar-border: oklch(92% 0.004 286.32deg);
|
||||
--sidebar-ring: oklch(70.5% 0.015 286.067deg);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(14.1% 0.005 285.823deg);
|
||||
--foreground: oklch(98.5% 0 0deg);
|
||||
--card: oklch(21% 0.006 285.885deg);
|
||||
--card-foreground: oklch(98.5% 0 0deg);
|
||||
--popover: oklch(21% 0.006 285.885deg);
|
||||
--popover-foreground: oklch(98.5% 0 0deg);
|
||||
--primary: oklch(92% 0.004 286.32deg);
|
||||
--primary-foreground: oklch(21% 0.006 285.885deg);
|
||||
--secondary: oklch(27.4% 0.006 286.033deg);
|
||||
--secondary-foreground: oklch(98.5% 0 0deg);
|
||||
--muted: oklch(27.4% 0.006 286.033deg);
|
||||
--muted-foreground: oklch(70.5% 0.015 286.067deg);
|
||||
--accent: oklch(27.4% 0.006 286.033deg);
|
||||
--accent-foreground: oklch(98.5% 0 0deg);
|
||||
--destructive: oklch(70.4% 0.191 22.216deg);
|
||||
--border: oklch(100% 0 0deg / 10%);
|
||||
--input: oklch(100% 0 0deg / 15%);
|
||||
--ring: oklch(55.2% 0.016 285.938deg);
|
||||
--chart-1: oklch(48.8% 0.243 264.376deg);
|
||||
--chart-2: oklch(69.6% 0.17 162.48deg);
|
||||
--chart-3: oklch(76.9% 0.188 70.08deg);
|
||||
--chart-4: oklch(62.7% 0.265 303.9deg);
|
||||
--chart-5: oklch(64.5% 0.246 16.439deg);
|
||||
--sidebar: oklch(21% 0.006 285.885deg);
|
||||
--sidebar-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-primary: oklch(48.8% 0.243 264.376deg);
|
||||
--sidebar-primary-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-accent: oklch(27.4% 0.006 286.033deg);
|
||||
--sidebar-accent-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-border: oklch(100% 0 0deg / 10%);
|
||||
--sidebar-ring: oklch(55.2% 0.016 285.938deg);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/* src/app/styles/tailwind.css */
|
||||
@layer theme, base, antd, components, utilities;
|
||||
|
||||
@import 'tailwindcss';
|
||||
@import 'tw-animate-css';
|
||||
|
||||
@import './tailwind/base.css';
|
||||
@import './tailwind/utilities.css';
|
||||
@import './tailwind/theme.css';
|
||||
@import './tailwind/shadcn.css';
|
||||
|
||||
@custom-variant dark (&:is(.dark, .dark *, [data-theme='dark'], [data-theme='dark'] *));
|
||||
|
||||
@theme inline {
|
||||
--font-heading: var(--font-sans);
|
||||
--font-sans: var(--font-sans);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-background: var(--background);
|
||||
--radius-sm: calc(var(--radius) * 0.6);
|
||||
--radius-md: calc(var(--radius) * 0.8);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) * 1.4);
|
||||
--radius-2xl: calc(var(--radius) * 1.8);
|
||||
--radius-3xl: calc(var(--radius) * 2.2);
|
||||
--radius-4xl: calc(var(--radius) * 2.6);
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.145 0 0);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.145 0 0);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.145 0 0);
|
||||
--primary: oklch(0.205 0 0);
|
||||
--primary-foreground: oklch(0.985 0 0);
|
||||
--secondary: oklch(0.97 0 0);
|
||||
--secondary-foreground: oklch(0.205 0 0);
|
||||
--muted: oklch(0.97 0 0);
|
||||
--muted-foreground: oklch(0.556 0 0);
|
||||
--accent: oklch(0.97 0 0);
|
||||
--accent-foreground: oklch(0.205 0 0);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.922 0 0);
|
||||
--input: oklch(0.922 0 0);
|
||||
--ring: oklch(0.708 0 0);
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--radius: 0.625rem;
|
||||
--sidebar: oklch(0.985 0 0);
|
||||
--sidebar-foreground: oklch(0.145 0 0);
|
||||
--sidebar-primary: oklch(0.205 0 0);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.97 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||
--sidebar-border: oklch(0.922 0 0);
|
||||
--sidebar-ring: oklch(0.708 0 0);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.145 0 0);
|
||||
--foreground: oklch(0.985 0 0);
|
||||
--card: oklch(0.205 0 0);
|
||||
--card-foreground: oklch(0.985 0 0);
|
||||
--popover: oklch(0.205 0 0);
|
||||
--popover-foreground: oklch(0.985 0 0);
|
||||
--primary: oklch(0.922 0 0);
|
||||
--primary-foreground: oklch(0.205 0 0);
|
||||
--secondary: oklch(0.269 0 0);
|
||||
--secondary-foreground: oklch(0.985 0 0);
|
||||
--muted: oklch(0.269 0 0);
|
||||
--muted-foreground: oklch(0.708 0 0);
|
||||
--accent: oklch(0.269 0 0);
|
||||
--accent-foreground: oklch(0.985 0 0);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.556 0 0);
|
||||
--chart-1: oklch(0.87 0 0);
|
||||
--chart-2: oklch(0.556 0 0);
|
||||
--chart-3: oklch(0.439 0 0);
|
||||
--chart-4: oklch(0.371 0 0);
|
||||
--chart-5: oklch(0.269 0 0);
|
||||
--sidebar: oklch(0.205 0 0);
|
||||
--sidebar-foreground: oklch(0.985 0 0);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||
--sidebar-accent: oklch(0.269 0 0);
|
||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.556 0 0);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
html {
|
||||
@apply font-sans;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/********************************************************* 自定义tailwind基本样式 *********************************************************/
|
||||
|
||||
@layer base {
|
||||
html {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
/* 以下为自定义样式 */
|
||||
html,
|
||||
body {
|
||||
@apply font-base h-[100vh] w-full p-0 m-0;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply text-sm;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply text-2xl;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@apply text-xl;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@apply text-lg;
|
||||
}
|
||||
|
||||
h5 {
|
||||
@apply text-sm;
|
||||
}
|
||||
|
||||
h6 {
|
||||
@apply text-xs;
|
||||
}
|
||||
|
||||
button,
|
||||
[role='button'] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-ring: var(--ring);
|
||||
--color-input: var(--input);
|
||||
--color-border: var(--border);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-card: var(--card);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(100% 0 0deg);
|
||||
--foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--card: oklch(100% 0 0deg);
|
||||
--card-foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--popover: oklch(100% 0 0deg);
|
||||
--popover-foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--primary: oklch(21% 0.006 285.885deg);
|
||||
--primary-foreground: oklch(98.5% 0 0deg);
|
||||
--secondary: oklch(96.7% 0.001 286.375deg);
|
||||
--secondary-foreground: oklch(21% 0.006 285.885deg);
|
||||
--muted: oklch(96.7% 0.001 286.375deg);
|
||||
--muted-foreground: oklch(55.2% 0.016 285.938deg);
|
||||
--accent: oklch(96.7% 0.001 286.375deg);
|
||||
--accent-foreground: oklch(21% 0.006 285.885deg);
|
||||
--destructive: oklch(57.7% 0.245 27.325deg);
|
||||
--border: oklch(92% 0.004 286.32deg);
|
||||
--input: oklch(92% 0.004 286.32deg);
|
||||
--ring: oklch(70.5% 0.015 286.067deg);
|
||||
--chart-1: oklch(64.6% 0.222 41.116deg);
|
||||
--chart-2: oklch(60% 0.118 184.704deg);
|
||||
--chart-3: oklch(39.8% 0.07 227.392deg);
|
||||
--chart-4: oklch(82.8% 0.189 84.429deg);
|
||||
--chart-5: oklch(76.9% 0.188 70.08deg);
|
||||
--sidebar: oklch(98.5% 0 0deg);
|
||||
--sidebar-foreground: oklch(14.1% 0.005 285.823deg);
|
||||
--sidebar-primary: oklch(21% 0.006 285.885deg);
|
||||
--sidebar-primary-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-accent: oklch(96.7% 0.001 286.375deg);
|
||||
--sidebar-accent-foreground: oklch(21% 0.006 285.885deg);
|
||||
--sidebar-border: oklch(92% 0.004 286.32deg);
|
||||
--sidebar-ring: oklch(70.5% 0.015 286.067deg);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(14.1% 0.005 285.823deg);
|
||||
--foreground: oklch(98.5% 0 0deg);
|
||||
--card: oklch(21% 0.006 285.885deg);
|
||||
--card-foreground: oklch(98.5% 0 0deg);
|
||||
--popover: oklch(21% 0.006 285.885deg);
|
||||
--popover-foreground: oklch(98.5% 0 0deg);
|
||||
--primary: oklch(92% 0.004 286.32deg);
|
||||
--primary-foreground: oklch(21% 0.006 285.885deg);
|
||||
--secondary: oklch(27.4% 0.006 286.033deg);
|
||||
--secondary-foreground: oklch(98.5% 0 0deg);
|
||||
--muted: oklch(27.4% 0.006 286.033deg);
|
||||
--muted-foreground: oklch(70.5% 0.015 286.067deg);
|
||||
--accent: oklch(27.4% 0.006 286.033deg);
|
||||
--accent-foreground: oklch(98.5% 0 0deg);
|
||||
--destructive: oklch(70.4% 0.191 22.216deg);
|
||||
--border: oklch(100% 0 0deg / 10%);
|
||||
--input: oklch(100% 0 0deg / 15%);
|
||||
--ring: oklch(55.2% 0.016 285.938deg);
|
||||
--chart-1: oklch(48.8% 0.243 264.376deg);
|
||||
--chart-2: oklch(69.6% 0.17 162.48deg);
|
||||
--chart-3: oklch(76.9% 0.188 70.08deg);
|
||||
--chart-4: oklch(62.7% 0.265 303.9deg);
|
||||
--chart-5: oklch(64.5% 0.246 16.439deg);
|
||||
--sidebar: oklch(21% 0.006 285.885deg);
|
||||
--sidebar-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-primary: oklch(48.8% 0.243 264.376deg);
|
||||
--sidebar-primary-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-accent: oklch(27.4% 0.006 286.033deg);
|
||||
--sidebar-accent-foreground: oklch(98.5% 0 0deg);
|
||||
--sidebar-border: oklch(100% 0 0deg / 10%);
|
||||
--sidebar-ring: oklch(55.2% 0.016 285.938deg);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/********************************************************* 自定义tailwind主题扩展 *********************************************************/
|
||||
|
||||
@theme {
|
||||
--breakpoint-xs: 30rem;
|
||||
--breakpoint-sm: 36rem;
|
||||
--breakpoint-md: 48rem;
|
||||
--breakpoint-lg: 62rem;
|
||||
--breakpoint-xl: 75rem;
|
||||
--breakpoint-2xl: 87.5rem;
|
||||
--shadow-nysm: 0 0 2px 0 rgb(0 0 0 / 5%);
|
||||
--shadow-ny: 0 0 3px 0 rgb(0 0 0 / 10%), 0 0 2px - 1px rgb(0 0 0 / 10%);
|
||||
--shadow-nymd: 0 0 6px -1px rgb(0 0 0 / 10%), 0 0 4px -2px rgb(0 0 0 / 10%);
|
||||
--shadow-nylg: 0 0 15px -3px rgb(0 0 0 / 10%), 0 0 6px -4px rgb(0 0 0 / 10%);
|
||||
--shadow-spread: 0 5px 40px rgb(0 0 0 / 10%);
|
||||
|
||||
/* 默认字体 */
|
||||
--font-base:
|
||||
-apple-system, blinkmacsystemfont, tahoma, arial, 'Hiragino Sans GB', 'Microsoft YaHei',
|
||||
'WenQuanYi Micro Hei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Noto Color Emoji';
|
||||
|
||||
/* 霞鹜文楷字体 */
|
||||
--font-lxgw:
|
||||
'LXGW WenKai', '楷体', 'STKaiti', -apple-system, blinkmacsystemfont, tahoma, arial,
|
||||
'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif,
|
||||
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
|
||||
/* 默认代码字体 */
|
||||
--font-code:
|
||||
'Fira Code', -apple-system, blinkmacsystemfont, tahoma, arial, 'Hiragino Sans GB',
|
||||
'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/********************************************************* 自定义tailwind工具类 *********************************************************/
|
||||
@utility page-item {
|
||||
@apply flex flex-auto flex-col mt-20 items-center;
|
||||
}
|
||||
|
||||
/* 页面包装容器 */
|
||||
@utility page-container {
|
||||
@apply max-w-[90%] md:max-w-[80%] lg:max-w-[70%] xl:max-w-[60%] flex-auto mb-5;
|
||||
}
|
||||
|
||||
/* 页面包装容器 */
|
||||
|
||||
/* 空白页样式,一般用于404和error页面 */
|
||||
@utility page-blank {
|
||||
@apply bg-white/80 backdrop-blur-sm h-full w-full drop-shadow-lg rounded-md flex justify-center items-center;
|
||||
|
||||
html.dark & {
|
||||
@apply bg-black/50;
|
||||
}
|
||||
}
|
||||
|
||||
/* 全透明图标按钮 */
|
||||
@utility btn-icon-transparent {
|
||||
@apply block w-auto! border-none! bg-transparent! shadow-none! ring-0! hover:bg-transparent! focus-visible:ring-0!;
|
||||
}
|
||||
|
||||
@utility page-block {
|
||||
@apply bg-zinc-100/80;
|
||||
|
||||
html.dark & {
|
||||
@apply bg-zinc-800/50;
|
||||
}
|
||||
}
|
||||
|
||||
@utility page-block-hover {
|
||||
@apply hover:bg-white/90;
|
||||
|
||||
html.dark & {
|
||||
@apply hover:bg-black/80;
|
||||
}
|
||||
}
|
||||
|
||||
/* 只显示一行文字, 溢出部分以省略号代替 */
|
||||
@utility ellips {
|
||||
@apply inline-block overflow-hidden max-w-full whitespace-nowrap text-ellipsis break-all;
|
||||
}
|
||||
|
||||
/* 鼠标移动到文字或链接出现动画下划线 */
|
||||
@utility animate-decoration {
|
||||
padding-bottom: 2px;
|
||||
background: linear-gradient(hsl(var(--foreground)), hsl(var(--foreground))) 0% 100% / 0% 1px
|
||||
no-repeat;
|
||||
transition: background-size ease-out 200ms;
|
||||
|
||||
&:not(:focus):hover {
|
||||
background-size: 100% 1px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 粗下划线 */
|
||||
@utility animate-decoration-lg {
|
||||
&:not(:focus):hover {
|
||||
background-size: 100% 2px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 取消下划线 */
|
||||
@utility none-animate-decoration {
|
||||
background-size: 0 !important;
|
||||
transition: none !important;
|
||||
|
||||
&:hover,
|
||||
&:not(:focus):hover {
|
||||
background-size: 100% 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 透明滚动条 */
|
||||
@utility transparent-scrollbar {
|
||||
&::-webkit-scrollbar {
|
||||
@apply w-1 h-1;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
|
||||
html.dark &::-webkit-scrollbar-track {
|
||||
@apply bg-zinc-800;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply bg-gray-300 rounded;
|
||||
}
|
||||
|
||||
html.dark &::-webkit-scrollbar-thumb {
|
||||
@apply bg-zinc-600;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-corner {
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
|
||||
html.dark &::-webkit-scrollbar-corner {
|
||||
@apply bg-zinc-800;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user