Last active
October 26, 2024 05:17
-
-
Save kotsutsumi/38818ae5fb14e36a29afd5248ac26b7f to your computer and use it in GitHub Desktop.
Next.js PandaCSS ArkUI ParkUI 一括セットアップスクリプト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Next.jsへのセットアップ | |
# 作成するプロジェクト名を設定("next-app-現在時刻") | |
CREATE_NEXT_APP_NAME=`date +next-app-%y%m%d%H%M%S` | |
# CREATE_NEXT_APP_NAME="my-app" | |
# プロジェクト生成 | |
npx create-next-app@latest ${CREATE_NEXT_APP_NAME} --ts --eslint --no-tailwind --app --src-dir src/ --no-import-alias --no-turbopack | |
# ディレクトリ移動 | |
cd ${CREATE_NEXT_APP_NAME} | |
# Prettierインストール | |
npm install --save-dev --save-exact prettier | |
# .prettierrc作成 | |
cat <<EOF > .prettierrc | |
{ | |
"tabWidth": 4, | |
"singleQuote": true, | |
"semi": false, | |
"trailingComma": "none", | |
"printWidth": 140 | |
} | |
EOF | |
# .editorconfig作成 | |
cat <<EOF > .editorconfig | |
root = true | |
[*] | |
charset = utf-8 | |
end_of_line = lf | |
insert_final_newline = true | |
indent_style = space | |
indent_size = 4 | |
trim_trailing_whitespace = true | |
[*.md] | |
trim_trailing_whitespace = false | |
[*.{yml,yaml}] | |
indent_size = 2 | |
EOF | |
# Panda CSSセットアップ | |
npm install -D @pandacss/dev | |
npx panda init --postcss | |
npm pkg set scripts.prepare="panda codegen" | |
sed -i '' 's/include\: \["\.\/src\/\*\*\/\*\.{js,jsx,ts,tsx}", "\.\/pages\/\*\*\/\*\.{js,jsx,ts,tsx}"\],/include\: \["\.\/src\/components\/\*\*\/\*\.{ts,tsx,js,jsx}", "\.\/src\/app\/\*\*\/\*\.{ts,tsx,js,jsx}"\],/' panda.config.ts | |
echo "@layer reset, base, tokens, recipes, utilities;" > src/app/globals.css | |
rm -f src/app/page.module.css | |
cat <<EOF > src/app/page.tsx | |
import { css } from 'styled-system/css'; | |
import { Button } from '@/components/ui/button'; | |
export default function Home() { | |
return ( | |
<div className={css({ fontSize: "2xl", fontWeight: 'bold' })}> | |
<Button>Hello 🐼!</Button> | |
</div> | |
) | |
} | |
EOF | |
# Ark UIセットアップ | |
npm install @ark-ui/react --force | |
npm install @park-ui/panda-preset -D --force | |
# jstFramework/presets設定 | |
sed -i '' 's/import { defineConfig } from "@pandacss\/dev";/import { defineConfig } from "@pandacss\/dev";\nimport { createPreset } from "@park-ui\/panda\-preset"/' panda.config.ts | |
sed -i '' 's/});/\n \/\/ jsxFramework\n jsxFramework\: "react",\n\n \/\/ presets\n presets\: \[\n "@pandacss\/preset\-base",\n \n"@pandacss\/preset\-panda", "@park\-ui\/panda\-preset",\n \/\/ Create a custom preset\n \/\/ https\:\/\/park-ui\.com\/ \- Place the settings created by “Make it yours” here\n createPreset\(\{ accentColor\: "blue", grayColor\: "neutral", borderRadius\: "xs" \}\)\n \]\n});/' panda.config.ts | |
# park-ui.json作成 | |
cat <<EOF > park-ui.json | |
{ | |
"$schema": "https://park-ui.com/registry/latest/schema.json", | |
"jsFramework": "react", | |
"outputPath": "./src/components/ui" | |
} | |
EOF | |
# コンポーネント展開 | |
npx @park-ui/cli components add --all | |
# styled-system再生成 | |
npm run prepare | |
# tsconfig.jsonにパス追加 | |
sed -i '' 's/"@\/\*"\: \["\.\/src\/\*"]/"@\/\*"\: \["\.\/src\/\*"],\n "\*"\: \["\.\/\*"]/' tsconfig.json | |
# ビルドエラー修正 | |
sed -i '' 's/export interface CheckboxProps extends StyledCheckbox.RootProps {}/export type CheckboxProps = StyledCheckbox.RootProps/' src/components/ui/checkbox.tsx | |
sed -i '' 's/export interface NumberInputProps extends StyledNumberInput.RootProps {}/export type NumberInputProps = StyledNumberInput.RootProps/' src/components/ui/number-input.tsx | |
sed -i '' 's/export interface PaginationProps extends StyledPagination.RootProps {}/export type PaginationProps = StyledPagination.RootProps/' src/components/ui/pagination.tsx | |
sed -i '' 's/export interface RatingGroupProps extends StyledRatingGroup.RootProps {}/export type RatingGroupProps = StyledRatingGroup.RootProps/' src/components/ui/rating-group.tsx | |
sed -i '' 's/ const { children, marks, \.\.\.rootProps } = props/ \/\/ eslint\-disable\-next\-line @typescript\-eslint\/no-unused\-vars\n const { children, marks, \.\.\.rootProps } = props/' src/components/ui/slider.tsx | |
sed -i '' 's/ const withRootProvider = <P extends {}>/ \/\/ eslint\-disable\-next\-line @typescript\-eslint\/no\-empty\-object\-type\n const withRootProvider = <P extends {}>/' src/components/ui/styled/utils/create-style-context.tsx | |
sed -i '' 's/ \/\/ @ts-expect\-error/ \/\/ @ts-expect-error \- displayName is not defined on StyledComponent/' src/components/ui/styled/utils/create-style-context.tsx | |
sed -i '' 's/export interface SwitchProps extends StyledSwitch.RootProps {}/export type SwitchProps = StyledSwitch.RootProps/' src/components/ui/switch.tsx | |
# Next Themesインストール | |
npm i next-themes --force | |
# React Iconsインストール | |
npm install react-icons --save --force | |
# layout.tsx修正 | |
cat <<EOF > src/app/layout.tsx | |
import type { Metadata } from 'next' | |
import { ThemeProvider } from 'next-themes' | |
import localFont from 'next/font/local' | |
import './globals.css' | |
const geistSans = localFont({ | |
src: './fonts/GeistVF.woff', | |
variable: '--font-geist-sans', | |
weight: '100 900' | |
}) | |
const geistMono = localFont({ | |
src: './fonts/GeistMonoVF.woff', | |
variable: '--font-geist-mono', | |
weight: '100 900' | |
}) | |
export const metadata: Metadata = { | |
title: 'Create Next App', | |
description: 'Generated by create next app' | |
} | |
export default function RootLayout({ | |
children | |
}: Readonly<{ | |
children: React.ReactNode | |
}>) { | |
return ( | |
<html lang="en" suppressHydrationWarning> | |
<body className={\`\${geistSans.variable} \${geistMono.variable}\` }> | |
<ThemeProvider attribute="class">{children}</ThemeProvider> | |
</body> | |
</html> | |
) | |
} | |
EOF | |
# extディレクトリ作成 | |
mkdir src/components/ui/ext | |
# ThemeToggleButton作成 | |
cat <<EOS > src/components/ui/ext/ThemeToggleButton.tsx | |
/** | |
* ThemeToggleButton Component | |
*/ | |
'use client' | |
import { useTheme } from 'next-themes' | |
import { MdOutlineDarkMode, MdOutlineLightMode } from 'react-icons/md' | |
import { Button } from '../button' | |
export default function ThemeToggleButton() { | |
const { theme, setTheme } = useTheme() | |
return ( | |
<div> | |
<Button | |
variant="ghost" | |
onClick={() => { | |
if (theme === 'light') { | |
setTheme('dark') | |
} else { | |
setTheme('light') | |
} | |
}} | |
> | |
{theme !== 'light' ? <MdOutlineLightMode /> : <MdOutlineDarkMode />} | |
</Button> | |
</div> | |
) | |
} | |
// EOF | |
EOS | |
# ビルド | |
npm run build |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Next.js 15 に対応
パッケージに--forceを付けてインストール
パッケージがNext.js 15対応されたら--forceは不要。