uniweb 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +336 -11
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -261,6 +261,119 @@ async function createWorkspace(projectDir, projectName) {
|
|
|
261
261
|
dist
|
|
262
262
|
.DS_Store
|
|
263
263
|
*.local
|
|
264
|
+
`)
|
|
265
|
+
|
|
266
|
+
// README.md
|
|
267
|
+
writeFile(join(projectDir, 'README.md'), `# ${projectName}
|
|
268
|
+
|
|
269
|
+
A Uniweb workspace with a site and foundation for co-development.
|
|
270
|
+
|
|
271
|
+
## Quick Start
|
|
272
|
+
|
|
273
|
+
\`\`\`bash
|
|
274
|
+
pnpm install
|
|
275
|
+
pnpm dev
|
|
276
|
+
\`\`\`
|
|
277
|
+
|
|
278
|
+
Open [http://localhost:3000](http://localhost:3000) to see your site.
|
|
279
|
+
|
|
280
|
+
## Project Structure
|
|
281
|
+
|
|
282
|
+
\`\`\`
|
|
283
|
+
${projectName}/
|
|
284
|
+
├── packages/
|
|
285
|
+
│ ├── site/ # Your website
|
|
286
|
+
│ │ ├── pages/ # Content pages (markdown + YAML)
|
|
287
|
+
│ │ ├── src/ # Site entry point
|
|
288
|
+
│ │ └── vite.config.js
|
|
289
|
+
│ └── foundation/ # Your component library
|
|
290
|
+
│ └── src/
|
|
291
|
+
│ ├── components/ # React components
|
|
292
|
+
│ ├── meta.js # Foundation metadata
|
|
293
|
+
│ └── styles.css # Tailwind styles
|
|
294
|
+
├── package.json
|
|
295
|
+
└── pnpm-workspace.yaml
|
|
296
|
+
\`\`\`
|
|
297
|
+
|
|
298
|
+
## Development
|
|
299
|
+
|
|
300
|
+
### Standard Mode (recommended)
|
|
301
|
+
|
|
302
|
+
\`\`\`bash
|
|
303
|
+
pnpm dev
|
|
304
|
+
\`\`\`
|
|
305
|
+
|
|
306
|
+
Edit components in \`packages/foundation/src/components/\` and see changes instantly via HMR.
|
|
307
|
+
Edit content in \`packages/site/pages/\` to add or modify pages.
|
|
308
|
+
|
|
309
|
+
### Runtime Loading Mode
|
|
310
|
+
|
|
311
|
+
\`\`\`bash
|
|
312
|
+
pnpm dev:runtime
|
|
313
|
+
\`\`\`
|
|
314
|
+
|
|
315
|
+
Tests production behavior where the foundation is loaded as a separate module.
|
|
316
|
+
Use this to debug issues that only appear in production.
|
|
317
|
+
|
|
318
|
+
## Building for Production
|
|
319
|
+
|
|
320
|
+
\`\`\`bash
|
|
321
|
+
# Build both foundation and site
|
|
322
|
+
pnpm build
|
|
323
|
+
\`\`\`
|
|
324
|
+
|
|
325
|
+
Output:
|
|
326
|
+
- \`packages/foundation/dist/\` — Bundled foundation (JS + CSS + schema)
|
|
327
|
+
- \`packages/site/dist/\` — Production-ready site
|
|
328
|
+
|
|
329
|
+
## Adding Components
|
|
330
|
+
|
|
331
|
+
1. Create a new folder in \`packages/foundation/src/components/YourComponent/\`
|
|
332
|
+
2. Add \`index.jsx\` with your React component
|
|
333
|
+
3. Add \`meta.js\` describing the component's content slots and options
|
|
334
|
+
4. Export from \`packages/foundation/src/index.js\`
|
|
335
|
+
|
|
336
|
+
## Adding Pages
|
|
337
|
+
|
|
338
|
+
1. Create a folder in \`packages/site/pages/your-page/\`
|
|
339
|
+
2. Add \`page.yml\` with page metadata
|
|
340
|
+
3. Add markdown files (\`1-section.md\`, \`2-section.md\`, etc.) for each section
|
|
341
|
+
|
|
342
|
+
Each markdown file specifies which component to use:
|
|
343
|
+
|
|
344
|
+
\`\`\`markdown
|
|
345
|
+
---
|
|
346
|
+
component: Hero
|
|
347
|
+
title: Your Title
|
|
348
|
+
subtitle: Your subtitle
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
Optional body content here.
|
|
352
|
+
\`\`\`
|
|
353
|
+
|
|
354
|
+
## Configuration
|
|
355
|
+
|
|
356
|
+
Each site has a \`site.yml\` that configures which foundation it uses:
|
|
357
|
+
|
|
358
|
+
\`\`\`yaml
|
|
359
|
+
name: site
|
|
360
|
+
defaultLanguage: en
|
|
361
|
+
foundation: foundation # References packages/foundation
|
|
362
|
+
\`\`\`
|
|
363
|
+
|
|
364
|
+
To add multiple sites or foundations, create new packages and update each site's \`site.yml\`.
|
|
365
|
+
|
|
366
|
+
## What is Uniweb?
|
|
367
|
+
|
|
368
|
+
Uniweb is a **Component Web Platform** that bridges content and components.
|
|
369
|
+
Foundations define the vocabulary (available components, options, design rules).
|
|
370
|
+
Sites provide content that flows through Foundations.
|
|
371
|
+
|
|
372
|
+
Learn more:
|
|
373
|
+
- [Uniweb on GitHub](https://github.com/uniweb)
|
|
374
|
+
- [CLI Documentation](https://github.com/uniweb/cli)
|
|
375
|
+
- [uniweb.app](https://uniweb.app) — Full publishing platform
|
|
376
|
+
|
|
264
377
|
`)
|
|
265
378
|
|
|
266
379
|
// Create site package
|
|
@@ -301,6 +414,7 @@ async function createSite(projectDir, projectName, isWorkspace = false) {
|
|
|
301
414
|
devDependencies: {
|
|
302
415
|
'@vitejs/plugin-react': '^4.2.1',
|
|
303
416
|
autoprefixer: '^10.4.18',
|
|
417
|
+
'js-yaml': '^4.1.0',
|
|
304
418
|
postcss: '^8.4.35',
|
|
305
419
|
react: '^18.2.0',
|
|
306
420
|
'react-dom': '^18.2.0',
|
|
@@ -311,13 +425,24 @@ async function createSite(projectDir, projectName, isWorkspace = false) {
|
|
|
311
425
|
},
|
|
312
426
|
})
|
|
313
427
|
|
|
314
|
-
// Foundation import name
|
|
428
|
+
// Foundation import name (used for initial site.yml)
|
|
315
429
|
const foundationImport = isWorkspace ? 'foundation' : 'foundation-example'
|
|
316
430
|
|
|
317
|
-
// tailwind.config.js -
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
431
|
+
// tailwind.config.js - reads foundation from site.yml
|
|
432
|
+
writeFile(join(projectDir, 'tailwind.config.js'), `import { readFileSync, existsSync } from 'fs'
|
|
433
|
+
import yaml from 'js-yaml'
|
|
434
|
+
|
|
435
|
+
// Read foundation from site.yml
|
|
436
|
+
const siteConfig = yaml.load(readFileSync('./site.yml', 'utf8'))
|
|
437
|
+
const foundation = siteConfig.foundation || 'foundation'
|
|
438
|
+
|
|
439
|
+
// Resolve foundation path (workspace sibling or node_modules)
|
|
440
|
+
const workspacePath = \`../\${foundation}/src/**/*.{js,jsx,ts,tsx}\`
|
|
441
|
+
const npmPath = \`./node_modules/\${foundation}/src/**/*.{js,jsx,ts,tsx}\`
|
|
442
|
+
const contentPath = existsSync(\`../\${foundation}\`) ? workspacePath : npmPath
|
|
443
|
+
|
|
444
|
+
export default {
|
|
445
|
+
content: [contentPath],
|
|
321
446
|
theme: {
|
|
322
447
|
extend: {
|
|
323
448
|
colors: {
|
|
@@ -339,15 +464,31 @@ async function createSite(projectDir, projectName, isWorkspace = false) {
|
|
|
339
464
|
}
|
|
340
465
|
`)
|
|
341
466
|
|
|
342
|
-
// vite.config.js
|
|
467
|
+
// vite.config.js - reads foundation from site.yml
|
|
343
468
|
writeFile(join(projectDir, 'vite.config.js'), `import { defineConfig } from 'vite'
|
|
469
|
+
import { readFileSync, existsSync } from 'fs'
|
|
470
|
+
import yaml from 'js-yaml'
|
|
344
471
|
import react from '@vitejs/plugin-react'
|
|
345
472
|
import svgr from 'vite-plugin-svgr'
|
|
346
473
|
import { siteContentPlugin, foundationPlugin } from '@uniweb/runtime/vite'
|
|
347
474
|
|
|
475
|
+
// Read foundation from site.yml
|
|
476
|
+
const siteConfig = yaml.load(readFileSync('./site.yml', 'utf8'))
|
|
477
|
+
const foundation = siteConfig.foundation || 'foundation'
|
|
478
|
+
|
|
479
|
+
// Check if foundation is a workspace sibling or npm package
|
|
480
|
+
const isWorkspaceFoundation = existsSync(\`../\${foundation}\`)
|
|
481
|
+
const foundationPath = isWorkspaceFoundation ? \`../\${foundation}\` : \`./node_modules/\${foundation}\`
|
|
482
|
+
|
|
348
483
|
const useRuntimeLoading = process.env.VITE_FOUNDATION_MODE === 'runtime'
|
|
349
484
|
|
|
350
485
|
export default defineConfig({
|
|
486
|
+
resolve: {
|
|
487
|
+
alias: {
|
|
488
|
+
// Alias #foundation to the actual foundation package
|
|
489
|
+
'#foundation': foundation,
|
|
490
|
+
},
|
|
491
|
+
},
|
|
351
492
|
plugins: [
|
|
352
493
|
react(),
|
|
353
494
|
svgr(),
|
|
@@ -356,8 +497,8 @@ export default defineConfig({
|
|
|
356
497
|
inject: true,
|
|
357
498
|
}),
|
|
358
499
|
useRuntimeLoading && foundationPlugin({
|
|
359
|
-
name:
|
|
360
|
-
path:
|
|
500
|
+
name: foundation,
|
|
501
|
+
path: foundationPath,
|
|
361
502
|
serve: '/foundation',
|
|
362
503
|
watch: true,
|
|
363
504
|
}),
|
|
@@ -390,7 +531,7 @@ export default defineConfig({
|
|
|
390
531
|
</html>
|
|
391
532
|
`)
|
|
392
533
|
|
|
393
|
-
// main.jsx
|
|
534
|
+
// main.jsx - uses #foundation alias (configured in vite.config.js from site.yml)
|
|
394
535
|
writeFile(join(projectDir, 'src/main.jsx'), `import { initRuntime } from '@uniweb/runtime'
|
|
395
536
|
|
|
396
537
|
const useRuntimeLoading = import.meta.env.VITE_FOUNDATION_MODE === 'runtime'
|
|
@@ -402,8 +543,9 @@ async function start() {
|
|
|
402
543
|
cssUrl: '/foundation/assets/style.css'
|
|
403
544
|
})
|
|
404
545
|
} else {
|
|
405
|
-
|
|
406
|
-
await import('
|
|
546
|
+
// #foundation alias is resolved by Vite based on site.yml config
|
|
547
|
+
const foundation = await import('#foundation')
|
|
548
|
+
await import('#foundation/styles')
|
|
407
549
|
initRuntime(foundation)
|
|
408
550
|
}
|
|
409
551
|
}
|
|
@@ -414,6 +556,9 @@ start().catch(console.error)
|
|
|
414
556
|
// site.yml
|
|
415
557
|
writeFile(join(projectDir, 'site.yml'), `name: ${projectName}
|
|
416
558
|
defaultLanguage: en
|
|
559
|
+
|
|
560
|
+
# Foundation to use for this site
|
|
561
|
+
foundation: ${foundationImport}
|
|
417
562
|
`)
|
|
418
563
|
|
|
419
564
|
// pages/home/page.yml
|
|
@@ -433,6 +578,93 @@ ctaUrl: "#"
|
|
|
433
578
|
Your content goes here.
|
|
434
579
|
`)
|
|
435
580
|
|
|
581
|
+
// README.md (only for standalone site, not workspace)
|
|
582
|
+
if (!isWorkspace) {
|
|
583
|
+
writeFile(join(projectDir, 'README.md'), `# ${projectName}
|
|
584
|
+
|
|
585
|
+
A Uniweb site — a content-driven website powered by a Foundation component library.
|
|
586
|
+
|
|
587
|
+
## Quick Start
|
|
588
|
+
|
|
589
|
+
\`\`\`bash
|
|
590
|
+
pnpm install
|
|
591
|
+
pnpm dev
|
|
592
|
+
\`\`\`
|
|
593
|
+
|
|
594
|
+
Open [http://localhost:3000](http://localhost:3000) to see your site.
|
|
595
|
+
|
|
596
|
+
## Project Structure
|
|
597
|
+
|
|
598
|
+
\`\`\`
|
|
599
|
+
${projectName}/
|
|
600
|
+
├── pages/ # Your content
|
|
601
|
+
│ └── home/
|
|
602
|
+
│ ├── page.yml # Page metadata
|
|
603
|
+
│ └── 1-hero.md # Section content
|
|
604
|
+
├── src/
|
|
605
|
+
│ └── main.jsx # Site entry point
|
|
606
|
+
├── site.yml # Site configuration
|
|
607
|
+
├── vite.config.js
|
|
608
|
+
└── package.json
|
|
609
|
+
\`\`\`
|
|
610
|
+
|
|
611
|
+
## Adding Pages
|
|
612
|
+
|
|
613
|
+
1. Create a folder in \`pages/your-page/\`
|
|
614
|
+
2. Add \`page.yml\`:
|
|
615
|
+
|
|
616
|
+
\`\`\`yaml
|
|
617
|
+
title: Your Page Title
|
|
618
|
+
order: 2
|
|
619
|
+
\`\`\`
|
|
620
|
+
|
|
621
|
+
3. Add section files (\`1-hero.md\`, \`2-features.md\`, etc.):
|
|
622
|
+
|
|
623
|
+
\`\`\`markdown
|
|
624
|
+
---
|
|
625
|
+
component: Hero
|
|
626
|
+
title: Section Title
|
|
627
|
+
subtitle: Section subtitle
|
|
628
|
+
---
|
|
629
|
+
|
|
630
|
+
Optional markdown content here.
|
|
631
|
+
\`\`\`
|
|
632
|
+
|
|
633
|
+
## How It Works
|
|
634
|
+
|
|
635
|
+
- Each folder in \`pages/\` becomes a route (\`/home\`, \`/about\`, etc.)
|
|
636
|
+
- Section files are numbered to control order (\`1-*.md\`, \`2-*.md\`)
|
|
637
|
+
- The \`component\` field specifies which Foundation component renders the section
|
|
638
|
+
- Other frontmatter fields become the component's content
|
|
639
|
+
|
|
640
|
+
## Configuration
|
|
641
|
+
|
|
642
|
+
The \`site.yml\` file configures your site:
|
|
643
|
+
|
|
644
|
+
\`\`\`yaml
|
|
645
|
+
name: ${projectName}
|
|
646
|
+
defaultLanguage: en
|
|
647
|
+
foundation: ${foundationImport} # Which foundation to use
|
|
648
|
+
\`\`\`
|
|
649
|
+
|
|
650
|
+
To use a different foundation, update the \`foundation\` field and install the package.
|
|
651
|
+
|
|
652
|
+
## Building for Production
|
|
653
|
+
|
|
654
|
+
\`\`\`bash
|
|
655
|
+
pnpm build
|
|
656
|
+
\`\`\`
|
|
657
|
+
|
|
658
|
+
Output is in \`dist/\` — ready to deploy to any static host.
|
|
659
|
+
|
|
660
|
+
## Learn More
|
|
661
|
+
|
|
662
|
+
- [Uniweb on GitHub](https://github.com/uniweb)
|
|
663
|
+
- [uniweb.app](https://uniweb.app)
|
|
664
|
+
|
|
665
|
+
`)
|
|
666
|
+
}
|
|
667
|
+
|
|
436
668
|
success(`Created site: ${projectName}`)
|
|
437
669
|
}
|
|
438
670
|
|
|
@@ -677,6 +909,99 @@ export default {
|
|
|
677
909
|
}
|
|
678
910
|
`)
|
|
679
911
|
|
|
912
|
+
// README.md (only for standalone foundation, not workspace)
|
|
913
|
+
if (!isWorkspace) {
|
|
914
|
+
writeFile(join(projectDir, 'README.md'), `# ${projectName}
|
|
915
|
+
|
|
916
|
+
A Uniweb Foundation — a React component library for content-driven websites.
|
|
917
|
+
|
|
918
|
+
## Quick Start
|
|
919
|
+
|
|
920
|
+
\`\`\`bash
|
|
921
|
+
pnpm install
|
|
922
|
+
pnpm dev # Start Vite dev server for component development
|
|
923
|
+
pnpm build # Build for production
|
|
924
|
+
\`\`\`
|
|
925
|
+
|
|
926
|
+
## Project Structure
|
|
927
|
+
|
|
928
|
+
\`\`\`
|
|
929
|
+
${projectName}/
|
|
930
|
+
├── src/
|
|
931
|
+
│ ├── components/ # Your components
|
|
932
|
+
│ │ └── Hero/
|
|
933
|
+
│ │ ├── index.jsx # React component
|
|
934
|
+
│ │ └── meta.js # Component metadata
|
|
935
|
+
│ ├── meta.js # Foundation metadata
|
|
936
|
+
│ ├── index.js # Exports
|
|
937
|
+
│ └── styles.css # Tailwind styles
|
|
938
|
+
├── package.json
|
|
939
|
+
├── vite.config.js
|
|
940
|
+
└── tailwind.config.js
|
|
941
|
+
\`\`\`
|
|
942
|
+
|
|
943
|
+
## Adding Components
|
|
944
|
+
|
|
945
|
+
1. Create \`src/components/YourComponent/index.jsx\`:
|
|
946
|
+
|
|
947
|
+
\`\`\`jsx
|
|
948
|
+
export function YourComponent({ content }) {
|
|
949
|
+
const { title, description } = content
|
|
950
|
+
return (
|
|
951
|
+
<section className="py-12 px-6">
|
|
952
|
+
<h2>{title}</h2>
|
|
953
|
+
<p>{description}</p>
|
|
954
|
+
</section>
|
|
955
|
+
)
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
export default YourComponent
|
|
959
|
+
\`\`\`
|
|
960
|
+
|
|
961
|
+
2. Create \`src/components/YourComponent/meta.js\`:
|
|
962
|
+
|
|
963
|
+
\`\`\`js
|
|
964
|
+
export default {
|
|
965
|
+
title: 'Your Component',
|
|
966
|
+
description: 'What this component does',
|
|
967
|
+
category: 'Content',
|
|
968
|
+
elements: {
|
|
969
|
+
title: { label: 'Title', required: true },
|
|
970
|
+
description: { label: 'Description' },
|
|
971
|
+
},
|
|
972
|
+
}
|
|
973
|
+
\`\`\`
|
|
974
|
+
|
|
975
|
+
3. Export from \`src/index.js\`:
|
|
976
|
+
|
|
977
|
+
\`\`\`js
|
|
978
|
+
export { YourComponent } from './components/YourComponent/index.jsx'
|
|
979
|
+
\`\`\`
|
|
980
|
+
|
|
981
|
+
## Build Output
|
|
982
|
+
|
|
983
|
+
After \`pnpm build\`:
|
|
984
|
+
|
|
985
|
+
\`\`\`
|
|
986
|
+
dist/
|
|
987
|
+
├── foundation.js # Bundled components
|
|
988
|
+
├── assets/style.css # Compiled Tailwind CSS
|
|
989
|
+
└── schema.json # Component metadata for editors
|
|
990
|
+
\`\`\`
|
|
991
|
+
|
|
992
|
+
## What is a Foundation?
|
|
993
|
+
|
|
994
|
+
A Foundation defines the vocabulary for Uniweb sites:
|
|
995
|
+
- **Components** — The building blocks creators can use
|
|
996
|
+
- **Elements** — Content slots (title, description, images, etc.)
|
|
997
|
+
- **Properties** — Configuration options exposed to creators
|
|
998
|
+
- **Presets** — Pre-configured variations of components
|
|
999
|
+
|
|
1000
|
+
Learn more at [github.com/uniweb](https://github.com/uniweb)
|
|
1001
|
+
|
|
1002
|
+
`)
|
|
1003
|
+
}
|
|
1004
|
+
|
|
680
1005
|
success(`Created foundation: ${projectName}`)
|
|
681
1006
|
}
|
|
682
1007
|
|