skillui 1.1.2 → 1.1.4
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/README.md +20 -15
- package/dist/cli.js +105073 -194
- package/package.json +15 -6
- package/dist/cli.d.ts +0 -3
- package/dist/extractors/components.d.ts +0 -11
- package/dist/extractors/components.js +0 -455
- package/dist/extractors/framework.d.ts +0 -4
- package/dist/extractors/framework.js +0 -126
- package/dist/extractors/tokens/computed.d.ts +0 -7
- package/dist/extractors/tokens/computed.js +0 -249
- package/dist/extractors/tokens/css.d.ts +0 -3
- package/dist/extractors/tokens/css.js +0 -510
- package/dist/extractors/tokens/http-css.d.ts +0 -14
- package/dist/extractors/tokens/http-css.js +0 -1689
- package/dist/extractors/tokens/tailwind.d.ts +0 -3
- package/dist/extractors/tokens/tailwind.js +0 -353
- package/dist/extractors/tokens/tokens-file.d.ts +0 -3
- package/dist/extractors/tokens/tokens-file.js +0 -229
- package/dist/extractors/ultra/animations.d.ts +0 -21
- package/dist/extractors/ultra/animations.js +0 -527
- package/dist/extractors/ultra/components-dom.d.ts +0 -13
- package/dist/extractors/ultra/components-dom.js +0 -149
- package/dist/extractors/ultra/interactions.d.ts +0 -14
- package/dist/extractors/ultra/interactions.js +0 -222
- package/dist/extractors/ultra/layout.d.ts +0 -14
- package/dist/extractors/ultra/layout.js +0 -123
- package/dist/extractors/ultra/pages.d.ts +0 -16
- package/dist/extractors/ultra/pages.js +0 -228
- package/dist/font-resolver.d.ts +0 -10
- package/dist/font-resolver.js +0 -280
- package/dist/modes/dir.d.ts +0 -6
- package/dist/modes/dir.js +0 -213
- package/dist/modes/repo.d.ts +0 -6
- package/dist/modes/repo.js +0 -76
- package/dist/modes/ultra.d.ts +0 -22
- package/dist/modes/ultra.js +0 -281
- package/dist/modes/url.d.ts +0 -14
- package/dist/modes/url.js +0 -161
- package/dist/normalizer.d.ts +0 -11
- package/dist/normalizer.js +0 -867
- package/dist/playwright-loader.d.ts +0 -10
- package/dist/playwright-loader.js +0 -71
- package/dist/screenshot.d.ts +0 -9
- package/dist/screenshot.js +0 -94
- package/dist/types-ultra.d.ts +0 -157
- package/dist/types-ultra.js +0 -4
- package/dist/types.d.ts +0 -182
- package/dist/types.js +0 -4
- package/dist/writers/animations-md.d.ts +0 -17
- package/dist/writers/animations-md.js +0 -313
- package/dist/writers/components-md.d.ts +0 -8
- package/dist/writers/components-md.js +0 -151
- package/dist/writers/design-md.d.ts +0 -7
- package/dist/writers/design-md.js +0 -704
- package/dist/writers/interactions-md.d.ts +0 -8
- package/dist/writers/interactions-md.js +0 -146
- package/dist/writers/layout-md.d.ts +0 -8
- package/dist/writers/layout-md.js +0 -120
- package/dist/writers/skill.d.ts +0 -12
- package/dist/writers/skill.js +0 -1006
- package/dist/writers/tokens-json.d.ts +0 -11
- package/dist/writers/tokens-json.js +0 -164
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractComputedTokens = extractComputedTokens;
|
|
4
|
-
/**
|
|
5
|
-
* URL mode: Extract computed styles from live DOM using Playwright.
|
|
6
|
-
* Playwright is an optional peer dependency.
|
|
7
|
-
*/
|
|
8
|
-
async function extractComputedTokens(url, maxPages = 5) {
|
|
9
|
-
const tokens = {
|
|
10
|
-
colors: [],
|
|
11
|
-
fonts: [],
|
|
12
|
-
spacingValues: [],
|
|
13
|
-
shadows: [],
|
|
14
|
-
cssVariables: [],
|
|
15
|
-
breakpoints: [],
|
|
16
|
-
borderRadii: [],
|
|
17
|
-
gradients: [],
|
|
18
|
-
fontVarMap: {},
|
|
19
|
-
animations: [],
|
|
20
|
-
darkModeVars: [],
|
|
21
|
-
zIndexValues: [],
|
|
22
|
-
containerMaxWidth: null,
|
|
23
|
-
fontSources: [],
|
|
24
|
-
pageSections: [],
|
|
25
|
-
transitionDurations: [],
|
|
26
|
-
transitionEasings: [],
|
|
27
|
-
};
|
|
28
|
-
let playwright;
|
|
29
|
-
try {
|
|
30
|
-
playwright = require('playwright');
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
// Playwright not installed — caller should handle this
|
|
34
|
-
return tokens;
|
|
35
|
-
}
|
|
36
|
-
const browser = await playwright.chromium.launch({ headless: true });
|
|
37
|
-
const context = await browser.newContext({
|
|
38
|
-
viewport: { width: 1440, height: 900 },
|
|
39
|
-
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
40
|
-
});
|
|
41
|
-
try {
|
|
42
|
-
const visited = new Set();
|
|
43
|
-
const toVisit = [url];
|
|
44
|
-
while (toVisit.length > 0 && visited.size < maxPages) {
|
|
45
|
-
const currentUrl = toVisit.shift();
|
|
46
|
-
if (visited.has(currentUrl))
|
|
47
|
-
continue;
|
|
48
|
-
visited.add(currentUrl);
|
|
49
|
-
try {
|
|
50
|
-
const page = await context.newPage();
|
|
51
|
-
await page.goto(currentUrl, { waitUntil: 'networkidle', timeout: 20000 });
|
|
52
|
-
// Wait a moment for any JS-rendered content
|
|
53
|
-
await page.waitForTimeout(1500);
|
|
54
|
-
// Extract comprehensive styles from the page
|
|
55
|
-
const pageTokens = await page.evaluate(() => {
|
|
56
|
-
const colors = [];
|
|
57
|
-
const fonts = [];
|
|
58
|
-
const spacingValues = [];
|
|
59
|
-
const shadows = [];
|
|
60
|
-
const cssVars = [];
|
|
61
|
-
const borderRadii = [];
|
|
62
|
-
// ── Extract CSS custom properties from all stylesheets ──
|
|
63
|
-
try {
|
|
64
|
-
const sheets = document.styleSheets;
|
|
65
|
-
for (let i = 0; i < sheets.length; i++) {
|
|
66
|
-
try {
|
|
67
|
-
const rules = sheets[i].cssRules;
|
|
68
|
-
for (let j = 0; j < rules.length; j++) {
|
|
69
|
-
const rule = rules[j];
|
|
70
|
-
if (rule instanceof CSSStyleRule) {
|
|
71
|
-
// Get CSS variables from :root, body, html, .dark, etc.
|
|
72
|
-
if (/^(:root|html|body|\.dark)/.test(rule.selectorText)) {
|
|
73
|
-
for (let k = 0; k < rule.style.length; k++) {
|
|
74
|
-
const prop = rule.style[k];
|
|
75
|
-
if (prop.startsWith('--')) {
|
|
76
|
-
cssVars.push({
|
|
77
|
-
name: prop,
|
|
78
|
-
value: rule.style.getPropertyValue(prop).trim(),
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// Cross-origin stylesheets
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
// Ignore
|
|
93
|
-
}
|
|
94
|
-
// ── Sample elements for computed styles ──
|
|
95
|
-
// Target semantically meaningful elements
|
|
96
|
-
const selectors = [
|
|
97
|
-
'body',
|
|
98
|
-
'header', 'nav', 'main', 'footer', 'aside',
|
|
99
|
-
'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
|
100
|
-
'p', 'a', 'span',
|
|
101
|
-
'button', 'input', 'select', 'textarea',
|
|
102
|
-
'table', 'th', 'td',
|
|
103
|
-
'img', 'svg',
|
|
104
|
-
'[class*="card"]', '[class*="modal"]', '[class*="dialog"]',
|
|
105
|
-
'[class*="badge"]', '[class*="chip"]', '[class*="tag"]',
|
|
106
|
-
'[class*="btn"]', '[class*="button"]',
|
|
107
|
-
'[class*="nav"]', '[class*="menu"]',
|
|
108
|
-
'[class*="hero"]', '[class*="banner"]',
|
|
109
|
-
'[class*="container"]', '[class*="wrapper"]',
|
|
110
|
-
'section', 'article', 'div',
|
|
111
|
-
];
|
|
112
|
-
const allElements = new Set();
|
|
113
|
-
for (const sel of selectors) {
|
|
114
|
-
try {
|
|
115
|
-
const els = document.querySelectorAll(sel);
|
|
116
|
-
els.forEach(el => allElements.add(el));
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
// Invalid selector
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const colorMap = new Map();
|
|
123
|
-
const fontMap = new Map();
|
|
124
|
-
const sampleSize = Math.min(allElements.size, 500);
|
|
125
|
-
let count = 0;
|
|
126
|
-
for (const el of allElements) {
|
|
127
|
-
if (count++ >= sampleSize)
|
|
128
|
-
break;
|
|
129
|
-
const style = getComputedStyle(el);
|
|
130
|
-
// ── Colors ──
|
|
131
|
-
for (const prop of ['color', 'backgroundColor', 'borderColor', 'outlineColor']) {
|
|
132
|
-
const val = style[prop];
|
|
133
|
-
if (val && val !== 'rgba(0, 0, 0, 0)' && val !== 'transparent' && val !== 'inherit') {
|
|
134
|
-
colorMap.set(val, (colorMap.get(val) || 0) + 1);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
// ── Fonts ──
|
|
138
|
-
const family = style.fontFamily.split(',')[0].replace(/["']/g, '').trim();
|
|
139
|
-
if (family && family !== 'inherit') {
|
|
140
|
-
if (!fontMap.has(family)) {
|
|
141
|
-
fontMap.set(family, {
|
|
142
|
-
size: style.fontSize,
|
|
143
|
-
weight: style.fontWeight,
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// ── Spacing ──
|
|
148
|
-
for (const prop of [
|
|
149
|
-
'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight',
|
|
150
|
-
'marginTop', 'marginBottom', 'marginLeft', 'marginRight',
|
|
151
|
-
'gap', 'rowGap', 'columnGap',
|
|
152
|
-
]) {
|
|
153
|
-
const val = parseFloat(style[prop]);
|
|
154
|
-
if (val > 0 && val <= 200)
|
|
155
|
-
spacingValues.push(Math.round(val));
|
|
156
|
-
}
|
|
157
|
-
// ── Shadows ──
|
|
158
|
-
const shadow = style.boxShadow;
|
|
159
|
-
if (shadow && shadow !== 'none') {
|
|
160
|
-
shadows.push({ value: shadow });
|
|
161
|
-
}
|
|
162
|
-
// ── Border Radius ──
|
|
163
|
-
const radius = style.borderRadius;
|
|
164
|
-
if (radius && radius !== '0px') {
|
|
165
|
-
borderRadii.push(radius);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
// Convert color map
|
|
169
|
-
for (const [val, freq] of colorMap.entries()) {
|
|
170
|
-
colors.push({ value: val, frequency: freq });
|
|
171
|
-
}
|
|
172
|
-
// Convert font map
|
|
173
|
-
for (const [family, info] of fontMap.entries()) {
|
|
174
|
-
fonts.push({ family, size: info.size, weight: info.weight });
|
|
175
|
-
}
|
|
176
|
-
return { colors, fonts, spacingValues, shadows, cssVars, borderRadii };
|
|
177
|
-
});
|
|
178
|
-
// Convert rgb() colors to hex
|
|
179
|
-
for (const color of pageTokens.colors) {
|
|
180
|
-
const hex = rgbStringToHex(color.value);
|
|
181
|
-
if (hex) {
|
|
182
|
-
const existing = tokens.colors.find(c => c.value === hex);
|
|
183
|
-
if (existing) {
|
|
184
|
-
existing.frequency += color.frequency;
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
tokens.colors.push({ value: hex, frequency: color.frequency, source: 'computed' });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
for (const font of pageTokens.fonts) {
|
|
192
|
-
if (font.family && !tokens.fonts.find(f => f.family === font.family)) {
|
|
193
|
-
tokens.fonts.push({ ...font, source: 'computed' });
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
tokens.spacingValues.push(...pageTokens.spacingValues);
|
|
197
|
-
for (const shadow of pageTokens.shadows) {
|
|
198
|
-
if (!tokens.shadows.find(s => s.value === shadow.value)) {
|
|
199
|
-
tokens.shadows.push(shadow);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
for (const cssVar of pageTokens.cssVars) {
|
|
203
|
-
if (!tokens.cssVariables.find(v => v.name === cssVar.name)) {
|
|
204
|
-
tokens.cssVariables.push({ name: cssVar.name, value: cssVar.value });
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
for (const radius of pageTokens.borderRadii) {
|
|
208
|
-
if (!tokens.borderRadii.includes(radius)) {
|
|
209
|
-
tokens.borderRadii.push(radius);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// Find links for crawling
|
|
213
|
-
const links = await page.evaluate((baseUrl) => {
|
|
214
|
-
const origin = new URL(baseUrl).origin;
|
|
215
|
-
return Array.from(document.querySelectorAll('a[href]'))
|
|
216
|
-
.map(a => {
|
|
217
|
-
try {
|
|
218
|
-
return new URL(a.href, baseUrl).href;
|
|
219
|
-
}
|
|
220
|
-
catch {
|
|
221
|
-
return '';
|
|
222
|
-
}
|
|
223
|
-
})
|
|
224
|
-
.filter(href => href.startsWith(origin) && !href.includes('#'));
|
|
225
|
-
}, currentUrl);
|
|
226
|
-
for (const link of links.slice(0, 10)) {
|
|
227
|
-
if (!visited.has(link))
|
|
228
|
-
toVisit.push(link);
|
|
229
|
-
}
|
|
230
|
-
await page.close();
|
|
231
|
-
}
|
|
232
|
-
catch {
|
|
233
|
-
// Skip pages that fail to load
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
finally {
|
|
238
|
-
await browser.close();
|
|
239
|
-
}
|
|
240
|
-
return tokens;
|
|
241
|
-
}
|
|
242
|
-
function rgbStringToHex(rgb) {
|
|
243
|
-
const match = rgb.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
|
|
244
|
-
if (!match)
|
|
245
|
-
return null;
|
|
246
|
-
const [, r, g, b] = match;
|
|
247
|
-
return '#' + [r, g, b].map(c => parseInt(c).toString(16).padStart(2, '0')).join('').toLowerCase();
|
|
248
|
-
}
|
|
249
|
-
//# sourceMappingURL=computed.js.map
|