@emberkit/cli 0.6.1-alpha.1 → 0.6.1-alpha.11

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.
@@ -85,7 +85,7 @@ const Layout: RouteComponent = ({ children }) => {
85
85
  </header>
86
86
  <main className="flex-1">{children}</main>
87
87
  <footer className="border-t border-gray-200 py-8 text-center text-sm text-gray-500">
88
- <p>Built with <a href="https://emberkit.dev" className="text-gray-700 hover:underline">EmberKit</a></p>
88
+ <p>Built with <a href="https://emberkit.orangeember.com" className="text-gray-700 hover:underline">EmberKit</a></p>
89
89
  </footer>
90
90
  </div>
91
91
  </>
@@ -137,7 +137,7 @@ const HomePage: RouteComponent = () => {
137
137
  <div className="space-y-10">
138
138
  {posts.map((post) => (
139
139
  <article key={post.slug} className="group">
140
- <a href={\`/posts/\${post.slug}\`} className="block">
140
+ <a href={post.slug} className="block">
141
141
  <h2 className="text-xl font-semibold font-serif mb-2 group-hover:text-blue-600 transition-colors">
142
142
  {post.title}
143
143
  </h2>
@@ -156,7 +156,7 @@ const HomePage: RouteComponent = () => {
156
156
  };
157
157
 
158
158
  export default HomePage;`,
159
- "src/routes/[slug].tsx": `import type { RouteComponent, RouteParams } from '@emberkit/core';
159
+ "src/routes/[slug].tsx": `import type { RouteParams } from '@emberkit/core';
160
160
  import { Head } from '@emberkit/core';
161
161
 
162
162
  interface PostData {
@@ -190,11 +190,11 @@ const posts: Record<string, PostData> = {
190
190
  content: \`
191
191
  <p>Signals are the reactive primitive at the core of EmberKit.</p>
192
192
  <h2>Creating Signals</h2>
193
- <pre><code>const count = signal(0);</code></pre>
193
+ <pre><code>const [count, setCount] = createSignal(0);</code></pre>
194
194
  <h2>Computed Values</h2>
195
- <pre><code>const doubled = computed(() => count.value * 2);</code></pre>
195
+ <pre><code>const doubled = createMemo(() => count() * 2);</code></pre>
196
196
  <h2>Side Effects</h2>
197
- <pre><code>effect(() => console.log(count.value));</code></pre>
197
+ <pre><code>createEffect(() => console.log(count()));</code></pre>
198
198
  \`,
199
199
  },
200
200
  'file-based-routing': {
@@ -212,11 +212,7 @@ const posts: Record<string, PostData> = {
212
212
  },
213
213
  };
214
214
 
215
- interface Params {
216
- slug: string;
217
- }
218
-
219
- const PostPage: RouteComponent<Params> = ({ params }: RouteParams<Params>) => {
215
+ export default function PostPage({ params }: RouteParams<{ slug: string }>) {
220
216
  const post = posts[params.slug];
221
217
 
222
218
  if (!post) {
@@ -250,9 +246,7 @@ const PostPage: RouteComponent<Params> = ({ params }: RouteParams<Params>) => {
250
246
  </article>
251
247
  </>
252
248
  );
253
- };
254
-
255
- export default PostPage;`,
249
+ }`,
256
250
  "src/routes/about.tsx": `import type { RouteComponent } from '@emberkit/core';
257
251
  import { Head } from '@emberkit/core';
258
252
 
@@ -266,7 +260,7 @@ const AboutPage: RouteComponent = () => {
266
260
  <h1 className="text-4xl font-bold font-serif mb-6">About</h1>
267
261
  <div className="prose">
268
262
  <p>Hi, I'm the author of this blog. I write about web development, frameworks, and building fast user interfaces.</p>
269
- <p>This blog is built with <a href="https://emberkit.dev">EmberKit</a>, a minimalist TypeScript-first JSX framework.</p>
263
+ <p>This blog is built with <a href="https://emberkit.orangeember.com">EmberKit</a>, a minimalist TypeScript-first JSX framework.</p>
270
264
  <h2>Tech Stack</h2>
271
265
  <ul>
272
266
  <li>EmberKit for routing and rendering</li>
@@ -28,11 +28,11 @@ body {
28
28
  @apply bg-gray-50 text-gray-900 font-sans;
29
29
  }`,
30
30
  "src/routes/_layout.tsx": `import type { RouteComponent } from '@emberkit/core';
31
- import { signal } from '@emberkit/core';
31
+ import { createSignal } from '@emberkit/core';
32
32
  import { Sidebar, Header } from '@emberkit/ui';
33
33
 
34
34
  const Layout: RouteComponent = ({ children }) => {
35
- const sidebarOpen = signal(true);
35
+ const [sidebarOpen, setSidebarOpen] = createSignal(true);
36
36
 
37
37
  const sidebarItems = [
38
38
  { label: 'Dashboard', href: '/dashboard', icon: 'grid' },
@@ -47,15 +47,15 @@ const Layout: RouteComponent = ({ children }) => {
47
47
  <Sidebar
48
48
  logo={<span className="font-bold text-lg">&#9889; {{name}}</span>}
49
49
  items={sidebarItems}
50
- collapsed={!sidebarOpen.value}
51
- onToggle={() => { sidebarOpen.value = !sidebarOpen.value; }}
50
+ collapsed={!sidebarOpen()}
51
+ onToggle={() => { setSidebarOpen(!sidebarOpen()); }}
52
52
  className="w-64"
53
53
  />
54
54
  <div className="flex-1 flex flex-col min-w-0">
55
55
  <Header
56
56
  title="Dashboard"
57
57
  user={{ name: 'User', avatar: '' }}
58
- onMenuClick={() => { sidebarOpen.value = !sidebarOpen.value; }}
58
+ onMenuClick={() => { setSidebarOpen(!sidebarOpen()); }}
59
59
  />
60
60
  <main className="flex-1 p-6 overflow-auto">
61
61
  {children}
@@ -162,7 +162,7 @@ const DashboardPage: RouteComponent = () => {
162
162
  export default DashboardPage;`,
163
163
  "src/routes/users.tsx": `import type { RouteComponent } from '@emberkit/core';
164
164
  import { Card, Badge, Button, Input } from '@emberkit/ui';
165
- import { signal } from '@emberkit/core';
165
+ import { createSignal } from '@emberkit/core';
166
166
 
167
167
  interface User {
168
168
  id: number;
@@ -182,12 +182,12 @@ const users: User[] = [
182
182
  ];
183
183
 
184
184
  const UsersPage: RouteComponent = () => {
185
- const search = signal('');
185
+ const [search, setSearch] = createSignal('');
186
186
 
187
187
  const filteredUsers = users.filter(
188
188
  (u) =>
189
- u.name.toLowerCase().includes(search.value.toLowerCase()) ||
190
- u.email.toLowerCase().includes(search.value.toLowerCase())
189
+ u.name.toLowerCase().includes(search().toLowerCase()) ||
190
+ u.email.toLowerCase().includes(search().toLowerCase())
191
191
  );
192
192
 
193
193
  const statusVariant = (status: User['status']) => {
@@ -212,8 +212,8 @@ const UsersPage: RouteComponent = () => {
212
212
  <div className="mb-4">
213
213
  <Input
214
214
  placeholder="Search users..."
215
- value={search.value}
216
- onInput={(e) => { search.value = e.currentTarget.value; }}
215
+ value={search()}
216
+ onInput={(e) => { setSearch(e.currentTarget.value); }}
217
217
  className="max-w-sm"
218
218
  />
219
219
  </div>
@@ -260,17 +260,17 @@ const UsersPage: RouteComponent = () => {
260
260
  export default UsersPage;`,
261
261
  "src/routes/settings.tsx": `import type { RouteComponent } from '@emberkit/core';
262
262
  import { Card, Input, Button, Alert } from '@emberkit/ui';
263
- import { signal } from '@emberkit/core';
263
+ import { createSignal } from '@emberkit/core';
264
264
 
265
265
  const SettingsPage: RouteComponent = () => {
266
- const name = signal('John Doe');
267
- const email = signal('john@example.com');
268
- const saved = signal(false);
266
+ const [name, setName] = createSignal('John Doe');
267
+ const [email, setEmail] = createSignal('john@example.com');
268
+ const [saved, setSaved] = createSignal(false);
269
269
 
270
270
  const handleSave = (e: Event) => {
271
271
  e.preventDefault();
272
- saved.value = true;
273
- setTimeout(() => { saved.value = false; }, 3000);
272
+ setSaved(true);
273
+ setTimeout(() => { setSaved(false); }, 3000);
274
274
  };
275
275
 
276
276
  return (
@@ -280,7 +280,7 @@ const SettingsPage: RouteComponent = () => {
280
280
  <p className="text-gray-600 mt-1">Manage your account preferences.</p>
281
281
  </div>
282
282
 
283
- {saved.value && (
283
+ {saved() && (
284
284
  <Alert variant="success">Settings saved successfully!</Alert>
285
285
  )}
286
286
 
@@ -289,14 +289,14 @@ const SettingsPage: RouteComponent = () => {
289
289
  <form onSubmit={handleSave} className="space-y-4">
290
290
  <Input
291
291
  label="Full Name"
292
- value={name.value}
293
- onInput={(e) => { name.value = e.currentTarget.value; }}
292
+ value={name()}
293
+ onInput={(e) => { setName(e.currentTarget.value); }}
294
294
  />
295
295
  <Input
296
296
  label="Email"
297
297
  type="email"
298
- value={email.value}
299
- onInput={(e) => { email.value = e.currentTarget.value; }}
298
+ value={email()}
299
+ onInput={(e) => { setEmail(e.currentTarget.value); }}
300
300
  />
301
301
  <div className="flex justify-end">
302
302
  <Button variant="primary" type="submit">Save Changes</Button>
@@ -103,11 +103,11 @@ const Layout: RouteComponent = ({ children }) => {
103
103
 
104
104
  export default Layout;`,
105
105
  "src/routes/index.tsx": `import type { RouteComponent } from '@emberkit/core';
106
- import { signal } from '@emberkit/core';
106
+ import { createSignal } from '@emberkit/core';
107
107
  import { Button, Card, Badge } from '@emberkit/ui';
108
108
 
109
109
  const HomePage: RouteComponent = () => {
110
- const annual = signal(false);
110
+ const [annual, setAnnual] = createSignal(false);
111
111
 
112
112
  const features = [
113
113
  { icon: '&#9889;', title: 'Lightning Fast', desc: 'Sub-10KB runtime with tree-shakeable architecture' },
@@ -121,8 +121,8 @@ const HomePage: RouteComponent = () => {
121
121
  const plans = [
122
122
  {
123
123
  name: 'Starter',
124
- price: annual.value ? '$0' : '$0',
125
- period: annual.value ? '/year' : '/month',
124
+ price: annual() ? '$0' : '$0',
125
+ period: annual() ? '/year' : '/month',
126
126
  desc: 'Perfect for side projects',
127
127
  features: ['1 user', '5 projects', '1GB storage', 'Community support'],
128
128
  cta: 'Get Started Free',
@@ -130,8 +130,8 @@ const HomePage: RouteComponent = () => {
130
130
  },
131
131
  {
132
132
  name: 'Pro',
133
- price: annual.value ? '$199' : '$19',
134
- period: annual.value ? '/year' : '/month',
133
+ price: annual() ? '$199' : '$19',
134
+ period: annual() ? '/year' : '/month',
135
135
  desc: 'For growing teams',
136
136
  features: ['10 users', 'Unlimited projects', '50GB storage', 'Priority support', 'Analytics', 'API access'],
137
137
  cta: 'Start Free Trial',
@@ -211,14 +211,14 @@ const HomePage: RouteComponent = () => {
211
211
  <p className="text-lg text-slate-600 mb-8">Choose the plan that works for your team</p>
212
212
  <div className="inline-flex items-center gap-3 p-1 bg-white rounded-lg border border-slate-200">
213
213
  <button
214
- className={\`px-4 py-2 text-sm font-medium rounded-md transition-colors \${!annual.value ? 'bg-brand-600 text-white' : 'text-slate-600'}\`}
215
- onClick={() => { annual.value = false; }}
214
+ className={\`px-4 py-2 text-sm font-medium rounded-md transition-colors \${!annual() ? 'bg-brand-600 text-white' : 'text-slate-600'}\`}
215
+ onClick={() => { setAnnual(false); }}
216
216
  >
217
217
  Monthly
218
218
  </button>
219
219
  <button
220
- className={\`px-4 py-2 text-sm font-medium rounded-md transition-colors \${annual.value ? 'bg-brand-600 text-white' : 'text-slate-600'}\`}
221
- onClick={() => { annual.value = true; }}
220
+ className={\`px-4 py-2 text-sm font-medium rounded-md transition-colors \${annual() ? 'bg-brand-600 text-white' : 'text-slate-600'}\`}
221
+ onClick={() => { setAnnual(true); }}
222
222
  >
223
223
  Annual <span className="text-brand-600 ml-1 font-semibold">-20%</span>
224
224
  </button>
@@ -280,19 +280,19 @@ export default HomePage;`,
280
280
  "src/routes/login.tsx": `import type { RouteComponent } from '@emberkit/core';
281
281
  import { Head } from '@emberkit/core';
282
282
  import { Button, Input, Card } from '@emberkit/ui';
283
- import { signal } from '@emberkit/core';
283
+ import { createSignal } from '@emberkit/core';
284
284
 
285
285
  const LoginPage: RouteComponent = () => {
286
- const email = signal('');
287
- const password = signal('');
288
- const error = signal<string | null>(null);
286
+ const [email, setEmail] = createSignal('');
287
+ const [password, setPassword] = createSignal('');
288
+ const [error, setError] = createSignal<string | null>(null);
289
289
 
290
290
  const handleSubmit = (e: Event) => {
291
291
  e.preventDefault();
292
- error.value = null;
292
+ setError(null);
293
293
 
294
- if (!email.value || !password.value) {
295
- error.value = 'Please fill in all fields';
294
+ if (!email() || !password()) {
295
+ setError('Please fill in all fields');
296
296
  return;
297
297
  }
298
298
 
@@ -315,18 +315,18 @@ const LoginPage: RouteComponent = () => {
315
315
  label="Email"
316
316
  type="email"
317
317
  placeholder="you@example.com"
318
- value={email.value}
319
- onInput={(e) => { email.value = e.currentTarget.value; }}
318
+ value={email()}
319
+ onInput={(e) => { setEmail(e.currentTarget.value); }}
320
320
  />
321
321
  <Input
322
322
  label="Password"
323
323
  type="password"
324
324
  placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;"
325
- value={password.value}
326
- onInput={(e) => { password.value = e.currentTarget.value; }}
325
+ value={password()}
326
+ onInput={(e) => { setPassword(e.currentTarget.value); }}
327
327
  />
328
- {error.value && (
329
- <p className="text-red-500 text-sm">{error.value}</p>
328
+ {error() && (
329
+ <p className="text-red-500 text-sm">{error()}</p>
330
330
  )}
331
331
  <div className="flex items-center justify-between text-sm">
332
332
  <label className="flex items-center gap-2">
@@ -350,20 +350,20 @@ export default LoginPage;`,
350
350
  "src/routes/signup.tsx": `import type { RouteComponent } from '@emberkit/core';
351
351
  import { Head } from '@emberkit/core';
352
352
  import { Button, Input, Card } from '@emberkit/ui';
353
- import { signal } from '@emberkit/core';
353
+ import { createSignal } from '@emberkit/core';
354
354
 
355
355
  const SignupPage: RouteComponent = () => {
356
- const name = signal('');
357
- const email = signal('');
358
- const password = signal('');
359
- const error = signal<string | null>(null);
356
+ const [name, setName] = createSignal('');
357
+ const [email, setEmail] = createSignal('');
358
+ const [password, setPassword] = createSignal('');
359
+ const [error, setError] = createSignal<string | null>(null);
360
360
 
361
361
  const handleSubmit = (e: Event) => {
362
362
  e.preventDefault();
363
- error.value = null;
363
+ setError(null);
364
364
 
365
- if (!name.value || !email.value || !password.value) {
366
- error.value = 'Please fill in all fields';
365
+ if (!name() || !email() || !password()) {
366
+ setError('Please fill in all fields');
367
367
  return;
368
368
  }
369
369
 
@@ -385,25 +385,25 @@ const SignupPage: RouteComponent = () => {
385
385
  <Input
386
386
  label="Full Name"
387
387
  placeholder="John Doe"
388
- value={name.value}
389
- onInput={(e) => { name.value = e.currentTarget.value; }}
388
+ value={name()}
389
+ onInput={(e) => { setName(e.currentTarget.value); }}
390
390
  />
391
391
  <Input
392
392
  label="Email"
393
393
  type="email"
394
394
  placeholder="you@example.com"
395
- value={email.value}
396
- onInput={(e) => { email.value = e.currentTarget.value; }}
395
+ value={email()}
396
+ onInput={(e) => { setEmail(e.currentTarget.value); }}
397
397
  />
398
398
  <Input
399
399
  label="Password"
400
400
  type="password"
401
401
  placeholder="8+ characters"
402
- value={password.value}
403
- onInput={(e) => { password.value = e.currentTarget.value; }}
402
+ value={password()}
403
+ onInput={(e) => { setPassword(e.currentTarget.value); }}
404
404
  />
405
- {error.value && (
406
- <p className="text-red-500 text-sm">{error.value}</p>
405
+ {error() && (
406
+ <p className="text-red-500 text-sm">{error()}</p>
407
407
  )}
408
408
  <p className="text-xs text-slate-500">
409
409
  By signing up, you agree to our {' '}
@@ -77,7 +77,7 @@ const Layout: RouteComponent = ({ children }) => {
77
77
  <nav className="flex items-center gap-6">
78
78
  <a href="/" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">Home</a>
79
79
  <a href="/about" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">About</a>
80
- <a href="https://emberkit.dev/docs" target="_blank" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">
80
+ <a href="https://emberkit.orangeember.com" target="_blank" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">
81
81
  Docs <span className="text-xs">&#8599;</span>
82
82
  </a>
83
83
  </nav>
@@ -85,7 +85,7 @@ const Layout: RouteComponent = ({ children }) => {
85
85
  </header>
86
86
  <main className="relative z-10 flex-1">{children}</main>
87
87
  <footer className="relative z-10 border-t border-slate-800/50 py-8 text-center text-sm text-slate-500">
88
- <p>Built with <a href="https://emberkit.dev" className="text-ember-500 hover:underline">EmberKit</a></p>
88
+ <p>Built with <a href="https://emberkit.orangeember.com" className="text-ember-500 hover:underline">EmberKit</a></p>
89
89
  </footer>
90
90
  </div>
91
91
  </>
@@ -94,10 +94,10 @@ const Layout: RouteComponent = ({ children }) => {
94
94
 
95
95
  export default Layout;`,
96
96
  "src/routes/index.tsx": `import type { RouteComponent } from '@emberkit/core';
97
- import { signal } from '@emberkit/core';
97
+ import { createSignal } from '@emberkit/core';
98
98
 
99
99
  const HomePage: RouteComponent = () => {
100
- const count = signal(0);
100
+ const [count, setCount] = createSignal(0);
101
101
 
102
102
  return (
103
103
  <div className="relative max-w-6xl mx-auto px-6 py-16 space-y-24">
@@ -115,7 +115,7 @@ const HomePage: RouteComponent = () => {
115
115
  <a href="/about" className="px-6 py-3 bg-ember-500 hover:bg-ember-600 text-white font-semibold rounded-lg transition-all hover:scale-105 shadow-lg shadow-ember-500/20">
116
116
  Learn More
117
117
  </a>
118
- <a href="https://emberkit.dev/docs" target="_blank" className="px-6 py-3 border border-slate-700 hover:border-ember-500 text-slate-300 hover:text-ember-500 font-semibold rounded-lg transition-all">
118
+ <a href="https://emberkit.orangeember.com" target="_blank" className="px-6 py-3 border border-slate-700 hover:border-ember-500 text-slate-300 hover:text-ember-500 font-semibold rounded-lg transition-all">
119
119
  Read Docs &#8594;
120
120
  </a>
121
121
  </div>
@@ -142,14 +142,14 @@ const HomePage: RouteComponent = () => {
142
142
  <div className="flex items-center justify-center gap-6">
143
143
  <button
144
144
  className="w-12 h-12 rounded-lg bg-slate-800 border border-slate-700 hover:bg-ember-500 hover:border-ember-500 text-ember-500 hover:text-white text-xl transition-all hover:scale-110"
145
- onClick={() => count.value--}
145
+ onClick={() => setCount(c => c - 1)}
146
146
  >
147
147
  &#8722;
148
148
  </button>
149
- <span className="text-5xl font-bold tabular-nums min-w-[80px] bg-clip-text text-transparent bg-gradient-to-b from-white to-slate-400">{count}</span>
149
+ <span className="text-5xl font-bold tabular-nums min-w-[80px] text-amber-400" data-ek-bind={count}>{count()}</span>
150
150
  <button
151
151
  className="w-12 h-12 rounded-lg bg-slate-800 border border-slate-700 hover:bg-ember-500 hover:border-ember-500 text-ember-500 hover:text-white text-xl transition-all hover:scale-110"
152
- onClick={() => count.value++}
152
+ onClick={() => setCount(c => c + 1)}
153
153
  >
154
154
  +
155
155
  </button>
@@ -80,7 +80,7 @@ const Layout: RouteComponent = ({ children }) => {
80
80
  <nav className="flex items-center gap-8">
81
81
  <a href="/" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">Home</a>
82
82
  <a href="/about" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">About</a>
83
- <a href="https://emberkit.dev/docs" target="_blank" rel="noopener noreferrer" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">
83
+ <a href="https://emberkit.orangeember.com" target="_blank" rel="noopener noreferrer" className="text-slate-400 hover:text-ember-500 font-medium transition-colors">
84
84
  Docs <span className="text-xs">&#8599;</span>
85
85
  </a>
86
86
  </nav>
@@ -94,7 +94,7 @@ const Layout: RouteComponent = ({ children }) => {
94
94
  </main>
95
95
 
96
96
  <footer className="relative z-10 border-t border-slate-800/50 py-8 text-center text-sm text-slate-500">
97
- <p>Built with <a href="https://emberkit.dev" className="text-ember-500 hover:underline">EmberKit</a></p>
97
+ <p>Built with <a href="https://emberkit.orangeember.com" className="text-ember-500 hover:underline">EmberKit</a></p>
98
98
  </footer>
99
99
  </div>
100
100
  </>
@@ -103,196 +103,179 @@ const Layout: RouteComponent = ({ children }) => {
103
103
 
104
104
  export default Layout;`,
105
105
  "src/routes/index.tsx": `import type { RouteComponent } from '@emberkit/core';
106
- import { Button, Card, Heading, Text, Badge, Input } from '@emberkit/ui';
107
- import { signal } from '@emberkit/core';
106
+ import { createSignal } from '@emberkit/core';
107
+ import {
108
+ Button,
109
+ Card,
110
+ Heading,
111
+ Text,
112
+ Badge,
113
+ Tabs,
114
+ Alert,
115
+ Icon,
116
+ } from '@emberkit/ui';
108
117
 
109
118
  const HomePage: RouteComponent = () => {
110
- const email = signal('');
111
- const activeTab = signal('buttons');
119
+ const [activeTab, setActiveTab] = createSignal('features');
120
+
121
+ const features = [
122
+ { icon: '⚡', title: 'Lightning Fast', desc: 'Sub-10KB runtime with tree-shakeable architecture' },
123
+ { icon: '📘', title: 'TypeScript First', desc: 'Full type safety with intelligent autocomplete' },
124
+ { icon: '📁', title: 'File-Based Routing', desc: 'Routes automatically created from your file structure' },
125
+ ];
126
+
127
+ const components = [
128
+ { name: 'Button', desc: 'Multiple variants and sizes for all use cases' },
129
+ { name: 'Card', desc: 'Flexible container component with padding options' },
130
+ { name: 'Badge', desc: 'Status indicators with different variants' },
131
+ { name: 'Alert', desc: 'Notification component for important messages' },
132
+ { name: 'Tabs', desc: 'Organized content switching interface' },
133
+ { name: 'Input', desc: 'Styled form input with validation support' },
134
+ ];
112
135
 
113
136
  return (
114
137
  <div className="relative space-y-24">
115
- {/* Hero */}
138
+ {/* Hero Section */}
116
139
  <section className="relative text-center py-20">
117
140
  <div className="pointer-events-none absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 h-[400px] w-[400px] rounded-full bg-ember-500/15 blur-[150px] animate-pulse-glow" />
118
-
119
- <div className="relative z-10 animate-fade-in-down">
120
- <Badge variant="primary" className="mb-6 inline-flex">
121
- &#10024; Built with EmberKit UI
141
+ <div className="relative z-10 space-y-6 animate-fade-in-down">
142
+ <Badge variant="primary" className="inline-block">
143
+ Welcome to {{name}}
122
144
  </Badge>
123
- <Heading level="h1" size="4xl" weight="bold" className="mb-6">
124
- Welcome to{' '}
125
- <span className="bg-gradient-to-r from-ember-400 via-ember-500 to-amber-500 bg-clip-text text-transparent">
126
- {{name}}
127
- </span>
145
+ <Heading level="h1" size="4xl" weight="bold">
146
+ Built with EmberKit <span className="bg-gradient-to-r from-ember-400 via-ember-500 to-amber-500 bg-clip-text text-transparent">UI System</span>
128
147
  </Heading>
129
- <Text size="xl" color="muted" className="max-w-2xl mx-auto mb-10">
130
- A modern starter template with EmberKit UI components and Tailwind CSS.
131
- Build beautiful interfaces with our pre-built component library.
148
+ <Text size="xl" color="muted" className="max-w-2xl mx-auto">
149
+ A modern, component-driven template using the EmberKit design system. Beautiful, accessible, and production-ready.
132
150
  </Text>
133
- <div className="flex gap-4 justify-center flex-wrap">
134
- <Button variant="primary" size="lg" className="shadow-lg shadow-ember-500/20 hover:shadow-ember-500/40 transition-shadow">
151
+ <div className="flex gap-4 justify-center flex-wrap pt-4">
152
+ <Button variant="primary" size="lg">
135
153
  Get Started
136
154
  </Button>
137
155
  <Button variant="secondary" size="lg">
138
- View Docs &#8594;
156
+ View Docs
139
157
  </Button>
140
158
  </div>
141
159
  </div>
142
160
  </section>
143
161
 
144
- {/* Features Grid */}
162
+ {/* Features Grid using Cards */}
145
163
  <section>
146
- <Heading level="h2" size="2xl" weight="semibold" className="mb-2 text-center">
164
+ <Heading level="h2" size="2xl" weight="semibold" className="text-center mb-2">
147
165
  Why EmberKit?
148
166
  </Heading>
149
- <Text color="muted" className="text-center mb-10 max-w-lg mx-auto">
167
+ <Text color="muted" className="text-center mb-12 max-w-lg mx-auto">
150
168
  Everything you need to build fast, beautiful web applications.
151
169
  </Text>
152
170
  <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
153
- {[
154
- { icon: '&#9889;', title: 'Lightning Fast', desc: 'Sub-10KB runtime with tree-shakeable architecture' },
155
- { icon: '&#128303;', title: 'TypeScript First', desc: 'Full type safety with intelligent autocomplete' },
156
- { icon: '&#128726;', title: 'File-Based Routing', desc: 'Routes automatically created from your file structure' },
157
- ].map((f, i) => (
158
- <Card key={f.title} padding="lg" className="relative group hover:border-ember-500/50 transition-all duration-300 hover:-translate-y-1 cursor-pointer">
171
+ {features.map((feature) => (
172
+ <Card key={feature.title} padding="lg" className="relative group hover:border-ember-500/50 transition-all hover:-translate-y-1 cursor-pointer">
159
173
  <div className="absolute inset-0 rounded-xl bg-gradient-to-br from-ember-500/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
160
- <div className="relative">
161
- <div className="w-12 h-12 rounded-xl bg-ember-500/10 flex items-center justify-center text-2xl mb-4 group-hover:scale-110 transition-transform">
162
- {f.icon}
163
- </div>
164
- <Heading level="h3" size="lg" weight="semibold" className="mb-2">
165
- {f.title}
174
+ <div className="relative space-y-3">
175
+ <div className="text-3xl">{feature.icon}</div>
176
+ <Heading level="h3" size="md" weight="semibold">
177
+ {feature.title}
166
178
  </Heading>
167
- <Text color="muted">{f.desc}</Text>
179
+ <Text color="muted" size="sm">
180
+ {feature.desc}
181
+ </Text>
168
182
  </div>
169
183
  </Card>
170
184
  ))}
171
185
  </div>
172
186
  </section>
173
187
 
174
- {/* Component Showcase */}
188
+ {/* Component Showcase with Tabs */}
175
189
  <section>
176
- <Heading level="h2" size="2xl" weight="semibold" className="mb-2 text-center">
177
- UI Components
190
+ <Heading level="h2" size="2xl" weight="semibold" className="text-center mb-2">
191
+ Design System Components
178
192
  </Heading>
179
- <Text color="muted" className="text-center mb-8">
180
- Explore our pre-built component library.
193
+ <Text color="muted" className="text-center mb-8 max-w-lg mx-auto">
194
+ Pre-built, accessible components ready to use in your project.
181
195
  </Text>
182
196
 
183
- {/* Tabs */}
184
- <div className="flex justify-center mb-8">
185
- <div className="inline-flex p-1 rounded-lg bg-slate-800/50 border border-slate-700/50">
186
- {[
187
- { id: 'buttons', label: 'Buttons' },
188
- { id: 'cards', label: 'Cards' },
189
- { id: 'forms', label: 'Forms' },
190
- ].map((tab) => (
191
- <button
192
- key={tab.id}
193
- className={\`px-4 py-2 text-sm font-medium rounded-md transition-all \${activeTab.value === tab.id ? 'bg-ember-500 text-white shadow-md' : 'text-slate-400 hover:text-slate-200'}\`}
194
- onClick={() => { activeTab.value = tab.id; }}
195
- >
196
- {tab.label}
197
- </button>
198
- ))}
199
- </div>
200
- </div>
201
-
202
- {/* Tab Content */}
203
- {activeTab.value === 'buttons' && (
204
- <Card padding="xl" className="max-w-2xl mx-auto">
205
- <div className="text-center mb-6">
206
- <Badge variant="primary" className="mb-2">Buttons</Badge>
207
- <Heading level="h3" size="lg" weight="semibold">Button Variants</Heading>
208
- </div>
209
- <div className="flex flex-wrap gap-3 justify-center">
210
- <Button variant="primary">Primary</Button>
211
- <Button variant="secondary">Secondary</Button>
212
- <Button variant="ghost">Ghost</Button>
213
- <Button variant="primary" size="sm">Small</Button>
214
- <Button variant="secondary" size="lg">Large</Button>
215
- </div>
216
- <div className="mt-6 pt-6 border-t border-slate-700/50">
217
- <Heading level="h4" size="sm" weight="semibold" className="mb-3 text-slate-400">With Icons</Heading>
218
- <div className="flex flex-wrap gap-3 justify-center">
219
- <Button variant="primary">&#9889; Get Started</Button>
220
- <Button variant="secondary">Learn More &#8594;</Button>
221
- <Button variant="ghost">&#10084; Like</Button>
197
+ <div className="space-y-8">
198
+ {/* Buttons Section */}
199
+ <Card padding="xl">
200
+ <Heading level="h3" size="lg" weight="semibold" className="mb-6">
201
+ Button Component
202
+ </Heading>
203
+ <div className="space-y-4">
204
+ <Text color="muted" size="sm">
205
+ The Button component comes in multiple variants and sizes for different use cases.
206
+ </Text>
207
+ <div className="flex flex-wrap gap-2 pt-4">
208
+ <Button variant="primary">Primary</Button>
209
+ <Button variant="secondary">Secondary</Button>
210
+ <Button variant="ghost">Ghost</Button>
211
+ <Button variant="primary" size="sm">Small</Button>
212
+ <Button variant="secondary" size="lg">Large</Button>
222
213
  </div>
223
214
  </div>
224
215
  </Card>
225
- )}
226
-
227
- {activeTab.value === 'cards' && (
228
- <div className="grid md:grid-cols-2 gap-6 max-w-3xl mx-auto">
229
- <Card padding="lg" className="hover:border-ember-500/50 transition-colors">
230
- <Badge variant="success" className="mb-3">Analytics</Badge>
231
- <Heading level="h3" size="lg" weight="semibold" className="mb-2">
232
- Revenue Growth
233
- </Heading>
234
- <div className="text-3xl font-bold text-ember-400 mb-1">$45,231</div>
235
- <Text color="muted" className="text-sm">+20.1% from last month</Text>
236
- <div className="mt-4 h-2 rounded-full bg-slate-700 overflow-hidden">
237
- <div className="h-full w-3/4 rounded-full bg-gradient-to-r from-ember-500 to-amber-500" />
238
- </div>
239
- </Card>
240
- <Card padding="lg" className="hover:border-ember-500/50 transition-colors">
241
- <Badge variant="info" className="mb-3">Users</Badge>
242
- <Heading level="h3" size="lg" weight="semibold" className="mb-2">
243
- Active Users
244
- </Heading>
245
- <div className="text-3xl font-bold text-blue-400 mb-1">2,338</div>
246
- <Text color="muted" className="text-sm">+15.3% from last month</Text>
247
- <div className="mt-4 h-2 rounded-full bg-slate-700 overflow-hidden">
248
- <div className="h-full w-1/2 rounded-full bg-gradient-to-r from-blue-500 to-cyan-500" />
249
- </div>
250
- </Card>
251
- </div>
252
- )}
253
216
 
254
- {activeTab.value === 'forms' && (
255
- <Card padding="xl" className="max-w-md mx-auto">
256
- <div className="text-center mb-6">
257
- <Badge variant="info" className="mb-2">Forms</Badge>
258
- <Heading level="h3" size="lg" weight="semibold">Newsletter Signup</Heading>
217
+ {/* Badge & Alert Section */}
218
+ <Card padding="xl">
219
+ <Heading level="h3" size="lg" weight="semibold" className="mb-6">
220
+ Status Components
221
+ </Heading>
222
+ <div className="space-y-6">
223
+ <div>
224
+ <Text weight="semibold" className="mb-3">Badges</Text>
225
+ <div className="flex flex-wrap gap-2">
226
+ <Badge variant="primary">Primary</Badge>
227
+ <Badge variant="success">Success</Badge>
228
+ <Badge variant="warning">Warning</Badge>
229
+ <Badge variant="info">Info</Badge>
230
+ </div>
231
+ </div>
232
+ <Alert variant="success">
233
+ ✓ This is a success alert message. Use it to confirm important actions.
234
+ </Alert>
235
+ <Alert variant="info">
236
+ ℹ This is an info alert. Useful for displaying helpful information.
237
+ </Alert>
259
238
  </div>
260
- <div className="space-y-4">
261
- <Input
262
- label="Name"
263
- placeholder="John Doe"
264
- />
265
- <Input
266
- label="Email"
267
- type="email"
268
- placeholder="you@example.com"
269
- value={email.value}
270
- onChange={(e) => { email.value = e.currentTarget.value; }}
271
- />
272
- <Button variant="primary" className="w-full shadow-lg shadow-ember-500/20">
273
- Subscribe &#10148;
274
- </Button>
239
+ </Card>
240
+
241
+ {/* Components Grid */}
242
+ <Card padding="xl">
243
+ <Heading level="h3" size="lg" weight="semibold" className="mb-6">
244
+ Available Components
245
+ </Heading>
246
+ <div className="grid md:grid-cols-2 gap-4">
247
+ {components.map((comp) => (
248
+ <div key={comp.name} className="p-4 rounded-lg bg-slate-800/30 border border-slate-700/50">
249
+ <Text weight="semibold" size="sm">{comp.name}</Text>
250
+ <Text color="muted" size="xs" className="mt-1">{comp.desc}</Text>
251
+ </div>
252
+ ))}
275
253
  </div>
276
254
  </Card>
277
- )}
255
+ </div>
278
256
  </section>
279
257
 
280
- {/* CTA */}
258
+ {/* CTA Section */}
281
259
  <section className="relative py-20">
282
260
  <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
283
261
  <div className="w-[500px] h-[200px] rounded-full bg-ember-500/10 blur-[100px]" />
284
262
  </div>
285
- <div className="relative z-10 text-center">
263
+ <Card padding="xl" className="relative z-10 max-w-2xl mx-auto text-center">
286
264
  <Heading level="h2" size="2xl" weight="semibold" className="mb-4">
287
- Ready to build something amazing?
265
+ Ready to Build?
288
266
  </Heading>
289
- <Text color="muted" className="max-w-xl mx-auto mb-8">
267
+ <Text color="muted" className="mb-8">
290
268
  Start building your next project with EmberKit's powerful components and TypeScript-first API.
291
269
  </Text>
292
- <Button variant="primary" size="lg" className="shadow-lg shadow-ember-500/25 hover:shadow-ember-500/40 transition-shadow">
293
- Create Project &#10148;
294
- </Button>
295
- </div>
270
+ <div className="flex gap-4 justify-center">
271
+ <Button variant="primary" size="lg">
272
+ Create Project →
273
+ </Button>
274
+ <Button variant="secondary" size="lg">
275
+ Learn More
276
+ </Button>
277
+ </div>
278
+ </Card>
296
279
  </section>
297
280
  </div>
298
281
  );
@@ -301,9 +284,18 @@ const HomePage: RouteComponent = () => {
301
284
  export default HomePage;`,
302
285
  "src/routes/about.tsx": `import type { RouteComponent } from '@emberkit/core';
303
286
  import { Head } from '@emberkit/core';
304
- import { Heading, Text, Button, Card, Badge } from '@emberkit/ui';
287
+ import { Heading, Text, Button, Card, Badge, Alert } from '@emberkit/ui';
305
288
 
306
289
  const AboutPage: RouteComponent = () => {
290
+ const features = [
291
+ { icon: '⚙️', title: 'TypeScript-first', desc: 'Full type safety with intelligent autocomplete' },
292
+ { icon: '🎨', title: 'UI Components', desc: 'Pre-built design system components' },
293
+ { icon: '🎯', title: 'Tailwind CSS', desc: 'Utility-first styling framework' },
294
+ { icon: '📁', title: 'File Routing', desc: 'Automatic routes from file structure' },
295
+ ];
296
+
297
+ const techStack = ['EmberKit', 'TypeScript', 'Tailwind CSS', 'Vite', 'JSX', 'Design System'];
298
+
307
299
  return (
308
300
  <>
309
301
  <Head>
@@ -311,59 +303,69 @@ const AboutPage: RouteComponent = () => {
311
303
  </Head>
312
304
  <div className="max-w-3xl mx-auto space-y-12">
313
305
  {/* Header */}
314
- <div className="text-center">
315
- <Badge variant="primary" className="mb-4 inline-flex">About</Badge>
306
+ <div className="text-center space-y-4">
307
+ <Badge variant="primary" className="inline-block">
308
+ About Us
309
+ </Badge>
316
310
  <Heading level="h1" size="3xl" weight="bold">
317
- About {' '}
318
- <span className="bg-gradient-to-r from-ember-400 to-ember-600 bg-clip-text text-transparent">{{name}}</span>
311
+ About <span className="bg-gradient-to-r from-ember-400 to-ember-600 bg-clip-text text-transparent">{{name}}</span>
319
312
  </Heading>
313
+ <Text size="lg" color="muted" className="max-w-2xl mx-auto">
314
+ A modern, component-driven project built with EmberKit and the UI design system.
315
+ </Text>
320
316
  </div>
321
317
 
322
- {/* Description */}
318
+ {/* Description Card */}
323
319
  <Card padding="xl" className="border-ember-500/20">
324
320
  <Text size="lg" color="muted" className="leading-relaxed">
325
- This project was created with EmberKit and the UI component library.
326
- It demonstrates how to build modern, beautiful interfaces with our
327
- pre-built components and Tailwind CSS.
321
+ This project demonstrates how to build modern, beautiful interfaces with EmberKit's pre-built components and Tailwind CSS.
322
+ It showcases best practices in component-driven development, accessible design, and TypeScript-first architecture.
328
323
  </Text>
329
324
  </Card>
330
325
 
331
- {/* Features */}
332
- <div className="grid sm:grid-cols-2 gap-4">
333
- {[
334
- { icon: '&#128268;', title: 'TypeScript-first', desc: 'Full type safety with intelligent autocomplete' },
335
- { icon: '&#127912;', title: 'UI Components', desc: 'Pre-built atoms, molecules, and organisms' },
336
- { icon: '&#127752;', title: 'Tailwind CSS', desc: 'Utility-first styling with custom theme' },
337
- { icon: '&#128726;', title: 'File Routing', desc: 'Automatic routes from your file structure' },
338
- ].map((f) => (
339
- <Card key={f.title} padding="lg" className="hover:border-ember-500/50 transition-all hover:-translate-y-0.5">
340
- <div className="text-2xl mb-3">{f.icon}</div>
341
- <Heading level="h3" size="md" weight="semibold" className="mb-1">
342
- {f.title}
343
- </Heading>
344
- <Text color="muted" size="sm">{f.desc}</Text>
345
- </Card>
346
- ))}
347
- </div>
348
-
349
- {/* Tech Stack */}
350
- <Card padding="xl">
351
- <Heading level="h3" size="lg" weight="semibold" className="mb-4 text-center">
352
- Tech Stack
326
+ {/* Features Grid */}
327
+ <section>
328
+ <Heading level="h2" size="xl" weight="semibold" className="mb-6">
329
+ Key Features
353
330
  </Heading>
354
- <div className="flex flex-wrap gap-2 justify-center">
355
- {['EmberKit', 'TypeScript', 'Tailwind CSS', 'Vite', 'JSX'].map((tech) => (
356
- <Badge key={tech} variant="primary" className="px-3 py-1.5">
357
- {tech}
358
- </Badge>
331
+ <div className="grid sm:grid-cols-2 gap-4">
332
+ {features.map((f) => (
333
+ <Card key={f.title} padding="lg" className="hover:border-ember-500/50 transition-all hover:-translate-y-0.5">
334
+ <div className="text-2xl mb-3">{f.icon}</div>
335
+ <Heading level="h3" size="md" weight="semibold" className="mb-1">
336
+ {f.title}
337
+ </Heading>
338
+ <Text color="muted" size="sm">{f.desc}</Text>
339
+ </Card>
359
340
  ))}
360
341
  </div>
361
- </Card>
342
+ </section>
343
+
344
+ {/* Tech Stack */}
345
+ <section>
346
+ <Card padding="xl">
347
+ <Heading level="h3" size="lg" weight="semibold" className="mb-6 text-center">
348
+ Tech Stack
349
+ </Heading>
350
+ <div className="flex flex-wrap gap-2 justify-center">
351
+ {techStack.map((tech) => (
352
+ <Badge key={tech} variant="primary" className="px-3 py-1.5">
353
+ {tech}
354
+ </Badge>
355
+ ))}
356
+ </div>
357
+ </Card>
358
+ </section>
359
+
360
+ {/* Benefits Alert */}
361
+ <Alert variant="success">
362
+ ✨ <strong>Pro Tip:</strong> This template uses the EmberKit design system components. Check the component library documentation to learn about all available components and their capabilities.
363
+ </Alert>
362
364
 
363
- {/* Back */}
364
- <div className="text-center">
365
+ {/* Back Button */}
366
+ <div className="text-center pt-4">
365
367
  <Button variant="secondary">
366
- &#8592; Back to Home
368
+ Back to Home
367
369
  </Button>
368
370
  </div>
369
371
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emberkit/cli",
3
- "version": "0.6.1-alpha.1",
3
+ "version": "0.6.1-alpha.11",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "CLI tool for EmberKit projects",