diff --git a/.eslintignore b/.eslintignore index ddf3147..c362ce5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,5 @@ **/node_modules/* **/out/* **/.next/* -/.eslintrc.js \ No newline at end of file +/.eslintrc.js +**/$path.ts diff --git a/.prettierignore b/.prettierignore index 8672cdb..f53d8b6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,5 @@ __tests__ node_modules yarn.lock package-lock.json -public \ No newline at end of file +public +**/$path.ts diff --git a/jest.config.js b/jest.config.js index e270bb9..2f891d7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/naming-convention */ const nextJest = require("next/jest"); // Provide the path to your Next.js app to load next.config.js and .env files in your test environment diff --git a/package.json b/package.json index fbec77a..13c4443 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,10 @@ "version": "1.0.0", "license": "MIT", "scripts": { - "dev": "next dev", - "build": "next build", + "dev": "run-p dev:*", + "dev:next": "next dev", + "dev:path": "pathpida --enableStatic --ignorePath .gitignore --output src/lib --watch", + "build": "pathpida --enableStatic --ignorePath .gitignore --output src/lib && next build", "start": "next start", "serve": "run-s build start", "lint": "next lint", @@ -57,6 +59,7 @@ "jest": "27.5.1", "lint-staged": "12.3.7", "npm-run-all": "4.1.5", + "pathpida": "^0.18.1", "postcss": "8.4.12", "prettier": "2.6.2", "react-test-renderer": "18.0.0", diff --git a/src/component/Button/NavLink.tsx b/src/component/Button/NavLink.tsx index 58a98ef..7569935 100644 --- a/src/component/Button/NavLink.tsx +++ b/src/component/Button/NavLink.tsx @@ -1,7 +1,7 @@ import type { LinkProps } from "next/link"; import Link from "next/link"; import { useRouter } from "next/router"; -import type { ReactElement } from "react"; +import type { FC, ReactElement } from "react"; import { cloneElement } from "react"; type Props = LinkProps & { children: ReactElement; activeClassName: string }; @@ -9,16 +9,21 @@ type Props = LinkProps & { children: ReactElement; activeClassName: string }; /** * @package */ -export const NavLink = (props: Props) => { - // eslint-disable-next-line react/destructuring-assignment - const { activeClassName, children, ...linkProps } = props; +export const NavLink: FC = ({ + activeClassName, + children, + ...linkProps +}) => { const router = useRouter(); - const pathname = router.pathname === "/root" ? "/" : router.pathname; - const className = - pathname === linkProps.href - ? `${activeClassName} ${children.props.className ?? ""}` - : children.props.className ?? ""; - - return {cloneElement(children, { className })}; + return ( + + {cloneElement(children, { + className: + router.pathname === linkProps.href + ? `${activeClassName} ${children.props.className ?? ""}` + : children.props.className ?? "", + })} + + ); }; diff --git a/src/layout/Footer.tsx b/src/layout/Footer.tsx index 15aede9..c33bfe1 100644 --- a/src/layout/Footer.tsx +++ b/src/layout/Footer.tsx @@ -1,9 +1,9 @@ -import type { VFC } from "react"; +import type { FC } from "react"; /** * @package */ -export const Footer: VFC = () => { +export const Footer: FC = () => { return (
© 20xx example diff --git a/src/layout/Header.tsx b/src/layout/Header.tsx index 928a937..b93462d 100644 --- a/src/layout/Header.tsx +++ b/src/layout/Header.tsx @@ -1,15 +1,16 @@ -import type { VFC } from "react"; +import type { FC } from "react"; import { NavLink } from "src/component/Button"; +import { pagesPath } from "src/lib/$path"; const items = [ - { href: "/", label: "Root" }, - { href: "/about", label: "About" }, + { href: pagesPath.$url().pathname, label: "Root" }, + { href: pagesPath.about.$url().pathname, label: "About" }, ]; /** * @package */ -export const Header: VFC = () => { +export const Header: FC = () => { return (

Title

diff --git a/src/layout/LayoutErrorBoundary.tsx b/src/layout/LayoutErrorBoundary.tsx index 806189a..902b1e8 100644 --- a/src/layout/LayoutErrorBoundary.tsx +++ b/src/layout/LayoutErrorBoundary.tsx @@ -1,4 +1,4 @@ -import type { ReactNode, VFC } from "react"; +import type { FC, ReactNode } from "react"; import type { FallbackProps } from "react-error-boundary"; import { ErrorBoundary } from "react-error-boundary"; @@ -14,7 +14,7 @@ const ErrorFallback = ({ error }: FallbackProps) => { /** * @package */ -export const LayoutErrorBoundary: VFC<{ children: ReactNode }> = ({ +export const LayoutErrorBoundary: FC<{ children: ReactNode }> = ({ children, }) => { return ( diff --git a/src/lib/$path.ts b/src/lib/$path.ts new file mode 100644 index 0000000..e943c04 --- /dev/null +++ b/src/lib/$path.ts @@ -0,0 +1,14 @@ +export const pagesPath = { + "about": { + $url: (url?: { hash?: string }) => ({ pathname: '/about' as const, hash: url?.hash }) + }, + $url: (url?: { hash?: string }) => ({ pathname: '/' as const, hash: url?.hash }) +} + +export type PagesPath = typeof pagesPath + +export const staticPath = { + favicon_ico: '/favicon.ico' +} as const + +export type StaticPath = typeof staticPath diff --git a/src/pages/about/index.tsx b/src/pages/about/index.tsx index d4bdf80..2139d50 100644 --- a/src/pages/about/index.tsx +++ b/src/pages/about/index.tsx @@ -1,5 +1,5 @@ -import type { VFC } from "react"; +import type { FC } from "react"; -export const About: VFC = () => { +export const About: FC = () => { return

About!

; }; diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index 6d00ef4..fa457dd 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1,7 +1,7 @@ -import type { VFC } from "react"; +import type { FC } from "react"; import { Button } from "src/component/Button"; -export const Index: VFC = () => { +export const Index: FC = () => { const handleClick = () => { window.alert("Hello, World!"); }; diff --git a/yarn.lock b/yarn.lock index 98b00f7..cb8bd5d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3843,7 +3843,7 @@ minimatch@^3.0.4, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -4192,6 +4192,15 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathpida@^0.18.1: + version "0.18.1" + resolved "https://registry.yarnpkg.com/pathpida/-/pathpida-0.18.1.tgz#2a0a4aaf30d75e1af75574ad2cf792ebc4c20839" + integrity sha512-rDWOi9lcbc2tV+2LSfQW7p5i6Tu0GSfsSXjYMP4qcXnnmuTYgOp7zE4ei2+P+wg9ntpwKAwHLpWZNNseJbKrSQ== + dependencies: + chokidar "^3.5.3" + ignore "^5.2.0" + minimist "^1.2.5" + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"