@zessjs/cli 1.0.0

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.
@@ -0,0 +1,85 @@
1
+ import { Match, Show, Switch, useMemo, useSignal } from '@zessjs/core'
2
+ import { Link } from '@zessjs/router'
3
+
4
+ const ConditionalPage = () => {
5
+ const [count, setCount] = useSignal(0)
6
+ const status = useMemo(() => {
7
+ const currentCount = count()
8
+ if (currentCount > 10) return 'success'
9
+ if (currentCount > 5) return 'warning'
10
+ return 'info'
11
+ })
12
+
13
+ return (
14
+ <div class="w-full text-center pb-8">
15
+ <header class="mb-8">
16
+ <h1 class="text-2xl font-bold mb-2">Conditional Rendering</h1>
17
+ <p class="text-gray-600">
18
+ This demonstrates Zess's conditional rendering components
19
+ </p>
20
+ </header>
21
+ <div class="flex justify-center items-center gap-4 mb-8">
22
+ <button
23
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
24
+ onClick={() => setCount((prevCount) => Math.max(0, prevCount - 1))}
25
+ >
26
+ -
27
+ </button>
28
+ <span class="text-3xl font-bold min-w-16">{count()}</span>
29
+ <button
30
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
31
+ onClick={() => setCount((prevCount) => prevCount + 1)}
32
+ >
33
+ +
34
+ </button>
35
+ </div>
36
+ <div class="mb-8 space-y-4 max-w-md mx-auto">
37
+ <div class="p-4 border border-gray-200 rounded bg-white">
38
+ <h3 class="text-lg font-semibold mb-2">Using Show Component</h3>
39
+ {/* Show component renders content conditionally based on the 'when' prop */}
40
+ {/* Falls back to the fallback content when condition is false */}
41
+ <Show
42
+ when={count() > 5}
43
+ fallback={
44
+ <p class="text-gray-600">Count is less than or equal to 5</p>
45
+ }
46
+ >
47
+ <p class="text-green-600 font-medium">
48
+ Count is greater than 5! 🎉
49
+ </p>
50
+ </Show>
51
+ </div>
52
+ <div class="p-4 border border-gray-200 rounded bg-white">
53
+ <h3 class="text-lg font-semibold mb-2">
54
+ Using {'<Switch>'} and {'<Match>'}
55
+ </h3>
56
+ {/* Switch component acts like a switch statement for rendering */}
57
+ {/* Only the first matching Match component within Switch is rendered */}
58
+ <Switch>
59
+ <Match when={status() === 'success'}>
60
+ <p class="text-green-600 font-medium">Status: Success</p>
61
+ </Match>
62
+ <Match when={status() === 'warning'}>
63
+ <p class="text-yellow-600 font-medium">Status: Warning</p>
64
+ </Match>
65
+ <Match when={status() === 'info'}>
66
+ <p class="text-blue-600 font-medium">Status: Info</p>
67
+ </Match>
68
+ </Switch>
69
+ </div>
70
+ </div>
71
+ <div>
72
+ {/* Link back to home page */}
73
+ <Link
74
+ to="/"
75
+ relative={false}
76
+ class="inline-block px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
77
+ >
78
+ Back to Home
79
+ </Link>
80
+ </div>
81
+ </div>
82
+ )
83
+ }
84
+
85
+ export default ConditionalPage
@@ -0,0 +1,50 @@
1
+ import { useMemo, useSignal } from '@zessjs/core'
2
+ import { Link } from '@zessjs/router'
3
+
4
+ const CounterPage = () => {
5
+ const [count, setCount] = useSignal(0)
6
+ const doubleCount = useMemo(() => count() * 2)
7
+
8
+ return (
9
+ <div class="w-full text-center pb-8">
10
+ <header class="mb-8">
11
+ <h1 class="text-2xl font-bold mb-2">Counter Example</h1>
12
+ <p class="text-gray-600">
13
+ This is a simple counter demonstrating Zess's signal system
14
+ </p>
15
+ </header>
16
+ <div class="flex justify-center items-center gap-4 mb-8">
17
+ <button
18
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
19
+ onClick={() => setCount((prevCount) => prevCount - 1)}
20
+ >
21
+ -
22
+ </button>
23
+ <span class="text-3xl font-bold min-w-16">{count()}</span>
24
+ <button
25
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
26
+ onClick={() => setCount((prevCount) => prevCount + 1)}
27
+ >
28
+ +
29
+ </button>
30
+ </div>
31
+ <div class="mb-8">
32
+ <p class="text-gray-700">
33
+ Double the count is: <strong>{doubleCount()}</strong>
34
+ </p>
35
+ </div>
36
+ <div>
37
+ {/* Link back to home page */}
38
+ <Link
39
+ to="/"
40
+ relative={false}
41
+ class="inline-block px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
42
+ >
43
+ Back to Home
44
+ </Link>
45
+ </div>
46
+ </div>
47
+ )
48
+ }
49
+
50
+ export default CounterPage
@@ -0,0 +1,43 @@
1
+ import { Link } from '@zessjs/router'
2
+
3
+ const HomePage = () => (
4
+ <div class="w-full text-center pb-8">
5
+ <section>
6
+ <h2 class="text-2xl font-semibold mb-6">Explore Examples</h2>
7
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
8
+ {/* Counter example card - links to counter page */}
9
+ <Link
10
+ to="counter"
11
+ class="block p-4 border border-gray-200 rounded hover:border-indigo-500 transition-all bg-white"
12
+ >
13
+ <h3 class="text-lg font-medium mb-2">Counter Example</h3>
14
+ <p class="text-sm text-gray-600">
15
+ Signal system and reactive updates
16
+ </p>
17
+ </Link>
18
+ {/* List example card - links to list page */}
19
+ <Link
20
+ to="list"
21
+ class="block p-4 border border-gray-200 rounded hover:border-purple-500 transition-all bg-white"
22
+ >
23
+ <h3 class="text-lg font-medium mb-2">List Example</h3>
24
+ <p class="text-sm text-gray-600">
25
+ Render lists and handle user input
26
+ </p>
27
+ </Link>
28
+ {/* Conditional rendering example card - links to conditional page */}
29
+ <Link
30
+ to="conditional"
31
+ class="block p-4 border border-gray-200 rounded hover:border-pink-500 transition-all bg-white"
32
+ >
33
+ <h3 class="text-lg font-medium mb-2">Conditional Rendering</h3>
34
+ <p class="text-sm text-gray-600">
35
+ {'<Show>'} and {'<Switch>'} components
36
+ </p>
37
+ </Link>
38
+ </div>
39
+ </section>
40
+ </div>
41
+ )
42
+
43
+ export default HomePage
@@ -0,0 +1,83 @@
1
+ import { For, Show, useSignal } from '@zessjs/core'
2
+ import { Link } from '@zessjs/router'
3
+
4
+ const ListPage = () => {
5
+ const [items, setItems] = useSignal([
6
+ 'Zess Compiler',
7
+ 'Zess Core',
8
+ 'Zess Router',
9
+ ])
10
+ const [newItem, setNewItem] = useSignal('')
11
+ const addItem = () => {
12
+ const item = newItem().trim()
13
+ if (item) {
14
+ setItems((prevItems) => [...prevItems, item])
15
+ setNewItem('')
16
+ }
17
+ }
18
+ const handleKeyPress = (e) => {
19
+ if (e.key === 'Enter') addItem()
20
+ }
21
+
22
+ return (
23
+ <div class="w-full text-center pb-8">
24
+ <header class="mb-8">
25
+ <h1 class="text-2xl font-bold mb-2">List Example</h1>
26
+ <p class="text-gray-600">
27
+ This shows how to render lists with {'<For>'} component
28
+ </p>
29
+ </header>
30
+ <div class="mb-8">
31
+ <div class="flex flex-col sm:flex-row gap-2 justify-center">
32
+ <input
33
+ type="text"
34
+ value={newItem()}
35
+ onInput={(e) => setNewItem(e.target.value)}
36
+ onKeyPress={handleKeyPress}
37
+ placeholder="Enter new item..."
38
+ class="px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-indigo-500"
39
+ />
40
+ <button
41
+ onClick={addItem}
42
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
43
+ >
44
+ Add Item
45
+ </button>
46
+ </div>
47
+ </div>
48
+ <div class="mb-8">
49
+ {/* Conditionally render the list or an empty state message */}
50
+ <Show
51
+ when={items().length > 0}
52
+ fallback={<p class="text-gray-500 py-4">No items in the list yet.</p>}
53
+ >
54
+ <ul class="space-y-2 max-w-md mx-auto">
55
+ {/* Zess For component for efficiently rendering lists */}
56
+ <For each={items()}>
57
+ {(item, index) => (
58
+ <li class="flex items-center p-2 border-b border-gray-200 bg-white">
59
+ <span class="mr-2 text-gray-500 font-medium">
60
+ {index() + 1}.
61
+ </span>
62
+ <span class="text-left flex-1">{item}</span>
63
+ </li>
64
+ )}
65
+ </For>
66
+ </ul>
67
+ </Show>
68
+ </div>
69
+ <div>
70
+ {/* Link back to home page */}
71
+ <Link
72
+ to="/"
73
+ relative={false}
74
+ class="inline-block px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
75
+ >
76
+ Back to Home
77
+ </Link>
78
+ </div>
79
+ </div>
80
+ )
81
+ }
82
+
83
+ export default ListPage
@@ -0,0 +1,15 @@
1
+ import { render } from '@zessjs/core'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ function HelloWorld() {
5
+ return <div>Hello World</div>
6
+ }
7
+
8
+ describe('HelloWorld', () => {
9
+ it('should render a <HelloWorld> component', () => {
10
+ const container = document.createElement('div')
11
+ const dispose = render(() => <HelloWorld />, container)
12
+ expect(container.textContent).toBe('Hello World')
13
+ dispose()
14
+ })
15
+ })
@@ -0,0 +1,11 @@
1
+ import tailwindcss from '@tailwindcss/vite'
2
+ import zess from '@zessjs/vite-plugin'
3
+ import { defineConfig } from 'vite'
4
+
5
+ export default defineConfig({
6
+ plugins: [tailwindcss(), zess()],
7
+ test: {
8
+ environment: 'jsdom',
9
+ include: ['./tests/*.test.{js,jsx}'],
10
+ },
11
+ })
@@ -0,0 +1,2 @@
1
+ import { sxzz } from '@sxzz/eslint-config'
2
+ export default sxzz()
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/svg+xml" href="/zess.svg" />
7
+ <title>Zess App</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/App.tsx"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,101 @@
1
+ import { render, type Component } from '@zessjs/core'
2
+ import { Link, Route, Router } from '@zessjs/router'
3
+ import viteLogo from './assets/vite.svg'
4
+ import ConditionalPage from './pages/ConditionalPage'
5
+ import CounterPage from './pages/CounterPage'
6
+ import HomePage from './pages/HomePage'
7
+ import ListPage from './pages/ListPage'
8
+ import './assets/style.css'
9
+ import zessLogo from '/zess.svg'
10
+
11
+ const AppLayout: Component<{ children?: JSX.Element }> = (props) => (
12
+ <div class="min-h-screen flex flex-col items-center bg-gradient-to-br from-blue-100 via-white to-yellow-100">
13
+ <nav class="w-full py-4 flex justify-center">
14
+ <div class="flex space-x-6 md:space-x-8">
15
+ {/* Home page link - active when at root URL */}
16
+ <Link
17
+ end
18
+ to="/"
19
+ class="text-gray-700 hover:text-indigo-600 transition-all duration-200"
20
+ activeClass="text-indigo-600 font-semibold"
21
+ >
22
+ Home
23
+ </Link>
24
+ {/* Counter page link */}
25
+ <Link
26
+ end
27
+ to="counter"
28
+ class="text-gray-700 hover:text-indigo-600 transition-all duration-200"
29
+ activeClass="text-indigo-600 font-semibold"
30
+ >
31
+ Counter
32
+ </Link>
33
+ {/* List page link */}
34
+ <Link
35
+ end
36
+ to="list"
37
+ class="text-gray-700 hover:text-indigo-600 transition-all duration-200"
38
+ activeClass="text-indigo-600 font-semibold"
39
+ >
40
+ List
41
+ </Link>
42
+ {/* Conditional page link */}
43
+ <Link
44
+ end
45
+ to="conditional"
46
+ class="text-gray-700 hover:text-indigo-600 transition-all duration-200"
47
+ activeClass="text-indigo-600 font-semibold"
48
+ >
49
+ Conditional
50
+ </Link>
51
+ </div>
52
+ </nav>
53
+ <div class="flex flex-col md:flex-row items-center justify-center my-8 md:my-12 space-y-4 md:space-y-0 md:space-x-12">
54
+ <img
55
+ src={zessLogo}
56
+ class="h-32 md:h-40 transition-all duration-300 hover:drop-shadow-[0_0_2em_#646cffaa]"
57
+ alt="Zess logo"
58
+ />
59
+ <img
60
+ src={viteLogo}
61
+ class="h-32 md:h-40 transition-all duration-300 hover:drop-shadow-[0_0_2em_#646cffaa]"
62
+ alt="Vite logo"
63
+ />
64
+ </div>
65
+ <h1 class="text-5xl md:text-6xl font-bold mb-8 md:mb-12">Hello Zess!</h1>
66
+ <main class="w-full max-w-4xl px-4 pb-12">{props.children}</main>
67
+ </div>
68
+ )
69
+
70
+ const ZessApp: Component = () => (
71
+ <Router root={AppLayout} mode="history">
72
+ {/* Route for Home page */}
73
+ <Route path="/" component={HomePage} />
74
+ {/* Route for Counter page */}
75
+ <Route path="counter" component={CounterPage} />
76
+ {/* Route for List page */}
77
+ <Route path="list" component={ListPage} />
78
+ {/* Route for Conditional page */}
79
+ <Route path="conditional" component={ConditionalPage} />
80
+ {/* Catch-all route for 404 page not found */}
81
+ <Route
82
+ path="*"
83
+ component={() => (
84
+ <div class="text-center py-16">
85
+ <h1 class="text-4xl font-bold mb-4">404</h1>
86
+ <p class="text-xl text-gray-600 mb-8">Page not found</p>
87
+ {/* Link to home page */}
88
+ <Link
89
+ to="/"
90
+ relative={false}
91
+ class="inline-block px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white rounded transition-all"
92
+ >
93
+ Go back to Home
94
+ </Link>
95
+ </div>
96
+ )}
97
+ />
98
+ </Router>
99
+ )
100
+
101
+ render(() => <ZessApp />, document.querySelector('#app')!)
@@ -0,0 +1,92 @@
1
+ import {
2
+ Match,
3
+ Show,
4
+ Switch,
5
+ useMemo,
6
+ useSignal,
7
+ type Component,
8
+ } from '@zessjs/core'
9
+ import { Link } from '@zessjs/router'
10
+
11
+ const ConditionalPage: Component = () => {
12
+ const [count, setCount] = useSignal(0)
13
+ const status = useMemo(() => {
14
+ const currentCount = count()
15
+ if (currentCount > 10) return 'success'
16
+ if (currentCount > 5) return 'warning'
17
+ return 'info'
18
+ })
19
+
20
+ return (
21
+ <div class="w-full text-center pb-8">
22
+ <header class="mb-8">
23
+ <h1 class="text-2xl font-bold mb-2">Conditional Rendering</h1>
24
+ <p class="text-gray-600">
25
+ This demonstrates Zess's conditional rendering components
26
+ </p>
27
+ </header>
28
+ <div class="flex justify-center items-center gap-4 mb-8">
29
+ <button
30
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
31
+ onClick={() => setCount((prevCount) => Math.max(0, prevCount - 1))}
32
+ >
33
+ -
34
+ </button>
35
+ <span class="text-3xl font-bold min-w-16">{count()}</span>
36
+ <button
37
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
38
+ onClick={() => setCount((prevCount) => prevCount + 1)}
39
+ >
40
+ +
41
+ </button>
42
+ </div>
43
+ <div class="mb-8 space-y-4 max-w-md mx-auto">
44
+ <div class="p-4 border border-gray-200 rounded bg-white">
45
+ <h3 class="text-lg font-semibold mb-2">Using Show Component</h3>
46
+ {/* Show component renders content conditionally based on the 'when' prop */}
47
+ {/* Falls back to the fallback content when condition is false */}
48
+ <Show
49
+ when={count() > 5}
50
+ fallback={
51
+ <p class="text-gray-600">Count is less than or equal to 5</p>
52
+ }
53
+ >
54
+ <p class="text-green-600 font-medium">
55
+ Count is greater than 5! 🎉
56
+ </p>
57
+ </Show>
58
+ </div>
59
+ <div class="p-4 border border-gray-200 rounded bg-white">
60
+ <h3 class="text-lg font-semibold mb-2">
61
+ Using {'<Switch>'} and {'<Match>'}
62
+ </h3>
63
+ {/* Switch component acts like a switch statement for rendering */}
64
+ {/* Only the first matching Match component within Switch is rendered */}
65
+ <Switch>
66
+ <Match when={status() === 'success'}>
67
+ <p class="text-green-600 font-medium">Status: Success</p>
68
+ </Match>
69
+ <Match when={status() === 'warning'}>
70
+ <p class="text-yellow-600 font-medium">Status: Warning</p>
71
+ </Match>
72
+ <Match when={status() === 'info'}>
73
+ <p class="text-blue-600 font-medium">Status: Info</p>
74
+ </Match>
75
+ </Switch>
76
+ </div>
77
+ </div>
78
+ <div>
79
+ {/* Link back to home page */}
80
+ <Link
81
+ to="/"
82
+ relative={false}
83
+ class="inline-block px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
84
+ >
85
+ Back to Home
86
+ </Link>
87
+ </div>
88
+ </div>
89
+ )
90
+ }
91
+
92
+ export default ConditionalPage
@@ -0,0 +1,50 @@
1
+ import { useMemo, useSignal, type Component } from '@zessjs/core'
2
+ import { Link } from '@zessjs/router'
3
+
4
+ const CounterPage: Component = () => {
5
+ const [count, setCount] = useSignal(0)
6
+ const doubleCount = useMemo(() => count() * 2)
7
+
8
+ return (
9
+ <div class="w-full text-center pb-8">
10
+ <header class="mb-8">
11
+ <h1 class="text-2xl font-bold mb-2">Counter Example</h1>
12
+ <p class="text-gray-600">
13
+ This is a simple counter demonstrating Zess's signal system
14
+ </p>
15
+ </header>
16
+ <div class="flex justify-center items-center gap-4 mb-8">
17
+ <button
18
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
19
+ onClick={() => setCount((prevCount) => prevCount - 1)}
20
+ >
21
+ -
22
+ </button>
23
+ <span class="text-3xl font-bold min-w-16">{count()}</span>
24
+ <button
25
+ class="px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
26
+ onClick={() => setCount((prevCount) => prevCount + 1)}
27
+ >
28
+ +
29
+ </button>
30
+ </div>
31
+ <div class="mb-8">
32
+ <p class="text-gray-700">
33
+ Double the count is: <strong>{doubleCount()}</strong>
34
+ </p>
35
+ </div>
36
+ <div>
37
+ {/* Link back to home page */}
38
+ <Link
39
+ to="/"
40
+ relative={false}
41
+ class="inline-block px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded transition-all"
42
+ >
43
+ Back to Home
44
+ </Link>
45
+ </div>
46
+ </div>
47
+ )
48
+ }
49
+
50
+ export default CounterPage
@@ -0,0 +1,44 @@
1
+ import { Link } from '@zessjs/router'
2
+ import type { Component } from '@zessjs/core'
3
+
4
+ const HomePage: Component = () => (
5
+ <div class="w-full text-center pb-8">
6
+ <section>
7
+ <h2 class="text-2xl font-semibold mb-6">Explore Examples</h2>
8
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
9
+ {/* Counter example card - links to counter page */}
10
+ <Link
11
+ to="counter"
12
+ class="block p-4 border border-gray-200 rounded hover:border-indigo-500 transition-all bg-white"
13
+ >
14
+ <h3 class="text-lg font-medium mb-2">Counter Example</h3>
15
+ <p class="text-sm text-gray-600">
16
+ Signal system and reactive updates
17
+ </p>
18
+ </Link>
19
+ {/* List example card - links to list page */}
20
+ <Link
21
+ to="list"
22
+ class="block p-4 border border-gray-200 rounded hover:border-purple-500 transition-all bg-white"
23
+ >
24
+ <h3 class="text-lg font-medium mb-2">List Example</h3>
25
+ <p class="text-sm text-gray-600">
26
+ Render lists and handle user input
27
+ </p>
28
+ </Link>
29
+ {/* Conditional rendering example card - links to conditional page */}
30
+ <Link
31
+ to="conditional"
32
+ class="block p-4 border border-gray-200 rounded hover:border-pink-500 transition-all bg-white"
33
+ >
34
+ <h3 class="text-lg font-medium mb-2">Conditional Rendering</h3>
35
+ <p class="text-sm text-gray-600">
36
+ {'<Show>'} and {'<Switch>'} components
37
+ </p>
38
+ </Link>
39
+ </div>
40
+ </section>
41
+ </div>
42
+ )
43
+
44
+ export default HomePage