atomsystem 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/templates/Theme/Theme.tsx +1 -1
- package/cli/init.js +51 -43
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { Radio } from "../Form/Form";
|
|
5
|
-
import { themes } from "
|
|
5
|
+
import { themes } from "../../../build/typescript/theme";
|
|
6
6
|
import { Button } from "../Button/Button";
|
|
7
7
|
import { ModalContent } from "../Modal/Modal";
|
|
8
8
|
|
package/cli/init.js
CHANGED
|
@@ -49,7 +49,7 @@ inquirer
|
|
|
49
49
|
|
|
50
50
|
try {
|
|
51
51
|
await execPromise(
|
|
52
|
-
"npm install next@latest react@latest react-dom@latest tailwindcss"
|
|
52
|
+
"npm install next@latest react@latest react-dom@latest tailwindcss clsx typescript @types/react @types/node @types/react-dom"
|
|
53
53
|
);
|
|
54
54
|
pkgSpinner.succeed("Next.js and React installation complete!");
|
|
55
55
|
} catch (err) {
|
|
@@ -96,53 +96,19 @@ inquirer
|
|
|
96
96
|
const appDir = path.join(projectRoot, "app");
|
|
97
97
|
if (!fs.existsSync(appDir)) mkdirSync(appDir);
|
|
98
98
|
|
|
99
|
+
// components 및 Theme 디렉토리 생성은 add.js 가 알아서 처리하므로 여기서는 page.tsx 와 layout.tsx, globals.css 만 생성합니다.
|
|
99
100
|
const files = [
|
|
100
|
-
{
|
|
101
|
-
path: path.join(appDir, "ThemeProvider.tsx"),
|
|
102
|
-
content: `"use client";
|
|
103
|
-
import { useEffect, useState } from "react";
|
|
104
|
-
import { themes } from "@/build/typescript/theme";
|
|
105
|
-
|
|
106
|
-
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
|
|
107
|
-
const [theme, setTheme] = useState<Record<string, string>>({});
|
|
108
|
-
const [isThemeLoading, setThemeLoading] = useState(false);
|
|
109
|
-
|
|
110
|
-
useEffect(() => {
|
|
111
|
-
const listenStorageChange = () => {
|
|
112
|
-
const newThemes: Record<string, string> = {};
|
|
113
|
-
Object.entries(themes).forEach(([group, groupThemes]) => {
|
|
114
|
-
const storedKey = group === "global" ? "theme" : \`theme-\${group}\`;
|
|
115
|
-
const currentTheme = localStorage.getItem(storedKey) || groupThemes[0];
|
|
116
|
-
newThemes[group] = currentTheme;
|
|
117
|
-
|
|
118
|
-
document.documentElement.classList.remove(...groupThemes);
|
|
119
|
-
document.documentElement.classList.add(currentTheme);
|
|
120
|
-
});
|
|
121
|
-
setTheme(newThemes);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
listenStorageChange();
|
|
125
|
-
window.addEventListener("storage", listenStorageChange);
|
|
126
|
-
setThemeLoading(true);
|
|
127
|
-
return () => window.removeEventListener("storage", listenStorageChange);
|
|
128
|
-
}, []);
|
|
129
|
-
|
|
130
|
-
if (isThemeLoading === false) return null;
|
|
131
|
-
return <>{children}</>;
|
|
132
|
-
};`,
|
|
133
|
-
},
|
|
134
101
|
{
|
|
135
102
|
path: path.join(appDir, "layout.tsx"),
|
|
136
|
-
content: `import { ThemeProvider } from "./
|
|
103
|
+
content: `import { ThemeProvider } from "./components/Theme/Theme";
|
|
137
104
|
import "./globals.css";
|
|
138
105
|
|
|
139
106
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
140
107
|
return (
|
|
141
|
-
<html lang="en">
|
|
108
|
+
<html lang="en" suppressHydrationWarning>
|
|
142
109
|
<body>
|
|
143
|
-
<ThemeProvider
|
|
144
|
-
|
|
145
|
-
</ThemeProvider>
|
|
110
|
+
<ThemeProvider />
|
|
111
|
+
{children}
|
|
146
112
|
</body>
|
|
147
113
|
</html>
|
|
148
114
|
)
|
|
@@ -156,12 +122,39 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
156
122
|
{
|
|
157
123
|
path: path.join(appDir, "page.tsx"),
|
|
158
124
|
content: `import { ThemeSelector } from "./components/Theme/Theme";
|
|
125
|
+
import { Button } from "./components/Button/Button";
|
|
126
|
+
import { Card, CardHeader, CardContent, CardFooter } from "./components/Card/Card";
|
|
159
127
|
|
|
160
128
|
export default function Page() {
|
|
161
129
|
return (
|
|
162
|
-
<main style={{ padding: "
|
|
163
|
-
<
|
|
164
|
-
|
|
130
|
+
<main style={{ padding: "40px", minHeight: "100vh", background: "var(--color-bg-wrapper)", transition: "background 0.3s ease" }}>
|
|
131
|
+
<div style={{ maxWidth: "800px", margin: "0 auto", display: "flex", flexDirection: "column", gap: "24px" }}>
|
|
132
|
+
<h1 style={{ fontSize: "var(--font-sizes-h2)", color: "var(--color-text-standard)", margin: 0 }}>Hello, atomsystem!</h1>
|
|
133
|
+
<p style={{ color: "var(--color-text-standard)", fontSize: "var(--font-sizes-body)", margin: 0 }}>
|
|
134
|
+
이 화면은 디자인 토큰이 적용된 샘플 화면입니다. 아래 테마를 변경해보세요.
|
|
135
|
+
</p>
|
|
136
|
+
|
|
137
|
+
<ThemeSelector />
|
|
138
|
+
|
|
139
|
+
<Card>
|
|
140
|
+
<CardHeader>
|
|
141
|
+
<h2 style={{ fontSize: "var(--font-sizes-h3)", margin: 0 }}>Sample Card Components</h2>
|
|
142
|
+
</CardHeader>
|
|
143
|
+
<CardContent>
|
|
144
|
+
<p style={{ margin: 0, color: "var(--color-text-disabled)" }}>
|
|
145
|
+
이 카드는 테마 변경 시 배경색, 텍스트 색상, 테두리 색상이 자동으로 변경됩니다.
|
|
146
|
+
여기 있는 버튼들은 제공된 Button 컴포넌트로 구성되었습니다.
|
|
147
|
+
</p>
|
|
148
|
+
</CardContent>
|
|
149
|
+
<CardFooter>
|
|
150
|
+
<div style={{ display: "flex", gap: "12px" }}>
|
|
151
|
+
<Button type="primary">Primary Button</Button>
|
|
152
|
+
<Button type="secondary">Secondary Button</Button>
|
|
153
|
+
<Button type="gray">Gray Button</Button>
|
|
154
|
+
</div>
|
|
155
|
+
</CardFooter>
|
|
156
|
+
</Card>
|
|
157
|
+
</div>
|
|
165
158
|
</main>
|
|
166
159
|
)
|
|
167
160
|
}`,
|
|
@@ -172,6 +165,21 @@ export default function Page() {
|
|
|
172
165
|
fs.writeFileSync(path, content);
|
|
173
166
|
console.log(`✅ Created ${path}`);
|
|
174
167
|
});
|
|
168
|
+
|
|
169
|
+
// add.js를 실행하여 Theme, Card 컴포넌트 및 하위 의존성을 복사합니다.
|
|
170
|
+
const addScriptPath = path.join(__dirname, "add.js");
|
|
171
|
+
if (fs.existsSync(addScriptPath)) {
|
|
172
|
+
console.log("⏳ Adding default components via add.js...");
|
|
173
|
+
try {
|
|
174
|
+
// Theme 설치 (Theme 내부에 Button 등이 포함되어 있음)
|
|
175
|
+
await execPromise(`node "${addScriptPath}" Theme`, { cwd: projectRoot });
|
|
176
|
+
// Card 설치
|
|
177
|
+
await execPromise(`node "${addScriptPath}" Card`, { cwd: projectRoot });
|
|
178
|
+
console.log("✅ Default components (Theme, Card, Button 등) added successfully.");
|
|
179
|
+
} catch (err) {
|
|
180
|
+
console.error("❌ Failed to add components:", err);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
175
183
|
} else {
|
|
176
184
|
console.log("🚀 Installation skipped.");
|
|
177
185
|
}
|