@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.
Files changed (136) hide show
  1. package/AFRICODE_FRAMEWORK_GUIDE.md +707 -0
  2. package/LICENSE +623 -0
  3. package/README.md +442 -0
  4. package/bin/africode.js +73 -0
  5. package/bin/africode.js.1758507140 +343 -0
  6. package/bin/cli.ts +83 -0
  7. package/bin/create-africode.js +158 -0
  8. package/bin/scaffold.ts +219 -0
  9. package/components/accordion.js +183 -0
  10. package/components/alert.js +131 -0
  11. package/components/auth.js +172 -0
  12. package/components/avatar.js +117 -0
  13. package/components/badge.js +104 -0
  14. package/components/base.d.ts +139 -0
  15. package/components/base.js +184 -0
  16. package/components/button.js +164 -0
  17. package/components/card.js +137 -0
  18. package/components/cultural-card.js +243 -0
  19. package/components/divider.js +83 -0
  20. package/components/dropdown.js +171 -0
  21. package/components/error-boundary.js +155 -0
  22. package/components/form.js +131 -0
  23. package/components/grid.js +273 -0
  24. package/components/hero.js +138 -0
  25. package/components/icon.js +36 -0
  26. package/components/index.js +57 -0
  27. package/components/input.js +256 -0
  28. package/components/kanga-card.js +185 -0
  29. package/components/language-switcher.js +108 -0
  30. package/components/loader.js +80 -0
  31. package/components/modal.js +262 -0
  32. package/components/motion.js +84 -0
  33. package/components/navbar.js +236 -0
  34. package/components/pattern-showcase.js +225 -0
  35. package/components/progress.js +134 -0
  36. package/components/react.js +111 -0
  37. package/components/section.js +54 -0
  38. package/components/select.js +322 -0
  39. package/components/sidebar.js +180 -0
  40. package/components/skeleton.js +85 -0
  41. package/components/table.js +181 -0
  42. package/components/tabs.js +202 -0
  43. package/components/theme-toggle.js +82 -0
  44. package/components/toast.js +139 -0
  45. package/components/tooltip.js +167 -0
  46. package/core/a2ui-schema-manager.js +344 -0
  47. package/core/a2ui.js +431 -0
  48. package/core/bun-runtime.js +799 -0
  49. package/core/cli/commands/add.js +23 -0
  50. package/core/cli/commands/audit.js +58 -0
  51. package/core/cli/commands/build.js +137 -0
  52. package/core/cli/commands/create-plugin.js +241 -0
  53. package/core/cli/commands/dev.js +228 -0
  54. package/core/cli/commands/lint.js +23 -0
  55. package/core/cli/commands/test.js +34 -0
  56. package/core/cli/migrator.js +71 -0
  57. package/core/cli/ui.js +46 -0
  58. package/core/compliance.js +628 -0
  59. package/core/config.js +263 -0
  60. package/core/db-advanced.js +481 -0
  61. package/core/db.js +284 -0
  62. package/core/enhanced-hmr.js +404 -0
  63. package/core/errors.js +222 -0
  64. package/core/file-router.js +290 -0
  65. package/core/heartbeat.js +64 -0
  66. package/core/hmr-client.js +204 -0
  67. package/core/hmr.js +196 -0
  68. package/core/html.d.ts +116 -0
  69. package/core/html.js +160 -0
  70. package/core/hydration.js +52 -0
  71. package/core/lipa-namba-journey.js +572 -0
  72. package/core/motion.js +106 -0
  73. package/core/nida-cig-middleware.js +455 -0
  74. package/core/patterns.d.ts +124 -0
  75. package/core/patterns.js +833 -0
  76. package/core/plugins/index.js +312 -0
  77. package/core/router.js +387 -0
  78. package/core/sdk-client.js +62 -0
  79. package/core/sdk.d.ts +133 -0
  80. package/core/sdk.js +123 -0
  81. package/core/seo.js +76 -0
  82. package/core/server/auth-endpoints.js +339 -0
  83. package/core/server/auth.js +180 -0
  84. package/core/server/csrf.js +206 -0
  85. package/core/server/db.js +39 -0
  86. package/core/server/middleware.js +324 -0
  87. package/core/server/rate-limit.js +238 -0
  88. package/core/server/render.js +69 -0
  89. package/core/server/router.js +120 -0
  90. package/core/shim.js +28 -0
  91. package/core/state.d.ts +86 -0
  92. package/core/state.js +242 -0
  93. package/core/store.d.ts +122 -0
  94. package/core/store.js +61 -0
  95. package/core/validation.d.ts +233 -0
  96. package/core/validation.js +590 -0
  97. package/core/websocket.js +639 -0
  98. package/dist/africode.js +2905 -0
  99. package/dist/africode.js.map +61 -0
  100. package/dist/build-info.json +23 -0
  101. package/dist/components.js +2888 -0
  102. package/dist/components.js.map +58 -0
  103. package/dist/styles/africanity.css +322 -0
  104. package/dist/styles/typography.css +141 -0
  105. package/docs/IDE-Guide.md +50 -0
  106. package/package.json +110 -0
  107. package/src/index.ts +196 -0
  108. package/styles/africanity.css +322 -0
  109. package/styles/typography.css +141 -0
  110. package/templates/starter/.env.example +15 -0
  111. package/templates/starter/africode.config.js +40 -0
  112. package/templates/starter/package.json +14 -0
  113. package/templates/starter/src/pages/index.html +46 -0
  114. package/templates/starter/src/pages/index.js +32 -0
  115. package/templates/starter/src/styles/main.css +4 -0
  116. package/templates/starter-3d/.env.example +7 -0
  117. package/templates/starter-3d/africode.config.js +29 -0
  118. package/templates/starter-3d/components/af-model-viewer.js +125 -0
  119. package/templates/starter-3d/package.json +15 -0
  120. package/templates/starter-3d/src/pages/index.html +46 -0
  121. package/templates/starter-3d/src/pages/index.js +50 -0
  122. package/templates/starter-3d/src/styles/main.css +4 -0
  123. package/templates/starter-react/.env.example +15 -0
  124. package/templates/starter-react/africode.config.js +40 -0
  125. package/templates/starter-react/package.json +16 -0
  126. package/templates/starter-react/src/pages/index.html +46 -0
  127. package/templates/starter-react/src/pages/index.js +68 -0
  128. package/templates/starter-react/src/styles/main.css +4 -0
  129. package/templates/starter-tailwind/.env.example +15 -0
  130. package/templates/starter-tailwind/africode.config.js +40 -0
  131. package/templates/starter-tailwind/package.json +20 -0
  132. package/templates/starter-tailwind/src/pages/index.html +46 -0
  133. package/templates/starter-tailwind/src/pages/index.js +37 -0
  134. package/templates/starter-tailwind/src/styles/main.css +4 -0
  135. package/templates/starter-tailwind/src/styles/tailwind.css +1 -0
  136. 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,4 @@
1
+ /* Custom Application Styles */
2
+ :root {
3
+ --brand-color: #FCD116;
4
+ }
@@ -0,0 +1,7 @@
1
+ # AfriCode Environment Configuration (3D Starter)
2
+
3
+ PORT=3000
4
+ NODE_ENV=development
5
+ DB_FILE=./data.db
6
+ SESSION_SECRET=replace_this_with_a_long_random_string
7
+ JWT_SECRET=replace_this_with_another_long_random_string
@@ -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,4 @@
1
+ /* Custom Application Styles */
2
+ :root {
3
+ --brand-color: #FCD116;
4
+ }
@@ -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>&lt;af-react&gt;</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,4 @@
1
+ /* Custom Application Styles */
2
+ :root {
3
+ --brand-color: #FCD116;
4
+ }
@@ -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
+ }