@bookklik/senangstart-css 0.2.3 → 0.2.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.
- package/dist/senangstart-css.js +100 -6
- package/dist/senangstart-css.min.js +26 -22
- package/dist/senangstart-tw.js +537 -0
- package/dist/senangstart-tw.min.js +2 -0
- package/docs/.vitepress/config.js +6 -0
- package/docs/guide/cdn.md +1 -1
- package/docs/ms/guide/cdn.md +1 -1
- package/docs/ms/reference/layout/position.md +4 -4
- package/docs/ms/reference/layout/z-index.md +8 -8
- package/docs/ms/reference/space/gap.md +1 -1
- package/docs/ms/reference/space/height.md +1 -1
- package/docs/ms/reference/space/margin.md +1 -1
- package/docs/ms/reference/space/padding.md +1 -1
- package/docs/ms/reference/space/scale-reference.md +46 -17
- package/docs/ms/reference/space/width.md +1 -1
- package/docs/ms/reference/space.md +1 -1
- package/docs/ms/reference/spacing.md +103 -21
- package/docs/ms/reference/visual/animation-fill.md +8 -8
- package/docs/ms/reference/visual/backdrop-blur.md +4 -4
- package/docs/ms/reference/visual/backdrop-brightness.md +8 -8
- package/docs/ms/reference/visual/backdrop-grayscale.md +6 -6
- package/docs/ms/reference/visual/backdrop-sepia.md +6 -6
- package/docs/ms/reference/visual/background-clip.md +2 -2
- package/docs/ms/reference/visual/background-image.md +4 -4
- package/docs/ms/reference/visual/filter-brightness.md +4 -4
- package/docs/ms/reference/visual/filter-contrast.md +4 -4
- package/docs/ms/reference/visual/filter-drop-shadow.md +6 -6
- package/docs/ms/reference/visual/filter-grayscale.md +4 -4
- package/docs/ms/reference/visual/filter-hue-rotate.md +4 -4
- package/docs/ms/reference/visual/filter-invert.md +2 -2
- package/docs/ms/reference/visual/filter-saturate.md +4 -4
- package/docs/ms/reference/visual/filter-sepia.md +4 -4
- package/docs/ms/reference/visual/font-family.md +2 -2
- package/docs/ms/reference/visual/gradient-from.md +57 -0
- package/docs/ms/reference/visual/gradient-to.md +57 -0
- package/docs/ms/reference/visual/gradient-via.md +54 -0
- package/docs/ms/reference/visual/letter-spacing.md +2 -2
- package/docs/ms/reference/visual/line-clamp.md +2 -2
- package/docs/ms/reference/visual/line-height.md +2 -2
- package/docs/ms/reference/visual/outline.md +2 -2
- package/docs/ms/reference/visual/ring-color.md +29 -0
- package/docs/ms/reference/visual/ring-offset.md +30 -0
- package/docs/ms/reference/visual/ring.md +62 -0
- package/docs/ms/reference/visual/stroke-width.md +6 -6
- package/docs/ms/reference/visual/stroke.md +4 -4
- package/docs/ms/reference/visual/text-indent.md +2 -2
- package/docs/ms/reference/visual/text-overflow.md +2 -2
- package/docs/ms/reference/visual/text-size.md +84 -84
- package/docs/ms/reference/visual/text-wrap.md +2 -2
- package/docs/ms/reference/visual/transform-backface.md +4 -4
- package/docs/ms/reference/visual/transform-perspective-origin.md +6 -6
- package/docs/ms/reference/visual/transform-perspective.md +6 -6
- package/docs/ms/reference/visual/transform-rotate-3d.md +6 -6
- package/docs/ms/reference/visual/transform-style.md +4 -4
- package/docs/ms/reference/visual/transform-translate-z.md +6 -6
- package/docs/ms/reference/visual/transform-translate.md +2 -2
- package/docs/ms/reference/visual/whitespace.md +2 -2
- package/docs/ms/reference/visual/word-break.md +2 -2
- package/docs/public/assets/senangstart-css.min.js +213 -1545
- package/docs/public/llms.txt +1718 -0
- package/docs/reference/layout/position.md +4 -4
- package/docs/reference/layout/z-index.md +8 -8
- package/docs/reference/space/gap.md +1 -1
- package/docs/reference/space/height.md +1 -1
- package/docs/reference/space/margin.md +1 -1
- package/docs/reference/space/padding.md +1 -1
- package/docs/reference/space/scale-reference.md +46 -17
- package/docs/reference/space/width.md +1 -1
- package/docs/reference/space.md +1 -1
- package/docs/reference/spacing.md +103 -21
- package/docs/reference/visual/animation-fill.md +8 -8
- package/docs/reference/visual/backdrop-blur.md +4 -4
- package/docs/reference/visual/backdrop-brightness.md +8 -8
- package/docs/reference/visual/backdrop-grayscale.md +6 -6
- package/docs/reference/visual/backdrop-sepia.md +6 -6
- package/docs/reference/visual/background-clip.md +2 -2
- package/docs/reference/visual/background-image.md +4 -4
- package/docs/reference/visual/filter-brightness.md +4 -4
- package/docs/reference/visual/filter-contrast.md +4 -4
- package/docs/reference/visual/filter-drop-shadow.md +6 -6
- package/docs/reference/visual/filter-grayscale.md +4 -4
- package/docs/reference/visual/filter-hue-rotate.md +4 -4
- package/docs/reference/visual/filter-invert.md +2 -2
- package/docs/reference/visual/filter-saturate.md +4 -4
- package/docs/reference/visual/filter-sepia.md +4 -4
- package/docs/reference/visual/font-family.md +2 -2
- package/docs/reference/visual/gradient-from.md +57 -0
- package/docs/reference/visual/gradient-to.md +57 -0
- package/docs/reference/visual/gradient-via.md +54 -0
- package/docs/reference/visual/letter-spacing.md +2 -2
- package/docs/reference/visual/line-clamp.md +2 -2
- package/docs/reference/visual/line-height.md +2 -2
- package/docs/reference/visual/outline.md +2 -2
- package/docs/reference/visual/ring-color.md +29 -0
- package/docs/reference/visual/ring-offset.md +30 -0
- package/docs/reference/visual/ring.md +62 -0
- package/docs/reference/visual/stroke-width.md +6 -6
- package/docs/reference/visual/stroke.md +4 -4
- package/docs/reference/visual/text-indent.md +2 -2
- package/docs/reference/visual/text-overflow.md +2 -2
- package/docs/reference/visual/text-size.md +84 -84
- package/docs/reference/visual/text-wrap.md +2 -2
- package/docs/reference/visual/transform-backface.md +4 -4
- package/docs/reference/visual/transform-perspective-origin.md +6 -6
- package/docs/reference/visual/transform-perspective.md +6 -6
- package/docs/reference/visual/transform-rotate-3d.md +6 -6
- package/docs/reference/visual/transform-style.md +4 -4
- package/docs/reference/visual/transform-translate-z.md +6 -6
- package/docs/reference/visual/transform-translate.md +2 -2
- package/docs/reference/visual/whitespace.md +2 -2
- package/docs/reference/visual/word-break.md +2 -2
- package/package.json +4 -2
- package/playground/tw-convertor.html +103 -589
- package/scripts/build-dist.js +45 -3
- package/scripts/bundle-jit.js +3 -3
- package/scripts/convert-tailwind.js +180 -1
- package/scripts/generate-llms-txt.js +264 -0
- package/src/cdn/{jit.js → senangstart-engine.js} +97 -8
- package/src/cdn/tw-conversion-engine.js +632 -0
- package/src/compiler/generators/css.js +27 -0
- package/src/config/defaults.js +37 -11
- package/src/core/constants.js +37 -8
- package/src/definitions/layout-positioning.js +6 -6
- package/src/definitions/space.js +46 -5
- package/src/definitions/visual-backgrounds.js +113 -15
- package/src/definitions/visual-borders.js +81 -2
- package/src/definitions/visual-filters.js +16 -16
- package/src/definitions/visual-svg.js +5 -5
- package/src/definitions/visual-transform3d.js +16 -16
- package/src/definitions/visual-transforms.js +1 -1
- package/src/definitions/visual-transitions.js +4 -4
- package/src/definitions/visual-typography.js +6 -6
- package/src/definitions/visual.js +4 -4
- package/tests/unit/compiler/generators/css.test.js +192 -0
- package/tests/unit/convert-tailwind.test.js +8 -0
package/scripts/build-dist.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as esbuild from 'esbuild';
|
|
9
|
-
import { mkdirSync, statSync } from 'fs';
|
|
9
|
+
import { mkdirSync, statSync, copyFileSync } from 'fs';
|
|
10
10
|
import { dirname, join } from 'path';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
|
|
@@ -21,7 +21,7 @@ console.log('📦 Building SenangStart CSS...\n');
|
|
|
21
21
|
|
|
22
22
|
// Build unminified version
|
|
23
23
|
await esbuild.build({
|
|
24
|
-
entryPoints: [join(root, 'src', 'cdn', '
|
|
24
|
+
entryPoints: [join(root, 'src', 'cdn', 'senangstart-engine.js')],
|
|
25
25
|
bundle: true,
|
|
26
26
|
format: 'iife',
|
|
27
27
|
outfile: join(distDir, 'senangstart-css.js'),
|
|
@@ -36,7 +36,7 @@ console.log(`✓ Created senangstart-css.js (${(unminSize / 1024).toFixed(1)} KB
|
|
|
36
36
|
|
|
37
37
|
// Build minified version
|
|
38
38
|
await esbuild.build({
|
|
39
|
-
entryPoints: [join(root, 'src', 'cdn', '
|
|
39
|
+
entryPoints: [join(root, 'src', 'cdn', 'senangstart-engine.js')],
|
|
40
40
|
bundle: true,
|
|
41
41
|
format: 'iife',
|
|
42
42
|
outfile: join(distDir, 'senangstart-css.min.js'),
|
|
@@ -49,6 +49,48 @@ await esbuild.build({
|
|
|
49
49
|
const minSize = statSync(join(distDir, 'senangstart-css.min.js')).size;
|
|
50
50
|
console.log(`✓ Created senangstart-css.min.js (${(minSize / 1024).toFixed(1)} KB)`);
|
|
51
51
|
|
|
52
|
+
// Build Tailwind converter - unminified
|
|
53
|
+
await esbuild.build({
|
|
54
|
+
entryPoints: [join(root, 'src', 'cdn', 'tw-conversion-engine.js')],
|
|
55
|
+
bundle: true,
|
|
56
|
+
format: 'iife',
|
|
57
|
+
outfile: join(distDir, 'senangstart-tw.js'),
|
|
58
|
+
minify: false,
|
|
59
|
+
banner: {
|
|
60
|
+
js: '/* SenangStart CSS - Tailwind Converter v0.2.0 | MIT License */'
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const twUnminSize = statSync(join(distDir, 'senangstart-tw.js')).size;
|
|
65
|
+
console.log(`✓ Created senangstart-tw.js (${(twUnminSize / 1024).toFixed(1)} KB)`);
|
|
66
|
+
|
|
67
|
+
// Build Tailwind converter - minified
|
|
68
|
+
await esbuild.build({
|
|
69
|
+
entryPoints: [join(root, 'src', 'cdn', 'tw-conversion-engine.js')],
|
|
70
|
+
bundle: true,
|
|
71
|
+
format: 'iife',
|
|
72
|
+
outfile: join(distDir, 'senangstart-tw.min.js'),
|
|
73
|
+
minify: true,
|
|
74
|
+
banner: {
|
|
75
|
+
js: '/* SenangStart TW v0.2.0 | MIT */'
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const twMinSize = statSync(join(distDir, 'senangstart-tw.min.js')).size;
|
|
80
|
+
console.log(`✓ Created senangstart-tw.min.js (${(twMinSize / 1024).toFixed(1)} KB)`);
|
|
81
|
+
|
|
82
|
+
// Copy to docs/public/assets for VitePress
|
|
83
|
+
const docsAssetsDir = join(root, 'docs', 'public', 'assets');
|
|
84
|
+
mkdirSync(docsAssetsDir, { recursive: true });
|
|
85
|
+
copyFileSync(
|
|
86
|
+
join(distDir, 'senangstart-css.min.js'),
|
|
87
|
+
join(docsAssetsDir, 'senangstart-css.min.js')
|
|
88
|
+
);
|
|
89
|
+
console.log(`✓ Copied to docs/public/assets/senangstart-css.min.js`);
|
|
90
|
+
|
|
52
91
|
console.log('\n📦 Dist build complete!');
|
|
53
92
|
console.log(' dist/senangstart-css.js');
|
|
54
93
|
console.log(' dist/senangstart-css.min.js');
|
|
94
|
+
console.log(' dist/senangstart-tw.js');
|
|
95
|
+
console.log(' dist/senangstart-tw.min.js');
|
|
96
|
+
|
package/scripts/bundle-jit.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Bundle JIT Runtime with esbuild
|
|
5
|
-
* Bundles src/cdn/
|
|
5
|
+
* Bundles src/cdn/senangstart-engine.js into a self-contained IIFE for browser use
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as esbuild from 'esbuild';
|
|
@@ -16,7 +16,7 @@ console.log('📦 Bundling JIT runtime...');
|
|
|
16
16
|
|
|
17
17
|
// Build unminified version
|
|
18
18
|
await esbuild.build({
|
|
19
|
-
entryPoints: [join(root, 'src', 'cdn', '
|
|
19
|
+
entryPoints: [join(root, 'src', 'cdn', 'senangstart-engine.js')],
|
|
20
20
|
bundle: true,
|
|
21
21
|
format: 'iife',
|
|
22
22
|
outfile: join(root, 'dist', 'senangstart-css.js'),
|
|
@@ -30,7 +30,7 @@ console.log('✓ Created dist/senangstart-css.js');
|
|
|
30
30
|
|
|
31
31
|
// Build minified version
|
|
32
32
|
await esbuild.build({
|
|
33
|
-
entryPoints: [join(root, 'src', 'cdn', '
|
|
33
|
+
entryPoints: [join(root, 'src', 'cdn', 'senangstart-engine.js')],
|
|
34
34
|
bundle: true,
|
|
35
35
|
format: 'iife',
|
|
36
36
|
outfile: join(root, 'dist', 'senangstart-css.min.js'),
|
|
@@ -318,7 +318,21 @@ const visualKeywordMappings = {
|
|
|
318
318
|
|
|
319
319
|
// Appearance
|
|
320
320
|
'appearance-none': 'appearance:none',
|
|
321
|
-
'appearance-auto': 'appearance:auto'
|
|
321
|
+
'appearance-auto': 'appearance:auto',
|
|
322
|
+
|
|
323
|
+
// 3D Transforms
|
|
324
|
+
'perspective': 'perspective',
|
|
325
|
+
'perspective-origin': 'perspective-origin',
|
|
326
|
+
'transform-style': 'transform-style',
|
|
327
|
+
'backface-visibility': 'backface',
|
|
328
|
+
'mask': 'mask',
|
|
329
|
+
'mask-image': 'mask-image',
|
|
330
|
+
'mask-mode': 'mask-mode',
|
|
331
|
+
'mask-origin': 'mask-origin',
|
|
332
|
+
'mask-position': 'mask-position',
|
|
333
|
+
'mask-repeat': 'mask-repeat',
|
|
334
|
+
'mask-size': 'mask-size',
|
|
335
|
+
'mask-type': 'mask-type'
|
|
322
336
|
};
|
|
323
337
|
|
|
324
338
|
// ======================
|
|
@@ -583,6 +597,171 @@ function convertClass(twClass, options = {}) {
|
|
|
583
597
|
return { category: 'visual', value: prefix + "opacity:" + opacityMatch[1] };
|
|
584
598
|
}
|
|
585
599
|
|
|
600
|
+
// Gradient direction (bg-gradient-to-*)
|
|
601
|
+
const bgGradientMatch = baseClass.match(/^bg-gradient-to-(t|tr|r|br|b|bl|l|tl)$/);
|
|
602
|
+
if (bgGradientMatch) {
|
|
603
|
+
return { category: 'visual', value: prefix + "bg-image:gradient-to-" + bgGradientMatch[1] };
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// Gradient from-* (starting color)
|
|
607
|
+
const fromMatch = baseClass.match(/^from-(.+)$/);
|
|
608
|
+
if (fromMatch) {
|
|
609
|
+
return { category: 'visual', value: prefix + "from:" + fromMatch[1] };
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Gradient via-* (middle color)
|
|
613
|
+
const viaMatch = baseClass.match(/^via-(.+)$/);
|
|
614
|
+
if (viaMatch) {
|
|
615
|
+
return { category: 'visual', value: prefix + "via:" + viaMatch[1] };
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Gradient to-* (ending color) - Note: must come after bg-gradient-to-*
|
|
619
|
+
const toMatch = baseClass.match(/^to-(.+)$/);
|
|
620
|
+
if (toMatch) {
|
|
621
|
+
return { category: 'visual', value: prefix + "to:" + toMatch[1] };
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// ======================
|
|
625
|
+
// 3D TRANSFORMS
|
|
626
|
+
// ======================
|
|
627
|
+
|
|
628
|
+
// Perspective
|
|
629
|
+
const perspectiveMatch = baseClass.match(/^perspective(?:-(.+))?$/);
|
|
630
|
+
if (perspectiveMatch) {
|
|
631
|
+
const val = perspectiveMatch[1] || 'normal';
|
|
632
|
+
return { category: 'visual', value: prefix + "perspective:" + val };
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Perspective origin
|
|
636
|
+
const perspectiveOriginMatch = baseClass.match(/^perspective-origin(?:-(.+))?$/);
|
|
637
|
+
if (perspectiveOriginMatch) {
|
|
638
|
+
const val = perspectiveOriginMatch[1] || 'center';
|
|
639
|
+
return { category: 'visual', value: prefix + "perspective-origin:" + val };
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Rotate X/Y/Z (3D rotation)
|
|
643
|
+
const rotateAxisMatch = baseClass.match(/^rotate-([xyz])(?:-(.+))?$/);
|
|
644
|
+
if (rotateAxisMatch) {
|
|
645
|
+
const axis = rotateAxisMatch[1].toLowerCase();
|
|
646
|
+
const val = rotateAxisMatch[2] || '0';
|
|
647
|
+
return { category: 'visual', value: prefix + `rotate-${axis}:${val}` };
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Rotate (2D)
|
|
651
|
+
const rotateMatch = baseClass.match(/^rotate(?:-(.+))?$/);
|
|
652
|
+
if (rotateMatch && !rotateAxisMatch) {
|
|
653
|
+
const val = rotateMatch[1] || '0';
|
|
654
|
+
return { category: 'visual', value: prefix + `rotate:${val}` };
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Scale X/Y
|
|
658
|
+
const scaleAxisMatch = baseClass.match(/^scale-([xy])(?:-(.+))?$/);
|
|
659
|
+
if (scaleAxisMatch) {
|
|
660
|
+
const axis = scaleAxisMatch[1].toLowerCase();
|
|
661
|
+
const val = scaleAxisMatch[2] || '100';
|
|
662
|
+
return { category: 'visual', value: prefix + `scale-${axis}:${val}` };
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// Scale (uniform)
|
|
666
|
+
const scaleMatch = baseClass.match(/^scale(?:-(.+))?$/);
|
|
667
|
+
if (scaleMatch && !scaleAxisMatch) {
|
|
668
|
+
const val = scaleMatch[1] || '100';
|
|
669
|
+
return { category: 'visual', value: prefix + `scale:${val}` };
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// Skew X/Y
|
|
673
|
+
const skewAxisMatch = baseClass.match(/^skew-([xy])(?:-(.+))?$/);
|
|
674
|
+
if (skewAxisMatch) {
|
|
675
|
+
const axis = skewAxisMatch[1].toLowerCase();
|
|
676
|
+
const val = skewAxisMatch[2] || '0';
|
|
677
|
+
return { category: 'visual', value: prefix + `skew-${axis}:${val}` };
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Translate X/Y/Z
|
|
681
|
+
const translateAxisMatch = baseClass.match(/^translate-([xyz])(?:-(.+))?$/);
|
|
682
|
+
if (translateAxisMatch) {
|
|
683
|
+
const axis = translateAxisMatch[1].toLowerCase();
|
|
684
|
+
const val = translateAxisMatch[2] || '0';
|
|
685
|
+
return { category: 'visual', value: prefix + `translate-${axis}:${val}` };
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Transform style
|
|
689
|
+
const transformStyleMatch = baseClass.match(/^transform-style(?:-(.+))?$/);
|
|
690
|
+
if (transformStyleMatch) {
|
|
691
|
+
const val = transformStyleMatch[1] || 'flat';
|
|
692
|
+
return { category: 'visual', value: prefix + "transform-style:" + val };
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Backface visibility
|
|
696
|
+
const backfaceMatch = baseClass.match(/^backface(?:-(.+))?$/);
|
|
697
|
+
if (backfaceMatch) {
|
|
698
|
+
const val = backfaceMatch[1] || 'hidden';
|
|
699
|
+
return { category: 'visual', value: prefix + "backface:" + val };
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// Transform origin
|
|
703
|
+
const originMatch = baseClass.match(/^origin(?:-(.+))?$/);
|
|
704
|
+
if (originMatch) {
|
|
705
|
+
const val = originMatch[1] || 'center';
|
|
706
|
+
return { category: 'visual', value: prefix + "origin:" + val };
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// Mask
|
|
710
|
+
const maskMatch = baseClass.match(/^mask(?:-(.+))?$/);
|
|
711
|
+
if (maskMatch) {
|
|
712
|
+
const val = maskMatch[1] || 'none';
|
|
713
|
+
return { category: 'visual', value: prefix + "mask:" + val };
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
// Mask image
|
|
717
|
+
const maskImageMatch = baseClass.match(/^mask-image(?:-(.+))?$/);
|
|
718
|
+
if (maskImageMatch) {
|
|
719
|
+
const val = maskImageMatch[1] || 'none';
|
|
720
|
+
return { category: 'visual', value: prefix + "mask-image:" + val };
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// Mask mode
|
|
724
|
+
const maskModeMatch = baseClass.match(/^mask-mode(?:-(.+))?$/);
|
|
725
|
+
if (maskModeMatch) {
|
|
726
|
+
const val = maskModeMatch[1] || 'match';
|
|
727
|
+
return { category: 'visual', value: prefix + "mask-mode:" + val };
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// Mask origin
|
|
731
|
+
const maskOriginMatch = baseClass.match(/^mask-origin(?:-(.+))?$/);
|
|
732
|
+
if (maskOriginMatch) {
|
|
733
|
+
const val = maskOriginMatch[1] || 'center';
|
|
734
|
+
return { category: 'visual', value: prefix + "mask-origin:" + val };
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// Mask position
|
|
738
|
+
const maskPositionMatch = baseClass.match(/^mask-position(?:-(.+))?$/);
|
|
739
|
+
if (maskPositionMatch) {
|
|
740
|
+
const val = maskPositionMatch[1] || 'center';
|
|
741
|
+
return { category: 'visual', value: prefix + "mask-position:" + val };
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// Mask repeat
|
|
745
|
+
const maskRepeatMatch = baseClass.match(/^mask-repeat(?:-(.+))?$/);
|
|
746
|
+
if (maskRepeatMatch) {
|
|
747
|
+
const val = maskRepeatMatch[1] || 'repeat';
|
|
748
|
+
return { category: 'visual', value: prefix + "mask-repeat:" + val };
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Mask size
|
|
752
|
+
const maskSizeMatch = baseClass.match(/^mask-size(?:-(.+))?$/);
|
|
753
|
+
if (maskSizeMatch) {
|
|
754
|
+
const val = maskSizeMatch[1] || 'auto';
|
|
755
|
+
return { category: 'visual', value: prefix + "mask-size:" + val };
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Mask type
|
|
759
|
+
const maskTypeMatch = baseClass.match(/^mask-type(?:-(.+))?$/);
|
|
760
|
+
if (maskTypeMatch) {
|
|
761
|
+
const val = maskTypeMatch[1] || 'luminance';
|
|
762
|
+
return { category: 'visual', value: prefix + "mask-type:" + val };
|
|
763
|
+
}
|
|
764
|
+
|
|
586
765
|
return null;
|
|
587
766
|
}
|
|
588
767
|
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const PACKAGE_JSON_PATH = path.resolve(__dirname, '../package.json');
|
|
13
|
+
const DEFINITIONS_DIR = path.resolve(__dirname, '../src/definitions');
|
|
14
|
+
const OUTPUT_PATH = path.resolve(__dirname, '../docs/public/llms.txt');
|
|
15
|
+
|
|
16
|
+
// Load defaults from package.json
|
|
17
|
+
let defaults = {
|
|
18
|
+
name: 'SenangStart CSS',
|
|
19
|
+
description: '',
|
|
20
|
+
license: 'MIT',
|
|
21
|
+
homepage: ''
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
if (fs.existsSync(PACKAGE_JSON_PATH)) {
|
|
26
|
+
const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON_PATH, 'utf-8'));
|
|
27
|
+
if (pkg.name) defaults.name = pkg.name;
|
|
28
|
+
if (pkg.description) defaults.description = pkg.description;
|
|
29
|
+
if (pkg.license) defaults.license = pkg.license;
|
|
30
|
+
if (pkg.homepage) defaults.homepage = pkg.homepage;
|
|
31
|
+
}
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.warn('Warning: Could not read package.json for defaults.');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
function formatDefinition(key, def) {
|
|
39
|
+
let output = `## ${def.title || def.name || key}\n`;
|
|
40
|
+
if (def.description) {
|
|
41
|
+
output += `> ${def.description}\n`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Add Syntax/Usage if available
|
|
45
|
+
if (def.syntax) {
|
|
46
|
+
output += `\n**Syntax:** \`${def.syntax}\`\n`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (def.values && Array.isArray(def.values)) {
|
|
50
|
+
output += `\n`;
|
|
51
|
+
def.values.forEach(val => {
|
|
52
|
+
let valDesc = val.description || '';
|
|
53
|
+
// If CSS is present, maybe show it, or keep it high level?
|
|
54
|
+
// Tailwind example had: `bg-none`: Removes background image (`background-image: none;`).
|
|
55
|
+
// Our values are like { value: 'none', css: '...', description: '...' }
|
|
56
|
+
// The utility class is constructed via syntax, usually properties like `text:left` or `bg:primary`.
|
|
57
|
+
// The 'value' field is just the suffix/argument.
|
|
58
|
+
|
|
59
|
+
// Let's try to infer the full utility format if possible, or just list the value.
|
|
60
|
+
// If syntax is visual="text:[alignment]", and value is 'left', then utility is text:left.
|
|
61
|
+
|
|
62
|
+
let displayValue = val.value;
|
|
63
|
+
// Attempt to contextualize the value based on syntax
|
|
64
|
+
// e.g. syntax="visual="text:[alignment]"", value="left" -> text:left
|
|
65
|
+
// This might be complex to regex universally, but let's try a simple approach if possible.
|
|
66
|
+
// For now, just listing the value is safe.
|
|
67
|
+
|
|
68
|
+
let line = `* \`${displayValue}\``;
|
|
69
|
+
if (valDesc) line += `: ${valDesc}`;
|
|
70
|
+
if (val.css && val.css.length < 50) line += ` (\`${val.css}\`)`; // only show if short
|
|
71
|
+
|
|
72
|
+
output += `${line}\n`;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
output += `\n`;
|
|
76
|
+
return output;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function loadDefinitions() {
|
|
80
|
+
const definitions = new Map();
|
|
81
|
+
if (!fs.existsSync(DEFINITIONS_DIR)) return [];
|
|
82
|
+
|
|
83
|
+
const files = fs.readdirSync(DEFINITIONS_DIR).filter(f => f.endsWith('.js'));
|
|
84
|
+
|
|
85
|
+
for (const file of files) {
|
|
86
|
+
try {
|
|
87
|
+
const filePath = path.join(DEFINITIONS_DIR, file);
|
|
88
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
89
|
+
const module = await import(fileUrl);
|
|
90
|
+
|
|
91
|
+
// Iterate over exports, skipping default if it's just a collection of others
|
|
92
|
+
for (const [key, value] of Object.entries(module)) {
|
|
93
|
+
if (key === 'default') continue;
|
|
94
|
+
// Check if it looks like a definition (has name/property/values)
|
|
95
|
+
if (value && value.name && value.property && Array.isArray(value.values)) {
|
|
96
|
+
// Use definition name as key to prevent duplicates from re-exports
|
|
97
|
+
// e.g. layout.js re-exports definition from layout-flex.js
|
|
98
|
+
const defName = value.name;
|
|
99
|
+
if (!definitions.has(defName)) {
|
|
100
|
+
definitions.set(defName, { key, ...value });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch (e) {
|
|
105
|
+
console.error(`Error loading definition ${file}:`, e);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return Array.from(definitions.values());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function getGuideContent() {
|
|
112
|
+
return `
|
|
113
|
+
# Framework Overview
|
|
114
|
+
|
|
115
|
+
SenangStart CSS is a utility-first framework that uses **Natural Adjectives** instead of abstract numbers.
|
|
116
|
+
|
|
117
|
+
## Core Philosophy
|
|
118
|
+
- **Natural Scale**: Sizes map to physical mental models (e.g., \`tiny\` = pebble/4px, \`medium\` = smartphone/16px, \`giant\` = door/64px).
|
|
119
|
+
- **Intent-First**: Describe *what* you want ("give it air" -> scale up), not pixels.
|
|
120
|
+
- **Tri-Attribute Syntax**: Separation of concerns into three attributes:
|
|
121
|
+
1. \`layout\`: Structure & position (flex, grid, block, sticky).
|
|
122
|
+
2. \`space\`: Sizing, padding, margin, gap.
|
|
123
|
+
3. \`visual\`: Colors, typography, borders, shadows, effects.
|
|
124
|
+
|
|
125
|
+
## Syntax Reference
|
|
126
|
+
|
|
127
|
+
### 1. Layout Attribute
|
|
128
|
+
Controls internal flow and external positioning.
|
|
129
|
+
- **Flex**: \`layout="flex col center"\` (Flexbox, column direction, centered).
|
|
130
|
+
- **Grid**: \`layout="grid"\`
|
|
131
|
+
- **Position**: \`layout="absolute z:top"\`
|
|
132
|
+
|
|
133
|
+
### 2. Space Attribute
|
|
134
|
+
Controls dimensions and spacing using the Natural Scale.
|
|
135
|
+
- **Syntax**: \`[breakpoint]:[property]:[scale]\`
|
|
136
|
+
- **Properties**: \`p\` (padding), \`m\` (margin), \`g\` (gap), \`w\` (width), \`h\` (height).
|
|
137
|
+
- **Values**:
|
|
138
|
+
- \`none\` (0px)
|
|
139
|
+
- \`thin\` (1px), \`regular\` (2px), \`thick\` (3px)
|
|
140
|
+
- \`tiny\` (4px), \`tiny-2x\` (6px)
|
|
141
|
+
- \`small\` (8px), \`small-2x\` (10px), \`small-3x\` (12px), \`small-4x\` (14px)
|
|
142
|
+
- \`medium\` (16px), \`medium-2x\` (20px), \`medium-3x\` (24px), \`medium-4x\` (28px)
|
|
143
|
+
- \`large\` (32px), \`large-2x\` (36px), \`large-3x\` (40px), \`large-4x\` (44px)
|
|
144
|
+
- \`big\` (48px), \`big-2x\` (56px), \`big-3x\` (64px), \`big-4x\` (80px)
|
|
145
|
+
- \`giant\` (96px), \`giant-2x\` (112px), \`giant-3x\` (128px), \`giant-4x\` (144px)
|
|
146
|
+
- \`vast\` (160px), \`vast-2x\` (176px), \`vast-3x\` (192px), \`vast-4x\` (208px)
|
|
147
|
+
- \`vast-5x\` (224px), \`vast-6x\` (240px), \`vast-7x\` (256px), \`vast-8x\` (288px)
|
|
148
|
+
- \`vast-9x\` (320px), \`vast-10x\` (384px)
|
|
149
|
+
- **Arbitrary**: \`space="w:[350px]"\`
|
|
150
|
+
|
|
151
|
+
### 3. Visual Attribute
|
|
152
|
+
Controls appearance.
|
|
153
|
+
- **Colors**: \`bg:primary\`, \`text:white\`, \`border:grey\`.
|
|
154
|
+
- **Typography**: \`font:bold\`, \`text-size:big\`.
|
|
155
|
+
- **Effects**: \`rounded:medium\`, \`shadow:big\`, \`opacity:[0.5]\`.
|
|
156
|
+
|
|
157
|
+
## Modifiers
|
|
158
|
+
|
|
159
|
+
### Responsive Prefixes
|
|
160
|
+
Mobile-first breakpoints:
|
|
161
|
+
- (default): 0px+
|
|
162
|
+
- \`mob:\`: 480px+ ("Large Mobile")
|
|
163
|
+
- \`tab:\`: 768px+ ("Tablet")
|
|
164
|
+
- \`lap:\`: 1024px+ ("Laptop")
|
|
165
|
+
- \`desk:\`: 1280px+ ("Desktop")
|
|
166
|
+
|
|
167
|
+
Example: \`space="p:small tab:p:medium lap:p:big"\`
|
|
168
|
+
|
|
169
|
+
### State Prefixes
|
|
170
|
+
- \`hover:\`: \`visual="bg:primary hover:bg:primary-dark"\`
|
|
171
|
+
- \`focus:\`: \`visual="border:grey focus:border:brand"\`
|
|
172
|
+
- \`active:\`, \`disabled:\`, \`group-hover:\`
|
|
173
|
+
- \`dark:\`: \`visual="bg:white dark:bg:slate-900"\`
|
|
174
|
+
|
|
175
|
+
## Configuration
|
|
176
|
+
Use \`senangstart.config.js\` to override defaults.
|
|
177
|
+
\`\`\`js
|
|
178
|
+
export default {
|
|
179
|
+
theme: {
|
|
180
|
+
colors: { brand: '#8B5CF6' },
|
|
181
|
+
spacing: { huge: '256px' }
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
\`\`\`
|
|
185
|
+
`.trim();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async function generate() {
|
|
189
|
+
console.log('Generating docs/public/llms.txt with references...\n');
|
|
190
|
+
|
|
191
|
+
const name = defaults.name;
|
|
192
|
+
const description = defaults.description;
|
|
193
|
+
const domain = defaults.homepage || 'https://bookklik-technologies.github.io/senangstart-css';
|
|
194
|
+
const docsUrls = `${domain}/guide`;
|
|
195
|
+
const apiEndpoints = '';
|
|
196
|
+
const repo = 'https://github.com/bookklik-technologies/senangstart-css';
|
|
197
|
+
const email = '';
|
|
198
|
+
const license = defaults.license;
|
|
199
|
+
|
|
200
|
+
let content = `# ${name}\n`;
|
|
201
|
+
content += `> ${description}\n\n`;
|
|
202
|
+
|
|
203
|
+
if (docsUrls) {
|
|
204
|
+
content += `## Docs\n`;
|
|
205
|
+
docsUrls.split(',').map(url => url.trim()).forEach(url => {
|
|
206
|
+
if (url) content += `- [Documentation](${url})\n`;
|
|
207
|
+
});
|
|
208
|
+
content += `\n`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (apiEndpoints) {
|
|
212
|
+
content += `## API\n`;
|
|
213
|
+
apiEndpoints.split(',').map(url => url.trim()).forEach(url => {
|
|
214
|
+
if (url) content += `- [API Endpoint](${url})\n`;
|
|
215
|
+
});
|
|
216
|
+
content += `\n`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (repo) {
|
|
220
|
+
content += `## Source\n`;
|
|
221
|
+
content += `- [Repository](${repo})\n\n`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (email) {
|
|
225
|
+
content += `## Contact\n`;
|
|
226
|
+
content += `- [Email](mailto:${email})\n`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Append Guide Content
|
|
230
|
+
console.log('Adding curated guide content...');
|
|
231
|
+
const guidesContent = getGuideContent();
|
|
232
|
+
if (guidesContent) {
|
|
233
|
+
content += `\n# Documentation Guides\n\n${guidesContent}\n`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Load and Append Definitions
|
|
237
|
+
const definitions = await loadDefinitions();
|
|
238
|
+
if (definitions.length > 0) {
|
|
239
|
+
content += `\n# Utility Definitions\n\n`;
|
|
240
|
+
// Sort by name or category?
|
|
241
|
+
definitions.sort((a, b) => (a.name || a.key).localeCompare(b.name || b.key));
|
|
242
|
+
|
|
243
|
+
for (const def of definitions) {
|
|
244
|
+
content += formatDefinition(def.key, def);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Ensure directory exists
|
|
249
|
+
const dir = path.dirname(OUTPUT_PATH);
|
|
250
|
+
if (!fs.existsSync(dir)) {
|
|
251
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
fs.writeFileSync(OUTPUT_PATH, content, 'utf-8');
|
|
255
|
+
console.log(`\nSuccessfully generated ${OUTPUT_PATH}`);
|
|
256
|
+
console.log(`Included guide content and ${definitions.length} utility definitions.`);
|
|
257
|
+
// console.log('-----------------------------------');
|
|
258
|
+
// console.log(content.substring(0, 500) + '...');
|
|
259
|
+
// console.log('-----------------------------------');
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
generate();
|