@itayzrihan/create-box-app 1.0.0 → 1.0.1
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/package.json +1 -1
- package/template/.vscode/extensions.json +13 -0
- package/template/.vscode/launch.json +25 -0
- package/template/.vscode/settings.json +33 -0
- package/template/README.md +152 -3
- package/template/assets/README.md +26 -0
- package/template/package.json +7 -5
- package/template/src/api+echo.box +40 -0
- package/template/src/api+hello.box +29 -3
- package/template/src/api-demo.box +79 -0
- package/template/src/counter.box +136 -0
- package/template/src/learning-guide.box +208 -0
- package/template/src/main.box +74 -1
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommendations": [
|
|
3
|
+
"bradlc.vscode-tailwindcss",
|
|
4
|
+
"formulahendry.auto-rename-tag",
|
|
5
|
+
"formulahendry.auto-close-tag",
|
|
6
|
+
"christian-kohler.path-intellisense",
|
|
7
|
+
"pranaygp.vscode-css-peek",
|
|
8
|
+
"zignd.html-css-class-completion",
|
|
9
|
+
"ecmel.vscode-html-css",
|
|
10
|
+
"ritwickdey.liveserver"
|
|
11
|
+
],
|
|
12
|
+
"unwantedRecommendations": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "BOX Dev Server",
|
|
6
|
+
"type": "node",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"runtimeExecutable": "npm",
|
|
9
|
+
"runtimeArgs": ["run", "dev"],
|
|
10
|
+
"cwd": "${workspaceFolder}",
|
|
11
|
+
"console": "integratedTerminal",
|
|
12
|
+
"skipFiles": ["<node_internals>/**"]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "BOX Production Server",
|
|
16
|
+
"type": "node",
|
|
17
|
+
"request": "launch",
|
|
18
|
+
"program": "${workspaceFolder}/dist/server.js",
|
|
19
|
+
"cwd": "${workspaceFolder}",
|
|
20
|
+
"preLaunchTask": "npm: build",
|
|
21
|
+
"console": "integratedTerminal",
|
|
22
|
+
"skipFiles": ["<node_internals>/**"]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -1,11 +1,44 @@
|
|
|
1
1
|
{
|
|
2
|
+
// Associate .box files with HTML for syntax highlighting
|
|
2
3
|
"files.associations": {
|
|
3
4
|
"*.box": "html"
|
|
4
5
|
},
|
|
6
|
+
|
|
7
|
+
// Enable Emmet in .box files for fast HTML typing
|
|
5
8
|
"emmet.includeLanguages": {
|
|
6
9
|
"box": "html"
|
|
7
10
|
},
|
|
11
|
+
|
|
12
|
+
// Enable autocomplete in strings (useful for box-bind attributes)
|
|
8
13
|
"editor.quickSuggestions": {
|
|
9
14
|
"strings": true
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// Format on save for consistent code style
|
|
18
|
+
"editor.formatOnSave": true,
|
|
19
|
+
|
|
20
|
+
// Use 2 spaces for indentation (HTML/CSS/JS standard)
|
|
21
|
+
"editor.tabSize": 2,
|
|
22
|
+
|
|
23
|
+
// Wrap long lines for readability
|
|
24
|
+
"editor.wordWrap": "on",
|
|
25
|
+
|
|
26
|
+
// Show matching brackets clearly
|
|
27
|
+
"editor.bracketPairColorization.enabled": true,
|
|
28
|
+
|
|
29
|
+
// Auto-close HTML tags
|
|
30
|
+
"html.autoClosingTags": true,
|
|
31
|
+
|
|
32
|
+
// Show color decorators in CSS
|
|
33
|
+
"css.colorDecorators": true,
|
|
34
|
+
|
|
35
|
+
// Exclude build artifacts from explorer and search
|
|
36
|
+
"files.exclude": {
|
|
37
|
+
"**/node_modules": true,
|
|
38
|
+
"**/dist": false
|
|
39
|
+
},
|
|
40
|
+
"search.exclude": {
|
|
41
|
+
"**/node_modules": true,
|
|
42
|
+
"**/dist": true
|
|
10
43
|
}
|
|
11
44
|
}
|
package/template/README.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
# BOX Project
|
|
1
|
+
# 🚀 BOX Project
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Welcome to your BOX Framework application! This is a fully functional starter template with examples showing how to:
|
|
4
|
+
|
|
5
|
+
- Build **reactive components** with state management
|
|
6
|
+
- Create **API endpoints** (backend routes)
|
|
7
|
+
- Use **component composition** with `<include />`
|
|
8
|
+
- Develop with **instant hot-reload** (HMR)
|
|
4
9
|
|
|
5
10
|
## Quick Start
|
|
6
11
|
|
|
@@ -9,4 +14,148 @@ npm install
|
|
|
9
14
|
npm run dev
|
|
10
15
|
```
|
|
11
16
|
|
|
12
|
-
Visit http://localhost:3000
|
|
17
|
+
Visit **http://localhost:3000** and start building!
|
|
18
|
+
|
|
19
|
+
## 📁 Project Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
my-box-app/
|
|
23
|
+
├── .vscode/
|
|
24
|
+
│ ├── settings.json # IDE settings (.box → HTML highlighting)
|
|
25
|
+
│ ├── extensions.json # Recommended VS Code extensions
|
|
26
|
+
│ └── launch.json # Debug configurations
|
|
27
|
+
├── src/
|
|
28
|
+
│ ├── main.box # App entry point
|
|
29
|
+
│ ├── counter.box # State management example
|
|
30
|
+
│ ├── api-demo.box # API integration example
|
|
31
|
+
│ ├── learning-guide.box # Complete framework guide
|
|
32
|
+
│ ├── api+hello.box # GET /api/hello
|
|
33
|
+
│ └── api+echo.box # POST /api/echo
|
|
34
|
+
├── assets/ # Static files (images, fonts)
|
|
35
|
+
├── dist/ # Build output (auto-generated)
|
|
36
|
+
├── package.json
|
|
37
|
+
└── README.md
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 🎯 Development Workflow
|
|
41
|
+
|
|
42
|
+
1. Edit `.box` files in `src/`
|
|
43
|
+
2. Save and browser auto-refreshes
|
|
44
|
+
3. See your changes instantly (no build step needed!)
|
|
45
|
+
4. Use `npm run build` for production
|
|
46
|
+
|
|
47
|
+
## 📚 Key Concepts
|
|
48
|
+
|
|
49
|
+
### .box File Structure
|
|
50
|
+
|
|
51
|
+
Every `.box` file has three sections:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<style>
|
|
55
|
+
/* Scoped CSS - won't leak to other components */
|
|
56
|
+
.my-class { color: blue; }
|
|
57
|
+
</style>
|
|
58
|
+
|
|
59
|
+
<template>
|
|
60
|
+
<!-- HTML with special attributes -->
|
|
61
|
+
<div class="my-class">
|
|
62
|
+
<span box-bind="count">0</span>
|
|
63
|
+
<include src="./other.box" />
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<script>
|
|
68
|
+
// Vanilla JavaScript
|
|
69
|
+
Box.state.count = 42;
|
|
70
|
+
</script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Reactive State
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
// Set state (auto-updates DOM elements with box-bind="count")
|
|
77
|
+
Box.state.count = 0;
|
|
78
|
+
Box.state.count++; // UI updates automatically!
|
|
79
|
+
|
|
80
|
+
// Listen for changes
|
|
81
|
+
Box.on('count:changed', (value) => console.log(value));
|
|
82
|
+
|
|
83
|
+
// Emit custom events
|
|
84
|
+
Box.emit('user:login', userData);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### API Endpoints
|
|
88
|
+
|
|
89
|
+
Files named `api+name.box` become routes:
|
|
90
|
+
|
|
91
|
+
| File | Route |
|
|
92
|
+
|------|-------|
|
|
93
|
+
| `api+hello.box` | `GET /api/hello` |
|
|
94
|
+
| `api+echo.box` | `POST /api/echo` |
|
|
95
|
+
| `api+users+list.box` | `GET /api/users/list` |
|
|
96
|
+
|
|
97
|
+
## 🛠 Available Scripts
|
|
98
|
+
|
|
99
|
+
| Command | Description |
|
|
100
|
+
|---------|-------------|
|
|
101
|
+
| `npm run dev` | Start development server with HMR |
|
|
102
|
+
| `npm run build` | Build for production |
|
|
103
|
+
| `npm run start` | Run production server |
|
|
104
|
+
| `npm run preview` | Build and run production |
|
|
105
|
+
|
|
106
|
+
## 🔌 VS Code Setup
|
|
107
|
+
|
|
108
|
+
Your project comes pre-configured with:
|
|
109
|
+
|
|
110
|
+
- ✅ `.box` files recognized as HTML (syntax highlighting)
|
|
111
|
+
- ✅ Emmet support for fast HTML typing
|
|
112
|
+
- ✅ Recommended extensions for better DX
|
|
113
|
+
- ✅ Debug configurations ready to use
|
|
114
|
+
|
|
115
|
+
**Open the project folder in VS Code** to activate all settings.
|
|
116
|
+
|
|
117
|
+
## 🤖 AI-Friendly Code
|
|
118
|
+
|
|
119
|
+
Copy any `.box` file into Claude, ChatGPT, or your favorite AI assistant.
|
|
120
|
+
The pure HTML/CSS/JS structure makes it perfect for AI-assisted development.
|
|
121
|
+
|
|
122
|
+
### Prompt Template
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
I'm using BOX Framework. Here's my component:
|
|
126
|
+
|
|
127
|
+
[paste your .box file]
|
|
128
|
+
|
|
129
|
+
Help me [describe what you want to do].
|
|
130
|
+
|
|
131
|
+
Note: BOX uses:
|
|
132
|
+
- Box.state for reactive state
|
|
133
|
+
- box-bind="property" for two-way binding
|
|
134
|
+
- <include src="./file.box" /> for composition
|
|
135
|
+
- api+name.box files for backend endpoints
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 📦 Production Build
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm run build
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This generates `dist/` containing:
|
|
145
|
+
- `index.html` - Compiled frontend
|
|
146
|
+
- `style.css` - Minified styles
|
|
147
|
+
- `app.js` - Minified JavaScript
|
|
148
|
+
- `server.js` - Node.js backend server
|
|
149
|
+
|
|
150
|
+
Deploy `dist/` to any Node.js hosting (Vercel, Railway, Render, etc.)
|
|
151
|
+
|
|
152
|
+
## 📚 Learn More
|
|
153
|
+
|
|
154
|
+
- 📖 [BOX Framework GitHub](https://github.com/itayzrihan/box)
|
|
155
|
+
- 📦 [npm: @itayzrihan/box-framework](https://www.npmjs.com/package/@itayzrihan/box-framework)
|
|
156
|
+
|
|
157
|
+
Check the example components in `src/` - they're heavily commented with tips!
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
**Happy Vibe Coding! 🎉**
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Assets Folder
|
|
2
|
+
|
|
3
|
+
Put your static files here:
|
|
4
|
+
|
|
5
|
+
- Images (`.png`, `.jpg`, `.svg`, `.gif`, `.webp`)
|
|
6
|
+
- Fonts (`.woff`, `.woff2`, `.ttf`)
|
|
7
|
+
- Icons (`favicon.ico`)
|
|
8
|
+
- Any other static assets
|
|
9
|
+
|
|
10
|
+
These files will be copied to `dist/assets/` during build.
|
|
11
|
+
|
|
12
|
+
## Usage in .box files
|
|
13
|
+
|
|
14
|
+
Reference assets with relative paths:
|
|
15
|
+
|
|
16
|
+
```html
|
|
17
|
+
<img src="./assets/logo.png" alt="Logo" />
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or in CSS:
|
|
21
|
+
|
|
22
|
+
```css
|
|
23
|
+
.hero {
|
|
24
|
+
background-image: url('./assets/hero-bg.jpg');
|
|
25
|
+
}
|
|
26
|
+
```
|
package/template/package.json
CHANGED
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"description": "A BOX Framework application",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"build": "box build",
|
|
7
6
|
"dev": "box dev",
|
|
8
|
-
"
|
|
7
|
+
"build": "box build",
|
|
8
|
+
"start": "node dist/server.js",
|
|
9
|
+
"preview": "npm run build && npm run start"
|
|
9
10
|
},
|
|
10
11
|
"keywords": [
|
|
11
12
|
"box",
|
|
12
|
-
"framework"
|
|
13
|
+
"framework",
|
|
14
|
+
"vibe-coding"
|
|
13
15
|
],
|
|
14
16
|
"author": "",
|
|
15
17
|
"license": "MIT",
|
|
16
|
-
"
|
|
17
|
-
"box-framework": "^1.0.0"
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@itayzrihan/box-framework": "^1.0.0"
|
|
18
20
|
}
|
|
19
21
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BOX API ENDPOINT: POST /api/echo
|
|
3
|
+
* =================================
|
|
4
|
+
*
|
|
5
|
+
* Example POST endpoint that echoes back what you send.
|
|
6
|
+
* Test with:
|
|
7
|
+
*
|
|
8
|
+
* fetch('/api/echo', {
|
|
9
|
+
* method: 'POST',
|
|
10
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
11
|
+
* body: JSON.stringify({ name: 'Alice', message: 'Hello!' })
|
|
12
|
+
* })
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/* BOX_CONFIG: { "method": "POST", "auth": false } */
|
|
16
|
+
|
|
17
|
+
export default async (req, res, ctx) => {
|
|
18
|
+
try {
|
|
19
|
+
// req.body contains the parsed JSON body
|
|
20
|
+
const { name, message } = req.body || {};
|
|
21
|
+
|
|
22
|
+
if (!name || !message) {
|
|
23
|
+
return {
|
|
24
|
+
status: 400,
|
|
25
|
+
error: "Missing required fields: name, message"
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
status: 200,
|
|
31
|
+
data: {
|
|
32
|
+
received: { name, message },
|
|
33
|
+
echo: `${name} says: "${message}"`,
|
|
34
|
+
timestamp: new Date().toISOString()
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
} catch (err) {
|
|
38
|
+
return { status: 500, error: err.message || "Server error" };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -1,15 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BOX API ENDPOINT: /api/hello
|
|
3
|
+
* =============================
|
|
4
|
+
*
|
|
5
|
+
* This file creates a GET endpoint at /api/hello
|
|
6
|
+
*
|
|
7
|
+
* FILE NAMING CONVENTION:
|
|
8
|
+
* - api+name.box → GET /api/name
|
|
9
|
+
* - api+users+list.box → GET /api/users/list
|
|
10
|
+
* - Use BOX_CONFIG to change HTTP method (GET, POST, PUT, DELETE)
|
|
11
|
+
*
|
|
12
|
+
* AVAILABLE IN HANDLER:
|
|
13
|
+
* - req.body: Request body (for POST/PUT)
|
|
14
|
+
* - req.query: URL query parameters (?name=value)
|
|
15
|
+
* - req.headers: Request headers
|
|
16
|
+
* - ctx.env: Environment variables (process.env)
|
|
17
|
+
*
|
|
18
|
+
* RETURN FORMAT:
|
|
19
|
+
* - { status: 200, data: {...} } → JSON response
|
|
20
|
+
* - { status: 404, error: "Not found" } → Error response
|
|
21
|
+
*/
|
|
22
|
+
|
|
1
23
|
/* BOX_CONFIG: { "method": "GET", "auth": false } */
|
|
2
24
|
|
|
3
|
-
export default async (req, res,
|
|
25
|
+
export default async (req, res, ctx) => {
|
|
4
26
|
try {
|
|
27
|
+
// Example: Access query parameters
|
|
28
|
+
// const name = req.query.name || 'World';
|
|
29
|
+
|
|
5
30
|
const greeting = {
|
|
6
31
|
message: "Hello from BOX API!",
|
|
7
32
|
timestamp: new Date().toISOString(),
|
|
8
|
-
framework: "BOX Framework v1.0.0"
|
|
33
|
+
framework: "BOX Framework v1.0.0",
|
|
34
|
+
tip: "Edit src/api+hello.box to customize this endpoint"
|
|
9
35
|
};
|
|
10
36
|
|
|
11
37
|
return { status: 200, data: greeting };
|
|
12
38
|
} catch (err) {
|
|
13
|
-
return { status: 500, error: "Server error" };
|
|
39
|
+
return { status: 500, error: err.message || "Server error" };
|
|
14
40
|
}
|
|
15
41
|
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
/* API INTEGRATION COMPONENT
|
|
3
|
+
This component shows how to fetch data from BOX API endpoints */
|
|
4
|
+
|
|
5
|
+
.api-demo {
|
|
6
|
+
padding: 2rem;
|
|
7
|
+
background: #f8f9fa;
|
|
8
|
+
border-radius: 12px;
|
|
9
|
+
border-left: 4px solid #667eea;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.api-demo h3 {
|
|
13
|
+
margin-top: 0;
|
|
14
|
+
color: #667eea;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.api-response {
|
|
18
|
+
background: white;
|
|
19
|
+
padding: 1rem;
|
|
20
|
+
border-radius: 8px;
|
|
21
|
+
margin-top: 1rem;
|
|
22
|
+
font-family: 'Courier New', monospace;
|
|
23
|
+
font-size: 13px;
|
|
24
|
+
overflow-x: auto;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.loading {
|
|
28
|
+
color: #667eea;
|
|
29
|
+
font-style: italic;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.error {
|
|
33
|
+
color: #e74c3c;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.success {
|
|
37
|
+
color: #27ae60;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<div class="api-demo">
|
|
43
|
+
<h3>📡 API Call Example</h3>
|
|
44
|
+
<p>Click below to fetch data from your BOX API endpoint:</p>
|
|
45
|
+
<button id="fetchBtn" style="padding: 0.5rem 1rem; cursor: pointer;">
|
|
46
|
+
Fetch from /api/hello
|
|
47
|
+
</button>
|
|
48
|
+
<div id="response" class="api-response loading">
|
|
49
|
+
Click the button to see the response...
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script>
|
|
55
|
+
/* CALLING BOX APIS: BOX automatically generates API routes
|
|
56
|
+
from files named api+name.box
|
|
57
|
+
So api+hello.box → GET /api/hello */
|
|
58
|
+
|
|
59
|
+
const fetchBtn = document.querySelector('#fetchBtn');
|
|
60
|
+
const responseDiv = document.querySelector('#response');
|
|
61
|
+
|
|
62
|
+
fetchBtn.addEventListener('click', async () => {
|
|
63
|
+
responseDiv.className = 'api-response loading';
|
|
64
|
+
responseDiv.textContent = 'Loading...';
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
/* FETCH WITH FULL URL: In development (http://localhost:3000)
|
|
68
|
+
and production, all API calls are relative to the app root */
|
|
69
|
+
const response = await fetch('/api/hello');
|
|
70
|
+
const data = await response.json();
|
|
71
|
+
|
|
72
|
+
responseDiv.className = 'api-response success';
|
|
73
|
+
responseDiv.textContent = JSON.stringify(data, null, 2);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
responseDiv.className = 'api-response error';
|
|
76
|
+
responseDiv.textContent = `Error: ${error.message}`;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
</script>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
/* BOX Scoping: Each component's styles are automatically scoped
|
|
3
|
+
with a data-box attribute, preventing CSS collisions across your app */
|
|
4
|
+
.counter {
|
|
5
|
+
padding: 2rem;
|
|
6
|
+
background: white;
|
|
7
|
+
border-radius: 12px;
|
|
8
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
9
|
+
text-align: center;
|
|
10
|
+
max-width: 400px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.counter h2 {
|
|
14
|
+
color: #667eea;
|
|
15
|
+
margin: 0 0 1.5rem 0;
|
|
16
|
+
font-size: 24px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.counter-display {
|
|
20
|
+
font-size: 48px;
|
|
21
|
+
font-weight: bold;
|
|
22
|
+
color: #764ba2;
|
|
23
|
+
margin: 2rem 0;
|
|
24
|
+
font-family: 'Courier New', monospace;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.counter-controls {
|
|
28
|
+
display: flex;
|
|
29
|
+
gap: 1rem;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
flex-wrap: wrap;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.btn {
|
|
35
|
+
padding: 0.75rem 1.5rem;
|
|
36
|
+
font-size: 16px;
|
|
37
|
+
border: none;
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
transition: all 0.3s ease;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.btn-decrease {
|
|
45
|
+
background: #ff6b6b;
|
|
46
|
+
color: white;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.btn-decrease:hover {
|
|
50
|
+
background: #ee5a52;
|
|
51
|
+
transform: translateY(-2px);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.btn-increase {
|
|
55
|
+
background: #667eea;
|
|
56
|
+
color: white;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.btn-increase:hover {
|
|
60
|
+
background: #5a67d8;
|
|
61
|
+
transform: translateY(-2px);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.btn-reset {
|
|
65
|
+
background: #95a5a6;
|
|
66
|
+
color: white;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.btn-reset:hover {
|
|
70
|
+
background: #7f8c8d;
|
|
71
|
+
transform: translateY(-2px);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.counter-note {
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
color: #7f8c8d;
|
|
77
|
+
margin-top: 1.5rem;
|
|
78
|
+
line-height: 1.6;
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
81
|
+
|
|
82
|
+
<template>
|
|
83
|
+
<div class="counter">
|
|
84
|
+
<h2>Counter Demo</h2>
|
|
85
|
+
<div class="counter-display" box-bind="count">0</div>
|
|
86
|
+
|
|
87
|
+
<div class="counter-controls">
|
|
88
|
+
<button class="btn btn-decrease">− Decrease</button>
|
|
89
|
+
<button class="btn btn-increase">+ Increase</button>
|
|
90
|
+
<button class="btn btn-reset">⟲ Reset</button>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<div class="counter-note">
|
|
94
|
+
💡 <strong>Vibe Coding Tip:</strong> This counter demonstrates two-way binding.
|
|
95
|
+
The <code>box-bind="count"</code> attribute keeps the DOM in sync with
|
|
96
|
+
<code>Box.state.count</code> automatically. Change state, see the UI update instantly!
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</template>
|
|
100
|
+
|
|
101
|
+
<script>
|
|
102
|
+
/* REACTIVE STATE: Box.state uses JavaScript Proxy for reactivity
|
|
103
|
+
Any property you add to Box.state automatically updates the DOM
|
|
104
|
+
where it's referenced with box-bind="propertyName" */
|
|
105
|
+
|
|
106
|
+
Box.state.count = 0;
|
|
107
|
+
|
|
108
|
+
/* EVENT HANDLING: Query selectors work just like vanilla JS.
|
|
109
|
+
BOX components are scoped, so event handlers won't collide */
|
|
110
|
+
|
|
111
|
+
const decreaseBtn = document.querySelector('.btn-decrease');
|
|
112
|
+
const increaseBtn = document.querySelector('.btn-increase');
|
|
113
|
+
const resetBtn = document.querySelector('.btn-reset');
|
|
114
|
+
|
|
115
|
+
decreaseBtn.addEventListener('click', () => {
|
|
116
|
+
Box.state.count--;
|
|
117
|
+
Box.emit('count:changed', Box.state.count);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
increaseBtn.addEventListener('click', () => {
|
|
121
|
+
Box.state.count++;
|
|
122
|
+
Box.emit('count:changed', Box.state.count);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
resetBtn.addEventListener('click', () => {
|
|
126
|
+
Box.state.count = 0;
|
|
127
|
+
Box.emit('count:changed', Box.state.count);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
/* LIFECYCLE: Components run their script when they load.
|
|
131
|
+
Use Box.on() to listen for custom events or state changes */
|
|
132
|
+
|
|
133
|
+
Box.on('count:changed', (newCount) => {
|
|
134
|
+
console.log(`Count is now: ${newCount}`);
|
|
135
|
+
});
|
|
136
|
+
</script>
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
.learning-guide {
|
|
3
|
+
max-width: 900px;
|
|
4
|
+
margin: 0 auto;
|
|
5
|
+
padding: 2rem;
|
|
6
|
+
background: #fafafa;
|
|
7
|
+
border-radius: 12px;
|
|
8
|
+
line-height: 1.8;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.learning-guide h2 {
|
|
12
|
+
color: #667eea;
|
|
13
|
+
margin-top: 2rem;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.learning-guide h3 {
|
|
17
|
+
color: #764ba2;
|
|
18
|
+
margin-top: 1.5rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.learning-guide code {
|
|
22
|
+
background: #f0f0f0;
|
|
23
|
+
padding: 0.25rem 0.5rem;
|
|
24
|
+
border-radius: 4px;
|
|
25
|
+
font-family: 'Courier New', monospace;
|
|
26
|
+
color: #e74c3c;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.tip-box {
|
|
30
|
+
background: #e8f4f8;
|
|
31
|
+
border-left: 4px solid #667eea;
|
|
32
|
+
padding: 1rem;
|
|
33
|
+
margin: 1rem 0;
|
|
34
|
+
border-radius: 4px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.tip-box strong {
|
|
38
|
+
color: #667eea;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.code-block {
|
|
42
|
+
background: #2c3e50;
|
|
43
|
+
color: #ecf0f1;
|
|
44
|
+
padding: 1rem;
|
|
45
|
+
border-radius: 8px;
|
|
46
|
+
overflow-x: auto;
|
|
47
|
+
margin: 1rem 0;
|
|
48
|
+
font-family: 'Courier New', monospace;
|
|
49
|
+
font-size: 13px;
|
|
50
|
+
}
|
|
51
|
+
</style>
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<div class="learning-guide">
|
|
55
|
+
<h1>🎓 Vibe Coding Guide for BOX Framework</h1>
|
|
56
|
+
|
|
57
|
+
<p>
|
|
58
|
+
Welcome! This template shows you how to build amazing web apps with BOX Framework.
|
|
59
|
+
BOX is all about <strong>zero dependencies</strong>, <strong>component-driven development</strong>,
|
|
60
|
+
and <strong>AI-friendly code</strong>.
|
|
61
|
+
</p>
|
|
62
|
+
|
|
63
|
+
<h2>🏗️ Project Structure</h2>
|
|
64
|
+
<p>Your app is organized in the <code>src/</code> folder:</p>
|
|
65
|
+
<ul>
|
|
66
|
+
<li><code>main.box</code> - Your app's entry point</li>
|
|
67
|
+
<li><code>welcome.box</code> - The beautiful welcome screen</li>
|
|
68
|
+
<li><code>counter.box</code> - Example: Interactive state management</li>
|
|
69
|
+
<li><code>api-demo.box</code> - Example: API integration</li>
|
|
70
|
+
<li><code>api+hello.box</code> - Backend API endpoint</li>
|
|
71
|
+
</ul>
|
|
72
|
+
|
|
73
|
+
<h2>📝 Understanding .box Files</h2>
|
|
74
|
+
<p>Each <code>.box</code> file is a complete component with three sections:</p>
|
|
75
|
+
|
|
76
|
+
<h3>1. <style> - Scoped CSS</h3>
|
|
77
|
+
<div class="tip-box">
|
|
78
|
+
<strong>💡 Vibe Tip:</strong> Your styles are automatically scoped!
|
|
79
|
+
BOX adds a unique <code>data-box</code> attribute to prevent collisions.
|
|
80
|
+
Write CSS naturally without worrying about class name conflicts.
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<h3>2. <template> - HTML Structure</h3>
|
|
84
|
+
<p>Use standard HTML with special BOX attributes:</p>
|
|
85
|
+
<ul>
|
|
86
|
+
<li><code>box-bind="propertyName"</code> - Two-way binding with state</li>
|
|
87
|
+
<li><code><include src="./other.box" /></code> - Nest components</li>
|
|
88
|
+
</ul>
|
|
89
|
+
|
|
90
|
+
<div class="tip-box">
|
|
91
|
+
<strong>💡 Vibe Tip:</strong> <code>box-bind</code> automatically syncs your component
|
|
92
|
+
with <code>Box.state</code>. Change state, see the UI update instantly!
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<h3>3. <script> - Component Logic</h3>
|
|
96
|
+
<p>Vanilla JavaScript! No special syntax required.</p>
|
|
97
|
+
|
|
98
|
+
<h2>⚡ Key BOX Concepts</h2>
|
|
99
|
+
|
|
100
|
+
<h3>Reactive State</h3>
|
|
101
|
+
<div class="code-block">Box.state.myValue = 'hello';
|
|
102
|
+
Box.state.counter = 0;
|
|
103
|
+
|
|
104
|
+
// Any property you add automatically updates the DOM
|
|
105
|
+
Box.state.counter++; // Updates all box-bind="counter" elements</div>
|
|
106
|
+
|
|
107
|
+
<div class="tip-box">
|
|
108
|
+
<strong>💡 Vibe Tip:</strong> BOX uses JavaScript Proxy for reactivity.
|
|
109
|
+
It's simple, no virtual DOM, and super performant.
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<h3>Event Handling</h3>
|
|
113
|
+
<p>Use vanilla DOM queries and event listeners:</p>
|
|
114
|
+
<div class="code-block">const btn = document.querySelector('.my-button');
|
|
115
|
+
btn.addEventListener('click', () => {
|
|
116
|
+
Box.state.count++;
|
|
117
|
+
});</div>
|
|
118
|
+
|
|
119
|
+
<h3>Emitting Custom Events</h3>
|
|
120
|
+
<div class="code-block">// In one component:
|
|
121
|
+
Box.emit('user:logged-in', userData);
|
|
122
|
+
|
|
123
|
+
// In another component:
|
|
124
|
+
Box.on('user:logged-in', (data) => {
|
|
125
|
+
console.log('User logged in:', data);
|
|
126
|
+
});</div>
|
|
127
|
+
|
|
128
|
+
<h2>🔌 API Endpoints</h2>
|
|
129
|
+
<p>Files named <code>api+name.box</code> become API routes:</p>
|
|
130
|
+
<ul>
|
|
131
|
+
<li><code>api+hello.box</code> → <code>GET /api/hello</code></li>
|
|
132
|
+
<li><code>api+users.box</code> → <code>GET /api/users</code></li>
|
|
133
|
+
<li><code>api+post+create.box</code> → <code>POST /api/post/create</code></li>
|
|
134
|
+
</ul>
|
|
135
|
+
|
|
136
|
+
<h3>API Box Structure</h3>
|
|
137
|
+
<div class="code-block">/* BOX_CONFIG: { "method": "POST", "auth": false } */
|
|
138
|
+
|
|
139
|
+
export default async (req, res, context) => {
|
|
140
|
+
try {
|
|
141
|
+
const result = { success: true, data: req.body };
|
|
142
|
+
return { status: 200, data: result };
|
|
143
|
+
} catch (err) {
|
|
144
|
+
return { status: 500, error: err.message };
|
|
145
|
+
}
|
|
146
|
+
};</div>
|
|
147
|
+
|
|
148
|
+
<div class="tip-box">
|
|
149
|
+
<strong>💡 Vibe Tip:</strong> You write plain async functions.
|
|
150
|
+
BOX handles the HTTP routing, request parsing, and response formatting automatically.
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<h2>🚀 Development Workflow</h2>
|
|
154
|
+
<ol>
|
|
155
|
+
<li>Edit <code>.box</code> files in <code>src/</code></li>
|
|
156
|
+
<li>Save the file</li>
|
|
157
|
+
<li>Browser auto-refreshes (HMR)</li>
|
|
158
|
+
<li>See your changes instantly</li>
|
|
159
|
+
</ol>
|
|
160
|
+
|
|
161
|
+
<div class="tip-box">
|
|
162
|
+
<strong>💡 Vibe Tip:</strong> BOX watches for changes and rebuilds automatically.
|
|
163
|
+
No manual build step needed during development!
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<h2>📦 Building for Production</h2>
|
|
167
|
+
<div class="code-block">npm run build</div>
|
|
168
|
+
<p>This generates <code>dist/</code> with:</p>
|
|
169
|
+
<ul>
|
|
170
|
+
<li><code>index.html</code> - Compiled frontend</li>
|
|
171
|
+
<li><code>app.js</code> - Minified frontend code</li>
|
|
172
|
+
<li><code>style.css</code> - Minified styles</li>
|
|
173
|
+
<li><code>server.js</code> - Node.js backend server</li>
|
|
174
|
+
</ul>
|
|
175
|
+
|
|
176
|
+
<h2>🎯 Next Steps</h2>
|
|
177
|
+
<ol>
|
|
178
|
+
<li>✅ Run <code>npm run dev</code> to start the development server</li>
|
|
179
|
+
<li>✅ Edit <code>src/main.box</code> to customize your app</li>
|
|
180
|
+
<li>✅ Create new <code>.box</code> components in <code>src/</code></li>
|
|
181
|
+
<li>✅ Use <code>api+name.box</code> for backend endpoints</li>
|
|
182
|
+
<li>✅ Build with <code>npm run build</code> for production</li>
|
|
183
|
+
</ol>
|
|
184
|
+
|
|
185
|
+
<h2>📚 Learn More</h2>
|
|
186
|
+
<ul>
|
|
187
|
+
<li>📖 <a href="https://github.com/itayzrihan/box" target="_blank">BOX Framework GitHub</a></li>
|
|
188
|
+
<li>💬 Check the other example components: <code>counter.box</code> and <code>api-demo.box</code></li>
|
|
189
|
+
<li>🤖 These .box files are AI-friendly! Paste the entire component into Claude, ChatGPT, etc. for help</li>
|
|
190
|
+
</ul>
|
|
191
|
+
|
|
192
|
+
<h2>🎨 Your Turn!</h2>
|
|
193
|
+
<p>
|
|
194
|
+
Now that you understand the basics, start building! Edit <code>main.box</code> and add
|
|
195
|
+
your own components. BOX is designed to get out of your way so you can focus on
|
|
196
|
+
building great UIs.
|
|
197
|
+
</p>
|
|
198
|
+
|
|
199
|
+
<p style="text-align: center; margin-top: 3rem; color: #667eea; font-size: 18px;">
|
|
200
|
+
<strong>Happy Vibe Coding! 🚀</strong>
|
|
201
|
+
</p>
|
|
202
|
+
</div>
|
|
203
|
+
</template>
|
|
204
|
+
|
|
205
|
+
<script>
|
|
206
|
+
// This is just a documentation component, no logic needed!
|
|
207
|
+
console.log('📚 Learning guide loaded. Check the examples in counter.box and api-demo.box!');
|
|
208
|
+
</script>
|
package/template/src/main.box
CHANGED
|
@@ -3,15 +3,88 @@
|
|
|
3
3
|
min-height: 100vh;
|
|
4
4
|
display: flex;
|
|
5
5
|
flex-direction: column;
|
|
6
|
+
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
7
|
+
padding: 2rem;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.app-container {
|
|
11
|
+
max-width: 1200px;
|
|
12
|
+
margin: 0 auto;
|
|
13
|
+
width: 100%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.app-header {
|
|
17
|
+
text-align: center;
|
|
18
|
+
margin-bottom: 3rem;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.app-header h1 {
|
|
22
|
+
color: #667eea;
|
|
23
|
+
margin: 0;
|
|
24
|
+
font-size: 32px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.app-header p {
|
|
28
|
+
color: #7f8c8d;
|
|
29
|
+
margin: 0.5rem 0 0 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.examples-grid {
|
|
33
|
+
display: grid;
|
|
34
|
+
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
35
|
+
gap: 2rem;
|
|
36
|
+
margin-bottom: 3rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@media (max-width: 768px) {
|
|
40
|
+
.examples-grid {
|
|
41
|
+
grid-template-columns: 1fr;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.app-header h1 {
|
|
45
|
+
font-size: 24px;
|
|
46
|
+
}
|
|
6
47
|
}
|
|
7
48
|
</style>
|
|
8
49
|
|
|
9
50
|
<template>
|
|
10
51
|
<div class="app">
|
|
11
|
-
<
|
|
52
|
+
<div class="app-container">
|
|
53
|
+
<div class="app-header">
|
|
54
|
+
<h1>⚡ BOX Framework</h1>
|
|
55
|
+
<p>Zero-dependency, full-stack web framework</p>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Learning Guide -->
|
|
59
|
+
<include src="./learning-guide.box" />
|
|
60
|
+
|
|
61
|
+
<!-- Examples Section -->
|
|
62
|
+
<div style="text-align: center; margin-top: 3rem; margin-bottom: 1rem;">
|
|
63
|
+
<h2 style="color: #667eea;">📖 Live Examples</h2>
|
|
64
|
+
<p style="color: #7f8c8d;">Click around to see BOX in action</p>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div class="examples-grid">
|
|
68
|
+
<include src="./counter.box" />
|
|
69
|
+
<include src="./api-demo.box" />
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div style="text-align: center; margin-top: 3rem; padding: 2rem; background: rgba(255,255,255,0.8); border-radius: 12px;">
|
|
73
|
+
<h3 style="color: #667eea; margin-top: 0;">Ready to build?</h3>
|
|
74
|
+
<p style="color: #7f8c8d;">
|
|
75
|
+
Edit files in <code style="background: #f0f0f0; padding: 0.25rem 0.5rem; border-radius: 4px;">src/</code>
|
|
76
|
+
and watch changes live. Check <code style="background: #f0f0f0; padding: 0.25rem 0.5rem; border-radius: 4px;">counter.box</code>
|
|
77
|
+
and <code style="background: #f0f0f0; padding: 0.25rem 0.5rem; border-radius: 4px;">api-demo.box</code> for code examples.
|
|
78
|
+
</p>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
12
81
|
</div>
|
|
13
82
|
</template>
|
|
14
83
|
|
|
15
84
|
<script>
|
|
85
|
+
// This is your app's entry point
|
|
86
|
+
// BOX automatically includes all files referenced with <include />
|
|
87
|
+
console.log('🚀 BOX App loaded successfully!');
|
|
88
|
+
</script>
|
|
16
89
|
console.log('📦 BOX App initialized!');
|
|
17
90
|
</script>
|