mirror of
https://github.com/ourongxing/newsnow.git
synced 2025-01-19 03:09:14 +08:00
chore: update
This commit is contained in:
parent
c0655ad164
commit
51429cdd54
@ -3,4 +3,5 @@ import { ourongxing } from "@ourongxing/eslint-config"
|
||||
export default ourongxing({
|
||||
type: "app",
|
||||
react: true,
|
||||
ignores: ["routeTree.gen.ts"],
|
||||
})
|
||||
|
@ -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",
|
||||
|
24
pnpm-lock.yaml
generated
24
pnpm-lock.yaml
generated
@ -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
|
||||
|
||||
|
24
shared/data.ts
Normal file
24
shared/data.ts
Normal 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
8
shared/types.ts
Normal 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
7
src/atoms/news.ts
Normal 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")
|
@ -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 (
|
||||
<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() {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<img src={logo} alt="logo" />
|
||||
<header className="flex justify-between items-center">
|
||||
<Link className="text-8 flex gap-2 items-center" to="/">
|
||||
<img src={logo} alt="logo" className="h-10" />
|
||||
<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>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
21
src/components/NavBar.tsx
Normal file
21
src/components/NavBar.tsx
Normal 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>
|
||||
)
|
||||
}
|
6
src/components/NewsCard.tsx
Normal file
6
src/components/NewsCard.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
export function NewsCard() {
|
||||
return (
|
||||
<div className="card">
|
||||
</div>
|
||||
)
|
||||
}
|
@ -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}
|
||||
/>
|
||||
)
|
||||
}
|
14
src/main.tsx
14
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)
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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 (
|
||||
<>
|
||||
<Header/>
|
||||
<ThemeToggle/>
|
||||
<div className="p-10">
|
||||
<Header />
|
||||
<Outlet />
|
||||
<ReactQueryDevtools buttonPosition="bottom-left" />
|
||||
<TanStackRouterDevtools position="bottom-right" />
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -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 (
|
||||
<div className="p-2">
|
||||
<h3>Welcome Home!</h3>
|
||||
</div>
|
||||
)
|
||||
function Index() {
|
||||
return <Link to="/section" search={{ n: "focus" }}> 关注 </Link>
|
||||
}
|
||||
|
18
src/routes/section.tsx
Normal file
18
src/routes/section.tsx
Normal 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>
|
||||
)
|
||||
}
|
@ -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%;
|
||||
}
|
@ -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"]
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"extends": "@ourongxing/tsconfig",
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./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"]
|
||||
}
|
||||
|
@ -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!",
|
||||
|
@ -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 }, {
|
||||
|
Loading…
x
Reference in New Issue
Block a user