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 |
コマンドライン一発生成
プロジェクト名は"next-app-現在時刻"になります。
プロジェクト名を変更する場合は、上記のCREATE_NEXT_APP_NAME変数の値を変更して実行してください。
/bin/bash -c "$(curl -fsSL https://gist.githubusercontent.com/kotsutsumi/38818ae5fb14e36a29afd5248ac26b7f/raw/0228d55da24fe6032364a035e4deee4593bff0eb/setup-nextjs-parkui.sh)"
Next.js 15 に対応
パッケージに--forceを付けてインストール
- next-themes
- react-icons
- @ark-ui/react
- @park-ui/panda-preset
パッケージがNext.js 15対応されたら--forceは不要。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ParkUI 公式ドキュメント手順では、パスの設定など細かい部分で動作しないため、Next.js PandaCSS ArkUI ParkUIが正常に動作するまでの環境を一括で作成するスクリプトを作成
※利用しているsedコマンドは、macOSでの前提です。