@africode/core 5.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.
- package/AFRICODE_FRAMEWORK_GUIDE.md +707 -0
- package/LICENSE +623 -0
- package/README.md +442 -0
- package/bin/africode.js +73 -0
- package/bin/africode.js.1758507140 +343 -0
- package/bin/cli.ts +83 -0
- package/bin/create-africode.js +158 -0
- package/bin/scaffold.ts +219 -0
- package/components/accordion.js +183 -0
- package/components/alert.js +131 -0
- package/components/auth.js +172 -0
- package/components/avatar.js +117 -0
- package/components/badge.js +104 -0
- package/components/base.d.ts +139 -0
- package/components/base.js +184 -0
- package/components/button.js +164 -0
- package/components/card.js +137 -0
- package/components/cultural-card.js +243 -0
- package/components/divider.js +83 -0
- package/components/dropdown.js +171 -0
- package/components/error-boundary.js +155 -0
- package/components/form.js +131 -0
- package/components/grid.js +273 -0
- package/components/hero.js +138 -0
- package/components/icon.js +36 -0
- package/components/index.js +57 -0
- package/components/input.js +256 -0
- package/components/kanga-card.js +185 -0
- package/components/language-switcher.js +108 -0
- package/components/loader.js +80 -0
- package/components/modal.js +262 -0
- package/components/motion.js +84 -0
- package/components/navbar.js +236 -0
- package/components/pattern-showcase.js +225 -0
- package/components/progress.js +134 -0
- package/components/react.js +111 -0
- package/components/section.js +54 -0
- package/components/select.js +322 -0
- package/components/sidebar.js +180 -0
- package/components/skeleton.js +85 -0
- package/components/table.js +181 -0
- package/components/tabs.js +202 -0
- package/components/theme-toggle.js +82 -0
- package/components/toast.js +139 -0
- package/components/tooltip.js +167 -0
- package/core/a2ui-schema-manager.js +344 -0
- package/core/a2ui.js +431 -0
- package/core/bun-runtime.js +799 -0
- package/core/cli/commands/add.js +23 -0
- package/core/cli/commands/audit.js +58 -0
- package/core/cli/commands/build.js +137 -0
- package/core/cli/commands/create-plugin.js +241 -0
- package/core/cli/commands/dev.js +228 -0
- package/core/cli/commands/lint.js +23 -0
- package/core/cli/commands/test.js +34 -0
- package/core/cli/migrator.js +71 -0
- package/core/cli/ui.js +46 -0
- package/core/compliance.js +628 -0
- package/core/config.js +263 -0
- package/core/db-advanced.js +481 -0
- package/core/db.js +284 -0
- package/core/enhanced-hmr.js +404 -0
- package/core/errors.js +222 -0
- package/core/file-router.js +290 -0
- package/core/heartbeat.js +64 -0
- package/core/hmr-client.js +204 -0
- package/core/hmr.js +196 -0
- package/core/html.d.ts +116 -0
- package/core/html.js +160 -0
- package/core/hydration.js +52 -0
- package/core/lipa-namba-journey.js +572 -0
- package/core/motion.js +106 -0
- package/core/nida-cig-middleware.js +455 -0
- package/core/patterns.d.ts +124 -0
- package/core/patterns.js +833 -0
- package/core/plugins/index.js +312 -0
- package/core/router.js +387 -0
- package/core/sdk-client.js +62 -0
- package/core/sdk.d.ts +133 -0
- package/core/sdk.js +123 -0
- package/core/seo.js +76 -0
- package/core/server/auth-endpoints.js +339 -0
- package/core/server/auth.js +180 -0
- package/core/server/csrf.js +206 -0
- package/core/server/db.js +39 -0
- package/core/server/middleware.js +324 -0
- package/core/server/rate-limit.js +238 -0
- package/core/server/render.js +69 -0
- package/core/server/router.js +120 -0
- package/core/shim.js +28 -0
- package/core/state.d.ts +86 -0
- package/core/state.js +242 -0
- package/core/store.d.ts +122 -0
- package/core/store.js +61 -0
- package/core/validation.d.ts +233 -0
- package/core/validation.js +590 -0
- package/core/websocket.js +639 -0
- package/dist/africode.js +2905 -0
- package/dist/africode.js.map +61 -0
- package/dist/build-info.json +23 -0
- package/dist/components.js +2888 -0
- package/dist/components.js.map +58 -0
- package/dist/styles/africanity.css +322 -0
- package/dist/styles/typography.css +141 -0
- package/docs/IDE-Guide.md +50 -0
- package/package.json +110 -0
- package/src/index.ts +196 -0
- package/styles/africanity.css +322 -0
- package/styles/typography.css +141 -0
- package/templates/starter/.env.example +15 -0
- package/templates/starter/africode.config.js +40 -0
- package/templates/starter/package.json +14 -0
- package/templates/starter/src/pages/index.html +46 -0
- package/templates/starter/src/pages/index.js +32 -0
- package/templates/starter/src/styles/main.css +4 -0
- package/templates/starter-3d/.env.example +7 -0
- package/templates/starter-3d/africode.config.js +29 -0
- package/templates/starter-3d/components/af-model-viewer.js +125 -0
- package/templates/starter-3d/package.json +15 -0
- package/templates/starter-3d/src/pages/index.html +46 -0
- package/templates/starter-3d/src/pages/index.js +50 -0
- package/templates/starter-3d/src/styles/main.css +4 -0
- package/templates/starter-react/.env.example +15 -0
- package/templates/starter-react/africode.config.js +40 -0
- package/templates/starter-react/package.json +16 -0
- package/templates/starter-react/src/pages/index.html +46 -0
- package/templates/starter-react/src/pages/index.js +68 -0
- package/templates/starter-react/src/styles/main.css +4 -0
- package/templates/starter-tailwind/.env.example +15 -0
- package/templates/starter-tailwind/africode.config.js +40 -0
- package/templates/starter-tailwind/package.json +20 -0
- package/templates/starter-tailwind/src/pages/index.html +46 -0
- package/templates/starter-tailwind/src/pages/index.js +37 -0
- package/templates/starter-tailwind/src/styles/main.css +4 -0
- package/templates/starter-tailwind/src/styles/tailwind.css +1 -0
- package/templates/starter-tailwind/src/tailwind-loader.js +30 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "africode-starter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "africode dev",
|
|
8
|
+
"build": "africode build",
|
|
9
|
+
"migrate": "africode migrate"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"africode": "^1.0.0"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Welcome to AfriCode</title>
|
|
8
|
+
|
|
9
|
+
<!-- Theme -->
|
|
10
|
+
<link rel="stylesheet" href="/node_modules/africode/styles/africanity.css">
|
|
11
|
+
<link rel="stylesheet" href="/node_modules/africode/styles/typography.css">
|
|
12
|
+
<link rel="stylesheet" href="/styles/main.css">
|
|
13
|
+
<script type="module" src="/node_modules/africode/core/sdk.js"></script>
|
|
14
|
+
|
|
15
|
+
<!-- SDK & Components -->
|
|
16
|
+
<script type="module">
|
|
17
|
+
import 'africode/components';
|
|
18
|
+
import { store } from 'africode';
|
|
19
|
+
|
|
20
|
+
console.log('AfriCode State Engine:', store);
|
|
21
|
+
</script>
|
|
22
|
+
</head>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
<af-navbar logo="Starter App" theme="dark"></af-navbar>
|
|
26
|
+
|
|
27
|
+
<main style="max-width: 1200px; margin: 0 auto; padding: 40px;">
|
|
28
|
+
<af-hero title="Umoja" subtitle="You are running on the AfriCode Framework." pattern="kente">
|
|
29
|
+
</af-hero>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-top: 40px;">
|
|
33
|
+
<af-card title="Getting Started">
|
|
34
|
+
<p>Edit <code>pages/index.html</code> to change this page.</p>
|
|
35
|
+
<af-button variant="primary">Read Docs</af-button>
|
|
36
|
+
</af-card>
|
|
37
|
+
|
|
38
|
+
<af-kanga-card proverb="Haba na haba hujaza kibaba.">
|
|
39
|
+
<h3>Steady Progress</h3>
|
|
40
|
+
<p>Little by little fills the measure.</p>
|
|
41
|
+
</af-kanga-card>
|
|
42
|
+
</div>
|
|
43
|
+
</main>
|
|
44
|
+
</body>
|
|
45
|
+
|
|
46
|
+
</html>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { html, Layout } from 'africode';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Home Page
|
|
5
|
+
* Route: /
|
|
6
|
+
*/
|
|
7
|
+
export default function HomePage() {
|
|
8
|
+
return Layout({
|
|
9
|
+
title: "Welcome to AfriCode",
|
|
10
|
+
children: html`
|
|
11
|
+
<af-navbar logo="My App" theme="dark"></af-navbar>
|
|
12
|
+
|
|
13
|
+
<main style="max-width: 1000px; margin: 0 auto; padding: 40px;">
|
|
14
|
+
<af-hero
|
|
15
|
+
title="Next-Gen African Web"
|
|
16
|
+
subtitle="Built with the AfriCode JS Framework."
|
|
17
|
+
pattern="kente">
|
|
18
|
+
</af-hero>
|
|
19
|
+
|
|
20
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-top: 40px;">
|
|
21
|
+
<af-card title="JS-First Architecture">
|
|
22
|
+
<p>No more HTML files. Logic and View utilize <code>pages/index.js</code>.</p>
|
|
23
|
+
</af-card>
|
|
24
|
+
|
|
25
|
+
<af-card title="Component System">
|
|
26
|
+
<p>Import components and use them directly in your template literals.</p>
|
|
27
|
+
</af-card>
|
|
28
|
+
</div>
|
|
29
|
+
</main>
|
|
30
|
+
`
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AfriCode Framework Configuration (3D Starter)
|
|
3
|
+
*/
|
|
4
|
+
export default {
|
|
5
|
+
entry: 'src/index.js',
|
|
6
|
+
server: {
|
|
7
|
+
port: process.env.PORT || 3000,
|
|
8
|
+
host: '0.0.0.0',
|
|
9
|
+
staticDir: 'public',
|
|
10
|
+
cors: true
|
|
11
|
+
},
|
|
12
|
+
directories: {
|
|
13
|
+
src: 'src',
|
|
14
|
+
pages: 'src/pages',
|
|
15
|
+
components: 'src/components',
|
|
16
|
+
styles: 'src/styles',
|
|
17
|
+
build: 'dist'
|
|
18
|
+
},
|
|
19
|
+
database: {
|
|
20
|
+
client: 'sqlite',
|
|
21
|
+
connection: { filename: process.env.DB_FILE || './data.db' },
|
|
22
|
+
useNullAsDefault: true,
|
|
23
|
+
walMode: true
|
|
24
|
+
},
|
|
25
|
+
theme: {
|
|
26
|
+
default: 'dark',
|
|
27
|
+
toggleAttribute: 'data-theme'
|
|
28
|
+
}
|
|
29
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { AfriCodeComponent, registerComponent } from 'africode/components/base.js';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
|
4
|
+
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
5
|
+
|
|
6
|
+
export class AfriModelViewer extends AfriCodeComponent {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.container = null;
|
|
10
|
+
this.scene = null;
|
|
11
|
+
this.camera = null;
|
|
12
|
+
this.renderer = null;
|
|
13
|
+
this.model = null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
connectedCallback() {
|
|
17
|
+
this.render();
|
|
18
|
+
this.initThree();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static get observedAttributes() {
|
|
22
|
+
return ['src', 'auto-rotate'];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
26
|
+
if (name === 'src' && this.model) {
|
|
27
|
+
// Reload logic would go here
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
render() {
|
|
32
|
+
this.shadowRoot.innerHTML = `
|
|
33
|
+
<style>
|
|
34
|
+
:host {
|
|
35
|
+
display: block;
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 400px;
|
|
38
|
+
border-radius: var(--radius-lg);
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
background: var(--afri-charcoal);
|
|
41
|
+
position: relative;
|
|
42
|
+
}
|
|
43
|
+
#container {
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
}
|
|
47
|
+
.loader {
|
|
48
|
+
position: absolute;
|
|
49
|
+
top: 50%; left: 50%;
|
|
50
|
+
transform: translate(-50%, -50%);
|
|
51
|
+
color: var(--afri-gold);
|
|
52
|
+
font-family: var(--font-logo);
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
55
|
+
<div id="container"></div>
|
|
56
|
+
<div class="loader">Loading Artifact...</div>
|
|
57
|
+
`;
|
|
58
|
+
this.container = this.shadowRoot.getElementById('container');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
initThree() {
|
|
62
|
+
const width = this.clientWidth || 300;
|
|
63
|
+
const height = this.clientHeight || 400;
|
|
64
|
+
|
|
65
|
+
// Scene
|
|
66
|
+
this.scene = new THREE.Scene();
|
|
67
|
+
this.scene.background = new THREE.Color('#1e293b'); // Matches afri-charcoal
|
|
68
|
+
|
|
69
|
+
// Camera
|
|
70
|
+
this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
|
|
71
|
+
this.camera.position.z = 5;
|
|
72
|
+
|
|
73
|
+
// Renderer
|
|
74
|
+
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
75
|
+
this.renderer.setSize(width, height);
|
|
76
|
+
this.container.appendChild(this.renderer.domElement);
|
|
77
|
+
|
|
78
|
+
// Lights
|
|
79
|
+
const light = new THREE.AmbientLight(0x404040, 2); // Soft white light
|
|
80
|
+
this.scene.add(light);
|
|
81
|
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
|
|
82
|
+
directionalLight.position.set(1, 1, 1);
|
|
83
|
+
this.scene.add(directionalLight);
|
|
84
|
+
|
|
85
|
+
// Controls
|
|
86
|
+
const controls = new OrbitControls(this.camera, this.renderer.domElement);
|
|
87
|
+
controls.enableDamping = true;
|
|
88
|
+
|
|
89
|
+
// Initial Geometry (Placeholder if no src)
|
|
90
|
+
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
|
|
91
|
+
const material = new THREE.MeshStandardMaterial({
|
|
92
|
+
color: 0xffb700, // afri-gold
|
|
93
|
+
metalness: 0.5,
|
|
94
|
+
roughness: 0.1
|
|
95
|
+
});
|
|
96
|
+
const cube = new THREE.Mesh(geometry, material);
|
|
97
|
+
this.scene.add(cube);
|
|
98
|
+
this.shadowRoot.querySelector('.loader').style.display = 'none';
|
|
99
|
+
|
|
100
|
+
// Animation Loop
|
|
101
|
+
const animate = () => {
|
|
102
|
+
requestAnimationFrame(animate);
|
|
103
|
+
|
|
104
|
+
if (this.hasAttribute('auto-rotate')) {
|
|
105
|
+
cube.rotation.x += 0.01;
|
|
106
|
+
cube.rotation.y += 0.01;
|
|
107
|
+
}
|
|
108
|
+
controls.update();
|
|
109
|
+
this.renderer.render(this.scene, this.camera);
|
|
110
|
+
};
|
|
111
|
+
animate();
|
|
112
|
+
|
|
113
|
+
// Resize Handler
|
|
114
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
115
|
+
const w = this.clientWidth;
|
|
116
|
+
const h = this.clientHeight;
|
|
117
|
+
this.camera.aspect = w / h;
|
|
118
|
+
this.camera.updateProjectionMatrix();
|
|
119
|
+
this.renderer.setSize(w, h);
|
|
120
|
+
});
|
|
121
|
+
resizeObserver.observe(this);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
registerComponent('af-model-viewer', AfriModelViewer);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "africode-starter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "africode dev",
|
|
8
|
+
"build": "africode build",
|
|
9
|
+
"migrate": "africode migrate"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"africode": "^2.4.0",
|
|
13
|
+
"three": "^0.160.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Welcome to AfriCode</title>
|
|
8
|
+
|
|
9
|
+
<!-- Theme -->
|
|
10
|
+
<link rel="stylesheet" href="/node_modules/africode/styles/africanity.css">
|
|
11
|
+
<link rel="stylesheet" href="/node_modules/africode/styles/typography.css">
|
|
12
|
+
<link rel="stylesheet" href="/styles/main.css">
|
|
13
|
+
<script type="module" src="/node_modules/africode/core/sdk.js"></script>
|
|
14
|
+
|
|
15
|
+
<!-- SDK & Components -->
|
|
16
|
+
<script type="module">
|
|
17
|
+
import 'africode/components';
|
|
18
|
+
import { store } from 'africode';
|
|
19
|
+
|
|
20
|
+
console.log('AfriCode State Engine:', store);
|
|
21
|
+
</script>
|
|
22
|
+
</head>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
<af-navbar logo="Starter App" theme="dark"></af-navbar>
|
|
26
|
+
|
|
27
|
+
<main style="max-width: 1200px; margin: 0 auto; padding: 40px;">
|
|
28
|
+
<af-hero title="Umoja" subtitle="You are running on the AfriCode Framework." pattern="kente">
|
|
29
|
+
</af-hero>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-top: 40px;">
|
|
33
|
+
<af-card title="Getting Started">
|
|
34
|
+
<p>Edit <code>pages/index.html</code> to change this page.</p>
|
|
35
|
+
<af-button variant="primary">Read Docs</af-button>
|
|
36
|
+
</af-card>
|
|
37
|
+
|
|
38
|
+
<af-kanga-card proverb="Haba na haba hujaza kibaba.">
|
|
39
|
+
<h3>Steady Progress</h3>
|
|
40
|
+
<p>Little by little fills the measure.</p>
|
|
41
|
+
</af-kanga-card>
|
|
42
|
+
</div>
|
|
43
|
+
</main>
|
|
44
|
+
</body>
|
|
45
|
+
|
|
46
|
+
</html>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { html, Layout } from 'africode';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Home Page
|
|
5
|
+
* Route: /
|
|
6
|
+
*/
|
|
7
|
+
export default function HomePage() {
|
|
8
|
+
return Layout({
|
|
9
|
+
title: "Welcome to AfriCode",
|
|
10
|
+
children: html`
|
|
11
|
+
<script type="module" src="/components/af-model-viewer.js"></script>
|
|
12
|
+
<af-navbar logo="AfriCode 3D" theme="dark"></af-navbar>
|
|
13
|
+
|
|
14
|
+
<main style="max-width: 1200px; margin: 0 auto; padding: 40px;">
|
|
15
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center;">
|
|
16
|
+
<div>
|
|
17
|
+
<h1 style="font-size: 3.5rem; background: linear-gradient(to right, var(--kente-gold), var(--maasai-red)); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
|
|
18
|
+
Future Heritage.
|
|
19
|
+
</h1>
|
|
20
|
+
<p style="font-size: 1.2rem; opacity: 0.8; line-height: 1.6;">
|
|
21
|
+
Experience the fusion of African artistry and WebGL performance.
|
|
22
|
+
This starter comes pre-configured with <b>Three.js</b>.
|
|
23
|
+
</p>
|
|
24
|
+
<div style="margin-top: 30px; display: flex; gap: 15px;">
|
|
25
|
+
<af-button variant="primary">Read Docs</af-button>
|
|
26
|
+
<af-button variant="outline">Explore 3D Assets</af-button>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div style="background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 20px; padding: 20px;">
|
|
31
|
+
<af-model-viewer auto-rotate></af-model-viewer>
|
|
32
|
+
<div style="text-align: center; margin-top: 15px; font-size: 0.9rem; opacity: 0.6;">
|
|
33
|
+
Interact with the model directly in the browser.
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div style="margin-top: 80px;">
|
|
39
|
+
<af-accordion>
|
|
40
|
+
<div slot="header">🏛️ How is this configured?</div>
|
|
41
|
+
<div slot="content">
|
|
42
|
+
Check <code>components/af-model-viewer.js</code>. We use a standard Custom Element that wraps a Three.js scene.
|
|
43
|
+
State updates are handled via attributes.
|
|
44
|
+
</div>
|
|
45
|
+
</af-accordion>
|
|
46
|
+
</div>
|
|
47
|
+
</main>
|
|
48
|
+
`
|
|
49
|
+
});
|
|
50
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# AfriCode Environment Configuration
|
|
2
|
+
|
|
3
|
+
# Server Settings
|
|
4
|
+
PORT=3000
|
|
5
|
+
NODE_ENV=development
|
|
6
|
+
|
|
7
|
+
# Database Settings
|
|
8
|
+
DB_FILE=./data.db
|
|
9
|
+
|
|
10
|
+
# Security
|
|
11
|
+
SESSION_SECRET=replace_this_with_a_long_random_string
|
|
12
|
+
JWT_SECRET=replace_this_with_another_long_random_string
|
|
13
|
+
|
|
14
|
+
# API Keys (Add yours here)
|
|
15
|
+
# PUBLIC_API_URL=http://localhost:3000
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AfriCode Framework Configuration
|
|
3
|
+
*/
|
|
4
|
+
export default {
|
|
5
|
+
// Project entry point
|
|
6
|
+
entry: 'src/index.js',
|
|
7
|
+
|
|
8
|
+
// Server Configuration
|
|
9
|
+
server: {
|
|
10
|
+
port: process.env.PORT || 3000,
|
|
11
|
+
host: '0.0.0.0',
|
|
12
|
+
staticDir: 'public',
|
|
13
|
+
cors: true
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
// Directory structure mapping
|
|
17
|
+
directories: {
|
|
18
|
+
src: 'src',
|
|
19
|
+
pages: 'src/pages',
|
|
20
|
+
components: 'src/components',
|
|
21
|
+
styles: 'src/styles',
|
|
22
|
+
build: 'dist'
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Database Configuration (SQLite)
|
|
26
|
+
database: {
|
|
27
|
+
client: 'sqlite',
|
|
28
|
+
connection: {
|
|
29
|
+
filename: process.env.DB_FILE || './data.db'
|
|
30
|
+
},
|
|
31
|
+
useNullAsDefault: true,
|
|
32
|
+
walMode: true // Write-Ahead Logging for performance
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
// Theme defaults
|
|
36
|
+
theme: {
|
|
37
|
+
default: 'dark',
|
|
38
|
+
toggleAttribute: 'data-theme'
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "africode-react-starter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "africode dev",
|
|
8
|
+
"build": "africode build",
|
|
9
|
+
"migrate": "africode migrate"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"africode": "^1.0.0",
|
|
13
|
+
"react": "^19.0.0",
|
|
14
|
+
"react-dom": "^19.0.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Welcome to AfriCode</title>
|
|
8
|
+
|
|
9
|
+
<!-- Theme -->
|
|
10
|
+
<link rel="stylesheet" href="/node_modules/africode/styles/africanity.css">
|
|
11
|
+
<link rel="stylesheet" href="/node_modules/africode/styles/typography.css">
|
|
12
|
+
<link rel="stylesheet" href="/styles/main.css">
|
|
13
|
+
<script type="module" src="/node_modules/africode/core/sdk.js"></script>
|
|
14
|
+
|
|
15
|
+
<!-- SDK & Components -->
|
|
16
|
+
<script type="module">
|
|
17
|
+
import 'africode/components';
|
|
18
|
+
import { store } from 'africode';
|
|
19
|
+
|
|
20
|
+
console.log('AfriCode State Engine:', store);
|
|
21
|
+
</script>
|
|
22
|
+
</head>
|
|
23
|
+
|
|
24
|
+
<body>
|
|
25
|
+
<af-navbar logo="Starter App" theme="dark"></af-navbar>
|
|
26
|
+
|
|
27
|
+
<main style="max-width: 1200px; margin: 0 auto; padding: 40px;">
|
|
28
|
+
<af-hero title="Umoja" subtitle="You are running on the AfriCode Framework." pattern="kente">
|
|
29
|
+
</af-hero>
|
|
30
|
+
|
|
31
|
+
<div
|
|
32
|
+
style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-top: 40px;">
|
|
33
|
+
<af-card title="Getting Started">
|
|
34
|
+
<p>Edit <code>pages/index.html</code> to change this page.</p>
|
|
35
|
+
<af-button variant="primary">Read Docs</af-button>
|
|
36
|
+
</af-card>
|
|
37
|
+
|
|
38
|
+
<af-kanga-card proverb="Haba na haba hujaza kibaba.">
|
|
39
|
+
<h3>Steady Progress</h3>
|
|
40
|
+
<p>Little by little fills the measure.</p>
|
|
41
|
+
</af-kanga-card>
|
|
42
|
+
</div>
|
|
43
|
+
</main>
|
|
44
|
+
</body>
|
|
45
|
+
|
|
46
|
+
</html>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { html, Layout } from 'africode';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Home Page — React Interop Starter
|
|
5
|
+
* Route: /
|
|
6
|
+
*
|
|
7
|
+
* This starter demonstrates mounting React components inside AfriCode
|
|
8
|
+
* pages using the <af-react> wrapper component.
|
|
9
|
+
*
|
|
10
|
+
* The React component is loaded via a client-side island script.
|
|
11
|
+
*/
|
|
12
|
+
export default function HomePage() {
|
|
13
|
+
return Layout({
|
|
14
|
+
title: "AfriCode + React",
|
|
15
|
+
children: html`
|
|
16
|
+
<af-navbar logo="React App" theme="dark"></af-navbar>
|
|
17
|
+
|
|
18
|
+
<main style="max-width: 1000px; margin: 0 auto; padding: 40px;">
|
|
19
|
+
<af-hero
|
|
20
|
+
title="AfriCode + React"
|
|
21
|
+
subtitle="React components as islands inside a Bun-first framework."
|
|
22
|
+
pattern="kente">
|
|
23
|
+
</af-hero>
|
|
24
|
+
|
|
25
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; margin-top: 40px;">
|
|
26
|
+
<af-card>
|
|
27
|
+
<h3>Islands Architecture</h3>
|
|
28
|
+
<p>React mounts inside <code><af-react></code> Web Components. AfriCode handles routing, builds, and HMR.</p>
|
|
29
|
+
</af-card>
|
|
30
|
+
|
|
31
|
+
<af-card>
|
|
32
|
+
<h3>State Bridge</h3>
|
|
33
|
+
<p>Use <code>useAfriCodeStore()</code> to subscribe React components to AfriCode's reactive state.</p>
|
|
34
|
+
</af-card>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<af-section title="Live React Island" variant="muted">
|
|
38
|
+
<af-react id="react-counter"></af-react>
|
|
39
|
+
</af-section>
|
|
40
|
+
</main>
|
|
41
|
+
|
|
42
|
+
<script type="module">
|
|
43
|
+
import React, { useState } from 'react';
|
|
44
|
+
import { AfriReact } from 'africode/components/react.js';
|
|
45
|
+
|
|
46
|
+
function Counter() {
|
|
47
|
+
const [count, setCount] = useState(0);
|
|
48
|
+
return React.createElement('div', { style: { padding: '24px', textAlign: 'center' } },
|
|
49
|
+
React.createElement('h3', { style: { color: 'var(--text-primary)' } }, 'React Counter'),
|
|
50
|
+
React.createElement('p', { style: { fontSize: '2rem', margin: '16px 0' } }, count),
|
|
51
|
+
React.createElement('button', {
|
|
52
|
+
onClick: () => setCount(c => c + 1),
|
|
53
|
+
style: {
|
|
54
|
+
padding: '10px 24px',
|
|
55
|
+
background: 'linear-gradient(135deg, #1eb53a, #fcd116)',
|
|
56
|
+
border: 'none', borderRadius: '8px',
|
|
57
|
+
fontWeight: 700, cursor: 'pointer'
|
|
58
|
+
}
|
|
59
|
+
}, 'Increment')
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const wrapper = document.getElementById('react-counter');
|
|
64
|
+
if (wrapper) wrapper.mount(Counter);
|
|
65
|
+
</script>
|
|
66
|
+
`
|
|
67
|
+
});
|
|
68
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# AfriCode Environment Configuration
|
|
2
|
+
|
|
3
|
+
# Server Settings
|
|
4
|
+
PORT=3000
|
|
5
|
+
NODE_ENV=development
|
|
6
|
+
|
|
7
|
+
# Database Settings
|
|
8
|
+
DB_FILE=./data.db
|
|
9
|
+
|
|
10
|
+
# Security
|
|
11
|
+
SESSION_SECRET=replace_this_with_a_long_random_string
|
|
12
|
+
JWT_SECRET=replace_this_with_another_long_random_string
|
|
13
|
+
|
|
14
|
+
# API Keys (Add yours here)
|
|
15
|
+
# PUBLIC_API_URL=http://localhost:3000
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AfriCode Framework Configuration
|
|
3
|
+
*/
|
|
4
|
+
export default {
|
|
5
|
+
// Project entry point
|
|
6
|
+
entry: 'src/index.js',
|
|
7
|
+
|
|
8
|
+
// Server Configuration
|
|
9
|
+
server: {
|
|
10
|
+
port: process.env.PORT || 3000,
|
|
11
|
+
host: '0.0.0.0',
|
|
12
|
+
staticDir: 'public',
|
|
13
|
+
cors: true
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
// Directory structure mapping
|
|
17
|
+
directories: {
|
|
18
|
+
src: 'src',
|
|
19
|
+
pages: 'src/pages',
|
|
20
|
+
components: 'src/components',
|
|
21
|
+
styles: 'src/styles',
|
|
22
|
+
build: 'dist'
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Database Configuration (SQLite)
|
|
26
|
+
database: {
|
|
27
|
+
client: 'sqlite',
|
|
28
|
+
connection: {
|
|
29
|
+
filename: process.env.DB_FILE || './data.db'
|
|
30
|
+
},
|
|
31
|
+
useNullAsDefault: true,
|
|
32
|
+
walMode: true // Write-Ahead Logging for performance
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
// Theme defaults
|
|
36
|
+
theme: {
|
|
37
|
+
default: 'dark',
|
|
38
|
+
toggleAttribute: 'data-theme'
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "africode-tailwind-starter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "concurrently \"africode dev\" \"npx @tailwindcss/cli -i ./src/styles/tailwind.css -o ./src/styles/tailwind.out.css --watch\"",
|
|
8
|
+
"build:css": "npx @tailwindcss/cli -i ./src/styles/tailwind.css -o ./src/styles/tailwind.out.css --minify",
|
|
9
|
+
"build": "npm run build:css && africode build",
|
|
10
|
+
"migrate": "africode migrate"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"africode": "^1.0.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@tailwindcss/cli": "^4.0.0",
|
|
17
|
+
"tailwindcss": "^4.0.0",
|
|
18
|
+
"concurrently": "^9.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|