chore: update

This commit is contained in:
Ou 2024-09-26 19:16:42 +08:00
parent c0655ad164
commit 51429cdd54
21 changed files with 201 additions and 92 deletions

View File

@ -3,4 +3,5 @@ import { ourongxing } from "@ourongxing/eslint-config"
export default ourongxing({ export default ourongxing({
type: "app", type: "app",
react: true, react: true,
ignores: ["routeTree.gen.ts"],
}) })

View File

@ -16,18 +16,22 @@
"@tanstack/react-query-devtools": "^5.58.0", "@tanstack/react-query-devtools": "^5.58.0",
"@tanstack/react-router": "^1.58.9", "@tanstack/react-router": "^1.58.9",
"@tanstack/router-devtools": "^1.58.9", "@tanstack/router-devtools": "^1.58.9",
"@tanstack/virtual-file-routes": "^1.56.0",
"@unocss/reset": "^0.62.4", "@unocss/reset": "^0.62.4",
"h3": "^1.12.0", "h3": "^1.12.0",
"jotai": "^2.10.0", "jotai": "^2.10.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-use": "^17.5.1", "react-use": "^17.5.1",
"vite-tsconfig-paths": "^5.0.1" "vite-tsconfig-paths": "^5.0.1",
"zod": "^3.23.8"
}, },
"devDependencies": { "devDependencies": {
"@analogjs/vite-plugin-nitro": "^1.8.1", "@analogjs/vite-plugin-nitro": "^1.8.1",
"@eslint-react/eslint-plugin": "^1.14.2", "@eslint-react/eslint-plugin": "^1.14.2",
"@iconify-json/ph": "^1.2.0",
"@ourongxing/eslint-config": "3.2.3-beta.4", "@ourongxing/eslint-config": "3.2.3-beta.4",
"@ourongxing/tsconfig": "^0.0.4",
"@tanstack/router-plugin": "^1.58.10", "@tanstack/router-plugin": "^1.58.10",
"@types/react": "^18.3.9", "@types/react": "^18.3.9",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",

24
pnpm-lock.yaml generated
View File

@ -20,6 +20,9 @@ importers:
'@tanstack/router-devtools': '@tanstack/router-devtools':
specifier: ^1.58.9 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) 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': '@unocss/reset':
specifier: ^0.62.4 specifier: ^0.62.4
version: 0.62.4 version: 0.62.4
@ -41,6 +44,9 @@ importers:
vite-tsconfig-paths: vite-tsconfig-paths:
specifier: ^5.0.1 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)) 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: devDependencies:
'@analogjs/vite-plugin-nitro': '@analogjs/vite-plugin-nitro':
specifier: ^1.8.1 specifier: ^1.8.1
@ -48,9 +54,15 @@ importers:
'@eslint-react/eslint-plugin': '@eslint-react/eslint-plugin':
specifier: ^1.14.2 specifier: ^1.14.2
version: 1.14.2(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.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': '@ourongxing/eslint-config':
specifier: 3.2.3-beta.4 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) 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': '@tanstack/router-plugin':
specifier: ^1.58.10 specifier: ^1.58.10
version: 1.58.10(vite@5.4.8(@types/node@22.6.1)(terser@5.33.0)) 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==} resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==}
engines: {node: '>=18.18'} engines: {node: '>=18.18'}
'@iconify-json/ph@1.2.0':
resolution: {integrity: sha512-013eLpgTmX1lACOuDnkuhC7gRHyYj9w/j8SyDmlyUYvsKQrwdRsv1otcXtwH3DevuDAzSkreeeRsCeez+gTyVA==}
'@iconify/types@2.0.0': '@iconify/types@2.0.0':
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
@ -991,6 +1006,9 @@ packages:
svelte-eslint-parser: svelte-eslint-parser:
optional: true optional: true
'@ourongxing/tsconfig@0.0.4':
resolution: {integrity: sha512-km6cJv5Evtjf7qzN8FLr7S7mu3tgm82i0RFNzsm8s2VER9IXS2NuH2YqJFlJ1lznnsdsyM+PK8A8bD0vz94qTg==}
'@parcel/watcher-android-arm64@2.4.1': '@parcel/watcher-android-arm64@2.4.1':
resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
@ -4697,6 +4715,10 @@ snapshots:
'@humanwhocodes/retry@0.3.0': {} '@humanwhocodes/retry@0.3.0': {}
'@iconify-json/ph@1.2.0':
dependencies:
'@iconify/types': 2.0.0
'@iconify/types@2.0.0': {} '@iconify/types@2.0.0': {}
'@iconify/utils@2.1.33': '@iconify/utils@2.1.33':
@ -4849,6 +4871,8 @@ snapshots:
- typescript - typescript
- vitest - vitest
'@ourongxing/tsconfig@0.0.4': {}
'@parcel/watcher-android-arm64@2.4.1': '@parcel/watcher-android-arm64@2.4.1':
optional: true optional: true

24
shared/data.ts Normal file
View File

@ -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[]

8
shared/types.ts Normal file
View File

@ -0,0 +1,8 @@
import type { sections } from "./data"
export interface Section {
name: string
id: string
}
export type SectionId = (typeof sections)[number]["id"]

7
src/atoms/news.ts Normal file
View File

@ -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<SectionId>("focus")

View File

@ -1,12 +1,31 @@
import { Link } from "@tanstack/react-router"
import logo from "~/assets/react.svg" import logo from "~/assets/react.svg"
import { useDark } from "~/hooks/useDark"
function ThemeToggle() {
const { toggleDark } = useDark()
return (
<button
type="button"
title="Toggle Dark Mode"
className="i-ph-sun-dim-duotone dark:i-ph-moon-stars-duotone btn-pure"
onClick={toggleDark}
/>
)
}
export function Header() { export function Header() {
return ( return (
<div> <header className="flex justify-between items-center">
<div> <Link className="text-8 flex gap-2 items-center" to="/">
<img src={logo} alt="logo" /> <img src={logo} alt="logo" className="h-10" />
<span>NewsNow</span> <span>NewsNow</span>
</Link>
<div className="flex gap-2">
<button type="button" className="i-ph:arrow-clockwise btn-pure"></button>
<ThemeToggle />
<Link className="i-ph:gear btn-pure" to="/setting" />
</div> </div>
</div> </header>
) )
} }

21
src/components/NavBar.tsx Normal file
View File

@ -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 (
<section className="flex gap-2">
{items.map(nav => (
<Link
key={nav.id}
to="/section"
search={{ n: nav.id }}
activeProps={{ className: "bg-blue-500" }}
>
{nav.name}
</Link>
))}
</section>
)
}

View File

@ -0,0 +1,6 @@
export function NewsCard() {
return (
<div className="card">
</div>
)
}

View File

@ -1,12 +0,0 @@
import { useDark } from "~/hooks/useDark"
export function ThemeToggle() {
const { toggleDark } = useDark()
return (
<div
title="Toggle Dark Mode"
className="i-ph-sun-dim-duotone dark:i-ph-moon-stars-duotone text-lg op50 hover:op75 cursor-pointer"
onClick={toggleDark}
/>
)
}

View File

@ -1,7 +1,7 @@
import ReactDOM from 'react-dom/client' import ReactDOM from "react-dom/client"
import { RouterProvider, createRouter } from '@tanstack/react-router' import { RouterProvider, createRouter } from "@tanstack/react-router"
import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { routeTree } from './routeTree.gen' import { routeTree } from "./routeTree.gen"
const queryClient = new QueryClient() const queryClient = new QueryClient()
@ -10,17 +10,17 @@ const router = createRouter({
context: { context: {
queryClient, queryClient,
}, },
defaultPreload: 'intent', defaultPreload: "intent",
defaultPreloadStaleTime: 0, defaultPreloadStaleTime: 0,
}) })
declare module '@tanstack/react-router' { declare module "@tanstack/react-router" {
interface Register { interface Register {
router: typeof router router: typeof router
} }
} }
const rootElement = document.getElementById('root')! const rootElement = document.getElementById("root")!
if (!rootElement.innerHTML) { if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement) const root = ReactDOM.createRoot(rootElement)

View File

@ -12,6 +12,7 @@
import { Route as rootRoute } from './routes/__root' import { Route as rootRoute } from './routes/__root'
import { Route as SettingImport } from './routes/setting' import { Route as SettingImport } from './routes/setting'
import { Route as SectionImport } from './routes/section'
import { Route as IndexImport } from './routes/index' import { Route as IndexImport } from './routes/index'
// Create/Update Routes // Create/Update Routes
@ -21,6 +22,11 @@ const SettingRoute = SettingImport.update({
getParentRoute: () => rootRoute, getParentRoute: () => rootRoute,
} as any) } as any)
const SectionRoute = SectionImport.update({
path: '/section',
getParentRoute: () => rootRoute,
} as any)
const IndexRoute = IndexImport.update({ const IndexRoute = IndexImport.update({
path: '/', path: '/',
getParentRoute: () => rootRoute, getParentRoute: () => rootRoute,
@ -37,6 +43,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof IndexImport preLoaderRoute: typeof IndexImport
parentRoute: typeof rootRoute parentRoute: typeof rootRoute
} }
'/section': {
id: '/section'
path: '/section'
fullPath: '/section'
preLoaderRoute: typeof SectionImport
parentRoute: typeof rootRoute
}
'/setting': { '/setting': {
id: '/setting' id: '/setting'
path: '/setting' path: '/setting'
@ -51,36 +64,41 @@ declare module '@tanstack/react-router' {
export interface FileRoutesByFullPath { export interface FileRoutesByFullPath {
'/': typeof IndexRoute '/': typeof IndexRoute
'/section': typeof SectionRoute
'/setting': typeof SettingRoute '/setting': typeof SettingRoute
} }
export interface FileRoutesByTo { export interface FileRoutesByTo {
'/': typeof IndexRoute '/': typeof IndexRoute
'/section': typeof SectionRoute
'/setting': typeof SettingRoute '/setting': typeof SettingRoute
} }
export interface FileRoutesById { export interface FileRoutesById {
__root__: typeof rootRoute __root__: typeof rootRoute
'/': typeof IndexRoute '/': typeof IndexRoute
'/section': typeof SectionRoute
'/setting': typeof SettingRoute '/setting': typeof SettingRoute
} }
export interface FileRouteTypes { export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/' | '/setting' fullPaths: '/' | '/section' | '/setting'
fileRoutesByTo: FileRoutesByTo fileRoutesByTo: FileRoutesByTo
to: '/' | '/setting' to: '/' | '/section' | '/setting'
id: '__root__' | '/' | '/setting' id: '__root__' | '/' | '/section' | '/setting'
fileRoutesById: FileRoutesById fileRoutesById: FileRoutesById
} }
export interface RootRouteChildren { export interface RootRouteChildren {
IndexRoute: typeof IndexRoute IndexRoute: typeof IndexRoute
SectionRoute: typeof SectionRoute
SettingRoute: typeof SettingRoute SettingRoute: typeof SettingRoute
} }
const rootRouteChildren: RootRouteChildren = { const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute, IndexRoute: IndexRoute,
SectionRoute: SectionRoute,
SettingRoute: SettingRoute, SettingRoute: SettingRoute,
} }
@ -97,12 +115,16 @@ export const routeTree = rootRoute
"filePath": "__root.tsx", "filePath": "__root.tsx",
"children": [ "children": [
"/", "/",
"/section",
"/setting" "/setting"
] ]
}, },
"/": { "/": {
"filePath": "index.tsx" "filePath": "index.tsx"
}, },
"/section": {
"filePath": "section.tsx"
},
"/setting": { "/setting": {
"filePath": "setting.tsx" "filePath": "setting.tsx"
} }

View File

@ -1,15 +1,12 @@
import { Link, Outlet, createRootRouteWithContext } from '@tanstack/react-router' import { Link, Outlet, createRootRouteWithContext } from "@tanstack/react-router"
import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { TanStackRouterDevtools } from "@tanstack/router-devtools"
import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import type { QueryClient } from '@tanstack/react-query'
import { ThemeToggle } from '~/components/ThemeToggle'
import "~/styles/globals.css" import "~/styles/globals.css"
import "@unocss/reset/tailwind.css" import "@unocss/reset/tailwind.css"
import { Header } from '~/components/Header' import "virtual:uno.css"
import { Header } from "~/components/Header"
export const Route = createRootRouteWithContext<{ export const Route = createRootRouteWithContext()({
queryClient: QueryClient
}>()({
component: RootComponent, component: RootComponent,
notFoundComponent: () => { notFoundComponent: () => {
return ( return (
@ -23,12 +20,11 @@ export const Route = createRootRouteWithContext<{
function RootComponent() { function RootComponent() {
return ( return (
<> <div className="p-10">
<Header/> <Header />
<ThemeToggle/>
<Outlet /> <Outlet />
<ReactQueryDevtools buttonPosition="bottom-left" /> <ReactQueryDevtools buttonPosition="bottom-left" />
<TanStackRouterDevtools position="bottom-right" /> <TanStackRouterDevtools position="bottom-right" />
</> </div>
) )
} }

View File

@ -1,13 +1,9 @@
import { createFileRoute } from '@tanstack/react-router' import { Link, createFileRoute } from "@tanstack/react-router"
export const Route = createFileRoute('/')({ export const Route = createFileRoute("/")({
component: Home, component: Index,
}) })
function Home() { function Index() {
return ( return <Link to="/section" search={{ n: "focus" }}> </Link>
<div className="p-2">
<h3>Welcome Home!</h3>
</div>
)
} }

18
src/routes/section.tsx Normal file
View File

@ -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 (
<div className="p-10">
<NavBar />
</div>
)
}

View File

@ -1,6 +1,6 @@
html, html,
body, body,
#app { #root {
height: 100vh; height: 100vh;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -21,8 +21,4 @@ body {
button:disabled { button:disabled {
cursor: not-allowed; cursor: not-allowed;
pointer-events: all !important; pointer-events: all !important;
}
th:nth-child(2) {
width: 100%;
} }

View File

@ -1,28 +1,13 @@
{ {
"extends": "@ourongxing/tsconfig",
"compilerOptions": { "compilerOptions": {
"target": "ES2020",
"jsx": "react-jsx", "jsx": "react-jsx",
"lib": ["ES2020", "DOM", "DOM.Iterable"], "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": ".", "baseUrl": ".",
"paths": { "paths": {
"~/*": ["src/*"] "~/*": ["src/*"],
"@shared/*": ["shared/*"]
} }
}, },
"include": ["src"] "include": ["src", "shared"]
} }

View File

@ -1,4 +1,5 @@
{ {
"extends": "@ourongxing/tsconfig",
"references": [ "references": [
{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" } { "path": "./tsconfig.node.json" }

View File

@ -1,22 +1,12 @@
{ {
"extends": "@ourongxing/tsconfig",
"compilerOptions": { "compilerOptions": {
"target": "ES2022", "lib": ["ES2020"],
"lib": ["ES2023", "DOM"], "baseUrl": ".",
"moduleDetection": "force", "paths": {
"module": "ESNext", "#/*": ["server/*"],
"@shared/*": ["shared/*"]
/* Bundler mode */ }
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
/* Linting */
"strict": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noEmit": true,
"isolatedModules": true,
"skipLibCheck": true
}, },
"include": ["server", "*.config.*"] "include": ["server", "*.config.*", "shared"]
} }

View File

@ -24,6 +24,7 @@ export default defineConfig({
"border-active": "border-primary-600/25 dark:border-primary-400/25", "border-active": "border-primary-600/25 dark:border-primary-400/25",
"bg-active": "bg-primary-400:10", "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": "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-sm": "btn-action text-sm",
"btn-action-active": "color-active border-active! bg-active op100!", "btn-action-active": "color-active border-active! bg-active op100!",

View File

@ -1,9 +1,10 @@
import process from "node:process"
import { defineConfig } from "vite" import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc" import react from "@vitejs/plugin-react-swc"
import nitro from "vite-plugin-with-nitro" import nitro from "vite-plugin-with-nitro"
import { TanStackRouterVite } from "@tanstack/router-plugin/vite" import { TanStackRouterVite } from "@tanstack/router-plugin/vite"
import process from "node:process"
import tsconfigPath from "vite-tsconfig-paths" import tsconfigPath from "vite-tsconfig-paths"
import unocss from "unocss/vite"
export default defineConfig({ export default defineConfig({
resolve: { resolve: {
@ -13,6 +14,7 @@ export default defineConfig({
TanStackRouterVite({ TanStackRouterVite({
autoCodeSplitting: true, autoCodeSplitting: true,
}), }),
unocss(),
tsconfigPath(), tsconfigPath(),
react(), react(),
nitro({ ssr: false }, { nitro({ ssr: false }, {