diff --git a/eslint.config.mjs b/eslint.config.mjs index c689d43..977bdf5 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,4 +3,5 @@ import { ourongxing } from "@ourongxing/eslint-config" export default ourongxing({ type: "app", react: true, + ignores: ["routeTree.gen.ts"], }) diff --git a/package.json b/package.json index 871f9bd..877f01e 100644 --- a/package.json +++ b/package.json @@ -16,18 +16,22 @@ "@tanstack/react-query-devtools": "^5.58.0", "@tanstack/react-router": "^1.58.9", "@tanstack/router-devtools": "^1.58.9", + "@tanstack/virtual-file-routes": "^1.56.0", "@unocss/reset": "^0.62.4", "h3": "^1.12.0", "jotai": "^2.10.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-use": "^17.5.1", - "vite-tsconfig-paths": "^5.0.1" + "vite-tsconfig-paths": "^5.0.1", + "zod": "^3.23.8" }, "devDependencies": { "@analogjs/vite-plugin-nitro": "^1.8.1", "@eslint-react/eslint-plugin": "^1.14.2", + "@iconify-json/ph": "^1.2.0", "@ourongxing/eslint-config": "3.2.3-beta.4", + "@ourongxing/tsconfig": "^0.0.4", "@tanstack/router-plugin": "^1.58.10", "@types/react": "^18.3.9", "@types/react-dom": "^18.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bbc44ec..d5b0371 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@tanstack/router-devtools': specifier: ^1.58.9 version: 1.58.9(@tanstack/react-router@1.58.9(@tanstack/router-generator@1.58.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tanstack/virtual-file-routes': + specifier: ^1.56.0 + version: 1.56.0 '@unocss/reset': specifier: ^0.62.4 version: 0.62.4 @@ -41,6 +44,9 @@ importers: vite-tsconfig-paths: specifier: ^5.0.1 version: 5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.6.1)(terser@5.33.0)) + zod: + specifier: ^3.23.8 + version: 3.23.8 devDependencies: '@analogjs/vite-plugin-nitro': specifier: ^1.8.1 @@ -48,9 +54,15 @@ importers: '@eslint-react/eslint-plugin': specifier: ^1.14.2 version: 1.14.2(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2) + '@iconify-json/ph': + specifier: ^1.2.0 + version: 1.2.0 '@ourongxing/eslint-config': specifier: 3.2.3-beta.4 version: 3.2.3-beta.4(@eslint-react/eslint-plugin@1.14.2(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(@typescript-eslint/utils@8.7.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(@vue/compiler-sfc@3.5.8)(eslint-plugin-react-hooks@5.1.0-rc-fb9a90fa48-20240614(eslint@9.11.1(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.12(eslint@9.11.1(jiti@1.21.6)))(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2) + '@ourongxing/tsconfig': + specifier: ^0.0.4 + version: 0.0.4 '@tanstack/router-plugin': specifier: ^1.58.10 version: 1.58.10(vite@5.4.8(@types/node@22.6.1)(terser@5.33.0)) @@ -867,6 +879,9 @@ packages: resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} engines: {node: '>=18.18'} + '@iconify-json/ph@1.2.0': + resolution: {integrity: sha512-013eLpgTmX1lACOuDnkuhC7gRHyYj9w/j8SyDmlyUYvsKQrwdRsv1otcXtwH3DevuDAzSkreeeRsCeez+gTyVA==} + '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -991,6 +1006,9 @@ packages: svelte-eslint-parser: optional: true + '@ourongxing/tsconfig@0.0.4': + resolution: {integrity: sha512-km6cJv5Evtjf7qzN8FLr7S7mu3tgm82i0RFNzsm8s2VER9IXS2NuH2YqJFlJ1lznnsdsyM+PK8A8bD0vz94qTg==} + '@parcel/watcher-android-arm64@2.4.1': resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} engines: {node: '>= 10.0.0'} @@ -4697,6 +4715,10 @@ snapshots: '@humanwhocodes/retry@0.3.0': {} + '@iconify-json/ph@1.2.0': + dependencies: + '@iconify/types': 2.0.0 + '@iconify/types@2.0.0': {} '@iconify/utils@2.1.33': @@ -4849,6 +4871,8 @@ snapshots: - typescript - vitest + '@ourongxing/tsconfig@0.0.4': {} + '@parcel/watcher-android-arm64@2.4.1': optional: true diff --git a/shared/data.ts b/shared/data.ts new file mode 100644 index 0000000..95d4aeb --- /dev/null +++ b/shared/data.ts @@ -0,0 +1,24 @@ +import type { Section } from "./types" + +export const sections = [ + { + name: "关注", + id: "focus", + }, + { + name: "综合", + id: "main", + }, + { + name: "国内", + id: "china", + }, + { + name: "国外", + id: "world", + }, + { + name: "数码", + id: "digital", + }, +] as const satisfies Section[] diff --git a/shared/types.ts b/shared/types.ts new file mode 100644 index 0000000..400c86e --- /dev/null +++ b/shared/types.ts @@ -0,0 +1,8 @@ +import type { sections } from "./data" + +export interface Section { + name: string + id: string +} + +export type SectionId = (typeof sections)[number]["id"] diff --git a/src/atoms/news.ts b/src/atoms/news.ts new file mode 100644 index 0000000..03dacea --- /dev/null +++ b/src/atoms/news.ts @@ -0,0 +1,7 @@ +import { atom } from "jotai" +import { sections } from "@shared/data" +import type { SectionId } from "@shared/types" + +export const sectionsAtom = atom(sections) + +export const activeSectionAtom = atom("focus") diff --git a/src/components/Header.tsx b/src/components/Header.tsx index d34aeda..1692507 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,12 +1,31 @@ +import { Link } from "@tanstack/react-router" import logo from "~/assets/react.svg" +import { useDark } from "~/hooks/useDark" + +function ThemeToggle() { + const { toggleDark } = useDark() + return ( + + + - + ) } diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx new file mode 100644 index 0000000..cf733e8 --- /dev/null +++ b/src/components/NavBar.tsx @@ -0,0 +1,21 @@ +import { Link } from "@tanstack/react-router" +import { useAtomValue } from "jotai" +import { sectionsAtom } from "~/atoms/news" + +export function NavBar() { + const items = useAtomValue(sectionsAtom) + return ( +
+ {items.map(nav => ( + + {nav.name} + + ))} +
+ ) +} diff --git a/src/components/NewsCard.tsx b/src/components/NewsCard.tsx new file mode 100644 index 0000000..8e69bf8 --- /dev/null +++ b/src/components/NewsCard.tsx @@ -0,0 +1,6 @@ +export function NewsCard() { + return ( +
+
+ ) +} diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx deleted file mode 100644 index 19c1b06..0000000 --- a/src/components/ThemeToggle.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { useDark } from "~/hooks/useDark" - -export function ThemeToggle() { - const { toggleDark } = useDark() - return ( -
- ) -} diff --git a/src/main.tsx b/src/main.tsx index 90e50dd..7350874 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,7 @@ -import ReactDOM from 'react-dom/client' -import { RouterProvider, createRouter } from '@tanstack/react-router' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { routeTree } from './routeTree.gen' +import ReactDOM from "react-dom/client" +import { RouterProvider, createRouter } from "@tanstack/react-router" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" +import { routeTree } from "./routeTree.gen" const queryClient = new QueryClient() @@ -10,17 +10,17 @@ const router = createRouter({ context: { queryClient, }, - defaultPreload: 'intent', + defaultPreload: "intent", defaultPreloadStaleTime: 0, }) -declare module '@tanstack/react-router' { +declare module "@tanstack/react-router" { interface Register { router: typeof router } } -const rootElement = document.getElementById('root')! +const rootElement = document.getElementById("root")! if (!rootElement.innerHTML) { const root = ReactDOM.createRoot(rootElement) diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 56b0245..da3d470 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -12,6 +12,7 @@ import { Route as rootRoute } from './routes/__root' import { Route as SettingImport } from './routes/setting' +import { Route as SectionImport } from './routes/section' import { Route as IndexImport } from './routes/index' // Create/Update Routes @@ -21,6 +22,11 @@ const SettingRoute = SettingImport.update({ getParentRoute: () => rootRoute, } as any) +const SectionRoute = SectionImport.update({ + path: '/section', + getParentRoute: () => rootRoute, +} as any) + const IndexRoute = IndexImport.update({ path: '/', getParentRoute: () => rootRoute, @@ -37,6 +43,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof IndexImport parentRoute: typeof rootRoute } + '/section': { + id: '/section' + path: '/section' + fullPath: '/section' + preLoaderRoute: typeof SectionImport + parentRoute: typeof rootRoute + } '/setting': { id: '/setting' path: '/setting' @@ -51,36 +64,41 @@ declare module '@tanstack/react-router' { export interface FileRoutesByFullPath { '/': typeof IndexRoute + '/section': typeof SectionRoute '/setting': typeof SettingRoute } export interface FileRoutesByTo { '/': typeof IndexRoute + '/section': typeof SectionRoute '/setting': typeof SettingRoute } export interface FileRoutesById { __root__: typeof rootRoute '/': typeof IndexRoute + '/section': typeof SectionRoute '/setting': typeof SettingRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/' | '/setting' + fullPaths: '/' | '/section' | '/setting' fileRoutesByTo: FileRoutesByTo - to: '/' | '/setting' - id: '__root__' | '/' | '/setting' + to: '/' | '/section' | '/setting' + id: '__root__' | '/' | '/section' | '/setting' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute + SectionRoute: typeof SectionRoute SettingRoute: typeof SettingRoute } const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, + SectionRoute: SectionRoute, SettingRoute: SettingRoute, } @@ -97,12 +115,16 @@ export const routeTree = rootRoute "filePath": "__root.tsx", "children": [ "/", + "/section", "/setting" ] }, "/": { "filePath": "index.tsx" }, + "/section": { + "filePath": "section.tsx" + }, "/setting": { "filePath": "setting.tsx" } diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 91b7a09..e940373 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,15 +1,12 @@ -import { Link, Outlet, createRootRouteWithContext } from '@tanstack/react-router' -import { TanStackRouterDevtools } from '@tanstack/router-devtools' -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' -import type { QueryClient } from '@tanstack/react-query' -import { ThemeToggle } from '~/components/ThemeToggle' +import { Link, Outlet, createRootRouteWithContext } from "@tanstack/react-router" +import { TanStackRouterDevtools } from "@tanstack/router-devtools" +import { ReactQueryDevtools } from "@tanstack/react-query-devtools" import "~/styles/globals.css" import "@unocss/reset/tailwind.css" -import { Header } from '~/components/Header' +import "virtual:uno.css" +import { Header } from "~/components/Header" -export const Route = createRootRouteWithContext<{ - queryClient: QueryClient -}>()({ +export const Route = createRootRouteWithContext()({ component: RootComponent, notFoundComponent: () => { return ( @@ -23,12 +20,11 @@ export const Route = createRootRouteWithContext<{ function RootComponent() { return ( - <> -
- +
+
- +
) } diff --git a/src/routes/index.tsx b/src/routes/index.tsx index b7b6138..cf02676 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,13 +1,9 @@ -import { createFileRoute } from '@tanstack/react-router' +import { Link, createFileRoute } from "@tanstack/react-router" -export const Route = createFileRoute('/')({ - component: Home, +export const Route = createFileRoute("/")({ + component: Index, }) -function Home() { - return ( -
-

Welcome Home!

-
- ) +function Index() { + return 关注 } diff --git a/src/routes/section.tsx b/src/routes/section.tsx new file mode 100644 index 0000000..30bd15c --- /dev/null +++ b/src/routes/section.tsx @@ -0,0 +1,18 @@ +import { createFileRoute } from "@tanstack/react-router" +import type { SectionId } from "~/atoms/news" +import { NavBar } from "~/components/NavBar" + +export const Route = createFileRoute("/section")({ + validateSearch: (search: any) => ({ + n: search.n as SectionId, + }), + component: Section, +}) + +export function Section() { + return ( +
+ +
+ ) +} diff --git a/src/styles/globals.css b/src/styles/globals.css index b3da007..c555843 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1,6 +1,6 @@ html, body, -#app { +#root { height: 100vh; margin: 0; padding: 0; @@ -21,8 +21,4 @@ body { button:disabled { cursor: not-allowed; pointer-events: all !important; -} - -th:nth-child(2) { - width: 100%; } \ No newline at end of file diff --git a/tsconfig.app.json b/tsconfig.app.json index 59faf43..6885eba 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -1,28 +1,13 @@ { + "extends": "@ourongxing/tsconfig", "compilerOptions": { - "target": "ES2020", "jsx": "react-jsx", "lib": ["ES2020", "DOM", "DOM.Iterable"], - "moduleDetection": "force", - "useDefineForClassFields": true, - "module": "ESNext", - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - - /* Linting */ - "strict": true, - "noFallthroughCasesInSwitch": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noEmit": true, - "isolatedModules": true, - "skipLibCheck": true, "baseUrl": ".", "paths": { - "~/*": ["src/*"] + "~/*": ["src/*"], + "@shared/*": ["shared/*"] } }, - "include": ["src"] + "include": ["src", "shared"] } diff --git a/tsconfig.json b/tsconfig.json index a2efd46..13a8dad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "@ourongxing/tsconfig", "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } diff --git a/tsconfig.node.json b/tsconfig.node.json index b2e9e86..c6576a5 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,22 +1,12 @@ { + "extends": "@ourongxing/tsconfig", "compilerOptions": { - "target": "ES2022", - "lib": ["ES2023", "DOM"], - "moduleDetection": "force", - "module": "ESNext", - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - - /* Linting */ - "strict": true, - "noFallthroughCasesInSwitch": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noEmit": true, - "isolatedModules": true, - "skipLibCheck": true + "lib": ["ES2020"], + "baseUrl": ".", + "paths": { + "#/*": ["server/*"], + "@shared/*": ["shared/*"] + } }, - "include": ["server", "*.config.*"] + "include": ["server", "*.config.*", "shared"] } diff --git a/uno.config.ts b/uno.config.ts index 85907ce..a96b5e2 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -24,6 +24,7 @@ export default defineConfig({ "border-active": "border-primary-600/25 dark:border-primary-400/25", "bg-active": "bg-primary-400:10", + "btn-pure": "text-lg op50 hover:op75", "btn-action": "border border-base rounded flex gap-2 items-center px2 py1 op75 hover:op100 hover:bg-hover", "btn-action-sm": "btn-action text-sm", "btn-action-active": "color-active border-active! bg-active op100!", diff --git a/vite.config.ts b/vite.config.ts index b383fc8..2985597 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,10 @@ +import process from "node:process" import { defineConfig } from "vite" import react from "@vitejs/plugin-react-swc" import nitro from "vite-plugin-with-nitro" import { TanStackRouterVite } from "@tanstack/router-plugin/vite" -import process from "node:process" import tsconfigPath from "vite-tsconfig-paths" +import unocss from "unocss/vite" export default defineConfig({ resolve: { @@ -13,6 +14,7 @@ export default defineConfig({ TanStackRouterVite({ autoCodeSplitting: true, }), + unocss(), tsconfigPath(), react(), nitro({ ssr: false }, {