next 16; react 19; node 24 (#263)
* next 16; react 19 * fix build errors * add typecheck to workflow * use node 24 * claude update
This commit is contained in:
1 parent
60fb98ddeb
commit
3df47621a2
12 files changed
+1721
-736
No files matched your search
@@ -14,7 +14,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -42,9 +42,8 @@ jobs:
|
||||
- name: Test
|
||||
run: npm test
|
||||
|
||||
build:
|
||||
name: Build
|
||||
needs: [lint, test]
|
||||
typecheck:
|
||||
name: Type Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -53,7 +52,27 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Type check
|
||||
run: npx tsc --noEmit
|
||||
|
||||
build:
|
||||
name: Build
|
||||
needs: [lint, test, typecheck]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
@@ -14,7 +14,7 @@ Website for the Art School of Shlisselburg ([art.shlisselburg.org](https://art.s
|
||||
- `npm run format` — auto-fix lint issues
|
||||
- `npm test` — run unit tests (Vitest, non-watch mode)
|
||||
|
||||
Node 22 required (see `mise.toml`). Deployed on Vercel.
|
||||
Node 24 required (see `mise.toml`). Deployed on Vercel.
|
||||
|
||||
## Git Workflow
|
||||
|
||||
@@ -28,7 +28,7 @@ Feature branches are named `issue-XXX` where `XXX` is the related GitHub issue n
|
||||
|
||||
## Code Style
|
||||
|
||||
ESLint 9 flat config (`eslint.config.js`) using `FlatCompat` from `@eslint/eslintrc` to bridge `eslint-config-next` (which doesn't support native flat config in Next.js 15.x). Extends `next/core-web-vitals`. Enforces: no semicolons, double quotes, 4-space indentation, always-multiline trailing commas, `eol-last`.
|
||||
ESLint 9 flat config (`eslint.config.js`) with native `eslint-config-next` 16.x support. Extends `next/core-web-vitals`. Enforces: no semicolons, double quotes, 4-space indentation, always-multiline trailing commas, `eol-last`.
|
||||
|
||||
**React components:** Use regular function declarations (not arrow functions) and `type` for props. Do not use `React.FC`.
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM node:22.19.0-alpine AS base
|
||||
FROM node:24.12.0-alpine AS base
|
||||
|
||||
# Install dependencies only when needed
|
||||
FROM base AS deps
|
||||
|
||||
+2
-10
@@ -1,15 +1,7 @@
|
||||
import { dirname } from "path"
|
||||
import { fileURLToPath } from "url"
|
||||
import { FlatCompat } from "@eslint/eslintrc"
|
||||
import { defineConfig, globalIgnores } from "eslint/config"
|
||||
import nextVitals from "eslint-config-next/core-web-vitals"
|
||||
import globals from "globals"
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
})
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores([
|
||||
".next/**",
|
||||
@@ -19,7 +11,7 @@ export default defineConfig([
|
||||
"public/static/**",
|
||||
"next-env.d.ts",
|
||||
]),
|
||||
...compat.extends("next/core-web-vitals"),
|
||||
...nextVitals,
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.browser,
|
||||
|
||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
/// <reference path="./.next/types/routes.d.ts" />
|
||||
import "./.next/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
@@ -3,9 +3,6 @@ import type { NextConfig } from "next"
|
||||
const config: NextConfig = {
|
||||
output: "standalone",
|
||||
trailingSlash: false,
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{ hostname: "hudozkacdn.tmshv.com" },
|
||||
|
||||
Generated
+1652
-691
File diff suppressed because it is too large.
Load diff
+12
-8
@@ -19,32 +19,36 @@
|
||||
"author": "Roman Timashev",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-navigation-menu": "^1.0.0",
|
||||
"@radix-ui/react-tooltip": "^1.0.0",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.0",
|
||||
"@radix-ui/react-tooltip": "^1.2.0",
|
||||
"classnames": "^2.5.0",
|
||||
"dangerously-set-html-content": "^1.0.13",
|
||||
"date-fns": "^4.0.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"next": "^15.5.0",
|
||||
"next": "^16.1.0",
|
||||
"next-seo": "^5.15.0",
|
||||
"react": "^18.3.0",
|
||||
"react-dom": "^18.3.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-icons": "^4.2.0",
|
||||
"sharp": "^0.34.0",
|
||||
"typograf": "^6.11.1",
|
||||
"valtio": "^2.1.7"
|
||||
},
|
||||
"overrides": {
|
||||
"dangerously-set-html-content": {
|
||||
"react": "$react"
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@types/node": "^22.19.9",
|
||||
"@types/react": "^18.0.18",
|
||||
"@types/react": "^19.2.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
||||
"@typescript-eslint/parser": "^8.54.0",
|
||||
"eslint": "^9.0.0",
|
||||
"eslint-config-next": "^15.5.0",
|
||||
"eslint-config-next": "^16.1.0",
|
||||
"globals": "^16.0.0",
|
||||
"happy-dom": "^20.5.0",
|
||||
"typescript": "^5.9.0",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useReducer } from "react"
|
||||
import { useCallback, useState } from "react"
|
||||
|
||||
export function useToggle(initialValue: boolean): [boolean, (nextValue?: boolean) => void] {
|
||||
return useReducer(
|
||||
(state: boolean, next?: boolean) => typeof next === "boolean" ? next : !state,
|
||||
initialValue,
|
||||
)
|
||||
const [state, setState] = useState(initialValue)
|
||||
const toggle = useCallback((next?: boolean) => {
|
||||
setState(prev => typeof next === "boolean" ? next : !prev)
|
||||
}, [])
|
||||
return [state, toggle]
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
||||
|
||||
export type TransitionProps = {
|
||||
children?: React.ReactNode
|
||||
@@ -7,9 +7,11 @@ export type TransitionProps = {
|
||||
show: boolean
|
||||
}
|
||||
|
||||
export const Transition: React.FC<TransitionProps> = props => {
|
||||
export function Transition(props: TransitionProps) {
|
||||
const [mounted, setMounted] = useState(props.show)
|
||||
const [opacity, setOpacity] = useState(0)
|
||||
const timerRef = useRef<ReturnType<typeof setTimeout>>(null)
|
||||
|
||||
const onTransitionEnd = useCallback(() => {
|
||||
if (opacity === 0) {
|
||||
setMounted(false)
|
||||
@@ -20,19 +22,27 @@ export const Transition: React.FC<TransitionProps> = props => {
|
||||
[props.duration],
|
||||
)
|
||||
|
||||
if (props.show && !mounted) {
|
||||
setMounted(true)
|
||||
}
|
||||
|
||||
if (!props.show && opacity !== 0) {
|
||||
setOpacity(0)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.show) {
|
||||
setOpacity(0)
|
||||
return
|
||||
}
|
||||
|
||||
setMounted(true)
|
||||
let t = setTimeout(() => {
|
||||
timerRef.current = setTimeout(() => {
|
||||
setOpacity(1)
|
||||
}, 16)
|
||||
|
||||
return () => {
|
||||
clearTimeout(t)
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
}
|
||||
}, [props.show])
|
||||
|
||||
|
||||
+3
-2
@@ -23,7 +23,7 @@
|
||||
"resolveJsonModule": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"moduleDetection": "force",
|
||||
"jsx": "preserve",
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
@@ -39,6 +39,7 @@
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts"
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user