@santi020k/lumen 0.4.0 → 1.1.0
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 +18 -2
- package/dist/cli.js +35 -9
- package/dist/consumer-rollout.d.ts +2 -0
- package/dist/consumer-rollout.d.ts.map +1 -1
- package/dist/consumer-rollout.js +33 -28
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +26 -8
- package/dist/integration-diagnostics.d.ts +21 -0
- package/dist/integration-diagnostics.d.ts.map +1 -0
- package/dist/integration-diagnostics.js +311 -0
- package/dist/registry-data.d.ts +185 -2
- package/dist/registry-data.d.ts.map +1 -1
- package/dist/registry-data.js +1738 -1309
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +18 -14
- package/dist/token-audit.d.ts.map +1 -1
- package/dist/token-audit.js +64 -9
- package/package.json +6 -4
- package/styles.css +522 -26
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { extname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
+
import { lumenComponentBehavior, lumenGlobalBehaviors, lumenStylingContracts } from '@santi020k/lumen-core';
|
|
5
|
+
const sourceExtensions = new Set(['.astro', '.css', '.js', '.jsx', '.mjs', '.ts', '.tsx']);
|
|
6
|
+
const ignoredDirectories = new Set([
|
|
7
|
+
'.astro',
|
|
8
|
+
'.git',
|
|
9
|
+
'.next',
|
|
10
|
+
'.open-next',
|
|
11
|
+
'.output',
|
|
12
|
+
'.turbo',
|
|
13
|
+
'.vercel',
|
|
14
|
+
'.vite',
|
|
15
|
+
'.wrangler',
|
|
16
|
+
'build',
|
|
17
|
+
'coverage',
|
|
18
|
+
'dist',
|
|
19
|
+
'node_modules',
|
|
20
|
+
'out'
|
|
21
|
+
]);
|
|
22
|
+
const publicRootSlots = new Set(Object.values(lumenStylingContracts).flatMap(contract => [contract.rootSlot, ...contract.parts]));
|
|
23
|
+
const discoverProject = async (root) => {
|
|
24
|
+
const packageRoots = [];
|
|
25
|
+
const sourceFiles = [];
|
|
26
|
+
const visit = async (directory) => {
|
|
27
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
28
|
+
if (ignoredDirectories.has(entry.name))
|
|
29
|
+
continue;
|
|
30
|
+
const path = join(directory, entry.name);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
await visit(path);
|
|
33
|
+
}
|
|
34
|
+
else if (entry.name === 'package.json') {
|
|
35
|
+
packageRoots.push(directory);
|
|
36
|
+
}
|
|
37
|
+
else if (sourceExtensions.has(extname(entry.name))) {
|
|
38
|
+
sourceFiles.push(path);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
await visit(root);
|
|
43
|
+
if (!packageRoots.includes(root))
|
|
44
|
+
packageRoots.push(root);
|
|
45
|
+
return { packageRoots, sourceFiles };
|
|
46
|
+
};
|
|
47
|
+
const importedNames = (source, packageName) => {
|
|
48
|
+
const names = [];
|
|
49
|
+
const pattern = new RegExp(`import\\s*\\{([\\s\\S]*?)\\}\\s*from\\s*['"]${packageName}['"]`, 'g');
|
|
50
|
+
for (const match of source.matchAll(pattern)) {
|
|
51
|
+
for (const entry of (match[1] ?? '').split(',')) {
|
|
52
|
+
const name = entry.trim().split(/\s+as\s+/u)[0];
|
|
53
|
+
if (name)
|
|
54
|
+
names.push(name);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return names;
|
|
58
|
+
};
|
|
59
|
+
const finding = (file, rule, message, remediation, severity = 'error') => ({ file, message, remediation, rule, severity });
|
|
60
|
+
const packageNamePattern = String.raw `@santi020k\/lumen-(?:astro|elements|react)(?:\/[^'"]*)?`;
|
|
61
|
+
const packageReferencePattern = new RegExp(String.raw `(?:^|\n)\s*(?:export|import)\s+(?:type\s+)?(?:[^'"\n]*?\s+from\s+)?['"]` +
|
|
62
|
+
String.raw `(${packageNamePattern})['"]`, 'g');
|
|
63
|
+
const dynamicPackageReferencePattern = new RegExp(String.raw `import\(\s*['"](${packageNamePattern})['"]\s*\)`, 'g');
|
|
64
|
+
const cssPackageReferencePattern = new RegExp(String.raw `(?:^|\n)\s*@import\s+(?:url\(\s*)?['"](${packageNamePattern})['"]`, 'g');
|
|
65
|
+
const layoutFilePattern = /(?:^|\/)(?:layouts?\/[^/]+|[^/]*layout[^/]*)\.astro$/iu;
|
|
66
|
+
const getPackageReferences = (source) => [
|
|
67
|
+
...source.matchAll(packageReferencePattern),
|
|
68
|
+
...source.matchAll(dynamicPackageReferencePattern),
|
|
69
|
+
...source.matchAll(cssPackageReferencePattern)
|
|
70
|
+
].flatMap(match => match[1] ? [match[1]] : []);
|
|
71
|
+
const packageFramework = (packageName) => {
|
|
72
|
+
const framework = /^@santi020k\/lumen-(astro|elements|react)(?:\/|$)/u.exec(packageName)?.[1];
|
|
73
|
+
return framework === 'astro' || framework === 'elements' || framework === 'react' ?
|
|
74
|
+
framework :
|
|
75
|
+
undefined;
|
|
76
|
+
};
|
|
77
|
+
const getFrameworks = (sources) => [
|
|
78
|
+
...new Set(sources.flatMap(item => getPackageReferences(item.source))
|
|
79
|
+
.filter(packageName => !packageName.endsWith('/styles.css') &&
|
|
80
|
+
!packageName.endsWith('/layers.css'))
|
|
81
|
+
.flatMap(packageName => {
|
|
82
|
+
const framework = packageFramework(packageName);
|
|
83
|
+
return framework ? [framework] : [];
|
|
84
|
+
}))
|
|
85
|
+
];
|
|
86
|
+
const getBoundaryRoot = (file, packageRoots, fallback) => packageRoots
|
|
87
|
+
.filter(packageRoot => file === packageRoot || file.startsWith(`${packageRoot}${sep}`))
|
|
88
|
+
.sort((left, right) => right.length - left.length)[0] ?? fallback;
|
|
89
|
+
const createBoundaries = (root, packageRoots, sources) => {
|
|
90
|
+
const grouped = new Map();
|
|
91
|
+
for (const source of sources) {
|
|
92
|
+
const boundaryRoot = getBoundaryRoot(source.file, packageRoots, root);
|
|
93
|
+
const entries = grouped.get(boundaryRoot) ?? [];
|
|
94
|
+
entries.push(source);
|
|
95
|
+
grouped.set(boundaryRoot, entries);
|
|
96
|
+
}
|
|
97
|
+
return [...grouped].map(([boundaryRoot, boundarySources]) => ({
|
|
98
|
+
root: boundaryRoot,
|
|
99
|
+
sources: boundarySources
|
|
100
|
+
}));
|
|
101
|
+
};
|
|
102
|
+
const collectCompatibilityFindings = (root, sources) => sources.flatMap(item => {
|
|
103
|
+
const file = relative(root, item.file);
|
|
104
|
+
const findings = [];
|
|
105
|
+
if (/surface\s*=\s*["']glass["']/u.test(item.source)) {
|
|
106
|
+
findings.push(finding(file, 'deprecated-surface-glass', 'The surface="glass" compatibility alias is deprecated.', 'Replace it with the glass prop or attribute.', 'advisory'));
|
|
107
|
+
}
|
|
108
|
+
if (item.source.includes('ui:datatable-selection-change')) {
|
|
109
|
+
findings.push(finding(file, 'deprecated-datatable-event', 'The ui:datatable-selection-change event alias is deprecated.', 'Rename it to ui:data-table-selection-change.', 'advisory'));
|
|
110
|
+
}
|
|
111
|
+
return findings;
|
|
112
|
+
});
|
|
113
|
+
const getCatalogFingerprint = (sources) => {
|
|
114
|
+
const names = [...new Set(sources.flatMap(item => [
|
|
115
|
+
...importedNames(item.source, '@santi020k/lumen-astro'),
|
|
116
|
+
...importedNames(item.source, '@santi020k/lumen-react')
|
|
117
|
+
]))]
|
|
118
|
+
.filter(name => name in lumenComponentBehavior)
|
|
119
|
+
.sort();
|
|
120
|
+
const contracts = names.map(name => [name, lumenComponentBehavior[name]]);
|
|
121
|
+
return createHash('sha256').update(JSON.stringify(contracts)).digest('hex');
|
|
122
|
+
};
|
|
123
|
+
const hasOnlyRuntimeBypassedComponents = (source, componentName, bypassAttribute) => {
|
|
124
|
+
const tagPattern = new RegExp(`<${componentName}(?=\\s|/|>)([^>]*)>`, 'g');
|
|
125
|
+
const tags = [...source.matchAll(tagPattern)];
|
|
126
|
+
const falsePattern = new RegExp(String.raw `\b${bypassAttribute}\s*=\s*(?:\{false\}|["']false["'])`, 'u');
|
|
127
|
+
const truePattern = new RegExp(String.raw `\b${bypassAttribute}(?:\s|/|$)|` +
|
|
128
|
+
String.raw `\b${bypassAttribute}\s*=\s*(?:\{true\}|["']true["'])`, 'u');
|
|
129
|
+
return tags.length > 0 && tags.every(match => {
|
|
130
|
+
const attributes = match[1] ?? '';
|
|
131
|
+
if (falsePattern.test(attributes))
|
|
132
|
+
return false;
|
|
133
|
+
return truePattern.test(attributes);
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
const componentNeedsAstroRuntime = (name, importingSources) => {
|
|
137
|
+
if (!(name in lumenComponentBehavior))
|
|
138
|
+
return false;
|
|
139
|
+
const behavior = lumenComponentBehavior[name];
|
|
140
|
+
if (behavior.astro !== 'ui-primitives')
|
|
141
|
+
return false;
|
|
142
|
+
if ('astroRuntimeBypass' in behavior && importingSources.length > 0 &&
|
|
143
|
+
importingSources.every(item => hasOnlyRuntimeBypassedComponents(item.source, name, behavior.astroRuntimeBypass)))
|
|
144
|
+
return false;
|
|
145
|
+
return true;
|
|
146
|
+
};
|
|
147
|
+
const getRuntimeImports = (sources) => {
|
|
148
|
+
const imports = sources.flatMap(item => importedNames(item.source, '@santi020k/lumen-astro')
|
|
149
|
+
.map(name => ({ file: item.file, name })));
|
|
150
|
+
return imports.filter(item => componentNeedsAstroRuntime(item.name, sources.filter(source => importedNames(source.source, '@santi020k/lumen-astro').includes(item.name))));
|
|
151
|
+
};
|
|
152
|
+
const getGlobalRuntimeBehaviors = (sources) => lumenGlobalBehaviors
|
|
153
|
+
.filter(behavior => sources.some(item => {
|
|
154
|
+
if (behavior.name === 'form-validation')
|
|
155
|
+
return item.source.includes('data-ui-form');
|
|
156
|
+
return behavior.authoredBy.split(',').some(eventName => item.source.includes(eventName.trim()));
|
|
157
|
+
}))
|
|
158
|
+
.map(behavior => behavior.name);
|
|
159
|
+
const collectRuntimeFindings = (repositoryRoot, boundary) => {
|
|
160
|
+
const runtimeImports = getRuntimeImports(boundary.sources);
|
|
161
|
+
const runtimeComponents = [
|
|
162
|
+
...new Set([
|
|
163
|
+
...runtimeImports.map(item => item.name),
|
|
164
|
+
...getGlobalRuntimeBehaviors(boundary.sources)
|
|
165
|
+
])
|
|
166
|
+
];
|
|
167
|
+
const mountSources = boundary.sources.filter(item => /<UIPrimitives(?:\s|\/|>)/u.test(item.source));
|
|
168
|
+
const findings = [];
|
|
169
|
+
if (runtimeComponents.length > 0 && mountSources.length === 0) {
|
|
170
|
+
const firstRuntimeImport = runtimeImports[0];
|
|
171
|
+
findings.push(finding(firstRuntimeImport ? relative(repositoryRoot, firstRuntimeImport.file) : relative(repositoryRoot, boundary.root), 'astro-runtime-missing', `Interactive Astro usage requires UIPrimitives: ${runtimeComponents.join(', ')}.`, 'Mount <UIPrimitives /> once in the application root, or use a documented controlled prop when application code owns the behavior.'));
|
|
172
|
+
}
|
|
173
|
+
for (const mount of mountSources) {
|
|
174
|
+
const mountCount = [...mount.source.matchAll(/<UIPrimitives(?:\s|\/|>)/g)].length;
|
|
175
|
+
if (mountCount > 1) {
|
|
176
|
+
findings.push(finding(relative(repositoryRoot, mount.file), 'astro-runtime-duplicate', 'UIPrimitives is mounted more than once in this file.', 'Keep one mount in the application root layout.'));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const layoutMounts = mountSources.filter(item => layoutFilePattern.test(item.file));
|
|
180
|
+
if (layoutMounts.length > 0) {
|
|
181
|
+
for (const mount of mountSources.filter(item => !layoutMounts.includes(item))) {
|
|
182
|
+
findings.push(finding(relative(repositoryRoot, mount.file), 'astro-runtime-duplicate', 'UIPrimitives is mounted in both a layout and a route within this application boundary.', 'Keep the layout mount and remove the route-level mount.'));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return { findings, runtimeComponents };
|
|
186
|
+
};
|
|
187
|
+
const styleImportByFramework = {
|
|
188
|
+
astro: '@santi020k/lumen-astro/styles.css',
|
|
189
|
+
elements: '@santi020k/lumen-elements/styles.css',
|
|
190
|
+
react: '@santi020k/lumen-react/styles.css'
|
|
191
|
+
};
|
|
192
|
+
const countOccurrences = (source, value) => source.split(value).length - 1;
|
|
193
|
+
const collectCssFindings = (root, sources) => sources
|
|
194
|
+
.filter(item => item.file.endsWith('.css'))
|
|
195
|
+
.flatMap(item => {
|
|
196
|
+
const layerIndex = item.source.search(/^\s*@import\s+(?:url\(\s*)?["'][^"']*\/layers\.css["']/mu);
|
|
197
|
+
const tailwindIndex = item.source.search(/^\s*@import\s+(?:url\(\s*)?["']tailwindcss["']/mu);
|
|
198
|
+
const styleIndex = item.source.search(/^\s*@import\s+(?:url\(\s*)?["'][^"']*\/styles\.css["']/mu);
|
|
199
|
+
const findings = [];
|
|
200
|
+
if (tailwindIndex >= 0 &&
|
|
201
|
+
styleIndex >= 0 &&
|
|
202
|
+
(layerIndex < 0 || !(layerIndex < tailwindIndex && tailwindIndex < styleIndex))) {
|
|
203
|
+
findings.push(finding(relative(root, item.file), 'tailwind-layer-order', 'Tailwind and Lumen imports do not use the verified cascade order.', 'Import Lumen layers.css, then tailwindcss, then the matching Lumen styles.css.'));
|
|
204
|
+
}
|
|
205
|
+
for (const match of item.source.matchAll(/\.ui-([a-z0-9-]+)/g)) {
|
|
206
|
+
const selector = match[1] ?? '';
|
|
207
|
+
if (!publicRootSlots.has(selector)) {
|
|
208
|
+
findings.push(finding(relative(root, item.file), 'internal-selector', `Selector .ui-${selector} is not a documented stable root hook.`, 'Prefer component props, semantic tokens, documented custom properties, or [data-slot].', 'advisory'));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return findings;
|
|
212
|
+
});
|
|
213
|
+
const collectFrameworkStyleFindings = (repositoryRoot, boundary, frameworks) => frameworks.flatMap(framework => {
|
|
214
|
+
const styleImport = styleImportByFramework[framework];
|
|
215
|
+
const references = boundary.sources.filter(item => item.source.includes(styleImport));
|
|
216
|
+
if (references.length === 0) {
|
|
217
|
+
return [finding(relative(repositoryRoot, boundary.root) || '.', 'framework-style-missing', `No ${styleImport} import was found in this application boundary.`, 'Load the matching adapter stylesheet once in the application root.')];
|
|
218
|
+
}
|
|
219
|
+
return references.flatMap(item => countOccurrences(item.source, styleImport) > 1 ?
|
|
220
|
+
[finding(relative(repositoryRoot, item.file), 'framework-style-duplicate', `The ${framework} stylesheet is loaded more than once in this file.`, 'Keep one stylesheet import in the application root.')] :
|
|
221
|
+
[]);
|
|
222
|
+
});
|
|
223
|
+
const collectAdapterMismatchFindings = (repositoryRoot, boundary, frameworks) => {
|
|
224
|
+
const adapters = Object.entries(styleImportByFramework)
|
|
225
|
+
.flatMap(([framework, styleImport]) => boundary.sources.some(item => item.source.includes(styleImport)) ?
|
|
226
|
+
[framework] :
|
|
227
|
+
[]);
|
|
228
|
+
return [...new Set(adapters)]
|
|
229
|
+
.filter(adapter => !frameworks.includes(adapter))
|
|
230
|
+
.map(adapter => finding(relative(repositoryRoot, boundary.root) || '.', 'adapter-style-mismatch', `The ${adapter} stylesheet is loaded without matching ${adapter} imports in this application boundary.`, 'Load the stylesheet from the adapter used by this application boundary.'));
|
|
231
|
+
};
|
|
232
|
+
const uniqueFindings = (findings) => [
|
|
233
|
+
...new Map(findings.map(item => [
|
|
234
|
+
`${item.file}\u0000${item.rule}\u0000${item.message}`,
|
|
235
|
+
item
|
|
236
|
+
])).values()
|
|
237
|
+
];
|
|
238
|
+
export const inspectLumenIntegration = async (repository) => {
|
|
239
|
+
const root = resolve(repository);
|
|
240
|
+
if (!(await stat(root)).isDirectory())
|
|
241
|
+
throw new Error(`Not a directory: ${root}`);
|
|
242
|
+
const discovered = await discoverProject(root);
|
|
243
|
+
const sources = await Promise.all(discovered.sourceFiles.map(async (file) => ({
|
|
244
|
+
file,
|
|
245
|
+
source: await readFile(file, 'utf8')
|
|
246
|
+
})));
|
|
247
|
+
const boundaries = createBoundaries(root, discovered.packageRoots, sources);
|
|
248
|
+
const frameworks = [...new Set(boundaries.flatMap(boundary => getFrameworks(boundary.sources)))];
|
|
249
|
+
const runtimeComponents = new Set();
|
|
250
|
+
const findings = [
|
|
251
|
+
...collectCompatibilityFindings(root, sources),
|
|
252
|
+
...collectCssFindings(root, sources)
|
|
253
|
+
];
|
|
254
|
+
for (const boundary of boundaries) {
|
|
255
|
+
const boundaryFrameworks = getFrameworks(boundary.sources);
|
|
256
|
+
const runtime = collectRuntimeFindings(root, boundary);
|
|
257
|
+
runtime.runtimeComponents.forEach(component => runtimeComponents.add(component));
|
|
258
|
+
findings.push(...runtime.findings, ...collectFrameworkStyleFindings(root, boundary, boundaryFrameworks), ...collectAdapterMismatchFindings(root, boundary, boundaryFrameworks));
|
|
259
|
+
}
|
|
260
|
+
const deduplicatedFindings = uniqueFindings(findings);
|
|
261
|
+
return {
|
|
262
|
+
catalogFingerprint: getCatalogFingerprint(sources),
|
|
263
|
+
findings: deduplicatedFindings,
|
|
264
|
+
frameworks,
|
|
265
|
+
generatedAt: new Date().toISOString(),
|
|
266
|
+
healthy: deduplicatedFindings.every(item => item.severity !== 'error'),
|
|
267
|
+
repository: root,
|
|
268
|
+
runtimeComponents: [...runtimeComponents]
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
export const formatLumenDiagnostics = (report) => {
|
|
272
|
+
const heading = report.healthy ? 'Lumen integration is healthy.' : 'Lumen integration has blocking findings.';
|
|
273
|
+
if (report.findings.length === 0)
|
|
274
|
+
return heading;
|
|
275
|
+
return [
|
|
276
|
+
heading,
|
|
277
|
+
...report.findings.map(item => `[${item.severity}] ${item.file} ${item.rule}: ${item.message} ${item.remediation}`)
|
|
278
|
+
].join('\n');
|
|
279
|
+
};
|
|
280
|
+
export const createLumenSetup = (framework, tailwind = false) => {
|
|
281
|
+
const setupByFramework = {
|
|
282
|
+
astro: {
|
|
283
|
+
styles: '@import "@santi020k/lumen-astro/styles.css";',
|
|
284
|
+
tailwind: '@import "@santi020k/lumen-astro/layers.css";\n' +
|
|
285
|
+
'@import "tailwindcss";\n' +
|
|
286
|
+
'@import "@santi020k/lumen-astro/styles.css";'
|
|
287
|
+
},
|
|
288
|
+
elements: {
|
|
289
|
+
styles: '@import "@santi020k/lumen-elements/styles.css";',
|
|
290
|
+
tailwind: '@import "@santi020k/lumen-elements/layers.css";\n' +
|
|
291
|
+
'@import "tailwindcss";\n' +
|
|
292
|
+
'@import "@santi020k/lumen-elements/styles.css";'
|
|
293
|
+
},
|
|
294
|
+
react: {
|
|
295
|
+
styles: '@import "@santi020k/lumen-react/styles.css";',
|
|
296
|
+
tailwind: '@import "@santi020k/lumen-react/layers.css";\n' +
|
|
297
|
+
'@import "tailwindcss";\n' +
|
|
298
|
+
'@import "@santi020k/lumen-react/styles.css";'
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
const styles = tailwind ? setupByFramework[framework].tailwind : setupByFramework[framework].styles;
|
|
302
|
+
if (framework === 'astro') {
|
|
303
|
+
return `${styles}\n\n---\nimport { UIPrimitives } from '@santi020k/lumen-astro'\n---\n\n<UIPrimitives />`;
|
|
304
|
+
}
|
|
305
|
+
if (framework === 'elements') {
|
|
306
|
+
return `${styles}\n\n` +
|
|
307
|
+
'import { defineLumenElements } from \'@santi020k/lumen-elements/define\'\n\n' +
|
|
308
|
+
'defineLumenElements()';
|
|
309
|
+
}
|
|
310
|
+
return styles;
|
|
311
|
+
};
|
package/dist/registry-data.d.ts
CHANGED
|
@@ -31,6 +31,42 @@ export declare const lumenRegistry: {
|
|
|
31
31
|
readonly name: "data-visualization";
|
|
32
32
|
readonly type: "recipe";
|
|
33
33
|
readonly components: readonly ["Chart", "Sparkline", "BarChart", "LineChart", "PieChart", "Stat", "Meter"];
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "analytics-dashboard";
|
|
36
|
+
readonly type: "recipe";
|
|
37
|
+
readonly components: readonly ["Sidebar", "Stat", "Sparkline", "LineChart", "BarChart", "DateRangePicker", "Table", "Badge"];
|
|
38
|
+
}, {
|
|
39
|
+
readonly name: "saas-admin";
|
|
40
|
+
readonly type: "recipe";
|
|
41
|
+
readonly components: readonly ["Sidebar", "Stat", "Sparkline", "Alert", "Progress", "SearchField", "Table", "Badge"];
|
|
42
|
+
}, {
|
|
43
|
+
readonly name: "commerce-dashboard";
|
|
44
|
+
readonly type: "recipe";
|
|
45
|
+
readonly components: readonly ["Sidebar", "Stat", "Sparkline", "BarChart", "PieChart", "Progress", "Table", "Badge"];
|
|
46
|
+
}, {
|
|
47
|
+
readonly name: "project-workspace";
|
|
48
|
+
readonly type: "recipe";
|
|
49
|
+
readonly components: readonly ["Sidebar", "Stat", "Sparkline", "Progress", "Timeline", "Avatar", "Table", "Badge"];
|
|
50
|
+
}, {
|
|
51
|
+
readonly name: "auth-onboarding";
|
|
52
|
+
readonly type: "recipe";
|
|
53
|
+
readonly components: readonly ["Card", "Stepper", "Field", "Label", "Input", "Alert", "Checkbox", "Progress", "Button"];
|
|
54
|
+
}, {
|
|
55
|
+
readonly name: "docs-shell";
|
|
56
|
+
readonly type: "recipe";
|
|
57
|
+
readonly components: readonly ["SkipLink", "NavigationMenu", "ThemeToggle", "Sidebar", "Sheet", "Prose", "Pagination", "Code", "CodeTabs"];
|
|
58
|
+
}, {
|
|
59
|
+
readonly name: "marketing-shell";
|
|
60
|
+
readonly type: "recipe";
|
|
61
|
+
readonly components: readonly ["SkipLink", "NavigationMenu", "ButtonLink", "Card", "ScrollReveal", "BackToTop"];
|
|
62
|
+
}, {
|
|
63
|
+
readonly name: "dashboard-shell";
|
|
64
|
+
readonly type: "recipe";
|
|
65
|
+
readonly components: readonly ["NavigationMenu", "Sidebar", "Card", "Stat", "StatTrend", "Badge", "SearchField", "DateRangePicker", "Empty", "Table", "Chart"];
|
|
66
|
+
}, {
|
|
67
|
+
readonly name: "validated-form";
|
|
68
|
+
readonly type: "recipe";
|
|
69
|
+
readonly components: readonly ["Form", "Field", "FieldError", "Label", "Input", "NativeSelect", "Textarea", "Button"];
|
|
34
70
|
}, {
|
|
35
71
|
readonly name: "ai-docs";
|
|
36
72
|
readonly type: "documentation";
|
|
@@ -166,6 +202,41 @@ export declare const lumenRegistry: {
|
|
|
166
202
|
readonly category: "Layout";
|
|
167
203
|
readonly files: readonly ["packages/astro/components/Card.astro", "packages/astro/styles/lumen.css"];
|
|
168
204
|
readonly dependencies: readonly ["styles"];
|
|
205
|
+
}, {
|
|
206
|
+
readonly name: "CardContent";
|
|
207
|
+
readonly type: "component";
|
|
208
|
+
readonly description: "Provides the main content region inside a card.";
|
|
209
|
+
readonly category: "Layout";
|
|
210
|
+
readonly files: readonly ["packages/astro/components/CardContent.astro", "packages/astro/styles/lumen.css"];
|
|
211
|
+
readonly dependencies: readonly ["Card", "styles"];
|
|
212
|
+
}, {
|
|
213
|
+
readonly name: "CardDescription";
|
|
214
|
+
readonly type: "component";
|
|
215
|
+
readonly description: "Adds supporting copy to a card header.";
|
|
216
|
+
readonly category: "Layout";
|
|
217
|
+
readonly files: readonly ["packages/astro/components/CardDescription.astro", "packages/astro/styles/lumen.css"];
|
|
218
|
+
readonly dependencies: readonly ["Card", "styles"];
|
|
219
|
+
}, {
|
|
220
|
+
readonly name: "CardFooter";
|
|
221
|
+
readonly type: "component";
|
|
222
|
+
readonly description: "Groups actions at the end of a card.";
|
|
223
|
+
readonly category: "Layout";
|
|
224
|
+
readonly files: readonly ["packages/astro/components/CardFooter.astro", "packages/astro/styles/lumen.css"];
|
|
225
|
+
readonly dependencies: readonly ["Card", "styles"];
|
|
226
|
+
}, {
|
|
227
|
+
readonly name: "CardHeader";
|
|
228
|
+
readonly type: "component";
|
|
229
|
+
readonly description: "Groups introductory content at the start of a card.";
|
|
230
|
+
readonly category: "Layout";
|
|
231
|
+
readonly files: readonly ["packages/astro/components/CardHeader.astro", "packages/astro/styles/lumen.css"];
|
|
232
|
+
readonly dependencies: readonly ["Card", "styles"];
|
|
233
|
+
}, {
|
|
234
|
+
readonly name: "CardTitle";
|
|
235
|
+
readonly type: "component";
|
|
236
|
+
readonly description: "Provides a semantic card title with a stable styling hook.";
|
|
237
|
+
readonly category: "Layout";
|
|
238
|
+
readonly files: readonly ["packages/astro/components/CardTitle.astro", "packages/astro/styles/lumen.css"];
|
|
239
|
+
readonly dependencies: readonly ["Card", "styles"];
|
|
169
240
|
}, {
|
|
170
241
|
readonly name: "Carousel";
|
|
171
242
|
readonly type: "component";
|
|
@@ -187,6 +258,13 @@ export declare const lumenRegistry: {
|
|
|
187
258
|
readonly category: "Forms";
|
|
188
259
|
readonly files: readonly ["packages/astro/components/Checkbox.astro", "packages/astro/styles/lumen.css"];
|
|
189
260
|
readonly dependencies: readonly ["styles"];
|
|
261
|
+
}, {
|
|
262
|
+
readonly name: "CheckboxGroup";
|
|
263
|
+
readonly type: "component";
|
|
264
|
+
readonly description: "Groups related checkbox choices under one legend.";
|
|
265
|
+
readonly category: "Forms";
|
|
266
|
+
readonly files: readonly ["packages/astro/components/CheckboxGroup.astro", "packages/astro/styles/lumen.css"];
|
|
267
|
+
readonly dependencies: readonly ["Checkbox", "styles"];
|
|
190
268
|
}, {
|
|
191
269
|
readonly name: "Collapsible";
|
|
192
270
|
readonly type: "component";
|
|
@@ -215,6 +293,20 @@ export declare const lumenRegistry: {
|
|
|
215
293
|
readonly category: "Forms";
|
|
216
294
|
readonly files: readonly ["packages/astro/components/Combobox.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
217
295
|
readonly dependencies: readonly ["styles", "runtime"];
|
|
296
|
+
}, {
|
|
297
|
+
readonly name: "Container";
|
|
298
|
+
readonly type: "component";
|
|
299
|
+
readonly description: "Centers page content within responsive gutters and a maximum width.";
|
|
300
|
+
readonly category: "Layout";
|
|
301
|
+
readonly files: readonly ["packages/astro/components/Container.astro", "packages/astro/styles/lumen.css"];
|
|
302
|
+
readonly dependencies: readonly ["styles"];
|
|
303
|
+
}, {
|
|
304
|
+
readonly name: "CopyButton";
|
|
305
|
+
readonly type: "component";
|
|
306
|
+
readonly description: "Copies arbitrary text or the content of another element with accessible feedback.";
|
|
307
|
+
readonly category: "Actions";
|
|
308
|
+
readonly files: readonly ["packages/astro/components/CopyButton.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
309
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
218
310
|
}, {
|
|
219
311
|
readonly name: "Command";
|
|
220
312
|
readonly type: "component";
|
|
@@ -292,6 +384,13 @@ export declare const lumenRegistry: {
|
|
|
292
384
|
readonly category: "Feedback";
|
|
293
385
|
readonly files: readonly ["packages/astro/components/Empty.astro", "packages/astro/styles/lumen.css"];
|
|
294
386
|
readonly dependencies: readonly ["styles"];
|
|
387
|
+
}, {
|
|
388
|
+
readonly name: "ErrorSummary";
|
|
389
|
+
readonly type: "component";
|
|
390
|
+
readonly description: "Summarizes form errors and links people back to invalid controls.";
|
|
391
|
+
readonly category: "Forms";
|
|
392
|
+
readonly files: readonly ["packages/astro/components/ErrorSummary.astro", "packages/astro/styles/lumen.css"];
|
|
393
|
+
readonly dependencies: readonly ["styles"];
|
|
295
394
|
}, {
|
|
296
395
|
readonly name: "Eyebrow";
|
|
297
396
|
readonly type: "component";
|
|
@@ -306,6 +405,13 @@ export declare const lumenRegistry: {
|
|
|
306
405
|
readonly category: "Forms";
|
|
307
406
|
readonly files: readonly ["packages/astro/components/Input.astro", "packages/astro/components/Label.astro", "packages/astro/components/Field.astro", "packages/astro/styles/lumen.css"];
|
|
308
407
|
readonly dependencies: readonly ["Input", "Label", "styles"];
|
|
408
|
+
}, {
|
|
409
|
+
readonly name: "FieldError";
|
|
410
|
+
readonly type: "component";
|
|
411
|
+
readonly description: "Displays an error connected to a form control.";
|
|
412
|
+
readonly category: "Forms";
|
|
413
|
+
readonly files: readonly ["packages/astro/components/FieldError.astro", "packages/astro/styles/lumen.css"];
|
|
414
|
+
readonly dependencies: readonly ["Field", "styles"];
|
|
309
415
|
}, {
|
|
310
416
|
readonly name: "FloatingBadge";
|
|
311
417
|
readonly type: "component";
|
|
@@ -313,6 +419,13 @@ export declare const lumenRegistry: {
|
|
|
313
419
|
readonly category: "Data display";
|
|
314
420
|
readonly files: readonly ["packages/astro/components/FloatingBadge.astro", "packages/astro/styles/lumen.css"];
|
|
315
421
|
readonly dependencies: readonly ["styles"];
|
|
422
|
+
}, {
|
|
423
|
+
readonly name: "Form";
|
|
424
|
+
readonly type: "component";
|
|
425
|
+
readonly description: "Adds consistent validation and submission state to a native form.";
|
|
426
|
+
readonly category: "Forms";
|
|
427
|
+
readonly files: readonly ["packages/astro/components/Form.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
428
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
316
429
|
}, {
|
|
317
430
|
readonly name: "FormattedDate";
|
|
318
431
|
readonly type: "component";
|
|
@@ -397,6 +510,13 @@ export declare const lumenRegistry: {
|
|
|
397
510
|
readonly category: "Data display";
|
|
398
511
|
readonly files: readonly ["packages/astro/components/LineChart.astro", "packages/astro/components/Chart.astro", "packages/astro/styles/lumen.css"];
|
|
399
512
|
readonly dependencies: readonly ["Chart", "styles"];
|
|
513
|
+
}, {
|
|
514
|
+
readonly name: "ListBox";
|
|
515
|
+
readonly type: "component";
|
|
516
|
+
readonly description: "Presents a visible single- or multi-select option list.";
|
|
517
|
+
readonly category: "Forms";
|
|
518
|
+
readonly files: readonly ["packages/astro/components/ListBox.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
519
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
400
520
|
}, {
|
|
401
521
|
readonly name: "Marker";
|
|
402
522
|
readonly type: "component";
|
|
@@ -453,6 +573,13 @@ export declare const lumenRegistry: {
|
|
|
453
573
|
readonly category: "Navigation";
|
|
454
574
|
readonly files: readonly ["packages/astro/components/Pagination.astro", "packages/astro/styles/lumen.css"];
|
|
455
575
|
readonly dependencies: readonly ["styles"];
|
|
576
|
+
}, {
|
|
577
|
+
readonly name: "PasswordField";
|
|
578
|
+
readonly type: "component";
|
|
579
|
+
readonly description: "Combines a password input with guidance, errors, and a visibility toggle.";
|
|
580
|
+
readonly category: "Forms";
|
|
581
|
+
readonly files: readonly ["packages/astro/components/PasswordField.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
582
|
+
readonly dependencies: readonly ["Button", "Field", "FieldError", "Input", "Label", "styles", "runtime"];
|
|
456
583
|
}, {
|
|
457
584
|
readonly name: "PhoneInput";
|
|
458
585
|
readonly type: "component";
|
|
@@ -486,8 +613,8 @@ export declare const lumenRegistry: {
|
|
|
486
613
|
readonly type: "component";
|
|
487
614
|
readonly description: "Shows completion, loading progress, or quota usage.";
|
|
488
615
|
readonly category: "Feedback";
|
|
489
|
-
readonly files: readonly ["packages/astro/components/Progress.astro", "packages/astro/styles/lumen.css"];
|
|
490
|
-
readonly dependencies: readonly ["styles"];
|
|
616
|
+
readonly files: readonly ["packages/astro/components/Progress.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
617
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
491
618
|
}, {
|
|
492
619
|
readonly name: "Prose";
|
|
493
620
|
readonly type: "component";
|
|
@@ -765,6 +892,48 @@ export declare const lumenRegistry: {
|
|
|
765
892
|
readonly category: "Data display";
|
|
766
893
|
readonly description: "A stat component.";
|
|
767
894
|
readonly files: readonly ["packages/astro/components/Stat.astro", "packages/react/src/components.tsx"];
|
|
895
|
+
}, {
|
|
896
|
+
readonly name: "StatDescription";
|
|
897
|
+
readonly type: "component";
|
|
898
|
+
readonly description: "Adds supporting context to a composed statistic.";
|
|
899
|
+
readonly category: "Data display";
|
|
900
|
+
readonly files: readonly ["packages/astro/components/StatDescription.astro", "packages/astro/styles/lumen.css"];
|
|
901
|
+
readonly dependencies: readonly ["Stat", "styles"];
|
|
902
|
+
}, {
|
|
903
|
+
readonly name: "StatIcon";
|
|
904
|
+
readonly type: "component";
|
|
905
|
+
readonly description: "Provides an icon region for a composed statistic.";
|
|
906
|
+
readonly category: "Data display";
|
|
907
|
+
readonly files: readonly ["packages/astro/components/StatIcon.astro", "packages/astro/styles/lumen.css"];
|
|
908
|
+
readonly dependencies: readonly ["Stat", "styles"];
|
|
909
|
+
}, {
|
|
910
|
+
readonly name: "StatLabel";
|
|
911
|
+
readonly type: "component";
|
|
912
|
+
readonly description: "Labels a composed statistic.";
|
|
913
|
+
readonly category: "Data display";
|
|
914
|
+
readonly files: readonly ["packages/astro/components/StatLabel.astro", "packages/astro/styles/lumen.css"];
|
|
915
|
+
readonly dependencies: readonly ["Stat", "styles"];
|
|
916
|
+
}, {
|
|
917
|
+
readonly name: "StatTrend";
|
|
918
|
+
readonly type: "component";
|
|
919
|
+
readonly description: "Communicates a metric delta with a semantic tone.";
|
|
920
|
+
readonly category: "Data display";
|
|
921
|
+
readonly files: readonly ["packages/astro/components/StatTrend.astro", "packages/astro/styles/lumen.css"];
|
|
922
|
+
readonly dependencies: readonly ["Stat", "styles"];
|
|
923
|
+
}, {
|
|
924
|
+
readonly name: "StatValue";
|
|
925
|
+
readonly type: "component";
|
|
926
|
+
readonly description: "Displays the prominent value in a composed statistic.";
|
|
927
|
+
readonly category: "Data display";
|
|
928
|
+
readonly files: readonly ["packages/astro/components/StatValue.astro", "packages/astro/styles/lumen.css"];
|
|
929
|
+
readonly dependencies: readonly ["Stat", "styles"];
|
|
930
|
+
}, {
|
|
931
|
+
readonly name: "Stack";
|
|
932
|
+
readonly type: "component";
|
|
933
|
+
readonly description: "Arranges children with tokenized direction, spacing, and alignment.";
|
|
934
|
+
readonly category: "Layout";
|
|
935
|
+
readonly files: readonly ["packages/astro/components/Stack.astro", "packages/astro/styles/lumen.css"];
|
|
936
|
+
readonly dependencies: readonly ["styles"];
|
|
768
937
|
}, {
|
|
769
938
|
readonly name: "Meter";
|
|
770
939
|
readonly type: "component";
|
|
@@ -915,6 +1084,20 @@ export declare const lumenRegistry: {
|
|
|
915
1084
|
readonly category: "Navigation";
|
|
916
1085
|
readonly description: "A floating action button with expandable sub-actions.";
|
|
917
1086
|
readonly files: readonly ["packages/astro/components/SpeedDial.astro", "packages/react/src/components.tsx"];
|
|
1087
|
+
}, {
|
|
1088
|
+
readonly name: "Grid";
|
|
1089
|
+
readonly type: "component";
|
|
1090
|
+
readonly category: "Layout";
|
|
1091
|
+
readonly description: "Arranges content in fixed or responsive tokenized columns.";
|
|
1092
|
+
readonly files: readonly ["packages/astro/components/Grid.astro", "packages/astro/styles/lumen.css"];
|
|
1093
|
+
readonly dependencies: readonly ["styles"];
|
|
1094
|
+
}, {
|
|
1095
|
+
readonly name: "VisuallyHidden";
|
|
1096
|
+
readonly type: "component";
|
|
1097
|
+
readonly category: "Layout";
|
|
1098
|
+
readonly description: "Keeps meaningful content available to assistive technology without displaying it.";
|
|
1099
|
+
readonly files: readonly ["packages/astro/components/VisuallyHidden.astro", "packages/astro/styles/lumen.css"];
|
|
1100
|
+
readonly dependencies: readonly ["styles"];
|
|
918
1101
|
}];
|
|
919
1102
|
};
|
|
920
1103
|
//# sourceMappingURL=registry-data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-data.d.ts","sourceRoot":"","sources":["../src/registry-data.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"registry-data.d.ts","sourceRoot":"","sources":["../src/registry-data.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+sEQ,CAAA"}
|