@bookklik/senangstart-css 0.2.4 → 0.2.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/.agent/skills/add-utility/scripts/scaffold-utility.js +209 -0
- package/.agent/skills/compiler-development/SKILL.md +272 -0
- package/.agent/skills/jit-engine/SKILL.md +241 -0
- package/.agent/skills/jit-engine/examples/add-visual-utility.js +117 -0
- package/.agent/skills/jit-engine/examples/scale-based-utilities.js +130 -0
- package/.agent/skills/jit-engine/examples/state-responsive-handling.js +177 -0
- package/.agent/skills/senangstart-architecture/SKILL.md +163 -0
- package/.agent/skills/tailwind-conversion/SKILL.md +264 -0
- package/.agent/workflows/add-utility.md +155 -0
- package/.agent/workflows/build.md +97 -0
- package/.agent/workflows/dev.md +58 -0
- package/.agent/workflows/docs.md +113 -0
- package/.agent/workflows/test.md +103 -0
- package/dist/senangstart-css.js +165 -20
- package/dist/senangstart-css.min.js +39 -26
- package/dist/senangstart-tw.js +262 -52
- package/dist/senangstart-tw.min.js +1 -1
- package/docs/.vitepress/config.js +10 -2
- 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 +42 -7
- 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 +40 -5
- 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/divide-reverse.md +66 -0
- package/docs/ms/reference/visual/divide-style.md +80 -0
- package/docs/ms/reference/visual/divide-width.md +89 -0
- package/docs/ms/reference/visual/divide.md +115 -0
- 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 -57
- package/docs/ms/reference/visual/gradient-to.md +57 -57
- package/docs/ms/reference/visual/gradient-via.md +54 -54
- 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 +2 -2
- 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 +39 -26
- package/docs/public/llms.txt +1756 -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 +42 -7
- 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 +40 -5
- 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/divide-reverse.md +66 -0
- package/docs/reference/visual/divide-style.md +80 -0
- package/docs/reference/visual/divide-width.md +89 -0
- package/docs/reference/visual/divide.md +115 -0
- 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 -57
- package/docs/reference/visual/gradient-to.md +57 -57
- package/docs/reference/visual/gradient-via.md +54 -54
- 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 +2 -2
- 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/docs/reference/visual.md +8 -2
- package/package.json +4 -2
- package/scripts/build-dist.js +2 -2
- package/scripts/bundle-jit.js +3 -3
- package/scripts/convert-tailwind.js +250 -2
- package/scripts/generate-llms-txt.js +264 -0
- package/src/cdn/{jit.js → senangstart-engine.js} +184 -38
- package/src/cdn/tw-conversion-engine.js +282 -68
- package/src/compiler/generators/css.js +115 -2
- package/src/config/defaults.js +37 -11
- package/src/core/constants.js +37 -8
- package/src/definitions/index.js +3 -0
- package/src/definitions/space.js +97 -20
- package/src/definitions/visual-borders.js +80 -1
- package/src/definitions/visual-divide.js +225 -0
- 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 +267 -3
- package/tests/unit/convert-tailwind.test.js +59 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Adding a Simple Visual Utility
|
|
3
|
+
*
|
|
4
|
+
* This example shows how to add a new 'glow' utility that adds
|
|
5
|
+
* a colored shadow effect to elements.
|
|
6
|
+
*
|
|
7
|
+
* Usage: visual="glow:primary glow:blue-500"
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ================================================
|
|
11
|
+
// Step 1: Add to Definition File
|
|
12
|
+
// ================================================
|
|
13
|
+
// File: src/definitions/visual.js or create visual-glow.js
|
|
14
|
+
|
|
15
|
+
export const glowDefinition = {
|
|
16
|
+
name: 'glow',
|
|
17
|
+
property: 'box-shadow',
|
|
18
|
+
category: 'visual',
|
|
19
|
+
attribute: 'visual',
|
|
20
|
+
description: 'Adds a colored glow effect around the element',
|
|
21
|
+
descriptionMs: 'Menambah kesan cahaya berwarna di sekeliling elemen',
|
|
22
|
+
syntax: 'glow:<color>',
|
|
23
|
+
values: [
|
|
24
|
+
{ name: 'primary', value: '0 0 20px var(--ss-color-primary)', description: 'Primary color glow' },
|
|
25
|
+
{ name: 'secondary', value: '0 0 20px var(--ss-color-secondary)', description: 'Secondary color glow' },
|
|
26
|
+
{ name: 'none', value: 'none', description: 'Remove glow' }
|
|
27
|
+
],
|
|
28
|
+
examples: [
|
|
29
|
+
{ code: 'visual="glow:primary"', description: 'Blue glow effect' },
|
|
30
|
+
{ code: 'visual="glow:secondary"', description: 'Purple glow effect' },
|
|
31
|
+
{ code: 'visual="hover:glow:primary"', description: 'Glow on hover' }
|
|
32
|
+
],
|
|
33
|
+
notes: 'Accepts any color from the color palette'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ================================================
|
|
37
|
+
// Step 2: Add Handler to JIT Engine
|
|
38
|
+
// ================================================
|
|
39
|
+
// File: src/cdn/senangstart-engine.js
|
|
40
|
+
// Add in generateVisualRule() function:
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
if (prop === 'glow') {
|
|
44
|
+
if (value === 'none') {
|
|
45
|
+
return 'box-shadow: none';
|
|
46
|
+
}
|
|
47
|
+
const color = config.theme.colors[value];
|
|
48
|
+
if (color) {
|
|
49
|
+
return `box-shadow: 0 0 20px ${color}`;
|
|
50
|
+
}
|
|
51
|
+
// Arbitrary color support
|
|
52
|
+
if (value.startsWith('[') && value.endsWith(']')) {
|
|
53
|
+
return `box-shadow: 0 0 20px ${value.slice(1, -1)}`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
// ================================================
|
|
59
|
+
// Step 3: Add Handler to CSS Generator
|
|
60
|
+
// ================================================
|
|
61
|
+
// File: src/compiler/generators/css.js
|
|
62
|
+
// Add in generateVisualRule() function (same logic as JIT):
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
if (prop === 'glow') {
|
|
66
|
+
if (value === 'none') {
|
|
67
|
+
return 'box-shadow: none';
|
|
68
|
+
}
|
|
69
|
+
const color = config.theme.colors[value];
|
|
70
|
+
if (color) {
|
|
71
|
+
return `box-shadow: 0 0 20px ${color}`;
|
|
72
|
+
}
|
|
73
|
+
if (token.isArbitrary) {
|
|
74
|
+
return `box-shadow: 0 0 20px ${sanitizeArbitraryValue(value)}`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
// ================================================
|
|
80
|
+
// Step 4: Write Test
|
|
81
|
+
// ================================================
|
|
82
|
+
// File: tests/unit/compiler/generators/glow.test.js
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
import { test, describe } from 'node:test';
|
|
86
|
+
import assert from 'node:assert';
|
|
87
|
+
import { generateVisualRule } from '../../../../src/compiler/generators/css.js';
|
|
88
|
+
|
|
89
|
+
const mockConfig = {
|
|
90
|
+
theme: {
|
|
91
|
+
colors: {
|
|
92
|
+
'primary': '#3B82F6',
|
|
93
|
+
'secondary': '#8B5CF6'
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
describe('glow utility', () => {
|
|
99
|
+
test('generates glow with primary color', () => {
|
|
100
|
+
const token = { property: 'glow', value: 'primary', attrType: 'visual' };
|
|
101
|
+
const result = generateVisualRule(token, mockConfig);
|
|
102
|
+
assert.strictEqual(result, 'box-shadow: 0 0 20px #3B82F6');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('generates glow:none', () => {
|
|
106
|
+
const token = { property: 'glow', value: 'none', attrType: 'visual' };
|
|
107
|
+
const result = generateVisualRule(token, mockConfig);
|
|
108
|
+
assert.strictEqual(result, 'box-shadow: none');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
// ================================================
|
|
114
|
+
// Step 5: Generate Documentation
|
|
115
|
+
// ================================================
|
|
116
|
+
// Run: npm run docs:generate
|
|
117
|
+
// This creates docs/reference/visual/glow.md automatically
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Handling Scale-Based Utilities
|
|
3
|
+
*
|
|
4
|
+
* This example shows patterns for utilities that use theme scales
|
|
5
|
+
* like spacing, colors, or custom scales.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ================================================
|
|
9
|
+
// Pattern 1: Using Existing Scale (spacing)
|
|
10
|
+
// ================================================
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
// In generateVisualRule():
|
|
14
|
+
if (prop === 'outline-offset') {
|
|
15
|
+
const space = config.theme.spacing[value];
|
|
16
|
+
if (space) {
|
|
17
|
+
return `outline-offset: ${space}`;
|
|
18
|
+
}
|
|
19
|
+
// Fallback to raw value for arbitrary
|
|
20
|
+
if (token.isArbitrary) {
|
|
21
|
+
return `outline-offset: ${value}`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
// ================================================
|
|
27
|
+
// Pattern 2: Adding a New Custom Scale
|
|
28
|
+
// ================================================
|
|
29
|
+
|
|
30
|
+
// Step 1: Add scale to defaultConfig in senangstart-engine.js
|
|
31
|
+
/*
|
|
32
|
+
const defaultConfig = {
|
|
33
|
+
theme: {
|
|
34
|
+
// ... existing scales
|
|
35
|
+
blur: {
|
|
36
|
+
'none': '0',
|
|
37
|
+
'tiny': '2px',
|
|
38
|
+
'small': '4px',
|
|
39
|
+
'medium': '8px',
|
|
40
|
+
'big': '16px',
|
|
41
|
+
'giant': '24px'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
// Step 2: Generate CSS variables in generateCSSVariables()
|
|
48
|
+
/*
|
|
49
|
+
Object.entries(config.theme.blur).forEach(([name, value]) => {
|
|
50
|
+
vars += ` --ss-blur-${name}: ${value};\n`;
|
|
51
|
+
});
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
// Step 3: Use in generator
|
|
55
|
+
/*
|
|
56
|
+
if (prop === 'blur') {
|
|
57
|
+
const blur = config.theme.blur[value];
|
|
58
|
+
if (blur) {
|
|
59
|
+
return `filter: blur(${blur})`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
// ================================================
|
|
65
|
+
// Pattern 3: Directional Utilities
|
|
66
|
+
// ================================================
|
|
67
|
+
|
|
68
|
+
/*
|
|
69
|
+
// Handle p-t, p-r, p-b, p-l, p-x, p-y patterns
|
|
70
|
+
if (prop.startsWith('p-')) {
|
|
71
|
+
const space = config.theme.spacing[value];
|
|
72
|
+
if (!space) return null;
|
|
73
|
+
|
|
74
|
+
const dir = prop.substring(2);
|
|
75
|
+
switch (dir) {
|
|
76
|
+
case 't': return `padding-top: ${space}`;
|
|
77
|
+
case 'r': return `padding-right: ${space}`;
|
|
78
|
+
case 'b': return `padding-bottom: ${space}`;
|
|
79
|
+
case 'l': return `padding-left: ${space}`;
|
|
80
|
+
case 'x': return `padding-left: ${space}; padding-right: ${space}`;
|
|
81
|
+
case 'y': return `padding-top: ${space}; padding-bottom: ${space}`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
// ================================================
|
|
87
|
+
// Pattern 4: Negative Values
|
|
88
|
+
// ================================================
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
// Handle negative margin: m-t:-small
|
|
92
|
+
if (prop.startsWith('m-') || prop === 'm') {
|
|
93
|
+
let isNegative = false;
|
|
94
|
+
let val = value;
|
|
95
|
+
|
|
96
|
+
if (value.startsWith('-')) {
|
|
97
|
+
isNegative = true;
|
|
98
|
+
val = value.substring(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const space = config.theme.spacing[val];
|
|
102
|
+
if (space) {
|
|
103
|
+
const finalValue = isNegative ? `-${space}` : space;
|
|
104
|
+
return `margin-${direction}: ${finalValue}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
// ================================================
|
|
110
|
+
// Pattern 5: Tailwind Compatibility (tw- prefix)
|
|
111
|
+
// ================================================
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
// In defaultConfig, add tw-* values for Tailwind compatibility
|
|
115
|
+
const defaultConfig = {
|
|
116
|
+
theme: {
|
|
117
|
+
spacing: {
|
|
118
|
+
// Native semantic values
|
|
119
|
+
'none': '0px',
|
|
120
|
+
'small': '8px',
|
|
121
|
+
// Tailwind compatibility values
|
|
122
|
+
'tw-0': '0px',
|
|
123
|
+
'tw-1': '0.25rem',
|
|
124
|
+
'tw-2': '0.5rem',
|
|
125
|
+
'tw-4': '1rem',
|
|
126
|
+
// ...
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
*/
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: State and Responsive Handling
|
|
3
|
+
*
|
|
4
|
+
* This example shows how states (hover, focus) and
|
|
5
|
+
* responsive prefixes (mob, tab) work in the engine.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ================================================
|
|
9
|
+
// State Handling in JIT Engine
|
|
10
|
+
// ================================================
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
// States are parsed in processTokens() before calling generators
|
|
14
|
+
function processTokens(attrValue, attrType) {
|
|
15
|
+
const tokens = attrValue.trim().split(/\s+/);
|
|
16
|
+
|
|
17
|
+
for (const token of tokens) {
|
|
18
|
+
const parts = token.split(':');
|
|
19
|
+
let state = null;
|
|
20
|
+
let breakpoint = null;
|
|
21
|
+
let propIdx = 0;
|
|
22
|
+
|
|
23
|
+
// Check for breakpoint prefix (mob:, tab:, etc.)
|
|
24
|
+
if (BREAKPOINTS.includes(parts[0])) {
|
|
25
|
+
breakpoint = parts[0];
|
|
26
|
+
propIdx++;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check for state prefix (hover:, focus:, etc.)
|
|
30
|
+
if (STATES.includes(parts[propIdx])) {
|
|
31
|
+
state = parts[propIdx];
|
|
32
|
+
propIdx++;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Rest is property:value
|
|
36
|
+
const property = parts[propIdx];
|
|
37
|
+
const value = parts.slice(propIdx + 1).join(':');
|
|
38
|
+
|
|
39
|
+
generateRule({ property, value, state, breakpoint });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
// ================================================
|
|
45
|
+
// Generating State-Based CSS
|
|
46
|
+
// ================================================
|
|
47
|
+
|
|
48
|
+
/*
|
|
49
|
+
function generateSelector(rawToken, attrType, state) {
|
|
50
|
+
// Escape special characters in selector
|
|
51
|
+
const escaped = rawToken.replace(/:/g, '\\:');
|
|
52
|
+
const baseSelector = `[${attrType}~="${rawToken}"]`;
|
|
53
|
+
|
|
54
|
+
if (state) {
|
|
55
|
+
// Add pseudo-class
|
|
56
|
+
return `${baseSelector}:${state}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return baseSelector;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Example output:
|
|
63
|
+
// [visual~="hover:bg:blue-500"]:hover { background-color: #3B82F6 }
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
// ================================================
|
|
67
|
+
// Responsive Breakpoint Handling
|
|
68
|
+
// ================================================
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
function wrapWithMediaQuery(css, breakpoint, config) {
|
|
72
|
+
if (!breakpoint) return css;
|
|
73
|
+
|
|
74
|
+
const minWidth = config.theme.screens[breakpoint];
|
|
75
|
+
return `@media (min-width: ${minWidth}) {\n ${css}\n}`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Example output:
|
|
79
|
+
// @media (min-width: 768px) {
|
|
80
|
+
// [layout~="tab:flex"] { display: flex }
|
|
81
|
+
// }
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
// ================================================
|
|
85
|
+
// Group Hover (Parent-Child States)
|
|
86
|
+
// ================================================
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
// group-hover: requires parent with 'group' class
|
|
90
|
+
if (state === 'group-hover') {
|
|
91
|
+
// Selector: .group:hover [visual~="group-hover:bg:blue-500"]
|
|
92
|
+
return `.group:hover ${baseSelector}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Usage:
|
|
96
|
+
// <div layout="group">
|
|
97
|
+
// <span visual="group-hover:text:blue-500">Hover parent to change me</span>
|
|
98
|
+
// </div>
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
// ================================================
|
|
102
|
+
// Dark Mode State
|
|
103
|
+
// ================================================
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
function getDarkModeSelector(config) {
|
|
107
|
+
if (config.darkMode === 'media') {
|
|
108
|
+
return '@media (prefers-color-scheme: dark)';
|
|
109
|
+
}
|
|
110
|
+
return '.dark'; // Selector mode
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// For dark: state
|
|
114
|
+
if (state === 'dark') {
|
|
115
|
+
if (config.darkMode === 'media') {
|
|
116
|
+
return `@media (prefers-color-scheme: dark) {\n ${baseSelector} { ${css} }\n}`;
|
|
117
|
+
} else {
|
|
118
|
+
return `.dark ${baseSelector} { ${css} }`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
// ================================================
|
|
124
|
+
// Combining States and Breakpoints
|
|
125
|
+
// ================================================
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
// Token: tab:hover:bg:blue-500
|
|
129
|
+
// Breakdown:
|
|
130
|
+
// breakpoint: 'tab' (768px)
|
|
131
|
+
// state: 'hover'
|
|
132
|
+
// property: 'bg'
|
|
133
|
+
// value: 'blue-500'
|
|
134
|
+
|
|
135
|
+
// Output:
|
|
136
|
+
// @media (min-width: 768px) {
|
|
137
|
+
// [visual~="tab:hover:bg:blue-500"]:hover {
|
|
138
|
+
// background-color: #3B82F6
|
|
139
|
+
// }
|
|
140
|
+
// }
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
// ================================================
|
|
144
|
+
// Available States (from constants.js)
|
|
145
|
+
// ================================================
|
|
146
|
+
|
|
147
|
+
const STATES = [
|
|
148
|
+
'hover',
|
|
149
|
+
'focus',
|
|
150
|
+
'active',
|
|
151
|
+
'focus-visible',
|
|
152
|
+
'focus-within',
|
|
153
|
+
'disabled',
|
|
154
|
+
'group-hover',
|
|
155
|
+
'first',
|
|
156
|
+
'last',
|
|
157
|
+
'odd',
|
|
158
|
+
'even',
|
|
159
|
+
'dark'
|
|
160
|
+
];
|
|
161
|
+
|
|
162
|
+
// ================================================
|
|
163
|
+
// Available Breakpoints (from constants.js)
|
|
164
|
+
// ================================================
|
|
165
|
+
|
|
166
|
+
const BREAKPOINTS = [
|
|
167
|
+
'mob', // 480px (mobile)
|
|
168
|
+
'tab', // 768px (tablet)
|
|
169
|
+
'lap', // 1024px (laptop)
|
|
170
|
+
'desk', // 1280px (desktop)
|
|
171
|
+
// Tailwind compat
|
|
172
|
+
'tw-sm', // 640px
|
|
173
|
+
'tw-md', // 768px
|
|
174
|
+
'tw-lg', // 1024px
|
|
175
|
+
'tw-xl', // 1280px
|
|
176
|
+
'tw-2xl' // 1536px
|
|
177
|
+
];
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: SenangStart CSS Architecture
|
|
3
|
+
description: Understanding the core architecture and design patterns of the SenangStart CSS framework
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SenangStart CSS Architecture
|
|
7
|
+
|
|
8
|
+
This skill covers the core architectural concepts of SenangStart CSS - a utility-first CSS framework using natural language naming conventions.
|
|
9
|
+
|
|
10
|
+
## Core Philosophy: Intent-First CSS
|
|
11
|
+
|
|
12
|
+
SenangStart CSS replaces abstract utility class names with **Natural Adjectives** that read like human language:
|
|
13
|
+
|
|
14
|
+
| Framework | Approach |
|
|
15
|
+
|-----------|----------|
|
|
16
|
+
| Tailwind | `class="flex items-center p-4 bg-blue-500"` |
|
|
17
|
+
| SenangStart | `layout="flex items:center" space="p:small" visual="bg:blue-500"` |
|
|
18
|
+
|
|
19
|
+
## The Tri-Attribute System
|
|
20
|
+
|
|
21
|
+
All utilities are organized into three semantic HTML attributes:
|
|
22
|
+
|
|
23
|
+
### 1. `layout` - Structure & Positioning
|
|
24
|
+
Controls how elements are arranged and positioned:
|
|
25
|
+
- Display modes: `flex`, `grid`, `block`, `inline`
|
|
26
|
+
- Flex properties: `row`, `col`, `wrap`, `items:center`, `justify:between`
|
|
27
|
+
- Grid: `cols:3`, `rows:2`, `gap:medium`
|
|
28
|
+
- Positioning: `relative`, `absolute`, `fixed`, `sticky`
|
|
29
|
+
|
|
30
|
+
### 2. `space` - Spacing & Dimensions
|
|
31
|
+
Controls size and spacing:
|
|
32
|
+
- Padding: `p:small`, `p-x:medium`, `p-t:big`
|
|
33
|
+
- Margin: `m:auto`, `m-b:giant`, `m-x:vast`
|
|
34
|
+
- Width/Height: `w:full`, `h:screen`, `min-w:0`, `max-h:fit`
|
|
35
|
+
- Gap: `gap:medium`, `gap-x:small`
|
|
36
|
+
|
|
37
|
+
### 3. `visual` - Appearance & Effects
|
|
38
|
+
Controls visual presentation:
|
|
39
|
+
- Colors: `bg:primary`, `text:white`, `border-color:grey`
|
|
40
|
+
- Borders: `border:thin`, `rounded:big`
|
|
41
|
+
- Typography: `text-size:giant`, `font:bold`, `line:tight`
|
|
42
|
+
- Effects: `shadow:medium`, `opacity:50`, `blur:small`
|
|
43
|
+
- Transforms: `scale:110`, `rotate:45`, `translate-x:medium`
|
|
44
|
+
|
|
45
|
+
## Semantic Scale System
|
|
46
|
+
|
|
47
|
+
Instead of numeric values, SenangStart uses human-readable scales:
|
|
48
|
+
|
|
49
|
+
### Spacing Scale
|
|
50
|
+
```
|
|
51
|
+
none → thin → regular → thick → tiny → small → medium → big → giant → vast
|
|
52
|
+
0px 1px 2px 3px 4px 8px 16px 32px 48px 64px
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Extended multipliers: `small-2x`, `medium-2x`, `big-2x`, etc.
|
|
56
|
+
|
|
57
|
+
### Other Scales
|
|
58
|
+
- **Radius**: `none`, `small`, `medium`, `big`, `round`
|
|
59
|
+
- **Shadow**: `none`, `small`, `medium`, `big`, `giant`
|
|
60
|
+
- **Font Size**: `tiny`, `small`, `base`, `medium`, `big`, `giant`, `vast`
|
|
61
|
+
|
|
62
|
+
## Source Code Structure
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
src/
|
|
66
|
+
├── cdn/
|
|
67
|
+
│ ├── senangstart-engine.js # Browser JIT runtime (core)
|
|
68
|
+
│ └── tw-conversion-engine.js # Tailwind converter
|
|
69
|
+
├── cli/
|
|
70
|
+
│ ├── index.js # CLI entry point
|
|
71
|
+
│ └── commands/ # init, build, dev commands
|
|
72
|
+
├── compiler/
|
|
73
|
+
│ ├── parser.js # Attribute parser
|
|
74
|
+
│ ├── tokenizer.js # Token extraction
|
|
75
|
+
│ └── generators/ # CSS generators
|
|
76
|
+
├── config/
|
|
77
|
+
│ └── defaults.js # Default configuration
|
|
78
|
+
├── core/
|
|
79
|
+
│ ├── constants.js # BREAKPOINTS, STATES, etc.
|
|
80
|
+
│ └── tokenizer-core.js # Shared tokenizer logic
|
|
81
|
+
├── definitions/ # ⭐ Single Source of Truth
|
|
82
|
+
│ ├── index.js # Central export
|
|
83
|
+
│ ├── layout*.js # Layout utilities
|
|
84
|
+
│ ├── space.js # Spacing utilities
|
|
85
|
+
│ └── visual*.js # Visual utilities
|
|
86
|
+
└── utils/
|
|
87
|
+
└── css-utils.js # CSS helper functions
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Definitions: Single Source of Truth
|
|
91
|
+
|
|
92
|
+
All utility definitions live in `src/definitions/`. Each definition object contains:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
{
|
|
96
|
+
name: 'display', // Utility name
|
|
97
|
+
property: 'display', // CSS property(s)
|
|
98
|
+
category: 'layout', // Category for docs
|
|
99
|
+
attribute: 'layout', // HTML attribute
|
|
100
|
+
description: 'Controls...', // English description
|
|
101
|
+
descriptionMs: 'Mengawal...', // Malay description
|
|
102
|
+
syntax: 'flex | grid | block | ...', // Usage syntax
|
|
103
|
+
values: [ // Possible values
|
|
104
|
+
{ name: 'flex', value: 'flex', description: '...' }
|
|
105
|
+
],
|
|
106
|
+
examples: [ // Code examples
|
|
107
|
+
{ code: 'layout="flex"', description: '...' }
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Definitions drive:
|
|
113
|
+
- JIT engine behavior
|
|
114
|
+
- Documentation generation
|
|
115
|
+
- Test expectations
|
|
116
|
+
- Type definitions
|
|
117
|
+
|
|
118
|
+
## Configuration System
|
|
119
|
+
|
|
120
|
+
Users can extend/override defaults via `senangstart.config.js`:
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
export default {
|
|
124
|
+
theme: {
|
|
125
|
+
spacing: { /* custom values */ },
|
|
126
|
+
colors: { /* brand colors */ },
|
|
127
|
+
// ... other scales
|
|
128
|
+
},
|
|
129
|
+
darkMode: 'media', // 'media' | 'selector'
|
|
130
|
+
preflight: true // Include base reset
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Responsive Design
|
|
135
|
+
|
|
136
|
+
Breakpoint prefixes on any utility:
|
|
137
|
+
```html
|
|
138
|
+
<div layout="flex mob:block tab:flex-row lap:gap:medium">
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Breakpoints:
|
|
142
|
+
- `mob`: 480px
|
|
143
|
+
- `tab`: 768px
|
|
144
|
+
- `lap`: 1024px
|
|
145
|
+
- `desk`: 1280px
|
|
146
|
+
|
|
147
|
+
## State Variants
|
|
148
|
+
|
|
149
|
+
State prefixes for interactive styling:
|
|
150
|
+
```html
|
|
151
|
+
<div visual="bg:white hover:bg:light focus:ring:thin active:scale:95">
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Supported states: `hover`, `focus`, `active`, `focus-visible`, `disabled`, `group-hover`
|
|
155
|
+
|
|
156
|
+
## Dark Mode
|
|
157
|
+
|
|
158
|
+
Automatic dark mode support:
|
|
159
|
+
```html
|
|
160
|
+
<div visual="bg:white dark:bg:dark text:black dark:text:white">
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Configured via `darkMode: 'media'` (system) or `darkMode: 'selector'` (class-based).
|