@santi020k/lumen 1.8.0 → 2.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 +3 -0
- package/dist/cli.js +29 -3
- package/dist/integration-diagnostics.d.ts.map +1 -1
- package/dist/integration-diagnostics.js +198 -30
- package/dist/registry-data.d.ts +96 -0
- package/dist/registry-data.d.ts.map +1 -1
- package/dist/registry-data.js +152 -0
- package/dist/registry-types.d.ts +17 -0
- package/dist/registry-types.d.ts.map +1 -1
- package/dist/registry.d.ts +2 -2
- package/dist/registry.d.ts.map +1 -1
- package/native-components.json +16 -16
- package/package.json +5 -5
- package/release-manifest.json +27 -17
- package/styles.css +11 -0
package/README.md
CHANGED
|
@@ -68,6 +68,9 @@ diagnostics are scoped to the nearest package boundary, generated build trees ar
|
|
|
68
68
|
application-controlled Astro `Toggle` instances do not require the shared runtime. It also suggests
|
|
69
69
|
matching Lumen primitives for likely hand-built dropdown, theme, dialog-focus, and keyboard-menu
|
|
70
70
|
behavior. These suggestions stay advisory because product-specific composition can be intentional.
|
|
71
|
+
Publishable shared UI libraries are not required to load global styles. Private wrapper packages
|
|
72
|
+
can declare `"lumen": { "styleOwnership": "consumer" }` when their applications own adapter CSS,
|
|
73
|
+
or `"application"` when the package itself owns setup.
|
|
71
74
|
Use `--json` for CI and rollout automation. `lumen init --framework <astro|react|elements>
|
|
72
75
|
[--tailwind]` prints the canonical non-destructive setup.
|
|
73
76
|
|
package/dist/cli.js
CHANGED
|
@@ -91,6 +91,29 @@ const getRegistryItemComponents = (item) => 'components' in item && Array.isArra
|
|
|
91
91
|
const getRegistryItemDependencies = (item) => 'dependencies' in item && item.dependencies.length > 0 ?
|
|
92
92
|
`dependencies: ${item.dependencies.join(', ')}` :
|
|
93
93
|
undefined;
|
|
94
|
+
const formatContractProp = (prop) => `${prop.name}: ${prop.type}${prop.required ? ' (required)' : ''}${prop.default ? ` = ${prop.default}` : ''}`;
|
|
95
|
+
const formatContractList = (label, values, separator) => values?.length ? `${label}: ${values.join(separator)}` : undefined;
|
|
96
|
+
const getRegistryItemContract = (item) => {
|
|
97
|
+
if (item.type !== 'component')
|
|
98
|
+
return [];
|
|
99
|
+
const contract = item.contract;
|
|
100
|
+
if (!contract)
|
|
101
|
+
return [];
|
|
102
|
+
const optionalLines = [
|
|
103
|
+
formatContractList('props', contract.props?.map(formatContractProp), '; '),
|
|
104
|
+
formatContractList('composition', contract.composition, ' '),
|
|
105
|
+
formatContractList('events', contract.events, ', '),
|
|
106
|
+
formatContractList('slots', contract.slots, ', '),
|
|
107
|
+
contract.runtime ? `runtime: ${contract.runtime}` : undefined,
|
|
108
|
+
formatContractList('styling parts', contract.stylingParts, ', '),
|
|
109
|
+
formatContractList('tokens', contract.tokens, ', ')
|
|
110
|
+
].filter((line) => Boolean(line));
|
|
111
|
+
return [
|
|
112
|
+
...Object.entries(contract.imports).map(([framework, value]) => `import (${framework}): ${value}`),
|
|
113
|
+
...Object.entries(contract.usage).map(([framework, value]) => `usage (${framework}): ${value}`),
|
|
114
|
+
...optionalLines
|
|
115
|
+
];
|
|
116
|
+
};
|
|
94
117
|
const formatItem = (itemName, registry = lumenRegistry) => {
|
|
95
118
|
const item = getLumenRegistryItem(itemName, registry);
|
|
96
119
|
if (!item) {
|
|
@@ -102,7 +125,8 @@ const formatItem = (itemName, registry = lumenRegistry) => {
|
|
|
102
125
|
getRegistryItemDescription(item),
|
|
103
126
|
getRegistryItemCategory(item),
|
|
104
127
|
getRegistryItemComponents(item),
|
|
105
|
-
getRegistryItemDependencies(item)
|
|
128
|
+
getRegistryItemDependencies(item),
|
|
129
|
+
...getRegistryItemContract(item)
|
|
106
130
|
];
|
|
107
131
|
const files = getRegistryItemFiles(item);
|
|
108
132
|
if (files) {
|
|
@@ -260,8 +284,10 @@ const run = async () => {
|
|
|
260
284
|
break;
|
|
261
285
|
}
|
|
262
286
|
case 'show': {
|
|
263
|
-
if (name)
|
|
264
|
-
|
|
287
|
+
if (name) {
|
|
288
|
+
const item = getLumenRegistryItem(name, registry);
|
|
289
|
+
output = json && item ? JSON.stringify(item, undefined, 2) : formatItem(name, registry);
|
|
290
|
+
}
|
|
265
291
|
break;
|
|
266
292
|
}
|
|
267
293
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-diagnostics.d.ts","sourceRoot":"","sources":["../src/integration-diagnostics.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"integration-diagnostics.d.ts","sourceRoot":"","sources":["../src/integration-diagnostics.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,uBAAuB,CAAA;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,sBAAsB,EAAE,CAAA;IAClC,UAAU,EAAE,CAAC,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B;AAowBD,eAAO,MAAM,uBAAuB,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,qBAAqB,CA4D/F,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,QAAQ,qBAAqB,KAAG,MAWtE,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,WAAW,OAAO,GAAG,UAAU,GAAG,OAAO,EAAE,kBAAgB,KAAG,MAsC9F,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
3
3
|
import { extname, join, relative, resolve, sep } from 'node:path';
|
|
4
|
-
import { lumenComponentBehavior, lumenGlobalBehaviors, lumenStylingContracts } from '@santi020k/lumen-core';
|
|
4
|
+
import { lumenComponentBehavior, lumenComponentNames, lumenGlobalBehaviors, lumenStylingContracts } from '@santi020k/lumen-core';
|
|
5
5
|
const sourceExtensions = new Set(['.astro', '.css', '.js', '.jsx', '.mjs', '.ts', '.tsx']);
|
|
6
6
|
const ignoredDirectories = new Set([
|
|
7
7
|
'.astro',
|
|
@@ -19,7 +19,15 @@ const ignoredDirectories = new Set([
|
|
|
19
19
|
'node_modules',
|
|
20
20
|
'out'
|
|
21
21
|
]);
|
|
22
|
-
const
|
|
22
|
+
const stylingContracts = lumenStylingContracts;
|
|
23
|
+
const publicRootSlots = new Set(Object.values(stylingContracts).flatMap(contract => [contract.rootSlot, ...contract.parts]));
|
|
24
|
+
const componentClassName = (name) => name
|
|
25
|
+
.replace(/([a-z\d])([A-Z])/gu, '$1-$2')
|
|
26
|
+
.toLowerCase();
|
|
27
|
+
const componentByClassName = new Map(lumenComponentNames.map((name) => [
|
|
28
|
+
componentClassName(name),
|
|
29
|
+
name
|
|
30
|
+
]));
|
|
23
31
|
const discoverProject = async (root) => {
|
|
24
32
|
const packageRoots = [];
|
|
25
33
|
const sourceFiles = [];
|
|
@@ -86,7 +94,41 @@ const getFrameworks = (sources) => [
|
|
|
86
94
|
const getBoundaryRoot = (file, packageRoots, fallback) => packageRoots
|
|
87
95
|
.filter(packageRoot => file === packageRoot || file.startsWith(`${packageRoot}${sep}`))
|
|
88
96
|
.sort((left, right) => right.length - left.length)[0] ?? fallback;
|
|
89
|
-
const
|
|
97
|
+
const readPackageManifest = async (root) => {
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(await readFile(join(root, 'package.json'), 'utf8'));
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const isPublishablePackageBoundary = (repositoryPath, manifest) => repositoryPath.includes('packages') && manifest?.private !== true;
|
|
106
|
+
const hasApplicationSource = (boundaryRoot, sources) => sources.some(item => /(?:^|\/)(?:app|pages|routes|layouts?)(?:\/|$)/iu.test(relative(boundaryRoot, item.file)));
|
|
107
|
+
const hasApplicationScript = (manifest) => {
|
|
108
|
+
if (manifest?.private !== true)
|
|
109
|
+
return false;
|
|
110
|
+
return Boolean(manifest.scripts?.dev ?? manifest.scripts?.start);
|
|
111
|
+
};
|
|
112
|
+
const isWorkspaceBoundary = (repositoryRoot, boundaryRoot, packageRootCount) => boundaryRoot === repositoryRoot && packageRootCount > 1;
|
|
113
|
+
const getFallbackBoundaryKind = (manifest) => manifest?.private === false ? 'library' : 'application';
|
|
114
|
+
const classifyBoundary = (repositoryRoot, boundaryRoot, manifest, sources, packageRootCount) => {
|
|
115
|
+
const declaredKind = manifest?.lumen?.integrationBoundary;
|
|
116
|
+
if (declaredKind)
|
|
117
|
+
return declaredKind;
|
|
118
|
+
const repositoryPath = relative(repositoryRoot, boundaryRoot).split(sep);
|
|
119
|
+
if (repositoryPath.includes('apps'))
|
|
120
|
+
return 'application';
|
|
121
|
+
if (isPublishablePackageBoundary(repositoryPath, manifest))
|
|
122
|
+
return 'library';
|
|
123
|
+
if (hasApplicationSource(boundaryRoot, sources))
|
|
124
|
+
return 'application';
|
|
125
|
+
if (hasApplicationScript(manifest))
|
|
126
|
+
return 'application';
|
|
127
|
+
if (isWorkspaceBoundary(repositoryRoot, boundaryRoot, packageRootCount))
|
|
128
|
+
return 'workspace';
|
|
129
|
+
return getFallbackBoundaryKind(manifest);
|
|
130
|
+
};
|
|
131
|
+
const createBoundaries = async (root, packageRoots, sources) => {
|
|
90
132
|
const grouped = new Map();
|
|
91
133
|
for (const source of sources) {
|
|
92
134
|
const boundaryRoot = getBoundaryRoot(source.file, packageRoots, root);
|
|
@@ -94,11 +136,43 @@ const createBoundaries = (root, packageRoots, sources) => {
|
|
|
94
136
|
entries.push(source);
|
|
95
137
|
grouped.set(boundaryRoot, entries);
|
|
96
138
|
}
|
|
97
|
-
return [...grouped].map(([boundaryRoot, boundarySources]) =>
|
|
98
|
-
|
|
99
|
-
|
|
139
|
+
return Promise.all([...grouped].map(async ([boundaryRoot, boundarySources]) => {
|
|
140
|
+
const manifest = await readPackageManifest(boundaryRoot);
|
|
141
|
+
const dependencies = [
|
|
142
|
+
...Object.keys(manifest?.dependencies ?? {}),
|
|
143
|
+
...Object.keys(manifest?.devDependencies ?? {}),
|
|
144
|
+
...Object.keys(manifest?.peerDependencies ?? {})
|
|
145
|
+
];
|
|
146
|
+
return {
|
|
147
|
+
dependencies,
|
|
148
|
+
kind: classifyBoundary(root, boundaryRoot, manifest, boundarySources, packageRoots.length),
|
|
149
|
+
...(manifest?.name ? { packageName: manifest.name } : {}),
|
|
150
|
+
root: boundaryRoot,
|
|
151
|
+
sources: boundarySources
|
|
152
|
+
};
|
|
100
153
|
}));
|
|
101
154
|
};
|
|
155
|
+
const getApplicationSources = (application, boundaries) => {
|
|
156
|
+
const byName = new Map(boundaries.flatMap(boundary => boundary.packageName ?
|
|
157
|
+
[[boundary.packageName, boundary]] :
|
|
158
|
+
[]));
|
|
159
|
+
const sources = [...application.sources];
|
|
160
|
+
const visited = new Set();
|
|
161
|
+
const includeDependencies = (boundary) => {
|
|
162
|
+
for (const dependencyName of boundary.dependencies) {
|
|
163
|
+
if (visited.has(dependencyName))
|
|
164
|
+
continue;
|
|
165
|
+
visited.add(dependencyName);
|
|
166
|
+
const dependency = byName.get(dependencyName);
|
|
167
|
+
if (dependency?.kind !== 'library')
|
|
168
|
+
continue;
|
|
169
|
+
sources.push(...dependency.sources);
|
|
170
|
+
includeDependencies(dependency);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
includeDependencies(application);
|
|
174
|
+
return sources;
|
|
175
|
+
};
|
|
102
176
|
const collectCompatibilityFindings = (root, sources) => sources.flatMap(item => {
|
|
103
177
|
const file = relative(root, item.file);
|
|
104
178
|
const findings = [];
|
|
@@ -108,6 +182,9 @@ const collectCompatibilityFindings = (root, sources) => sources.flatMap(item =>
|
|
|
108
182
|
if (item.source.includes('ui:datatable-selection-change')) {
|
|
109
183
|
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
184
|
}
|
|
185
|
+
if (importedNames(item.source, '@santi020k/lumen-astro').includes('UIPrimitives')) {
|
|
186
|
+
findings.push(finding(file, 'removed-root-export', 'UIPrimitives is no longer exported from the @santi020k/lumen-astro package root.', 'Import the default runtime from @santi020k/lumen-astro/runtime, or run lumen migrate-v2.'));
|
|
187
|
+
}
|
|
111
188
|
return findings;
|
|
112
189
|
});
|
|
113
190
|
const hasImportedPrimitive = (sources, names) => [
|
|
@@ -156,6 +233,47 @@ const duplicatedBehaviorRules = [
|
|
|
156
233
|
message: 'A raw menu with arrow-key handling may duplicate Lumen menu behavior.',
|
|
157
234
|
remediation: 'Review DropdownMenu, Menubar, or NavigationMenu before maintaining a separate keyboard controller.',
|
|
158
235
|
rule: 'hand-built-menu-keyboard'
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
detects: (source, sourceLower) => (source.includes('scrollY') || sourceLower.includes('scrolltop')) && (sourceLower.includes('scrollheight') || sourceLower.includes('scrollprogress')) && (source.includes('addEventListener(\'scroll\'') || source.includes('addEventListener("scroll"') ||
|
|
239
|
+
sourceLower.includes('onscroll')),
|
|
240
|
+
imports: ['ScrollProgress'],
|
|
241
|
+
message: 'Custom document scroll progress may duplicate Lumen ScrollProgress behavior.',
|
|
242
|
+
remediation: 'Review ScrollProgress before maintaining viewport measurement and progress synchronization.',
|
|
243
|
+
rule: 'hand-built-scroll-progress'
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
detects: (_source, sourceLower) => (sourceLower.includes('href="#main') || sourceLower.includes('href=\'#main')) && sourceLower.includes('skip'),
|
|
247
|
+
imports: ['SkipLink'],
|
|
248
|
+
message: 'A custom skip-to-content link may duplicate Lumen SkipLink behavior.',
|
|
249
|
+
remediation: 'Review SkipLink for its stable slot and fixed-position accessibility contract.',
|
|
250
|
+
rule: 'hand-built-skip-link'
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
detects: (source, sourceLower) => (source.includes('@radix-ui/react-slot') || sourceLower.includes('<slot')) && sourceLower.includes('aschild'),
|
|
254
|
+
imports: ['Button'],
|
|
255
|
+
message: 'A Radix Slot or asChild branch may duplicate Lumen Button composition.',
|
|
256
|
+
remediation: 'Review Button asChild before retaining a separate polymorphic action wrapper.',
|
|
257
|
+
rule: 'hand-built-polymorphic-button'
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
detects: (source, sourceLower) => sourceLower.includes('<input') &&
|
|
261
|
+
/\bsize\s*=\s*\{(?:size|props\.size)\}/u.test(source) &&
|
|
262
|
+
!source.includes('visualSize'),
|
|
263
|
+
imports: ['Input'],
|
|
264
|
+
message: 'A native input size passthrough may confuse HTML character width with Lumen visual sizing.',
|
|
265
|
+
remediation: 'Review Input visualSize and keep the native size attribute only when character width is intentional.',
|
|
266
|
+
rule: 'native-input-size-fallback'
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
detects: (source, sourceLower) => sourceLower.includes('card') &&
|
|
270
|
+
sourceLower.includes('card-header') &&
|
|
271
|
+
sourceLower.includes('card-content') &&
|
|
272
|
+
!source.includes('CardHeader'),
|
|
273
|
+
imports: ['Card'],
|
|
274
|
+
message: 'A hand-built card section hierarchy may duplicate Lumen Card compound parts.',
|
|
275
|
+
remediation: 'Review CardHeader, CardContent, and CardFooter while keeping domain-specific card content application-owned.',
|
|
276
|
+
rule: 'hand-built-card-structure'
|
|
159
277
|
}
|
|
160
278
|
];
|
|
161
279
|
const collectDuplicatedBehaviorFindings = (root, sources) => sources.flatMap(item => {
|
|
@@ -246,25 +364,63 @@ const styleImportByFramework = {
|
|
|
246
364
|
react: '@santi020k/lumen-react/styles.css'
|
|
247
365
|
};
|
|
248
366
|
const countOccurrences = (source, value) => source.split(value).length - 1;
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
367
|
+
const getInternalSelectorContract = (selector) => {
|
|
368
|
+
const [componentClass = ''] = selector.split(/--|__/u, 1);
|
|
369
|
+
const component = componentByClassName.get(componentClass);
|
|
370
|
+
if (!component)
|
|
371
|
+
return {};
|
|
372
|
+
const contract = stylingContracts[component];
|
|
373
|
+
if (!contract)
|
|
374
|
+
return { component };
|
|
375
|
+
if (selector.includes('__')) {
|
|
376
|
+
const partName = selector.split('__', 2)[1]?.replaceAll('_', '-') ?? '';
|
|
377
|
+
const slot = `${contract.rootSlot}-${partName}`;
|
|
378
|
+
return contract.parts.includes(slot) ? { component, slot } : { component };
|
|
260
379
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
380
|
+
return { component, slot: contract.rootSlot };
|
|
381
|
+
};
|
|
382
|
+
const consumerClassGuidance = (frameworks) => {
|
|
383
|
+
const detectedFrameworks = new Set(frameworks);
|
|
384
|
+
const adapters = [
|
|
385
|
+
detectedFrameworks.has('astro') && 'the public class prop in Astro',
|
|
386
|
+
detectedFrameworks.has('react') && 'the public className prop in React',
|
|
387
|
+
detectedFrameworks.has('elements') && 'a class attribute on the Elements host'
|
|
388
|
+
].filter((value) => Boolean(value));
|
|
389
|
+
if (adapters.length === 0) {
|
|
390
|
+
return 'Pass a consumer-owned class through the adapter\'s public class API.';
|
|
266
391
|
}
|
|
267
|
-
return
|
|
392
|
+
return `Pass a consumer-owned class through ${adapters.join(', ')}.`;
|
|
393
|
+
};
|
|
394
|
+
const internalSelectorFinding = (file, selector, frameworks) => {
|
|
395
|
+
const contract = getInternalSelectorContract(selector);
|
|
396
|
+
const componentContext = contract.component ?
|
|
397
|
+
` It most likely targets the ${contract.component} component.` :
|
|
398
|
+
'';
|
|
399
|
+
const stableSlotGuidance = contract.slot ?
|
|
400
|
+
` For a library-owned hook, use [data-slot="${contract.slot}"].` :
|
|
401
|
+
'';
|
|
402
|
+
return finding(file, 'internal-selector', `Selector .ui-${selector} is not a documented stable hook.${componentContext}`, `${consumerClassGuidance(frameworks)} Prefer semantic tokens and documented custom properties.${stableSlotGuidance}`, 'advisory');
|
|
403
|
+
};
|
|
404
|
+
const collectCssFindings = (root, boundaries) => boundaries.flatMap(boundary => {
|
|
405
|
+
const frameworks = getFrameworks(boundary.sources);
|
|
406
|
+
return boundary.sources.filter(item => item.file.endsWith('.css')).flatMap(item => {
|
|
407
|
+
const layerIndex = item.source.search(/^\s*@import\s+(?:url\(\s*)?["'][^"']*\/layers\.css["']/mu);
|
|
408
|
+
const tailwindIndex = item.source.search(/^\s*@import\s+(?:url\(\s*)?["']tailwindcss["']/mu);
|
|
409
|
+
const styleIndex = item.source.search(/^\s*@import\s+(?:url\(\s*)?["'][^"']*\/styles\.css["']/mu);
|
|
410
|
+
const findings = [];
|
|
411
|
+
if (tailwindIndex >= 0 &&
|
|
412
|
+
styleIndex >= 0 &&
|
|
413
|
+
(layerIndex < 0 || !(layerIndex < tailwindIndex && tailwindIndex < styleIndex))) {
|
|
414
|
+
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.'));
|
|
415
|
+
}
|
|
416
|
+
for (const match of item.source.matchAll(/\.ui-([a-z0-9_-]+)/g)) {
|
|
417
|
+
const selector = match[1] ?? '';
|
|
418
|
+
if (!publicRootSlots.has(selector)) {
|
|
419
|
+
findings.push(internalSelectorFinding(relative(root, item.file), selector, frameworks));
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return findings;
|
|
423
|
+
});
|
|
268
424
|
});
|
|
269
425
|
const collectFrameworkStyleFindings = (repositoryRoot, boundary, frameworks) => frameworks.flatMap(framework => {
|
|
270
426
|
const styleImport = styleImportByFramework[framework];
|
|
@@ -291,6 +447,10 @@ const collectAdapterMismatchFindings = (repositoryRoot, boundary, frameworks) =>
|
|
|
291
447
|
.filter(adapter => !frameworks.includes(adapter))
|
|
292
448
|
.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.'));
|
|
293
449
|
};
|
|
450
|
+
const collectSharedLibraryStyleFindings = (repositoryRoot, boundary) => Object.entries(styleImportByFramework)
|
|
451
|
+
.flatMap(([framework, styleImport]) => boundary.sources
|
|
452
|
+
.filter(item => item.source.includes(styleImport))
|
|
453
|
+
.map(item => finding(relative(repositoryRoot, item.file), 'shared-library-adapter-style', `A shared library loads the ${framework} adapter stylesheet, which can duplicate application-owned setup.`, 'Remove the adapter stylesheet from the shared package and load it once in each consuming application root.', 'advisory')));
|
|
294
454
|
const uniqueFindings = (findings) => [
|
|
295
455
|
...new Map(findings.map(item => [
|
|
296
456
|
`${item.file}\u0000${item.rule}\u0000${item.message}`,
|
|
@@ -306,18 +466,26 @@ export const inspectLumenIntegration = async (repository) => {
|
|
|
306
466
|
file,
|
|
307
467
|
source: await readFile(file, 'utf8')
|
|
308
468
|
})));
|
|
309
|
-
const boundaries = createBoundaries(root, discovered.packageRoots, sources);
|
|
310
|
-
const
|
|
469
|
+
const boundaries = await createBoundaries(root, discovered.packageRoots, sources);
|
|
470
|
+
const applicationBoundaries = boundaries.filter(boundary => boundary.kind === 'application');
|
|
471
|
+
const frameworks = [...new Set(applicationBoundaries.flatMap(boundary => getFrameworks(getApplicationSources(boundary, boundaries))))];
|
|
311
472
|
const runtimeComponents = new Set();
|
|
312
473
|
const findings = [
|
|
313
474
|
...collectCompatibilityFindings(root, sources),
|
|
314
|
-
...collectCssFindings(root,
|
|
475
|
+
...collectCssFindings(root, boundaries)
|
|
315
476
|
];
|
|
316
|
-
for (const boundary of boundaries) {
|
|
317
|
-
|
|
318
|
-
|
|
477
|
+
for (const boundary of boundaries.filter(item => item.kind === 'library')) {
|
|
478
|
+
findings.push(...collectSharedLibraryStyleFindings(root, boundary));
|
|
479
|
+
}
|
|
480
|
+
for (const boundary of applicationBoundaries) {
|
|
481
|
+
const effectiveBoundary = {
|
|
482
|
+
...boundary,
|
|
483
|
+
sources: getApplicationSources(boundary, boundaries)
|
|
484
|
+
};
|
|
485
|
+
const boundaryFrameworks = getFrameworks(effectiveBoundary.sources);
|
|
486
|
+
const runtime = collectRuntimeFindings(root, effectiveBoundary);
|
|
319
487
|
runtime.runtimeComponents.forEach(component => runtimeComponents.add(component));
|
|
320
|
-
findings.push(...collectDuplicatedBehaviorFindings(root,
|
|
488
|
+
findings.push(...collectDuplicatedBehaviorFindings(root, effectiveBoundary.sources), ...runtime.findings, ...collectFrameworkStyleFindings(root, boundary, boundaryFrameworks), ...collectAdapterMismatchFindings(root, boundary, boundaryFrameworks));
|
|
321
489
|
}
|
|
322
490
|
const deduplicatedFindings = uniqueFindings(findings);
|
|
323
491
|
return {
|
package/dist/registry-data.d.ts
CHANGED
|
@@ -321,6 +321,42 @@ export declare const lumenRegistry: {
|
|
|
321
321
|
readonly type: "component";
|
|
322
322
|
readonly description: "Copies arbitrary text or the content of another element with accessible feedback.";
|
|
323
323
|
readonly category: "Actions";
|
|
324
|
+
readonly contract: {
|
|
325
|
+
readonly imports: {
|
|
326
|
+
readonly astro: "import { CopyButton } from '@santi020k/lumen-astro'";
|
|
327
|
+
};
|
|
328
|
+
readonly usage: {
|
|
329
|
+
readonly astro: "<CopyButton value=\"https://example.com\" variant=\"default\">Copy link<span slot=\"copied\">Copied!</span><span slot=\"error\">Try again</span></CopyButton>";
|
|
330
|
+
};
|
|
331
|
+
readonly props: readonly [{
|
|
332
|
+
readonly name: "value";
|
|
333
|
+
readonly type: "string";
|
|
334
|
+
}, {
|
|
335
|
+
readonly name: "target";
|
|
336
|
+
readonly type: "string";
|
|
337
|
+
}, {
|
|
338
|
+
readonly name: "variant";
|
|
339
|
+
readonly type: "Button variant";
|
|
340
|
+
readonly default: "outline";
|
|
341
|
+
}, {
|
|
342
|
+
readonly name: "size";
|
|
343
|
+
readonly type: "default | sm | lg | icon";
|
|
344
|
+
readonly default: "default";
|
|
345
|
+
}, {
|
|
346
|
+
readonly name: "resetAfter";
|
|
347
|
+
readonly type: "number";
|
|
348
|
+
readonly default: "2000";
|
|
349
|
+
}, {
|
|
350
|
+
readonly name: "toast";
|
|
351
|
+
readonly type: "boolean";
|
|
352
|
+
readonly default: "false";
|
|
353
|
+
}];
|
|
354
|
+
readonly events: readonly ["ui:copy-success", "ui:copy-error"];
|
|
355
|
+
readonly slots: readonly ["default (idle)", "copied", "error"];
|
|
356
|
+
readonly runtime: "Mount the default export from @santi020k/lumen-astro/runtime once above the component.";
|
|
357
|
+
readonly stylingParts: readonly ["copy-button", "copy-idle", "copy-copied", "copy-error"];
|
|
358
|
+
readonly tokens: readonly ["brand-solid", "line", "surface-muted", "ink"];
|
|
359
|
+
};
|
|
324
360
|
readonly files: readonly ["packages/astro/components/CopyButton.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
325
361
|
readonly dependencies: readonly ["styles", "runtime"];
|
|
326
362
|
}, {
|
|
@@ -935,6 +971,38 @@ export declare const lumenRegistry: {
|
|
|
935
971
|
readonly type: "component";
|
|
936
972
|
readonly category: "Layout";
|
|
937
973
|
readonly description: "Reveals a group of direct children with tokenized, reduced-motion-aware staggering.";
|
|
974
|
+
readonly contract: {
|
|
975
|
+
readonly imports: {
|
|
976
|
+
readonly astro: "import { RevealGroup } from '@santi020k/lumen-astro'";
|
|
977
|
+
};
|
|
978
|
+
readonly usage: {
|
|
979
|
+
readonly astro: "<RevealGroup as=\"ul\"><li>First</li><li>Second</li></RevealGroup>";
|
|
980
|
+
};
|
|
981
|
+
readonly props: readonly [{
|
|
982
|
+
readonly name: "as";
|
|
983
|
+
readonly type: "div | ul | ol | section";
|
|
984
|
+
readonly default: "div";
|
|
985
|
+
}, {
|
|
986
|
+
readonly name: "animation";
|
|
987
|
+
readonly type: "fade | slide-up | scale";
|
|
988
|
+
readonly default: "slide-up";
|
|
989
|
+
}, {
|
|
990
|
+
readonly name: "duration";
|
|
991
|
+
readonly type: "fast | standard | slow";
|
|
992
|
+
readonly default: "slow";
|
|
993
|
+
}, {
|
|
994
|
+
readonly name: "stagger";
|
|
995
|
+
readonly type: "number";
|
|
996
|
+
readonly default: "80";
|
|
997
|
+
}, {
|
|
998
|
+
readonly name: "once";
|
|
999
|
+
readonly type: "boolean";
|
|
1000
|
+
readonly default: "true";
|
|
1001
|
+
}];
|
|
1002
|
+
readonly composition: readonly ["Children remain direct children of the selected semantic root."];
|
|
1003
|
+
readonly runtime: "Mount the Astro runtime once; content remains readable before JavaScript and with reduced motion.";
|
|
1004
|
+
readonly tokens: readonly ["motion-duration-fast", "motion-duration-standard", "motion-duration-slow"];
|
|
1005
|
+
};
|
|
938
1006
|
readonly files: readonly ["packages/astro/components/RevealGroup.astro", "packages/astro/runtime/UIPrimitives.astro", "packages/astro/styles/lumen.css", "packages/react/src/components.tsx"];
|
|
939
1007
|
readonly dependencies: readonly ["styles", "runtime"];
|
|
940
1008
|
}, {
|
|
@@ -949,6 +1017,34 @@ export declare const lumenRegistry: {
|
|
|
949
1017
|
readonly type: "component";
|
|
950
1018
|
readonly category: "Data display";
|
|
951
1019
|
readonly description: "A stat component.";
|
|
1020
|
+
readonly contract: {
|
|
1021
|
+
readonly imports: {
|
|
1022
|
+
readonly astro: "import { Stat, StatLabel, StatValue } from '@santi020k/lumen-astro'";
|
|
1023
|
+
readonly react: "import { Stat, StatLabel, StatValue } from '@santi020k/lumen-react'";
|
|
1024
|
+
};
|
|
1025
|
+
readonly usage: {
|
|
1026
|
+
readonly astro: "<Stat as=\"article\"><StatLabel>Revenue</StatLabel><StatValue>$12,400</StatValue></Stat>";
|
|
1027
|
+
readonly react: "<Stat as=\"article\"><StatLabel>Revenue</StatLabel><StatValue>$12,400</StatValue></Stat>";
|
|
1028
|
+
};
|
|
1029
|
+
readonly props: readonly [{
|
|
1030
|
+
readonly name: "as";
|
|
1031
|
+
readonly type: "article | div | section";
|
|
1032
|
+
readonly default: "div";
|
|
1033
|
+
}, {
|
|
1034
|
+
readonly name: "variant";
|
|
1035
|
+
readonly type: "accent | bare | default | glass";
|
|
1036
|
+
readonly default: "default";
|
|
1037
|
+
}, {
|
|
1038
|
+
readonly name: "label";
|
|
1039
|
+
readonly type: "string";
|
|
1040
|
+
}, {
|
|
1041
|
+
readonly name: "value";
|
|
1042
|
+
readonly type: "string";
|
|
1043
|
+
}];
|
|
1044
|
+
readonly composition: readonly ["Prefer StatLabel, StatValue, StatDescription, StatIcon, and StatTrend for structured content."];
|
|
1045
|
+
readonly stylingParts: readonly ["stat", "stat-label", "stat-value", "stat-description", "stat-icon", "stat-trend"];
|
|
1046
|
+
readonly tokens: readonly ["surface", "line", "ink", "ink-muted", "brand-soft"];
|
|
1047
|
+
};
|
|
952
1048
|
readonly files: readonly ["packages/astro/components/Stat.astro", "packages/react/src/components.tsx"];
|
|
953
1049
|
}, {
|
|
954
1050
|
readonly name: "StatDescription";
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2iFQ,CAAA"}
|
package/dist/registry-data.js
CHANGED
|
@@ -730,6 +730,66 @@ export const lumenRegistry = {
|
|
|
730
730
|
type: 'component',
|
|
731
731
|
description: 'Copies arbitrary text or the content of another element with accessible feedback.',
|
|
732
732
|
category: 'Actions',
|
|
733
|
+
contract: {
|
|
734
|
+
imports: {
|
|
735
|
+
astro: 'import { CopyButton } from \'@santi020k/lumen-astro\''
|
|
736
|
+
},
|
|
737
|
+
usage: {
|
|
738
|
+
astro: '<CopyButton value="https://example.com" variant="default">Copy link<span slot="copied">Copied!</span><span slot="error">Try again</span></CopyButton>'
|
|
739
|
+
},
|
|
740
|
+
props: [
|
|
741
|
+
{
|
|
742
|
+
name: 'value',
|
|
743
|
+
type: 'string'
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
name: 'target',
|
|
747
|
+
type: 'string'
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
name: 'variant',
|
|
751
|
+
type: 'Button variant',
|
|
752
|
+
default: 'outline'
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
name: 'size',
|
|
756
|
+
type: 'default | sm | lg | icon',
|
|
757
|
+
default: 'default'
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
name: 'resetAfter',
|
|
761
|
+
type: 'number',
|
|
762
|
+
default: '2000'
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
name: 'toast',
|
|
766
|
+
type: 'boolean',
|
|
767
|
+
default: 'false'
|
|
768
|
+
}
|
|
769
|
+
],
|
|
770
|
+
events: [
|
|
771
|
+
'ui:copy-success',
|
|
772
|
+
'ui:copy-error'
|
|
773
|
+
],
|
|
774
|
+
slots: [
|
|
775
|
+
'default (idle)',
|
|
776
|
+
'copied',
|
|
777
|
+
'error'
|
|
778
|
+
],
|
|
779
|
+
runtime: 'Mount the default export from @santi020k/lumen-astro/runtime once above the component.',
|
|
780
|
+
stylingParts: [
|
|
781
|
+
'copy-button',
|
|
782
|
+
'copy-idle',
|
|
783
|
+
'copy-copied',
|
|
784
|
+
'copy-error'
|
|
785
|
+
],
|
|
786
|
+
tokens: [
|
|
787
|
+
'brand-solid',
|
|
788
|
+
'line',
|
|
789
|
+
'surface-muted',
|
|
790
|
+
'ink'
|
|
791
|
+
]
|
|
792
|
+
},
|
|
733
793
|
files: [
|
|
734
794
|
'packages/astro/components/CopyButton.astro',
|
|
735
795
|
'packages/astro/styles/lumen.css',
|
|
@@ -1988,6 +2048,50 @@ export const lumenRegistry = {
|
|
|
1988
2048
|
type: 'component',
|
|
1989
2049
|
category: 'Layout',
|
|
1990
2050
|
description: 'Reveals a group of direct children with tokenized, reduced-motion-aware staggering.',
|
|
2051
|
+
contract: {
|
|
2052
|
+
imports: {
|
|
2053
|
+
astro: 'import { RevealGroup } from \'@santi020k/lumen-astro\''
|
|
2054
|
+
},
|
|
2055
|
+
usage: {
|
|
2056
|
+
astro: '<RevealGroup as="ul"><li>First</li><li>Second</li></RevealGroup>'
|
|
2057
|
+
},
|
|
2058
|
+
props: [
|
|
2059
|
+
{
|
|
2060
|
+
name: 'as',
|
|
2061
|
+
type: 'div | ul | ol | section',
|
|
2062
|
+
default: 'div'
|
|
2063
|
+
},
|
|
2064
|
+
{
|
|
2065
|
+
name: 'animation',
|
|
2066
|
+
type: 'fade | slide-up | scale',
|
|
2067
|
+
default: 'slide-up'
|
|
2068
|
+
},
|
|
2069
|
+
{
|
|
2070
|
+
name: 'duration',
|
|
2071
|
+
type: 'fast | standard | slow',
|
|
2072
|
+
default: 'slow'
|
|
2073
|
+
},
|
|
2074
|
+
{
|
|
2075
|
+
name: 'stagger',
|
|
2076
|
+
type: 'number',
|
|
2077
|
+
default: '80'
|
|
2078
|
+
},
|
|
2079
|
+
{
|
|
2080
|
+
name: 'once',
|
|
2081
|
+
type: 'boolean',
|
|
2082
|
+
default: 'true'
|
|
2083
|
+
}
|
|
2084
|
+
],
|
|
2085
|
+
composition: [
|
|
2086
|
+
'Children remain direct children of the selected semantic root.'
|
|
2087
|
+
],
|
|
2088
|
+
runtime: 'Mount the Astro runtime once; content remains readable before JavaScript and with reduced motion.',
|
|
2089
|
+
tokens: [
|
|
2090
|
+
'motion-duration-fast',
|
|
2091
|
+
'motion-duration-standard',
|
|
2092
|
+
'motion-duration-slow'
|
|
2093
|
+
]
|
|
2094
|
+
},
|
|
1991
2095
|
files: [
|
|
1992
2096
|
'packages/astro/components/RevealGroup.astro',
|
|
1993
2097
|
'packages/astro/runtime/UIPrimitives.astro',
|
|
@@ -2020,6 +2124,54 @@ export const lumenRegistry = {
|
|
|
2020
2124
|
type: 'component',
|
|
2021
2125
|
category: 'Data display',
|
|
2022
2126
|
description: 'A stat component.',
|
|
2127
|
+
contract: {
|
|
2128
|
+
imports: {
|
|
2129
|
+
astro: 'import { Stat, StatLabel, StatValue } from \'@santi020k/lumen-astro\'',
|
|
2130
|
+
react: 'import { Stat, StatLabel, StatValue } from \'@santi020k/lumen-react\''
|
|
2131
|
+
},
|
|
2132
|
+
usage: {
|
|
2133
|
+
astro: '<Stat as="article"><StatLabel>Revenue</StatLabel><StatValue>$12,400</StatValue></Stat>',
|
|
2134
|
+
react: '<Stat as="article"><StatLabel>Revenue</StatLabel><StatValue>$12,400</StatValue></Stat>'
|
|
2135
|
+
},
|
|
2136
|
+
props: [
|
|
2137
|
+
{
|
|
2138
|
+
name: 'as',
|
|
2139
|
+
type: 'article | div | section',
|
|
2140
|
+
default: 'div'
|
|
2141
|
+
},
|
|
2142
|
+
{
|
|
2143
|
+
name: 'variant',
|
|
2144
|
+
type: 'accent | bare | default | glass',
|
|
2145
|
+
default: 'default'
|
|
2146
|
+
},
|
|
2147
|
+
{
|
|
2148
|
+
name: 'label',
|
|
2149
|
+
type: 'string'
|
|
2150
|
+
},
|
|
2151
|
+
{
|
|
2152
|
+
name: 'value',
|
|
2153
|
+
type: 'string'
|
|
2154
|
+
}
|
|
2155
|
+
],
|
|
2156
|
+
composition: [
|
|
2157
|
+
'Prefer StatLabel, StatValue, StatDescription, StatIcon, and StatTrend for structured content.'
|
|
2158
|
+
],
|
|
2159
|
+
stylingParts: [
|
|
2160
|
+
'stat',
|
|
2161
|
+
'stat-label',
|
|
2162
|
+
'stat-value',
|
|
2163
|
+
'stat-description',
|
|
2164
|
+
'stat-icon',
|
|
2165
|
+
'stat-trend'
|
|
2166
|
+
],
|
|
2167
|
+
tokens: [
|
|
2168
|
+
'surface',
|
|
2169
|
+
'line',
|
|
2170
|
+
'ink',
|
|
2171
|
+
'ink-muted',
|
|
2172
|
+
'brand-soft'
|
|
2173
|
+
]
|
|
2174
|
+
},
|
|
2023
2175
|
files: [
|
|
2024
2176
|
'packages/astro/components/Stat.astro',
|
|
2025
2177
|
'packages/react/src/components.tsx'
|
package/dist/registry-types.d.ts
CHANGED
|
@@ -2,8 +2,25 @@ export interface LumenRegistryFile {
|
|
|
2
2
|
path: string;
|
|
3
3
|
source: string;
|
|
4
4
|
}
|
|
5
|
+
export interface LumenRegistryComponentContract {
|
|
6
|
+
composition?: readonly string[];
|
|
7
|
+
events?: readonly string[];
|
|
8
|
+
imports: Readonly<Record<string, string>>;
|
|
9
|
+
props?: readonly {
|
|
10
|
+
default?: string;
|
|
11
|
+
name: string;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
type: string;
|
|
14
|
+
}[];
|
|
15
|
+
runtime?: string;
|
|
16
|
+
slots?: readonly string[];
|
|
17
|
+
stylingParts?: readonly string[];
|
|
18
|
+
tokens?: readonly string[];
|
|
19
|
+
usage: Readonly<Record<string, string>>;
|
|
20
|
+
}
|
|
5
21
|
export interface LumenRegistryComponent {
|
|
6
22
|
category: string;
|
|
23
|
+
contract?: LumenRegistryComponentContract;
|
|
7
24
|
dependencies?: readonly string[];
|
|
8
25
|
description: string;
|
|
9
26
|
files: readonly (LumenRegistryFile | string)[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-types.d.ts","sourceRoot":"","sources":["../src/registry-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,SAAS,CAAC,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAA;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAA;IAC/C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,eAAe,GAAG,eAAe,GAAG,QAAQ,CAAA;CACnD;AAED,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG,iBAAiB,CAAA;AAE3E,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"}
|
|
1
|
+
{"version":3,"file":"registry-types.d.ts","sourceRoot":"","sources":["../src/registry-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,8BAA8B;IAC7C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACzC,KAAK,CAAC,EAAE,SAAS;QACf,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,CAAC,EAAE,OAAO,CAAA;QAClB,IAAI,EAAE,MAAM,CAAA;KACb,EAAE,CAAA;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACzB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACxC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,8BAA8B,CAAA;IACzC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,SAAS,CAAC,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAA;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAA;IAC/C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,eAAe,GAAG,eAAe,GAAG,QAAQ,CAAA;CACnD;AAED,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG,iBAAiB,CAAA;AAE3E,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"}
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { lumenRegistry } from './registry-data.js';
|
|
2
|
-
import type { LumenRegistry, LumenRegistryComponent, LumenRegistryEntry, LumenRegistryFile, LumenRegistryItem, LumenRegistryLoadOptions } from './registry-types.js';
|
|
2
|
+
import type { LumenRegistry, LumenRegistryComponent, LumenRegistryComponentContract, LumenRegistryEntry, LumenRegistryFile, LumenRegistryItem, LumenRegistryLoadOptions } from './registry-types.js';
|
|
3
3
|
export { lumenRegistry };
|
|
4
|
-
export type { LumenRegistry, LumenRegistryComponent, LumenRegistryEntry, LumenRegistryFile, LumenRegistryItem, LumenRegistryLoadOptions };
|
|
4
|
+
export type { LumenRegistry, LumenRegistryComponent, LumenRegistryComponentContract, LumenRegistryEntry, LumenRegistryFile, LumenRegistryItem, LumenRegistryLoadOptions };
|
|
5
5
|
export declare const getLumenRegistryEntries: (registry?: LumenRegistry) => LumenRegistryEntry[];
|
|
6
6
|
export declare const getLumenRegistryItem: (name: string, registry?: LumenRegistry) => LumenRegistryEntry | undefined;
|
|
7
7
|
export declare const loadLumenRegistry: (source: string | URL, options?: LumenRegistryLoadOptions) => Promise<LumenRegistry>;
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,CAAA;AAwBD,eAAO,MAAM,uBAAuB,GAAI,WAAU,aAA6B,KAAG,kBAAkB,EAGnG,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,WAAU,aAA6B,KACtC,kBAAkB,GAAG,SAQvB,CAAA;AA6JD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,GAAG,GAAG,EACpB,UAAS,wBAA6B,KACrC,OAAO,CAAC,aAAa,CAsBvB,CAAA;AAED,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,CAAA;AAwBD,eAAO,MAAM,uBAAuB,GAAI,WAAU,aAA6B,KAAG,kBAAkB,EAGnG,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,WAAU,aAA6B,KACtC,kBAAkB,GAAG,SAQvB,CAAA;AA6JD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,GAAG,GAAG,EACpB,UAAS,wBAA6B,KACrC,OAAO,CAAC,aAAa,CAsBvB,CAAA;AAED,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA"}
|
package/native-components.json
CHANGED
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
{
|
|
71
71
|
"id": "icon-button",
|
|
72
72
|
"tier": "universal",
|
|
73
|
-
"contract": "Shared intent and native touch target",
|
|
74
|
-
"accessibility": "Requires an action label",
|
|
73
|
+
"contract": "Shared intent and native touch target; SwiftUI supports semantic roles and loading",
|
|
74
|
+
"accessibility": "Requires an action label; SwiftUI loading preserves the name and disables repeat activation",
|
|
75
75
|
"symbols": {
|
|
76
76
|
"reactNative": "LumenIconButton",
|
|
77
77
|
"swiftUI": "LumenIconButton",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
{
|
|
93
93
|
"id": "button",
|
|
94
94
|
"tier": "universal",
|
|
95
|
-
"contract": "Intent, size, loading, and disabled states",
|
|
95
|
+
"contract": "Intent, size, loading, and disabled states; SwiftUI supports semantic button roles",
|
|
96
96
|
"accessibility": "Exposes native button and state semantics",
|
|
97
97
|
"symbols": {
|
|
98
98
|
"reactNative": "LumenButton",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"id": "field-group",
|
|
127
127
|
"tier": "shared",
|
|
128
128
|
"contract": "Label, description, required state, control content, and validation message",
|
|
129
|
-
"accessibility": "Keeps child control semantics independent
|
|
129
|
+
"accessibility": "Keeps child control semantics independent, presents readable field context, and announces validation updates",
|
|
130
130
|
"symbols": {
|
|
131
131
|
"reactNative": "LumenFieldGroup",
|
|
132
132
|
"swiftUI": "LumenFieldGroup",
|
|
@@ -136,8 +136,8 @@
|
|
|
136
136
|
{
|
|
137
137
|
"id": "toggle",
|
|
138
138
|
"tier": "shared",
|
|
139
|
-
"contract": "
|
|
140
|
-
"accessibility": "Exposes
|
|
139
|
+
"contract": "Full-row native switch behavior with visible label and disabled state",
|
|
140
|
+
"accessibility": "Exposes one labeled switch whose full row toggles the controlled state and preserves supporting guidance",
|
|
141
141
|
"symbols": {
|
|
142
142
|
"reactNative": "LumenToggle",
|
|
143
143
|
"swiftUI": "LumenToggle",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
{
|
|
148
148
|
"id": "settings-row",
|
|
149
149
|
"tier": "shared",
|
|
150
|
-
"contract": "Title, supporting text, optional graphic, and
|
|
150
|
+
"contract": "Title, supporting text, optional graphic, trailing control, and 56-unit minimum row height",
|
|
151
151
|
"accessibility": "Contains the native control without merging its interaction",
|
|
152
152
|
"symbols": {
|
|
153
153
|
"reactNative": "LumenSettingsRow",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
{
|
|
159
159
|
"id": "search-field",
|
|
160
160
|
"tier": "shared",
|
|
161
|
-
"contract": "Native search input with semantic surface and clear action",
|
|
161
|
+
"contract": "Native search input with semantic surface and a density-aware clear action",
|
|
162
162
|
"accessibility": "Labels the input and clear action while preserving native editing",
|
|
163
163
|
"symbols": {
|
|
164
164
|
"reactNative": "LumenSearchField",
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
{
|
|
203
203
|
"id": "checkbox",
|
|
204
204
|
"tier": "shared",
|
|
205
|
-
"contract": "Controlled Boolean selection with visible label
|
|
205
|
+
"contract": "Controlled Boolean selection with visible label, optional supporting text, and density-aware row target",
|
|
206
206
|
"accessibility": "Exposes native checkbox state, disabled state, and a readable label",
|
|
207
207
|
"symbols": {
|
|
208
208
|
"reactNative": "LumenCheckbox",
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
{
|
|
214
214
|
"id": "radio-group",
|
|
215
215
|
"tier": "shared",
|
|
216
|
-
"contract": "Single selection from labeled options with optional supporting text",
|
|
216
|
+
"contract": "Single selection from labeled options with optional supporting text and density-aware row targets",
|
|
217
217
|
"accessibility": "Exposes a named native radio group and selected or disabled option states",
|
|
218
218
|
"symbols": {
|
|
219
219
|
"reactNative": "LumenRadioGroup",
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
{
|
|
247
247
|
"id": "chip",
|
|
248
248
|
"tier": "shared",
|
|
249
|
-
"contract": "Compact display, selection, and removal with semantic
|
|
249
|
+
"contract": "Compact display, selection, and removal with semantic states and a 24-unit minimum remove target",
|
|
250
250
|
"accessibility": "Separates selection and removal actions while exposing selected and disabled state",
|
|
251
251
|
"symbols": {
|
|
252
252
|
"reactNative": "LumenChip",
|
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
{
|
|
291
291
|
"id": "spinner",
|
|
292
292
|
"tier": "universal",
|
|
293
|
-
"contract": "Brand-
|
|
293
|
+
"contract": "Brand-default indeterminate activity with an optional semantic tint",
|
|
294
294
|
"accessibility": "Exposes a loading label",
|
|
295
295
|
"symbols": {
|
|
296
296
|
"reactNative": "LumenSpinner",
|
|
@@ -324,7 +324,7 @@
|
|
|
324
324
|
"id": "toast",
|
|
325
325
|
"tier": "shared",
|
|
326
326
|
"contract": "App-controlled transient feedback with semantic tone, optional action, and dismissal",
|
|
327
|
-
"accessibility": "
|
|
327
|
+
"accessibility": "Uses native live feedback semantics while preserving independently labeled, full-target action and dismissal controls",
|
|
328
328
|
"symbols": {
|
|
329
329
|
"reactNative": "LumenToast",
|
|
330
330
|
"swiftUI": "LumenToast",
|
|
@@ -544,7 +544,7 @@
|
|
|
544
544
|
"id": "banner",
|
|
545
545
|
"tier": "shared",
|
|
546
546
|
"contract": "Semantic notice with optional actions and dismissal",
|
|
547
|
-
"accessibility": "Does not announce automatically and
|
|
547
|
+
"accessibility": "Does not announce automatically and exposes a labeled, full-target dismissal control",
|
|
548
548
|
"symbols": {
|
|
549
549
|
"reactNative": "LumenBanner",
|
|
550
550
|
"swiftUI": "LumenBanner",
|
|
@@ -576,8 +576,8 @@
|
|
|
576
576
|
{
|
|
577
577
|
"id": "status-bar",
|
|
578
578
|
"tier": "shared",
|
|
579
|
-
"contract": "Compact semantic status
|
|
580
|
-
"accessibility": "Status meaning remains present in text
|
|
579
|
+
"contract": "Compact semantic status that wraps beside fixed optional trailing content",
|
|
580
|
+
"accessibility": "Status meaning remains present in text before independently operable trailing content",
|
|
581
581
|
"symbols": {
|
|
582
582
|
"reactNative": "LumenStatusBar",
|
|
583
583
|
"swiftUI": "LumenStatusBar",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@santi020k/lumen",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -45,17 +45,17 @@
|
|
|
45
45
|
"lumen": "./bin/lumen.mjs"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"semver": "^7.8.
|
|
49
|
-
"@santi020k/lumen-core": "^1.
|
|
48
|
+
"semver": "^7.8.5",
|
|
49
|
+
"@santi020k/lumen-core": "^2.1.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@types/node": "^26.
|
|
52
|
+
"@types/node": "^26.4.0",
|
|
53
53
|
"@types/react": "^19.2.18",
|
|
54
54
|
"@types/semver": "^7.8.0",
|
|
55
55
|
"@vitest/coverage-v8": "^4.1.11",
|
|
56
56
|
"react": "^19.2.8",
|
|
57
|
-
"typescript": "^6.0.3",
|
|
58
57
|
"tailwindcss": "^4.3.3",
|
|
58
|
+
"typescript": "^6.0.3",
|
|
59
59
|
"vitest": "^4.1.11"
|
|
60
60
|
},
|
|
61
61
|
"engines": {
|
package/release-manifest.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"com.santi020k:lumen-compose",
|
|
7
7
|
"com.santi020k:lumen-compose-wear"
|
|
8
8
|
],
|
|
9
|
-
"version": "
|
|
9
|
+
"version": "2.1.0"
|
|
10
10
|
},
|
|
11
11
|
"npm": {
|
|
12
12
|
"packages": {
|
|
@@ -14,41 +14,41 @@
|
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"astro": ">=5"
|
|
16
16
|
},
|
|
17
|
-
"version": "1.
|
|
17
|
+
"version": "2.1.0"
|
|
18
18
|
},
|
|
19
19
|
"@santi020k/lumen-core": {
|
|
20
20
|
"peerDependencies": {},
|
|
21
|
-
"version": "1.
|
|
21
|
+
"version": "2.1.0"
|
|
22
22
|
},
|
|
23
23
|
"@santi020k/lumen-elements": {
|
|
24
24
|
"peerDependencies": {},
|
|
25
|
-
"version": "1.
|
|
25
|
+
"version": "2.1.0"
|
|
26
26
|
},
|
|
27
27
|
"@santi020k/lumen-icons-brand": {
|
|
28
28
|
"peerDependencies": {},
|
|
29
|
-
"version": "
|
|
29
|
+
"version": "2.0.0"
|
|
30
30
|
},
|
|
31
31
|
"@santi020k/lumen": {
|
|
32
32
|
"peerDependencies": {},
|
|
33
|
-
"version": "1.
|
|
33
|
+
"version": "2.1.0"
|
|
34
34
|
},
|
|
35
35
|
"@santi020k/lumen-mcp": {
|
|
36
36
|
"peerDependencies": {},
|
|
37
|
-
"version": "1.
|
|
37
|
+
"version": "2.1.0"
|
|
38
38
|
},
|
|
39
39
|
"@santi020k/lumen-react": {
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"react": ">=19"
|
|
42
42
|
},
|
|
43
|
-
"version": "1.
|
|
43
|
+
"version": "2.1.0"
|
|
44
44
|
},
|
|
45
45
|
"@santi020k/lumen-react-hook-form": {
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@santi020k/lumen-react": "^
|
|
47
|
+
"@santi020k/lumen-react": "^2.0.0",
|
|
48
48
|
"react": ">=19",
|
|
49
49
|
"react-hook-form": ">=7.76.0 <8"
|
|
50
50
|
},
|
|
51
|
-
"version": "
|
|
51
|
+
"version": "2.0.0"
|
|
52
52
|
},
|
|
53
53
|
"@santi020k/lumen-react-native": {
|
|
54
54
|
"peerDependencies": {
|
|
@@ -57,32 +57,42 @@
|
|
|
57
57
|
"react-native": ">=0.86.2",
|
|
58
58
|
"react-native-svg": ">=12 <16"
|
|
59
59
|
},
|
|
60
|
-
"version": "
|
|
60
|
+
"version": "2.1.0"
|
|
61
61
|
},
|
|
62
62
|
"@santi020k/lumen-tokens": {
|
|
63
63
|
"peerDependencies": {},
|
|
64
|
-
"version": "
|
|
64
|
+
"version": "2.0.0"
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"swift": {
|
|
69
69
|
"package": "https://github.com/santi020k/lumen.git",
|
|
70
70
|
"revision": null,
|
|
71
|
-
"tag": "
|
|
71
|
+
"tag": "v2.1.0"
|
|
72
72
|
},
|
|
73
|
-
"version": "1.
|
|
73
|
+
"version": "2.1.0"
|
|
74
74
|
},
|
|
75
75
|
"migration": {
|
|
76
|
-
"codemod":
|
|
76
|
+
"codemod": "lumen migrate v2 --dry-run",
|
|
77
77
|
"css": {
|
|
78
78
|
"astro": "@santi020k/lumen-astro/styles.css",
|
|
79
79
|
"elements": "@santi020k/lumen-elements/styles.css",
|
|
80
80
|
"react": "@santi020k/lumen-react/styles.css"
|
|
81
81
|
},
|
|
82
82
|
"deprecatedExports": [],
|
|
83
|
-
"removedExports": [
|
|
83
|
+
"removedExports": [
|
|
84
|
+
"@santi020k/lumen-astro#Sonner",
|
|
85
|
+
"@santi020k/lumen-astro#UIPrimitives",
|
|
86
|
+
"@santi020k/lumen-react#Sonner",
|
|
87
|
+
"@santi020k/lumen-react#SonnerProps",
|
|
88
|
+
"@santi020k/lumen-react-native#LumenDateField",
|
|
89
|
+
"@santi020k/lumen-react-native#LumenDateFieldProps",
|
|
90
|
+
"@santi020k/lumen-react-native#LumenDateRangeField",
|
|
91
|
+
"@santi020k/lumen-react-native#LumenDateRangeFieldProps",
|
|
92
|
+
"@santi020k/lumen-react-native#LumenDateRangeValue"
|
|
93
|
+
],
|
|
84
94
|
"runtime": {
|
|
85
|
-
"astro": "
|
|
95
|
+
"astro": "Import UIPrimitives from @santi020k/lumen-astro/runtime and mount it once when an imported component declares the ui-primitives runtime.",
|
|
86
96
|
"elements": "Call defineLumenElements once before rendering lumen-* elements.",
|
|
87
97
|
"react": "Use the public React behavior hooks for behavior-heavy primitives."
|
|
88
98
|
}
|
package/styles.css
CHANGED
|
@@ -1921,6 +1921,17 @@
|
|
|
1921
1921
|
color: hsl(var(--danger));
|
|
1922
1922
|
}
|
|
1923
1923
|
|
|
1924
|
+
.ui-copy-button [data-slot^="copy-"] {
|
|
1925
|
+
display: inline-flex;
|
|
1926
|
+
align-items: center;
|
|
1927
|
+
justify-content: center;
|
|
1928
|
+
gap: inherit;
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
.ui-copy-button [hidden] {
|
|
1932
|
+
display: none;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1924
1935
|
.ui-skeleton {
|
|
1925
1936
|
min-height: 1rem;
|
|
1926
1937
|
border-radius: var(--ui-radius-sm);
|