@jxrstudios/jxr 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/bin/jxr.js +6 -0
  2. package/dist/index.d.ts +43 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +57 -2
  5. package/dist/jxr-server-manager.d.ts.map +1 -1
  6. package/package.json +1 -1
  7. package/src/jxr-server-manager.ts +57 -1
  8. package/zzz_react_template/App.tsx +43 -156
  9. package/zzz_react_template/components/ErrorBoundary.tsx +62 -0
  10. package/zzz_react_template/components/ManusDialog.tsx +85 -0
  11. package/zzz_react_template/components/Map.tsx +155 -0
  12. package/zzz_react_template/components/jxr/CodeEditor.tsx +313 -0
  13. package/zzz_react_template/components/jxr/FileExplorer.tsx +230 -0
  14. package/zzz_react_template/components/jxr/IDEShell.tsx +159 -0
  15. package/zzz_react_template/components/jxr/LandingPage.tsx +414 -0
  16. package/zzz_react_template/components/jxr/LivePreview.tsx +169 -0
  17. package/zzz_react_template/components/jxr/PerformanceDashboard.tsx +379 -0
  18. package/zzz_react_template/components/jxr/TopBar.tsx +149 -0
  19. package/zzz_react_template/components/ui/accordion.tsx +64 -0
  20. package/zzz_react_template/components/ui/alert-dialog.tsx +155 -0
  21. package/zzz_react_template/components/ui/alert.tsx +66 -0
  22. package/zzz_react_template/components/ui/aspect-ratio.tsx +9 -0
  23. package/zzz_react_template/components/ui/avatar.tsx +51 -0
  24. package/zzz_react_template/components/ui/badge.tsx +46 -0
  25. package/zzz_react_template/components/ui/breadcrumb.tsx +109 -0
  26. package/zzz_react_template/components/ui/button-group.tsx +83 -0
  27. package/zzz_react_template/components/ui/button.tsx +60 -0
  28. package/zzz_react_template/components/ui/calendar.tsx +211 -0
  29. package/zzz_react_template/components/ui/card.tsx +92 -0
  30. package/zzz_react_template/components/ui/carousel.tsx +239 -0
  31. package/zzz_react_template/components/ui/chart.tsx +355 -0
  32. package/zzz_react_template/components/ui/checkbox.tsx +30 -0
  33. package/zzz_react_template/components/ui/collapsible.tsx +31 -0
  34. package/zzz_react_template/components/ui/command.tsx +184 -0
  35. package/zzz_react_template/components/ui/context-menu.tsx +250 -0
  36. package/zzz_react_template/components/ui/dialog.tsx +209 -0
  37. package/zzz_react_template/components/ui/drawer.tsx +133 -0
  38. package/zzz_react_template/components/ui/dropdown-menu.tsx +255 -0
  39. package/zzz_react_template/components/ui/empty.tsx +104 -0
  40. package/zzz_react_template/components/ui/field.tsx +242 -0
  41. package/zzz_react_template/components/ui/form.tsx +168 -0
  42. package/zzz_react_template/components/ui/hover-card.tsx +42 -0
  43. package/zzz_react_template/components/ui/input-group.tsx +168 -0
  44. package/zzz_react_template/components/ui/input-otp.tsx +75 -0
  45. package/zzz_react_template/components/ui/input.tsx +70 -0
  46. package/zzz_react_template/components/ui/item.tsx +193 -0
  47. package/zzz_react_template/components/ui/kbd.tsx +28 -0
  48. package/zzz_react_template/components/ui/label.tsx +22 -0
  49. package/zzz_react_template/components/ui/menubar.tsx +274 -0
  50. package/zzz_react_template/components/ui/navigation-menu.tsx +168 -0
  51. package/zzz_react_template/components/ui/pagination.tsx +127 -0
  52. package/zzz_react_template/components/ui/popover.tsx +46 -0
  53. package/zzz_react_template/components/ui/progress.tsx +29 -0
  54. package/zzz_react_template/components/ui/radio-group.tsx +43 -0
  55. package/zzz_react_template/components/ui/resizable.tsx +54 -0
  56. package/zzz_react_template/components/ui/scroll-area.tsx +56 -0
  57. package/zzz_react_template/components/ui/select.tsx +185 -0
  58. package/zzz_react_template/components/ui/separator.tsx +26 -0
  59. package/zzz_react_template/components/ui/sheet.tsx +139 -0
  60. package/zzz_react_template/components/ui/sidebar.tsx +734 -0
  61. package/zzz_react_template/components/ui/skeleton.tsx +13 -0
  62. package/zzz_react_template/components/ui/slider.tsx +61 -0
  63. package/zzz_react_template/components/ui/sonner.tsx +23 -0
  64. package/zzz_react_template/components/ui/spinner.tsx +16 -0
  65. package/zzz_react_template/components/ui/switch.tsx +29 -0
  66. package/zzz_react_template/components/ui/table.tsx +114 -0
  67. package/zzz_react_template/components/ui/tabs.tsx +64 -0
  68. package/zzz_react_template/components/ui/textarea.tsx +67 -0
  69. package/zzz_react_template/components/ui/toggle-group.tsx +73 -0
  70. package/zzz_react_template/components/ui/toggle.tsx +45 -0
  71. package/zzz_react_template/components/ui/tooltip.tsx +59 -0
  72. package/zzz_react_template/const.ts +17 -0
  73. package/zzz_react_template/contexts/JXRContext.tsx +264 -0
  74. package/zzz_react_template/contexts/ThemeContext.tsx +64 -0
  75. package/zzz_react_template/hooks/useComposition.ts +81 -0
  76. package/zzz_react_template/hooks/useMobile.tsx +21 -0
  77. package/zzz_react_template/hooks/usePersistFn.ts +20 -0
  78. package/zzz_react_template/index.css +518 -11
  79. package/zzz_react_template/lib/jxr-runtime/index.ts +201 -0
  80. package/zzz_react_template/lib/jxr-runtime/module-resolver.ts +520 -0
  81. package/zzz_react_template/lib/jxr-runtime/moq-transport.ts +267 -0
  82. package/zzz_react_template/lib/jxr-runtime/web-crypto.ts +279 -0
  83. package/zzz_react_template/lib/jxr-runtime/worker-pool.ts +321 -0
  84. package/zzz_react_template/lib/utils.ts +6 -0
  85. package/zzz_react_template/main.tsx +4 -9
  86. package/zzz_react_template/pages/Docs.tsx +955 -0
  87. package/zzz_react_template/pages/Home.tsx +1080 -0
  88. package/zzz_react_template/pages/NotFound.tsx +105 -0
  89. package/zzz_react_template/tsconfig.json +24 -0
package/bin/jxr.js CHANGED
@@ -55,6 +55,12 @@ if (command === "init") {
55
55
  );
56
56
  }
57
57
 
58
+ // Copy tsconfig.json
59
+ await cp(
60
+ path.join(templateDir, "tsconfig.json"),
61
+ path.join(projectDir, "tsconfig.json")
62
+ );
63
+
58
64
  console.log(`✅ Project created: ${projectDir}`);
59
65
  console.log("");
60
66
  console.log("Next steps:");
package/dist/index.d.ts CHANGED
@@ -26,4 +26,47 @@ export { JXRServerManager } from './jxr-server-manager.ts';
26
26
  export type { JXRServerConfig } from './jxr-server-manager.ts';
27
27
  export { JXRDeployer, jxrDeployer } from './deployer.ts';
28
28
  export type { DeployConfig, DeployResult, DeploymentStatus } from './deployer.ts';
29
+ export interface JXRConfig {
30
+ name: string;
31
+ platform: 'web' | 'native' | 'expo' | 'cloudflare-worker' | 'deno' | 'node';
32
+ workers?: {
33
+ size?: number;
34
+ enablePriority?: boolean;
35
+ maxQueueSize?: number;
36
+ taskTimeout?: number;
37
+ };
38
+ moq?: {
39
+ enabled?: boolean;
40
+ relayUrl?: string;
41
+ trackPriority?: 'high' | 'normal' | 'low';
42
+ maxSubscriptions?: number;
43
+ reconnectDelay?: number;
44
+ };
45
+ crypto?: {
46
+ enabled?: boolean;
47
+ algorithm?: 'AES-GCM' | 'AES-CBC';
48
+ keySize?: number;
49
+ signing?: boolean;
50
+ keyDerivation?: 'HKDF';
51
+ };
52
+ build?: {
53
+ entry?: string;
54
+ outDir?: string;
55
+ minify?: boolean;
56
+ sourcemap?: boolean;
57
+ splitting?: 'auto' | 'manual' | false;
58
+ target?: string[];
59
+ external?: string[];
60
+ };
61
+ devServer?: {
62
+ port?: number;
63
+ host?: string;
64
+ hmr?: boolean;
65
+ open?: boolean;
66
+ https?: boolean;
67
+ };
68
+ imports?: Record<string, string>;
69
+ plugins?: any[];
70
+ }
71
+ export declare function defineConfig(config: JXRConfig): JXRConfig;
29
72
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EACV,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,SAAS,GACV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1815,7 +1815,55 @@ var JXRServerManager = class {
1815
1815
  return;
1816
1816
  }
1817
1817
  if (vfsPath.endsWith(".css")) {
1818
- const escapedCSS = file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
1818
+ let cssContent = file.content;
1819
+ if (vfsPath === "/src/index.css") {
1820
+ try {
1821
+ const fs = await import("fs");
1822
+ const compiledPath = path.join(process.cwd(), "src", "index.compiled.css");
1823
+ if (fs.existsSync(compiledPath)) {
1824
+ cssContent = fs.readFileSync(compiledPath, "utf-8");
1825
+ console.log(`[JXR] Using pre-compiled Tailwind CSS from index.compiled.css`);
1826
+ } else {
1827
+ const { execSync } = await import("child_process");
1828
+ const os = await import("os");
1829
+ const tmpDir = os.tmpdir();
1830
+ const inputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.css`);
1831
+ const outputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.compiled.css`);
1832
+ fs.writeFileSync(inputFile, cssContent);
1833
+ try {
1834
+ execSync(`npx @tailwindcss/cli -i "${inputFile}" -o "${outputFile}" --minify`, {
1835
+ timeout: 3e4,
1836
+ stdio: "pipe"
1837
+ });
1838
+ cssContent = fs.readFileSync(outputFile, "utf-8");
1839
+ fs.unlinkSync(inputFile);
1840
+ fs.unlinkSync(outputFile);
1841
+ console.log(`[JXR] Compiled Tailwind CSS for ${vfsPath}`);
1842
+ } catch {
1843
+ const js2 = `
1844
+ const tailwindScript = document.createElement('script');
1845
+ tailwindScript.src = 'https://cdn.tailwindcss.com';
1846
+ tailwindScript.onload = function() {
1847
+ const style = document.createElement('style');
1848
+ style.textContent = \`${file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;
1849
+ document.head.appendChild(style);
1850
+ };
1851
+ document.head.appendChild(tailwindScript);
1852
+ export default \`${file.content.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;
1853
+ `;
1854
+ res.writeHead(200, {
1855
+ "Content-Type": "application/javascript",
1856
+ "Cache-Control": "no-cache"
1857
+ });
1858
+ res.end(js2);
1859
+ return;
1860
+ }
1861
+ }
1862
+ } catch (error) {
1863
+ console.warn(`[JXR] Tailwind handling error: ${error?.message || error}`);
1864
+ }
1865
+ }
1866
+ const escapedCSS = cssContent.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
1819
1867
  const js = `
1820
1868
  const style = document.createElement('style');
1821
1869
  style.textContent = \`${escapedCSS}\`;
@@ -1936,7 +1984,8 @@ export default \`${escapedCSS}\`;
1936
1984
  "clsx": "https://esm.sh/clsx@2.1.1",
1937
1985
  "tailwind-merge": "https://esm.sh/tailwind-merge@3.0.2",
1938
1986
  "class-variance-authority": "https://esm.sh/class-variance-authority@0.7.1",
1939
- "framer-motion": "https://esm.sh/framer-motion@12.5.0?external=react"
1987
+ "framer-motion": "https://esm.sh/framer-motion@12.5.0?external=react,motion-dom",
1988
+ "motion-dom": "https://esm.sh/motion-dom@12.5.0"
1940
1989
  }
1941
1990
  };
1942
1991
  const hasMainFile = this.projectFiles.some(
@@ -2135,6 +2184,11 @@ var jxrDeployer = new JXRDeployer(
2135
2184
  process.env.JXR_API_KEY || "",
2136
2185
  process.env.JXR_PROJECT_ID
2137
2186
  );
2187
+
2188
+ // src/index.ts
2189
+ function defineConfig(config) {
2190
+ return config;
2191
+ }
2138
2192
  export {
2139
2193
  DEFAULT_PROJECT_FILES,
2140
2194
  EnhancedTranspiler,
@@ -2148,6 +2202,7 @@ export {
2148
2202
  ModuleCache,
2149
2203
  VirtualFS,
2150
2204
  WorkerPool,
2205
+ defineConfig,
2151
2206
  findOrCreateEntryPoint,
2152
2207
  jxrCrypto,
2153
2208
  jxrDeployer,
@@ -1 +1 @@
1
- {"version":3,"file":"jxr-server-manager.d.ts","sourceRoot":"","sources":["../src/jxr-server-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAuC;gBAE1C,MAAM,GAAE,eAAoB;IAYlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,gBAAgB;IAoC9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,cAAc;YAUR,qBAAqB;IA2BnC,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2HtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B,OAAO,CAAC,YAAY;CA8GrB"}
1
+ {"version":3,"file":"jxr-server-manager.d.ts","sourceRoot":"","sources":["../src/jxr-server-manager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,QAAQ,CAAoD;IACpE,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,OAAO,CAAuC;gBAE1C,MAAM,GAAE,eAAoB;IAYlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,gBAAgB;IAoC9B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAqBxB,OAAO,CAAC,cAAc;YAUR,qBAAqB;IA2BnC,OAAO,CAAC,eAAe;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmLtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B3B,OAAO,CAAC,YAAY;CA+GrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxrstudios/jxr",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "JXR.js — Edge OS Runtime Framework for elite developers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -249,7 +249,63 @@ export class JXRServerManager {
249
249
 
250
250
  // Serve CSS files as JavaScript that injects the CSS
251
251
  if (vfsPath.endsWith('.css')) {
252
- const escapedCSS = file.content
252
+ let cssContent = file.content;
253
+
254
+ // Check for pre-compiled Tailwind CSS first
255
+ if (vfsPath === '/src/index.css') {
256
+ try {
257
+ const fs = await import('fs');
258
+ const compiledPath = path.join(process.cwd(), 'src', 'index.compiled.css');
259
+ if (fs.existsSync(compiledPath)) {
260
+ cssContent = fs.readFileSync(compiledPath, 'utf-8');
261
+ console.log(`[JXR] Using pre-compiled Tailwind CSS from index.compiled.css`);
262
+ } else {
263
+ // Try to compile on-the-fly
264
+ const { execSync } = await import('child_process');
265
+ const os = await import('os');
266
+
267
+ const tmpDir = os.tmpdir();
268
+ const inputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.css`);
269
+ const outputFile = path.join(tmpDir, `jxr-tailwind-${Date.now()}.compiled.css`);
270
+
271
+ fs.writeFileSync(inputFile, cssContent);
272
+
273
+ try {
274
+ execSync(`npx @tailwindcss/cli -i "${inputFile}" -o "${outputFile}" --minify`, {
275
+ timeout: 30000,
276
+ stdio: 'pipe'
277
+ });
278
+ cssContent = fs.readFileSync(outputFile, 'utf-8');
279
+ fs.unlinkSync(inputFile);
280
+ fs.unlinkSync(outputFile);
281
+ console.log(`[JXR] Compiled Tailwind CSS for ${vfsPath}`);
282
+ } catch {
283
+ // CDN fallback
284
+ const js = `
285
+ const tailwindScript = document.createElement('script');
286
+ tailwindScript.src = 'https://cdn.tailwindcss.com';
287
+ tailwindScript.onload = function() {
288
+ const style = document.createElement('style');
289
+ style.textContent = \`${file.content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`;
290
+ document.head.appendChild(style);
291
+ };
292
+ document.head.appendChild(tailwindScript);
293
+ export default \`${file.content.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$')}\`;
294
+ `;
295
+ res.writeHead(200, {
296
+ "Content-Type": "application/javascript",
297
+ "Cache-Control": "no-cache"
298
+ });
299
+ res.end(js);
300
+ return;
301
+ }
302
+ }
303
+ } catch (error: any) {
304
+ console.warn(`[JXR] Tailwind handling error: ${error?.message || error}`);
305
+ }
306
+ }
307
+
308
+ const escapedCSS = cssContent
253
309
  .replace(/\\/g, '\\\\')
254
310
  .replace(/`/g, '\\`')
255
311
  .replace(/\$/g, '\\$');
@@ -1,160 +1,47 @@
1
- import React, { useState } from 'react'
2
-
3
- const FEATURES = [
4
- { icon: '⚡', title: 'React 19', desc: 'Latest React with automatic batching and concurrent features' },
5
- { icon: '🎨', title: 'Tailwind CSS', desc: 'Utility-first styling with the Tailwind CDN in preview' },
6
- { icon: '📦', title: 'TypeScript', desc: 'Full type safety across your entire codebase' },
7
- { icon: '🚀', title: 'Vite', desc: 'Lightning-fast HMR and optimized production builds' },
8
- ]
1
+ /**
2
+ * JXR.js Marketing Website — App.tsx
3
+ * LavaFlow OS Design System
4
+ * Powered by JXR Studios × DamascusAI
5
+ */
6
+
7
+ import { Toaster } from "@/components/ui/sonner";
8
+ import { TooltipProvider } from "@/components/ui/tooltip";
9
+ import { Route, Switch } from "wouter";
10
+ import ErrorBoundary from "./components/ErrorBoundary";
11
+ import { ThemeProvider } from "./contexts/ThemeContext";
12
+ import Home from "./pages/Home";
13
+ import DocsPage from "./pages/Docs";
14
+ import NotFound from "./pages/NotFound";
15
+
16
+ function Router() {
17
+ return (
18
+ <Switch>
19
+ <Route path="/" component={Home} />
20
+ <Route path="/docs" component={DocsPage} />
21
+ <Route path="/docs/:section" component={DocsPage} />
22
+ <Route component={NotFound} />
23
+ </Switch>
24
+ );
25
+ }
9
26
 
10
27
  export default function App() {
11
- const [count, setCount] = useState(0)
12
-
13
28
  return (
14
- <div style={{
15
- minHeight: '100vh',
16
- background: 'linear-gradient(135deg, #0f0c29 0%, #302b63 50%, #24243e 100%)',
17
- display: 'flex',
18
- flexDirection: 'column',
19
- alignItems: 'center',
20
- justifyContent: 'center',
21
- padding: '2rem',
22
- fontFamily: "'Inter', system-ui, -apple-system, sans-serif",
23
- color: '#e2e8f0',
24
- }}>
25
- {/* Hero Card */}
26
- <div style={{
27
- background: 'rgba(255,255,255,0.05)',
28
- backdropFilter: 'blur(20px)',
29
- borderRadius: '1.5rem',
30
- border: '1px solid rgba(255,255,255,0.1)',
31
- padding: '3rem',
32
- maxWidth: '640px',
33
- width: '100%',
34
- textAlign: 'center',
35
- boxShadow: '0 25px 50px -12px rgba(0,0,0,0.5)',
36
- }}>
37
- {/* Logo */}
38
- <div style={{
39
- width: '64px',
40
- height: '64px',
41
- borderRadius: '16px',
42
- background: 'linear-gradient(135deg, #6366f1, #a855f7, #ec4899)',
43
- display: 'flex',
44
- alignItems: 'center',
45
- justifyContent: 'center',
46
- margin: '0 auto 1.5rem',
47
- fontSize: '1.5rem',
48
- fontWeight: 'bold',
49
- color: 'white',
50
- boxShadow: '0 0 30px rgba(99,102,241,0.4)',
51
- }}>
52
- x0
53
- </div>
54
-
55
- <h1 style={{
56
- fontSize: '2.25rem',
57
- fontWeight: 800,
58
- marginBottom: '0.75rem',
59
- background: 'linear-gradient(135deg, #c7d2fe, #e9d5ff, #fbcfe8)',
60
- WebkitBackgroundClip: 'text',
61
- WebkitTextFillColor: 'transparent',
62
- lineHeight: 1.2,
63
- }}>
64
- Your App is Live
65
- </h1>
66
-
67
- <p style={{
68
- fontSize: '1.1rem',
69
- color: 'rgba(226,232,240,0.7)',
70
- marginBottom: '2rem',
71
- lineHeight: 1.6,
72
- }}>
73
- This project is ready for development. Use the AI chat to describe
74
- what you want to build, or start editing files directly.
75
- </p>
76
-
77
- {/* Interactive Counter */}
78
- <div style={{
79
- display: 'flex',
80
- alignItems: 'center',
81
- justifyContent: 'center',
82
- gap: '1rem',
83
- marginBottom: '2.5rem',
84
- }}>
85
- <button
86
- onClick={() => setCount(c => c - 1)}
87
- style={{
88
- width: '40px', height: '40px', borderRadius: '12px',
89
- background: 'rgba(255,255,255,0.1)', border: '1px solid rgba(255,255,255,0.15)',
90
- color: '#e2e8f0', fontSize: '1.25rem', cursor: 'pointer',
91
- display: 'flex', alignItems: 'center', justifyContent: 'center',
92
- transition: 'all 0.15s',
93
- }}
94
- onMouseEnter={e => (e.currentTarget.style.background = 'rgba(255,255,255,0.2)')}
95
- onMouseLeave={e => (e.currentTarget.style.background = 'rgba(255,255,255,0.1)')}
96
- >
97
-
98
- </button>
99
- <div style={{
100
- padding: '0.5rem 1.5rem',
101
- borderRadius: '12px',
102
- background: 'rgba(99,102,241,0.2)',
103
- border: '1px solid rgba(99,102,241,0.3)',
104
- fontSize: '1.25rem',
105
- fontWeight: 700,
106
- fontVariantNumeric: 'tabular-nums',
107
- minWidth: '80px',
108
- }}>
109
- {count}
110
- </div>
111
- <button
112
- onClick={() => setCount(c => c + 1)}
113
- style={{
114
- width: '40px', height: '40px', borderRadius: '12px',
115
- background: 'linear-gradient(135deg, #6366f1, #a855f7)',
116
- border: 'none', color: 'white', fontSize: '1.25rem', cursor: 'pointer',
117
- display: 'flex', alignItems: 'center', justifyContent: 'center',
118
- boxShadow: '0 0 20px rgba(99,102,241,0.3)',
119
- transition: 'all 0.15s',
29
+ <ErrorBoundary>
30
+ <ThemeProvider defaultTheme="dark">
31
+ <TooltipProvider>
32
+ <Toaster
33
+ theme="dark"
34
+ toastOptions={{
35
+ style: {
36
+ background: 'oklch(0.13 0.007 285)',
37
+ border: '1px solid oklch(1 0 0 / 10%)',
38
+ color: 'oklch(0.93 0.005 65)',
39
+ },
120
40
  }}
121
- onMouseEnter={e => (e.currentTarget.style.transform = 'scale(1.1)')}
122
- onMouseLeave={e => (e.currentTarget.style.transform = 'scale(1)')}
123
- >
124
- +
125
- </button>
126
- </div>
127
-
128
- {/* Feature Grid */}
129
- <div style={{
130
- display: 'grid',
131
- gridTemplateColumns: 'repeat(2, 1fr)',
132
- gap: '0.75rem',
133
- textAlign: 'left',
134
- }}>
135
- {FEATURES.map((f) => (
136
- <div key={f.title} style={{
137
- padding: '1rem',
138
- borderRadius: '12px',
139
- background: 'rgba(255,255,255,0.04)',
140
- border: '1px solid rgba(255,255,255,0.06)',
141
- }}>
142
- <div style={{ fontSize: '1.25rem', marginBottom: '0.25rem' }}>{f.icon}</div>
143
- <div style={{ fontWeight: 600, fontSize: '0.875rem', marginBottom: '0.25rem' }}>{f.title}</div>
144
- <div style={{ fontSize: '0.75rem', color: 'rgba(226,232,240,0.5)', lineHeight: 1.4 }}>{f.desc}</div>
145
- </div>
146
- ))}
147
- </div>
148
- </div>
149
-
150
- {/* Footer */}
151
- <p style={{
152
- marginTop: '2rem',
153
- fontSize: '0.8rem',
154
- color: 'rgba(226,232,240,0.3)',
155
- }}>
156
- Built with x0 · React 19 · TypeScript · Tailwind CSS
157
- </p>
158
- </div>
159
- )
160
- }
41
+ />
42
+ <Router />
43
+ </TooltipProvider>
44
+ </ThemeProvider>
45
+ </ErrorBoundary>
46
+ );
47
+ }
@@ -0,0 +1,62 @@
1
+ import { cn } from "@/lib/utils";
2
+ import { AlertTriangle, RotateCcw } from "lucide-react";
3
+ import { Component, ReactNode } from "react";
4
+
5
+ interface Props {
6
+ children: ReactNode;
7
+ }
8
+
9
+ interface State {
10
+ hasError: boolean;
11
+ error: Error | null;
12
+ }
13
+
14
+ class ErrorBoundary extends Component<Props, State> {
15
+ constructor(props: Props) {
16
+ super(props);
17
+ this.state = { hasError: false, error: null };
18
+ }
19
+
20
+ static getDerivedStateFromError(error: Error): State {
21
+ return { hasError: true, error };
22
+ }
23
+
24
+ render() {
25
+ if (this.state.hasError) {
26
+ return (
27
+ <div className="flex items-center justify-center min-h-screen p-8 bg-background">
28
+ <div className="flex flex-col items-center w-full max-w-2xl p-8">
29
+ <AlertTriangle
30
+ size={48}
31
+ className="text-destructive mb-6 flex-shrink-0"
32
+ />
33
+
34
+ <h2 className="text-xl mb-4">An unexpected error occurred.</h2>
35
+
36
+ <div className="p-4 w-full rounded bg-muted overflow-auto mb-6">
37
+ <pre className="text-sm text-muted-foreground whitespace-break-spaces">
38
+ {this.state.error?.stack}
39
+ </pre>
40
+ </div>
41
+
42
+ <button
43
+ onClick={() => window.location.reload()}
44
+ className={cn(
45
+ "flex items-center gap-2 px-4 py-2 rounded-lg",
46
+ "bg-primary text-primary-foreground",
47
+ "hover:opacity-90 cursor-pointer"
48
+ )}
49
+ >
50
+ <RotateCcw size={16} />
51
+ Reload Page
52
+ </button>
53
+ </div>
54
+ </div>
55
+ );
56
+ }
57
+
58
+ return this.props.children;
59
+ }
60
+ }
61
+
62
+ export default ErrorBoundary;
@@ -0,0 +1,85 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ import { Button } from "@/components/ui/button";
4
+ import {
5
+ Dialog,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogFooter,
9
+ DialogTitle,
10
+ } from "@/components/ui/dialog";
11
+
12
+ interface ManusDialogProps {
13
+ title?: string;
14
+ logo?: string;
15
+ open?: boolean;
16
+ onLogin: () => void;
17
+ onOpenChange?: (open: boolean) => void;
18
+ onClose?: () => void;
19
+ }
20
+
21
+ export function ManusDialog({
22
+ title,
23
+ logo,
24
+ open = false,
25
+ onLogin,
26
+ onOpenChange,
27
+ onClose,
28
+ }: ManusDialogProps) {
29
+ const [internalOpen, setInternalOpen] = useState(open);
30
+
31
+ useEffect(() => {
32
+ if (!onOpenChange) {
33
+ setInternalOpen(open);
34
+ }
35
+ }, [open, onOpenChange]);
36
+
37
+ const handleOpenChange = (nextOpen: boolean) => {
38
+ if (onOpenChange) {
39
+ onOpenChange(nextOpen);
40
+ } else {
41
+ setInternalOpen(nextOpen);
42
+ }
43
+
44
+ if (!nextOpen) {
45
+ onClose?.();
46
+ }
47
+ };
48
+
49
+ return (
50
+ <Dialog
51
+ open={onOpenChange ? open : internalOpen}
52
+ onOpenChange={handleOpenChange}
53
+ >
54
+ <DialogContent className="py-5 bg-[#f8f8f7] rounded-[20px] w-[400px] shadow-[0px_4px_11px_0px_rgba(0,0,0,0.08)] border border-[rgba(0,0,0,0.08)] backdrop-blur-2xl p-0 gap-0 text-center">
55
+ <div className="flex flex-col items-center gap-2 p-5 pt-12">
56
+ {logo ? (
57
+ <div className="w-16 h-16 bg-white rounded-xl border border-[rgba(0,0,0,0.08)] flex items-center justify-center">
58
+ <img src={logo} alt="Dialog graphic" className="w-10 h-10 rounded-md" />
59
+ </div>
60
+ ) : null}
61
+
62
+ {/* Title and subtitle */}
63
+ {title ? (
64
+ <DialogTitle className="text-xl font-semibold text-[#34322d] leading-[26px] tracking-[-0.44px]">
65
+ {title}
66
+ </DialogTitle>
67
+ ) : null}
68
+ <DialogDescription className="text-sm text-[#858481] leading-5 tracking-[-0.154px]">
69
+ Please login with Manus to continue
70
+ </DialogDescription>
71
+ </div>
72
+
73
+ <DialogFooter className="px-5 py-5">
74
+ {/* Login button */}
75
+ <Button
76
+ onClick={onLogin}
77
+ className="w-full h-10 bg-[#1a1a19] hover:bg-[#1a1a19]/90 text-white rounded-[10px] text-sm font-medium leading-5 tracking-[-0.154px]"
78
+ >
79
+ Login with Manus
80
+ </Button>
81
+ </DialogFooter>
82
+ </DialogContent>
83
+ </Dialog>
84
+ );
85
+ }