juxscript 1.0.3 → 1.0.5

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 (73) hide show
  1. package/README.md +37 -92
  2. package/bin/cli.js +57 -56
  3. package/lib/components/alert.ts +240 -0
  4. package/lib/components/app.ts +216 -82
  5. package/lib/components/badge.ts +164 -0
  6. package/lib/components/barchart.ts +1248 -0
  7. package/lib/components/button.ts +188 -53
  8. package/lib/components/card.ts +75 -61
  9. package/lib/components/chart.ts +17 -15
  10. package/lib/components/checkbox.ts +199 -0
  11. package/lib/components/code.ts +66 -152
  12. package/lib/components/container.ts +104 -208
  13. package/lib/components/data.ts +1 -3
  14. package/lib/components/datepicker.ts +226 -0
  15. package/lib/components/dialog.ts +258 -0
  16. package/lib/components/docs-data.json +1969 -423
  17. package/lib/components/dropdown.ts +244 -0
  18. package/lib/components/element.ts +271 -0
  19. package/lib/components/fileupload.ts +319 -0
  20. package/lib/components/footer.ts +37 -18
  21. package/lib/components/header.ts +53 -33
  22. package/lib/components/heading.ts +119 -0
  23. package/lib/components/helpers.ts +34 -0
  24. package/lib/components/hero.ts +57 -31
  25. package/lib/components/include.ts +292 -0
  26. package/lib/components/input.ts +508 -77
  27. package/lib/components/layout.ts +144 -18
  28. package/lib/components/list.ts +83 -74
  29. package/lib/components/loading.ts +263 -0
  30. package/lib/components/main.ts +43 -17
  31. package/lib/components/menu.ts +108 -24
  32. package/lib/components/modal.ts +50 -21
  33. package/lib/components/nav.ts +60 -18
  34. package/lib/components/paragraph.ts +111 -0
  35. package/lib/components/progress.ts +276 -0
  36. package/lib/components/radio.ts +236 -0
  37. package/lib/components/req.ts +300 -0
  38. package/lib/components/script.ts +33 -74
  39. package/lib/components/select.ts +280 -0
  40. package/lib/components/sidebar.ts +87 -37
  41. package/lib/components/style.ts +47 -70
  42. package/lib/components/switch.ts +261 -0
  43. package/lib/components/table.ts +47 -24
  44. package/lib/components/tabs.ts +105 -63
  45. package/lib/components/theme-toggle.ts +361 -0
  46. package/lib/components/token-calculator.ts +380 -0
  47. package/lib/components/tooltip.ts +244 -0
  48. package/lib/components/view.ts +36 -20
  49. package/lib/components/write.ts +284 -0
  50. package/lib/globals.d.ts +21 -0
  51. package/lib/jux.ts +178 -68
  52. package/lib/presets/notion.css +521 -0
  53. package/lib/presets/notion.jux +27 -0
  54. package/lib/reactivity/state.ts +364 -0
  55. package/lib/themes/charts.js +126 -0
  56. package/machinery/compiler.js +126 -38
  57. package/machinery/generators/html.js +2 -3
  58. package/machinery/server.js +2 -2
  59. package/package.json +29 -3
  60. package/lib/components/import.ts +0 -430
  61. package/lib/components/node.ts +0 -200
  62. package/lib/components/reactivity.js +0 -104
  63. package/lib/components/theme.ts +0 -97
  64. package/lib/layouts/notion.css +0 -258
  65. package/lib/styles/base-theme.css +0 -186
  66. package/lib/styles/dark-theme.css +0 -144
  67. package/lib/styles/light-theme.css +0 -144
  68. package/lib/styles/tokens/dark.css +0 -86
  69. package/lib/styles/tokens/light.css +0 -86
  70. package/lib/templates/index.juxt +0 -33
  71. package/lib/themes/dark.css +0 -86
  72. package/lib/themes/light.css +0 -86
  73. /package/lib/{styles → presets}/global.css +0 -0
@@ -1,14 +1,23 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import esbuild from 'esbuild';
4
- import { generateDocs } from './doc-generator.js';
5
4
 
5
+ /**
6
+ * Compile a .jux file to .js and .html
7
+ *
8
+ * @param {string} juxFilePath - Path to the .jux file
9
+ * @param {Object} options - Compilation options
10
+ * @param {string} options.distDir - Output directory
11
+ * @param {string} options.projectRoot - Project root directory
12
+ * @param {boolean} options.isServe - Whether serving for development
13
+ * @returns {Promise<{jsOutputPath: string, htmlOutputPath: string}>}
14
+ */
6
15
  export async function compileJuxFile(juxFilePath, options = {}) {
7
16
  const { distDir, projectRoot, isServe = false } = options;
8
-
17
+
9
18
  const relativePath = path.relative(projectRoot, juxFilePath);
10
19
  const parsedPath = path.parse(relativePath);
11
-
20
+
12
21
  // Output paths
13
22
  const outputDir = path.join(distDir, parsedPath.dir);
14
23
  const jsOutputPath = path.join(outputDir, `${parsedPath.name}.js`);
@@ -27,17 +36,17 @@ export async function compileJuxFile(juxFilePath, options = {}) {
27
36
  // Calculate depth for relative paths
28
37
  const depth = parsedPath.dir.split(path.sep).filter(p => p).length;
29
38
  const libPath = depth === 0 ? './lib/jux.js' : '../'.repeat(depth) + 'lib/jux.js';
30
- const styleBasePath = depth === 0 ? './lib/styles/' : '../'.repeat(depth) + 'lib/styles/';
39
+ const styleBasePath = depth === 0 ? './lib/presets/' : '../'.repeat(depth) + 'lib/presets/';
31
40
 
32
41
  // Transform imports
33
42
  let transformedContent = juxContent;
34
-
43
+
35
44
  // Replace common import patterns with calculated path
36
45
  transformedContent = transformedContent.replace(
37
46
  /from\s+['"]\.\.?\/lib\/jux\.js['"]/g,
38
47
  `from '${libPath}'`
39
48
  );
40
-
49
+
41
50
  // Only inject import if:
42
51
  // 1. File is not empty (ignoring whitespace and comments)
43
52
  // 2. File uses 'jux.' but has no import statement
@@ -45,11 +54,11 @@ export async function compileJuxFile(juxFilePath, options = {}) {
45
54
  .replace(/\/\*[\s\S]*?\*\//g, '') // Remove block comments
46
55
  .replace(/\/\/.*/g, '') // Remove line comments
47
56
  .trim();
48
-
57
+
49
58
  const hasContent = contentWithoutComments.length > 0;
50
59
  const usesJux = /\bjux\./g.test(contentWithoutComments);
51
60
  const hasImport = /import\s+.*from/.test(transformedContent);
52
-
61
+
53
62
  if (hasContent && usesJux && !hasImport) {
54
63
  transformedContent = `import { jux } from '${libPath}';\n\n${transformedContent}`;
55
64
  }
@@ -61,28 +70,19 @@ export async function compileJuxFile(juxFilePath, options = {}) {
61
70
 
62
71
  // Generate HTML with correct script path
63
72
  const scriptPath = `./${parsedPath.name}.js`;
64
-
73
+
65
74
  const html = `<!DOCTYPE html>
66
75
  <html lang="en">
67
76
  <head>
68
77
  <meta charset="UTF-8">
69
78
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
70
79
  <title>${parsedPath.name}</title>
71
-
72
80
  <!-- JUX Core Styles -->
73
- <link rel="stylesheet" href="${styleBasePath}tokens/dark.css">
74
81
  <link rel="stylesheet" href="${styleBasePath}global.css">
75
82
  </head>
76
- <body data-theme="dark">
83
+ <body data-theme="">
77
84
  <!-- App container -->
78
85
  <div id="app" data-jux-page="${parsedPath.name}"></div>
79
-
80
- <!-- Main content -->
81
- <div id="appmain"></div>
82
-
83
- <!-- Modal overlay -->
84
- <div id="appmodal" aria-hidden="true" role="dialog"></div>
85
-
86
86
  <script type="module" src="${scriptPath}"></script>
87
87
  ${isServe ? `
88
88
  <!-- Hot reload -->
@@ -107,10 +107,16 @@ export async function compileJuxFile(juxFilePath, options = {}) {
107
107
  return { jsOutputPath, htmlOutputPath };
108
108
  }
109
109
 
110
+ /**
111
+ * Copy and build the JUX library from TypeScript to JavaScript
112
+ *
113
+ * @param {string} projectRoot - Root directory containing lib/
114
+ * @param {string} distDir - Destination directory for built files
115
+ */
110
116
  export async function copyLibToOutput(projectRoot, distDir) {
111
117
  // Simplified lib path resolution
112
118
  const libSrc = path.resolve(projectRoot, '../lib');
113
-
119
+
114
120
  if (!fs.existsSync(libSrc)) {
115
121
  throw new Error(`lib/ directory not found at ${libSrc}`);
116
122
  }
@@ -129,7 +135,7 @@ export async function copyLibToOutput(projectRoot, distDir) {
129
135
 
130
136
  // Find all TypeScript entry points
131
137
  const tsFiles = findFiles(libSrc, '.ts');
132
-
138
+
133
139
  if (tsFiles.length === 0) {
134
140
  console.warn('⚠️ No TypeScript files found in lib/');
135
141
  return;
@@ -168,50 +174,123 @@ export async function copyLibToOutput(projectRoot, distDir) {
168
174
  console.log('✅ Library ready\n');
169
175
  }
170
176
 
177
+ /**
178
+ * Copy project assets (CSS, JS, images) from jux/ to dist/
179
+ *
180
+ * @param {string} projectRoot - Source directory (jux/)
181
+ * @param {string} distDir - Destination directory (jux-dist/)
182
+ */
171
183
  export async function copyProjectAssets(projectRoot, distDir) {
172
184
  console.log('📦 Copying project assets...');
173
-
185
+
174
186
  // Find all CSS and JS files in project root (excluding node_modules, dist, .git)
175
187
  const allFiles = [];
176
188
  findProjectFiles(projectRoot, ['.css', '.js'], allFiles, projectRoot);
177
-
189
+
178
190
  console.log(` Found ${allFiles.length} asset file(s)`);
179
-
191
+
180
192
  for (const srcPath of allFiles) {
181
193
  const relativePath = path.relative(projectRoot, srcPath);
182
194
  const destPath = path.join(distDir, relativePath);
183
195
  const destDir = path.dirname(destPath);
184
-
196
+
185
197
  // Create destination directory if needed
186
198
  if (!fs.existsSync(destDir)) {
187
199
  fs.mkdirSync(destDir, { recursive: true });
188
200
  }
189
-
201
+
190
202
  // Copy file
191
203
  fs.copyFileSync(srcPath, destPath);
192
204
  console.log(` ✓ ${relativePath}`);
193
205
  }
194
-
206
+
195
207
  console.log('✅ Project assets copied\n');
196
208
  }
197
209
 
210
+ /**
211
+ * Transpile TypeScript files from jux/ to jux-dist/, preserving folder structure
212
+ *
213
+ * @param {string} srcDir - Source directory (jux/)
214
+ * @param {string} destDir - Destination directory (jux-dist/)
215
+ * @example
216
+ * // jux/samples/mypage.ts -> jux-dist/samples/mypage.js
217
+ * await transpileProjectTypeScript('jux/', 'jux-dist/');
218
+ */
219
+ export async function transpileProjectTypeScript(srcDir, destDir) {
220
+ console.log('🔷 Transpiling TypeScript files...');
221
+
222
+ // Find all TypeScript files in the project
223
+ const tsFiles = findFiles(srcDir, '.ts');
224
+
225
+ if (tsFiles.length === 0) {
226
+ console.log(' No TypeScript files found in project');
227
+ return;
228
+ }
229
+
230
+ console.log(` Found ${tsFiles.length} TypeScript file(s)`);
231
+
232
+ try {
233
+ // Build all TypeScript files with esbuild
234
+ await esbuild.build({
235
+ entryPoints: tsFiles,
236
+ bundle: false,
237
+ format: 'esm',
238
+ outdir: destDir,
239
+ outbase: srcDir,
240
+ platform: 'browser',
241
+ target: 'es2020',
242
+ loader: {
243
+ '.ts': 'ts'
244
+ },
245
+ logLevel: 'warning'
246
+ });
247
+
248
+ // Log each transpiled file
249
+ tsFiles.forEach(tsFile => {
250
+ const relativePath = path.relative(srcDir, tsFile);
251
+ const jsPath = relativePath.replace(/\.ts$/, '.js');
252
+ console.log(` ✓ ${relativePath} → ${jsPath}`);
253
+ });
254
+
255
+ console.log('✅ TypeScript transpiled\n');
256
+
257
+ } catch (err) {
258
+ console.error('❌ Failed to transpile TypeScript:', err.message);
259
+ throw err;
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Recursively find files with a specific extension
265
+ *
266
+ * @param {string} dir - Directory to search
267
+ * @param {string} extension - File extension (e.g., '.ts')
268
+ * @param {string[]} fileList - Accumulator for found files
269
+ * @returns {string[]} Array of file paths
270
+ */
198
271
  function findFiles(dir, extension, fileList = []) {
199
272
  const files = fs.readdirSync(dir);
200
-
273
+
201
274
  files.forEach(file => {
202
275
  const filePath = path.join(dir, file);
203
276
  const stat = fs.statSync(filePath);
204
-
277
+
205
278
  if (stat.isDirectory()) {
206
279
  findFiles(filePath, extension, fileList);
207
280
  } else if (file.endsWith(extension)) {
208
281
  fileList.push(filePath);
209
282
  }
210
283
  });
211
-
284
+
212
285
  return fileList;
213
286
  }
214
287
 
288
+ /**
289
+ * Copy non-TypeScript files (CSS, JSON, JS, SVG, etc.)
290
+ *
291
+ * @param {string} src - Source directory
292
+ * @param {string} dest - Destination directory
293
+ */
215
294
  function copyNonTsFiles(src, dest) {
216
295
  const entries = fs.readdirSync(src, { withFileTypes: true });
217
296
 
@@ -226,23 +305,32 @@ function copyNonTsFiles(src, dest) {
226
305
  copyNonTsFiles(srcPath, destPath);
227
306
  } else if (entry.isFile()) {
228
307
  const ext = path.extname(entry.name);
229
- // Copy CSS, JSON, and JS files (but not .ts files)
230
- if (ext === '.css' || ext === '.json' || (ext === '.js' && !srcPath.endsWith('.ts'))) {
308
+ // Copy CSS, JSON, SVG, and JS files (but not .ts files)
309
+ if (['.css', '.json', '.js', '.svg', '.png', '.jpg', '.jpeg', '.gif', '.webp'].includes(ext)) {
231
310
  fs.copyFileSync(srcPath, destPath);
232
- console.log(` → Copied: ${path.relative(src, srcPath)}`);
233
311
  }
234
312
  }
235
313
  }
236
314
  }
237
315
 
238
- function findProjectFiles(dir, extensions, fileList = [], rootDir = dir, excludeDirs = ['node_modules', 'dist', '.git', 'lib']) {
316
+ /**
317
+ * Find project files with specific extensions, excluding certain directories
318
+ *
319
+ * @param {string} dir - Directory to search
320
+ * @param {string[]} extensions - File extensions to find
321
+ * @param {string[]} fileList - Accumulator for found files
322
+ * @param {string} rootDir - Root directory for relative paths
323
+ * @param {string[]} excludeDirs - Directories to exclude
324
+ * @returns {string[]} Array of file paths
325
+ */
326
+ function findProjectFiles(dir, extensions, fileList = [], rootDir = dir, excludeDirs = ['node_modules', 'jux-dist', '.git', 'lib']) {
239
327
  if (!fs.existsSync(dir)) return fileList;
240
-
328
+
241
329
  const entries = fs.readdirSync(dir, { withFileTypes: true });
242
-
330
+
243
331
  for (const entry of entries) {
244
332
  const fullPath = path.join(dir, entry.name);
245
-
333
+
246
334
  if (entry.isDirectory()) {
247
335
  // Skip excluded directories
248
336
  if (excludeDirs.includes(entry.name)) {
@@ -257,6 +345,6 @@ function findProjectFiles(dir, extensions, fileList = [], rootDir = dir, exclude
257
345
  }
258
346
  }
259
347
  }
260
-
348
+
261
349
  return fileList;
262
350
  }
@@ -42,8 +42,7 @@ export function generateHTML(fileName, options = {}) {
42
42
  <title>${fileName}</title>
43
43
 
44
44
  <!-- JUX Core Styles -->
45
- <link rel="stylesheet" href="${prefix}lib/styles/tokens/dark.css">
46
- <link rel="stylesheet" href="${prefix}lib/styles/global.css">
45
+ <link rel="stylesheet" href="${prefix}lib/presets/global.css">
47
46
  </head>
48
47
  <body data-theme="dark">
49
48
  ${appStructure}
@@ -61,7 +60,7 @@ ${appStructure}
61
60
  */
62
61
  function buildAppStructure(pageName) {
63
62
  const page = pageName || 'index';
64
-
63
+
65
64
  return ` <!-- App Container -->
66
65
  <div id="app" data-jux-page="${page}">
67
66
  <!-- Header -->
@@ -186,7 +186,7 @@ async function initDatabase() {
186
186
  }
187
187
  }
188
188
 
189
- export async function start(port = 3000, config = {}) {
189
+ export async function start(port = 3000) {
190
190
  await initDatabase();
191
- return serve(port, config.distDir || './jux-dist'); // Changed default
191
+ return serve(port, './jux-dist'); // Changed default
192
192
  }
package/package.json CHANGED
@@ -1,23 +1,49 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "lib/jux.js",
7
- "types": "types/globals.d.ts",
7
+ "types": "lib/jux.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/jux.d.ts",
11
+ "import": "./lib/jux.js",
12
+ "default": "./lib/jux.js"
13
+ },
14
+ "./lib/*": "./lib/*",
15
+ "./lib/components/*": "./lib/components/*",
16
+ "./package.json": "./package.json"
17
+ },
18
+ "typesVersions": {
19
+ "*": {
20
+ "*": [
21
+ "lib/*"
22
+ ],
23
+ "lib/*": [
24
+ "lib/*"
25
+ ],
26
+ "lib/components/*": [
27
+ "lib/components/*"
28
+ ]
29
+ }
30
+ },
8
31
  "bin": {
9
32
  "jux": "./bin/cli.js"
10
33
  },
11
34
  "scripts": {
12
35
  "dev": "cd examples && npx jux serve",
13
36
  "build:examples": "cd examples && rm -rf dist && npx jux build",
14
- "test": "node test/run-tests.js"
37
+ "build": "tsc",
38
+ "test": "node test/run-tests.js",
39
+ "generate:icons": "node scripts/generate-icon-types.js"
15
40
  },
16
41
  "files": [
17
42
  "lib",
18
43
  "bin",
19
44
  "machinery",
20
45
  "types",
46
+ "lib/**/*.d.ts",
21
47
  "README.md",
22
48
  "LICENSE"
23
49
  ],