@santi020k/lumen 0.1.0 → 0.3.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 +29 -0
- package/dist/cli.js +89 -0
- package/dist/consumer-rollout.d.ts +52 -0
- package/dist/consumer-rollout.d.ts.map +1 -0
- package/dist/consumer-rollout.js +397 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/registry-data.d.ts +15 -5
- package/dist/registry-data.d.ts.map +1 -1
- package/dist/registry-data.js +39 -2
- package/dist/token-audit.d.ts +9 -0
- package/dist/token-audit.d.ts.map +1 -0
- package/dist/token-audit.js +25 -0
- package/layers.css +5 -0
- package/package.json +9 -3
- package/styles.css +330 -4
package/README.md
CHANGED
|
@@ -26,8 +26,37 @@ lumen add Button --target elements
|
|
|
26
26
|
lumen add scheduler
|
|
27
27
|
lumen add scheduler --target react
|
|
28
28
|
lumen add scheduler --target elements
|
|
29
|
+
lumen audit-tokens ./src
|
|
29
30
|
```
|
|
30
31
|
|
|
31
32
|
Use `lumen add <component>` for a local Astro wrapper, `--target react` for a React wrapper, or
|
|
32
33
|
`--target elements` for a custom-elements starter. Bundled recipes support the same Astro, React,
|
|
33
34
|
and Elements targets.
|
|
35
|
+
|
|
36
|
+
Run `lumen audit-tokens [path]` before incremental adoption when an existing stylesheet may already
|
|
37
|
+
declare names such as `--surface`, `--ink`, or `--line`. The audit reports complete CSS colors that
|
|
38
|
+
are incompatible with Lumen's HSL-channel token format and exits non-zero when it finds conflicts.
|
|
39
|
+
|
|
40
|
+
## Coordinated consumer rollout
|
|
41
|
+
|
|
42
|
+
Inventory one or more pnpm consumers before a release:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
lumen rollout 0.2.0 ../site ../dashboard --exclude ../legacy
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The report separates manifest, workspace-catalog, and lockfile references; identifies each
|
|
49
|
+
framework; checks the declared pnpm and Node contracts; and reports the complete resolved Lumen
|
|
50
|
+
package graph. Add `--report ./lumen-rollout.json` for a durable JSON record.
|
|
51
|
+
|
|
52
|
+
After committing an intentional baseline in each consumer, apply the upgrade serially:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
lumen rollout 0.2.0 ../site ../dashboard --apply --report ./lumen-rollout.json
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The command preserves `catalog:` indirection and pinned/caret range style, temporarily admits the
|
|
59
|
+
new release through `minimumReleaseAgeExclude`, runs installs through Corepack from each consumer
|
|
60
|
+
root, removes obsolete Lumen release-age exceptions, verifies the unified resolved version, and
|
|
61
|
+
runs available framework checks, builds, and browser scripts. It refuses dirty repositories,
|
|
62
|
+
missing exact pnpm declarations, and unsupported Node runtimes unless `--allow-dirty` is explicit.
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { consumerRolloutSucceeded, formatConsumerRollout, runConsumerRollout } from './consumer-rollout.js';
|
|
1
4
|
import { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, lumenRegistry } from './registry.js';
|
|
5
|
+
import { auditLumenTokenCss } from './token-audit.js';
|
|
2
6
|
const args = process.argv.slice(2);
|
|
3
7
|
const [command = 'help', name] = args;
|
|
4
8
|
const dryRun = args.includes('--dry-run');
|
|
@@ -14,7 +18,36 @@ const registryToken = registryTokenIndex >= 0 ? args[registryTokenIndex + 1] : p
|
|
|
14
18
|
const targetIndex = args.indexOf('--target');
|
|
15
19
|
const targetProvided = targetIndex >= 0;
|
|
16
20
|
const targetValue = targetIndex >= 0 ? args[targetIndex + 1] : undefined;
|
|
21
|
+
const applyRollout = args.includes('--apply');
|
|
22
|
+
const allowDirty = args.includes('--allow-dirty');
|
|
23
|
+
const noVerify = args.includes('--no-verify');
|
|
24
|
+
const reportIndex = args.indexOf('--report');
|
|
25
|
+
const reportPath = reportIndex >= 0 ? args[reportIndex + 1] : undefined;
|
|
26
|
+
const excludeValues = args.flatMap((value, index) => {
|
|
27
|
+
const nextValue = args[index + 1];
|
|
28
|
+
return value === '--exclude' && nextValue ? [nextValue] : [];
|
|
29
|
+
});
|
|
17
30
|
let conflict = 'skip';
|
|
31
|
+
const getRolloutArguments = () => {
|
|
32
|
+
const values = [];
|
|
33
|
+
const optionsWithValues = new Set(['--exclude', '--report']);
|
|
34
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
35
|
+
const value = args[index];
|
|
36
|
+
if (!value)
|
|
37
|
+
continue;
|
|
38
|
+
if (optionsWithValues.has(value)) {
|
|
39
|
+
index += 1;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!value.startsWith('--'))
|
|
43
|
+
values.push(value);
|
|
44
|
+
}
|
|
45
|
+
const [targetVersion, ...repositories] = values;
|
|
46
|
+
return {
|
|
47
|
+
repositories: repositories.length ? repositories : [process.cwd()],
|
|
48
|
+
...(targetVersion ? { targetVersion } : {})
|
|
49
|
+
};
|
|
50
|
+
};
|
|
18
51
|
const getAddTarget = (value, provided = false) => {
|
|
19
52
|
if (provided && !value) {
|
|
20
53
|
throw new Error('Missing Lumen add target. Use astro, react, or elements.');
|
|
@@ -83,6 +116,34 @@ const formatAddResult = async (itemName, registry) => {
|
|
|
83
116
|
...result.skipped.map(file => `- skipped existing ${file}`)
|
|
84
117
|
].join('\n');
|
|
85
118
|
};
|
|
119
|
+
const getCssFiles = async (path) => {
|
|
120
|
+
const details = await stat(path);
|
|
121
|
+
if (details.isFile())
|
|
122
|
+
return path.endsWith('.css') ? [path] : [];
|
|
123
|
+
const entries = await readdir(path, { withFileTypes: true });
|
|
124
|
+
const nested = await Promise.all(entries
|
|
125
|
+
.filter(entry => entry.name !== 'node_modules' && !entry.name.startsWith('.'))
|
|
126
|
+
.map(entry => getCssFiles(resolve(path, entry.name))));
|
|
127
|
+
return nested.flat();
|
|
128
|
+
};
|
|
129
|
+
const formatTokenAudit = async (inputPath) => {
|
|
130
|
+
const target = resolve(inputPath);
|
|
131
|
+
const files = await getCssFiles(target);
|
|
132
|
+
const findings = [];
|
|
133
|
+
for (const file of files) {
|
|
134
|
+
findings.push(...auditLumenTokenCss(await readFile(file, 'utf8'), file));
|
|
135
|
+
}
|
|
136
|
+
if (!findings.length)
|
|
137
|
+
return `No incompatible Lumen semantic token declarations found in ${target}.`;
|
|
138
|
+
process.exitCode = 1;
|
|
139
|
+
return [
|
|
140
|
+
`Found ${findings.length} incompatible Lumen semantic token declaration${findings.length === 1 ? '' : 's'}:`,
|
|
141
|
+
...findings.map(finding => (`${finding.file}:${finding.line}:${finding.column} --${finding.token}: ${finding.value}`)),
|
|
142
|
+
'',
|
|
143
|
+
'Lumen semantic colors must be HSL channels such as "220 13% 96%", not complete colors such as "#fff" or "hsl(...)".',
|
|
144
|
+
'Rename legacy variables during incremental migration or convert their values to channels before importing Lumen.'
|
|
145
|
+
].join('\n');
|
|
146
|
+
};
|
|
86
147
|
const help = [
|
|
87
148
|
'Lumen registry helper',
|
|
88
149
|
'',
|
|
@@ -91,6 +152,8 @@ const help = [
|
|
|
91
152
|
' lumen show <name> Show components and files for an item',
|
|
92
153
|
' lumen add <name> Install a recipe or component into the current project',
|
|
93
154
|
' lumen install Print install commands',
|
|
155
|
+
' lumen audit-tokens Report incompatible semantic color custom properties',
|
|
156
|
+
' lumen rollout [version] [repositories...] Inventory or upgrade pnpm consumers',
|
|
94
157
|
'',
|
|
95
158
|
'Options:',
|
|
96
159
|
' --cwd <path> Target directory for lumen add',
|
|
@@ -101,14 +164,24 @@ const help = [
|
|
|
101
164
|
' --registry <source> Load list/show data from a local or remote registry JSON file',
|
|
102
165
|
' --registry-token <key> Use a bearer token for private remote registries',
|
|
103
166
|
' --target <framework> Generate wrappers or recipe starters for astro, react, or elements',
|
|
167
|
+
' --apply Apply a rollout (requires a target version)',
|
|
168
|
+
' --allow-dirty Allow rollout after recording an uncommitted baseline',
|
|
169
|
+
' --exclude <path> Exclude a repository (repeatable)',
|
|
170
|
+
' --no-verify Skip downstream check, typecheck, build, and browser scripts',
|
|
171
|
+
' --report <path> Write the machine-readable rollout report as JSON',
|
|
104
172
|
''
|
|
105
173
|
].join('\n');
|
|
174
|
+
// eslint-disable-next-line complexity -- Command dispatch keeps CLI exit behavior and output in one place.
|
|
106
175
|
const run = async () => {
|
|
107
176
|
let output = help;
|
|
108
177
|
const registry = registrySource
|
|
109
178
|
? await loadLumenRegistry(registrySource, registryToken ? { token: registryToken } : {})
|
|
110
179
|
: lumenRegistry;
|
|
111
180
|
switch (command) {
|
|
181
|
+
case 'audit-tokens': {
|
|
182
|
+
output = await formatTokenAudit(name ?? cwd ?? process.cwd());
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
112
185
|
case 'add': {
|
|
113
186
|
if (name)
|
|
114
187
|
output = await formatAddResult(name, registry);
|
|
@@ -122,6 +195,22 @@ const run = async () => {
|
|
|
122
195
|
output = formatList(registry);
|
|
123
196
|
break;
|
|
124
197
|
}
|
|
198
|
+
case 'rollout': {
|
|
199
|
+
const rollout = getRolloutArguments();
|
|
200
|
+
const report = await runConsumerRollout({
|
|
201
|
+
allowDirty,
|
|
202
|
+
apply: applyRollout,
|
|
203
|
+
exclude: excludeValues,
|
|
204
|
+
...(reportPath ? { report: reportPath } : {}),
|
|
205
|
+
repositories: rollout.repositories,
|
|
206
|
+
...(rollout.targetVersion ? { targetVersion: rollout.targetVersion } : {}),
|
|
207
|
+
verify: !noVerify
|
|
208
|
+
});
|
|
209
|
+
output = formatConsumerRollout(report);
|
|
210
|
+
if (!consumerRolloutSucceeded(report))
|
|
211
|
+
process.exitCode = 1;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
125
214
|
case 'show': {
|
|
126
215
|
if (name)
|
|
127
216
|
output = formatItem(name, registry);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export type LumenFramework = 'astro' | 'elements' | 'react';
|
|
2
|
+
export interface ConsumerReference {
|
|
3
|
+
file: string;
|
|
4
|
+
packageName: string;
|
|
5
|
+
source: 'catalog' | 'manifest' | 'lockfile';
|
|
6
|
+
version: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ConsumerInventory {
|
|
9
|
+
branch: string | undefined;
|
|
10
|
+
currentCommit: string | undefined;
|
|
11
|
+
dirty: boolean;
|
|
12
|
+
frameworks: LumenFramework[];
|
|
13
|
+
nodeEngine: string | undefined;
|
|
14
|
+
nodeEngineSatisfied: boolean | undefined;
|
|
15
|
+
packageManager: string | undefined;
|
|
16
|
+
references: ConsumerReference[];
|
|
17
|
+
repository: string;
|
|
18
|
+
resolvedVersions: Record<string, string[]>;
|
|
19
|
+
targetVersion?: string;
|
|
20
|
+
valid: boolean;
|
|
21
|
+
warnings: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface ConsumerRolloutOptions {
|
|
24
|
+
allowDirty?: boolean;
|
|
25
|
+
apply?: boolean;
|
|
26
|
+
exclude?: string[];
|
|
27
|
+
report?: string;
|
|
28
|
+
repositories: string[];
|
|
29
|
+
targetVersion?: string;
|
|
30
|
+
verify?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface ConsumerRolloutReport {
|
|
33
|
+
generatedAt: string;
|
|
34
|
+
mode: 'apply' | 'inventory';
|
|
35
|
+
repositories: (ConsumerInventory & {
|
|
36
|
+
commands: {
|
|
37
|
+
command: string;
|
|
38
|
+
ok: boolean;
|
|
39
|
+
output: string;
|
|
40
|
+
}[];
|
|
41
|
+
})[];
|
|
42
|
+
targetVersion?: string;
|
|
43
|
+
}
|
|
44
|
+
export declare const consumerRolloutSucceeded: (report: ConsumerRolloutReport) => boolean;
|
|
45
|
+
export declare const satisfiesNodeEngine: (engine: string | undefined, currentVersion?: string) => boolean | undefined;
|
|
46
|
+
export declare const inspectLumenConsumer: (repository: string, targetVersion?: string) => Promise<ConsumerInventory>;
|
|
47
|
+
export declare const updateLumenManifestSource: (source: string, targetVersion: string) => string;
|
|
48
|
+
export declare const updateLumenWorkspaceSource: (source: string, targetVersion: string) => string;
|
|
49
|
+
export declare const addReleaseAgeTarget: (source: string, packages: string[], version: string) => string;
|
|
50
|
+
export declare const runConsumerRollout: (options: ConsumerRolloutOptions) => Promise<ConsumerRolloutReport>;
|
|
51
|
+
export declare const formatConsumerRollout: (report: ConsumerRolloutReport) => string;
|
|
52
|
+
//# sourceMappingURL=consumer-rollout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consumer-rollout.d.ts","sourceRoot":"","sources":["../src/consumer-rollout.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAA;AAE3D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAA;IAC3C,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,mBAAmB,EAAE,OAAO,GAAG,SAAS,CAAA;IACxC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,OAAO,GAAG,WAAW,CAAA;IAC3B,YAAY,EAAE,CAAC,iBAAiB,GAAG;QACjC,QAAQ,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,OAAO,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC7D,CAAC,EAAE,CAAA;IACJ,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,wBAAwB,GAAI,QAAQ,qBAAqB,KAAG,OAGtE,CAAA;AA8DH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,GAAG,SAAS,EAC1B,uBAAsC,KACrC,OAAO,GAAG,SAIZ,CAAA;AA+DD,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,gBAAgB,MAAM,KACrB,OAAO,CAAC,iBAAiB,CAiG3B,CAAA;AAUD,eAAO,MAAM,yBAAyB,GACpC,QAAQ,MAAM,EACd,eAAe,MAAM,KACpB,MAYF,CAAA;AAED,eAAO,MAAM,0BAA0B,GACrC,QAAQ,MAAM,EACd,eAAe,MAAM,KACpB,MAIF,CAAA;AAuFD,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,EAAE,UAAU,MAAM,EAAE,EAAE,SAAS,MAAM,KAAG,MAoCzF,CAAA;AAqGD,eAAO,MAAM,kBAAkB,GAC7B,SAAS,sBAAsB,KAC9B,OAAO,CAAC,qBAAqB,CAmD/B,CAAA;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,qBAAqB,KAAG,MAyBrE,CAAA"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join, relative, resolve } from 'node:path';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import { satisfies } from 'semver';
|
|
6
|
+
/* eslint-disable complexity -- Consumer inventory, semver checks, mutation, and verification intentionally evaluate full repository contracts. */
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const lumenPackagePattern = /^@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?$/;
|
|
9
|
+
const dependencyFields = [
|
|
10
|
+
'dependencies',
|
|
11
|
+
'devDependencies',
|
|
12
|
+
'optionalDependencies',
|
|
13
|
+
'peerDependencies'
|
|
14
|
+
];
|
|
15
|
+
export const consumerRolloutSucceeded = (report) => report.repositories.every(repository => repository.valid && repository.commands.every(command => command.ok));
|
|
16
|
+
const isLumenPackage = (name) => lumenPackagePattern.test(name);
|
|
17
|
+
const pathExists = async (path) => {
|
|
18
|
+
try {
|
|
19
|
+
await stat(path);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const findPackageManifests = async (root) => {
|
|
27
|
+
const results = [];
|
|
28
|
+
const visit = async (directory) => {
|
|
29
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
30
|
+
for (const entry of entries) {
|
|
31
|
+
if (entry.name === 'node_modules' || entry.name === '.git' || entry.name.startsWith('.turbo'))
|
|
32
|
+
continue;
|
|
33
|
+
const path = join(directory, entry.name);
|
|
34
|
+
if (entry.isDirectory()) {
|
|
35
|
+
await visit(path);
|
|
36
|
+
}
|
|
37
|
+
else if (entry.name === 'package.json') {
|
|
38
|
+
results.push(path);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
await visit(root);
|
|
43
|
+
return results;
|
|
44
|
+
};
|
|
45
|
+
const readManifest = async (path) => JSON.parse(await readFile(path, 'utf8'));
|
|
46
|
+
const readGitValue = async (root, args) => {
|
|
47
|
+
try {
|
|
48
|
+
const { stdout } = await execFileAsync('git', ['-C', root, ...args]);
|
|
49
|
+
return stdout.trim() || undefined;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
export const satisfiesNodeEngine = (engine, currentVersion = process.versions.node) => {
|
|
56
|
+
if (!engine)
|
|
57
|
+
return undefined;
|
|
58
|
+
return satisfies(currentVersion, engine);
|
|
59
|
+
};
|
|
60
|
+
const collectManifestReferences = (manifest, file, root) => dependencyFields.flatMap(field => Object.entries(manifest[field] ?? {})
|
|
61
|
+
.filter(([packageName]) => isLumenPackage(packageName))
|
|
62
|
+
.map(([packageName, version]) => ({
|
|
63
|
+
file: relative(root, file),
|
|
64
|
+
packageName,
|
|
65
|
+
source: 'manifest',
|
|
66
|
+
version
|
|
67
|
+
})));
|
|
68
|
+
const collectYamlReferences = (source, file) => {
|
|
69
|
+
const references = [];
|
|
70
|
+
for (const line of source.split(/\r?\n/)) {
|
|
71
|
+
const match = /^\s*['"]?(@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?)['"]?\s*:\s*['"]?([^'"\s#]+)['"]?/.exec(line);
|
|
72
|
+
if (match?.[1] && match[2]) {
|
|
73
|
+
references.push({ file, packageName: match[1], source: 'catalog', version: match[2] });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return references;
|
|
77
|
+
};
|
|
78
|
+
const collectLockReferences = (source) => {
|
|
79
|
+
const references = [];
|
|
80
|
+
const pattern = /@santi020k\/(lumen(?:-(?:astro|core|elements|mcp|react))?)@(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/g;
|
|
81
|
+
for (const match of source.matchAll(pattern)) {
|
|
82
|
+
if (match[1] && match[2]) {
|
|
83
|
+
references.push({
|
|
84
|
+
file: 'pnpm-lock.yaml',
|
|
85
|
+
packageName: `@santi020k/${match[1]}`,
|
|
86
|
+
source: 'lockfile',
|
|
87
|
+
version: match[2]
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return references;
|
|
92
|
+
};
|
|
93
|
+
const getResolvedVersions = (references) => {
|
|
94
|
+
const graph = {};
|
|
95
|
+
for (const reference of references.filter(item => item.source === 'lockfile')) {
|
|
96
|
+
graph[reference.packageName] ??= new Set();
|
|
97
|
+
graph[reference.packageName]?.add(reference.version);
|
|
98
|
+
}
|
|
99
|
+
return Object.fromEntries(Object.entries(graph).map(([name, versions]) => [name, [...versions].sort()]));
|
|
100
|
+
};
|
|
101
|
+
export const inspectLumenConsumer = async (repository, targetVersion) => {
|
|
102
|
+
const root = resolve(repository);
|
|
103
|
+
const rootManifestPath = join(root, 'package.json');
|
|
104
|
+
if (!await pathExists(rootManifestPath)) {
|
|
105
|
+
throw new Error(`No package.json found at consumer root: ${root}`);
|
|
106
|
+
}
|
|
107
|
+
const manifestPaths = await findPackageManifests(root);
|
|
108
|
+
const manifests = await Promise.all(manifestPaths.map(async (file) => ({
|
|
109
|
+
file,
|
|
110
|
+
manifest: await readManifest(file)
|
|
111
|
+
})));
|
|
112
|
+
const rootManifest = await readManifest(rootManifestPath);
|
|
113
|
+
const references = manifests.flatMap(({ file, manifest }) => collectManifestReferences(manifest, file, root));
|
|
114
|
+
const workspacePath = join(root, 'pnpm-workspace.yaml');
|
|
115
|
+
const lockPath = join(root, 'pnpm-lock.yaml');
|
|
116
|
+
if (await pathExists(workspacePath)) {
|
|
117
|
+
references.push(...collectYamlReferences(await readFile(workspacePath, 'utf8'), 'pnpm-workspace.yaml'));
|
|
118
|
+
}
|
|
119
|
+
if (await pathExists(lockPath)) {
|
|
120
|
+
references.push(...collectLockReferences(await readFile(lockPath, 'utf8')));
|
|
121
|
+
}
|
|
122
|
+
const resolvedVersions = getResolvedVersions(references);
|
|
123
|
+
const frameworks = ([
|
|
124
|
+
references.some(item => item.packageName === '@santi020k/lumen-astro') && 'astro',
|
|
125
|
+
references.some(item => item.packageName === '@santi020k/lumen-elements') && 'elements',
|
|
126
|
+
references.some(item => item.packageName === '@santi020k/lumen-react') && 'react'
|
|
127
|
+
].filter(Boolean));
|
|
128
|
+
const warnings = [];
|
|
129
|
+
const nodeEngineSatisfied = satisfiesNodeEngine(rootManifest.engines?.node);
|
|
130
|
+
const status = await readGitValue(root, ['status', '--porcelain']);
|
|
131
|
+
const dirty = Boolean(status);
|
|
132
|
+
if (!/^pnpm@\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(rootManifest.packageManager ?? '')) {
|
|
133
|
+
warnings.push('Missing an exact pnpm packageManager declaration.');
|
|
134
|
+
}
|
|
135
|
+
if (nodeEngineSatisfied === false) {
|
|
136
|
+
warnings.push(`Current Node ${process.versions.node} does not satisfy ${rootManifest.engines?.node ?? 'the declared engine'}.`);
|
|
137
|
+
}
|
|
138
|
+
if (dirty) {
|
|
139
|
+
warnings.push('Repository has uncommitted changes; create an intentional baseline or use --allow-dirty.');
|
|
140
|
+
}
|
|
141
|
+
if (targetVersion) {
|
|
142
|
+
for (const reference of references.filter(item => item.source !== 'lockfile')) {
|
|
143
|
+
const declaredVersion = reference.version.replace(/^[~^]/, '');
|
|
144
|
+
if (reference.version !== 'catalog:' &&
|
|
145
|
+
!reference.version.startsWith('workspace:') &&
|
|
146
|
+
declaredVersion !== targetVersion) {
|
|
147
|
+
warnings.push(`${reference.packageName} declares ${reference.version} in ${reference.file} instead of ${targetVersion}.`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const [packageName, versions] of Object.entries(resolvedVersions)) {
|
|
151
|
+
if (versions.some(version => version !== targetVersion)) {
|
|
152
|
+
warnings.push(`${packageName} resolves ${versions.join(', ')} instead of only ${targetVersion}.`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
branch: await readGitValue(root, ['branch', '--show-current']),
|
|
158
|
+
currentCommit: await readGitValue(root, ['rev-parse', 'HEAD']),
|
|
159
|
+
dirty,
|
|
160
|
+
frameworks,
|
|
161
|
+
nodeEngine: rootManifest.engines?.node,
|
|
162
|
+
nodeEngineSatisfied,
|
|
163
|
+
packageManager: rootManifest.packageManager,
|
|
164
|
+
references,
|
|
165
|
+
repository: root,
|
|
166
|
+
resolvedVersions,
|
|
167
|
+
...(targetVersion ? { targetVersion } : {}),
|
|
168
|
+
valid: warnings.length === 0,
|
|
169
|
+
warnings
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
const replaceRange = (range, targetVersion) => {
|
|
173
|
+
if (range === 'catalog:' || range.startsWith('workspace:') || range.startsWith('file:'))
|
|
174
|
+
return range;
|
|
175
|
+
const prefix = range.startsWith('^') || range.startsWith('~') ? (range.at(0) ?? '') : '';
|
|
176
|
+
return `${prefix}${targetVersion}`;
|
|
177
|
+
};
|
|
178
|
+
export const updateLumenManifestSource = (source, targetVersion) => {
|
|
179
|
+
const manifest = JSON.parse(source);
|
|
180
|
+
for (const field of dependencyFields) {
|
|
181
|
+
const dependencies = manifest[field];
|
|
182
|
+
for (const [name, range] of Object.entries(dependencies ?? {})) {
|
|
183
|
+
if (isLumenPackage(name) && dependencies)
|
|
184
|
+
dependencies[name] = replaceRange(range, targetVersion);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return `${JSON.stringify(manifest, undefined, 2)}\n`;
|
|
188
|
+
};
|
|
189
|
+
export const updateLumenWorkspaceSource = (source, targetVersion) => source.replaceAll(/^(\s*['"]?@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?['"]?\s*:\s*['"]?)([~^]?)(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)(['"]?\s*(?:#.*)?)$/gm, (_match, before, prefix, _version, after) => `${before}${prefix}${targetVersion}${after}`);
|
|
190
|
+
const getVerificationScripts = (manifest, frameworks) => {
|
|
191
|
+
const scripts = manifest.scripts ?? {};
|
|
192
|
+
const preferred = [
|
|
193
|
+
frameworks.includes('astro') && 'check',
|
|
194
|
+
(frameworks.includes('react') || frameworks.includes('elements')) && 'typecheck',
|
|
195
|
+
'build',
|
|
196
|
+
scripts['test:browser'] && 'test:browser',
|
|
197
|
+
scripts['test:e2e'] && 'test:e2e'
|
|
198
|
+
].filter((script) => Boolean(script && scripts[script]));
|
|
199
|
+
return [...new Set(preferred)];
|
|
200
|
+
};
|
|
201
|
+
const runCommand = async (root, executable, args) => {
|
|
202
|
+
const command = [executable, ...args].join(' ');
|
|
203
|
+
try {
|
|
204
|
+
const { stderr, stdout } = await execFileAsync(executable, args, {
|
|
205
|
+
cwd: root,
|
|
206
|
+
maxBuffer: 10 * 1024 * 1024
|
|
207
|
+
});
|
|
208
|
+
return { command, ok: true, output: `${stdout}${stderr}`.trim() };
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
const detail = error;
|
|
212
|
+
return {
|
|
213
|
+
command,
|
|
214
|
+
ok: false,
|
|
215
|
+
output: `${detail.stdout ?? ''}${detail.stderr ?? ''}`.trim() || detail.message || 'Command failed.'
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const parseFlowSequence = (source) => {
|
|
220
|
+
const match = /^\[([\s\S]*)\]\s*(?:#.*)?$/.exec(source.trim());
|
|
221
|
+
if (!match)
|
|
222
|
+
return undefined;
|
|
223
|
+
const values = [];
|
|
224
|
+
let current = '';
|
|
225
|
+
let quote;
|
|
226
|
+
for (const character of match[1] ?? '') {
|
|
227
|
+
if (quote) {
|
|
228
|
+
current += character;
|
|
229
|
+
if (character === quote)
|
|
230
|
+
quote = undefined;
|
|
231
|
+
}
|
|
232
|
+
else if (character === '"' || character === "'") {
|
|
233
|
+
current += character;
|
|
234
|
+
quote = character;
|
|
235
|
+
}
|
|
236
|
+
else if (character === ',') {
|
|
237
|
+
values.push(current);
|
|
238
|
+
current = '';
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
current += character;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (current.trim())
|
|
245
|
+
values.push(current);
|
|
246
|
+
return values.map(value => {
|
|
247
|
+
const trimmed = value.trim();
|
|
248
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
249
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
250
|
+
return trimmed.slice(1, -1);
|
|
251
|
+
}
|
|
252
|
+
return trimmed;
|
|
253
|
+
}).filter(Boolean);
|
|
254
|
+
};
|
|
255
|
+
export const addReleaseAgeTarget = (source, packages, version) => {
|
|
256
|
+
if (!/^\s*minimumReleaseAgeExclude\s*:/m.test(source))
|
|
257
|
+
return source;
|
|
258
|
+
const lines = source.split(/\r?\n/);
|
|
259
|
+
const index = lines.findIndex(line => /^\s*minimumReleaseAgeExclude\s*:/.test(line));
|
|
260
|
+
const declaration = lines[index] ?? '';
|
|
261
|
+
const rootIndent = /^\s*/.exec(declaration)?.[0] ?? '';
|
|
262
|
+
const indent = `${rootIndent} `;
|
|
263
|
+
const declarationValue = declaration.slice(declaration.indexOf(':') + 1);
|
|
264
|
+
const inlineValues = parseFlowSequence(declarationValue);
|
|
265
|
+
if (declarationValue.trim() && !inlineValues)
|
|
266
|
+
return source;
|
|
267
|
+
const existing = new Set([
|
|
268
|
+
...(inlineValues ?? []),
|
|
269
|
+
...lines.flatMap(line => {
|
|
270
|
+
const value = /^\s*-\s*['"]?([^'"]+)['"]?\s*$/.exec(line)?.[1];
|
|
271
|
+
return value ? [value] : [];
|
|
272
|
+
})
|
|
273
|
+
]);
|
|
274
|
+
const additions = packages
|
|
275
|
+
.map(packageName => `${packageName}@${version}`)
|
|
276
|
+
.filter(value => !existing.has(value))
|
|
277
|
+
.map(value => `${indent}- "${value}"`);
|
|
278
|
+
if (declaration.slice(declaration.indexOf(':') + 1).trim()) {
|
|
279
|
+
lines[index] = `${rootIndent}minimumReleaseAgeExclude:`;
|
|
280
|
+
additions.unshift(...(inlineValues ?? []).map(value => `${indent}- "${value}"`));
|
|
281
|
+
}
|
|
282
|
+
lines.splice(index + 1, 0, ...additions);
|
|
283
|
+
return lines.join('\n');
|
|
284
|
+
};
|
|
285
|
+
const removeObsoleteReleaseAgeEntries = (source, targetVersion) => source.split(/\r?\n/)
|
|
286
|
+
.filter(line => {
|
|
287
|
+
const match = /^\s*-\s*['"]?(@santi020k\/lumen(?:-(?:astro|core|elements|mcp|react))?)@([^'"]+)['"]?\s*$/.exec(line);
|
|
288
|
+
return !match || match[2] === targetVersion;
|
|
289
|
+
})
|
|
290
|
+
.join('\n');
|
|
291
|
+
const upgradeConsumer = async (inventory, targetVersion, allowDirty, verify) => {
|
|
292
|
+
if (inventory.dirty && !allowDirty) {
|
|
293
|
+
throw new Error(`${inventory.repository} is dirty. Commit a baseline or pass --allow-dirty.`);
|
|
294
|
+
}
|
|
295
|
+
if (!/^pnpm@\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(inventory.packageManager ?? '')) {
|
|
296
|
+
throw new Error(`${inventory.repository} must declare an exact pnpm packageManager version.`);
|
|
297
|
+
}
|
|
298
|
+
if (inventory.nodeEngineSatisfied === false) {
|
|
299
|
+
throw new Error(`${inventory.repository} must be upgraded under Node ${inventory.nodeEngine ?? 'matching its engine declaration'}.`);
|
|
300
|
+
}
|
|
301
|
+
const manifestPaths = await findPackageManifests(inventory.repository);
|
|
302
|
+
const desiredManifests = new Map();
|
|
303
|
+
for (const path of manifestPaths) {
|
|
304
|
+
const source = await readFile(path, 'utf8');
|
|
305
|
+
const updated = updateLumenManifestSource(source, targetVersion);
|
|
306
|
+
desiredManifests.set(path, updated);
|
|
307
|
+
if (updated !== source)
|
|
308
|
+
await writeFile(path, updated);
|
|
309
|
+
}
|
|
310
|
+
const workspacePath = join(inventory.repository, 'pnpm-workspace.yaml');
|
|
311
|
+
if (await pathExists(workspacePath)) {
|
|
312
|
+
const source = await readFile(workspacePath, 'utf8');
|
|
313
|
+
const packages = [...new Set(inventory.references.map(item => item.packageName))];
|
|
314
|
+
const updated = addReleaseAgeTarget(updateLumenWorkspaceSource(source, targetVersion), packages, targetVersion);
|
|
315
|
+
if (updated !== source)
|
|
316
|
+
await writeFile(workspacePath, updated);
|
|
317
|
+
}
|
|
318
|
+
const packageNames = [...new Set(inventory.references.map(item => item.packageName))];
|
|
319
|
+
const commands = [await runCommand(inventory.repository, 'corepack', [
|
|
320
|
+
'pnpm',
|
|
321
|
+
'update',
|
|
322
|
+
'--recursive',
|
|
323
|
+
...packageNames.map(packageName => `${packageName}@${targetVersion}`)
|
|
324
|
+
])];
|
|
325
|
+
if (!commands[0]?.ok)
|
|
326
|
+
return commands;
|
|
327
|
+
for (const [path, source] of desiredManifests) {
|
|
328
|
+
await writeFile(path, source);
|
|
329
|
+
}
|
|
330
|
+
commands.push(await runCommand(inventory.repository, 'corepack', ['pnpm', 'install']));
|
|
331
|
+
if (!commands.at(-1)?.ok)
|
|
332
|
+
return commands;
|
|
333
|
+
if (await pathExists(workspacePath)) {
|
|
334
|
+
const source = await readFile(workspacePath, 'utf8');
|
|
335
|
+
const updated = removeObsoleteReleaseAgeEntries(source, targetVersion);
|
|
336
|
+
if (updated !== source) {
|
|
337
|
+
await writeFile(workspacePath, updated);
|
|
338
|
+
commands.push(await runCommand(inventory.repository, 'corepack', ['pnpm', 'install']));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (verify && commands.every(command => command.ok)) {
|
|
342
|
+
const manifest = await readManifest(join(inventory.repository, 'package.json'));
|
|
343
|
+
for (const script of getVerificationScripts(manifest, inventory.frameworks)) {
|
|
344
|
+
const result = await runCommand(inventory.repository, 'corepack', ['pnpm', 'run', script]);
|
|
345
|
+
commands.push(result);
|
|
346
|
+
if (!result.ok)
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return commands;
|
|
351
|
+
};
|
|
352
|
+
export const runConsumerRollout = async (options) => {
|
|
353
|
+
if (options.apply && !options.targetVersion) {
|
|
354
|
+
throw new Error('A target version is required when applying a consumer rollout.');
|
|
355
|
+
}
|
|
356
|
+
const excluded = new Set((options.exclude ?? []).map(path => resolve(path)));
|
|
357
|
+
const repositories = options.repositories.map(path => resolve(path))
|
|
358
|
+
.filter(path => !excluded.has(path));
|
|
359
|
+
const report = {
|
|
360
|
+
generatedAt: new Date().toISOString(),
|
|
361
|
+
mode: options.apply ? 'apply' : 'inventory',
|
|
362
|
+
repositories: [],
|
|
363
|
+
...(options.targetVersion ? { targetVersion: options.targetVersion } : {})
|
|
364
|
+
};
|
|
365
|
+
for (const repository of repositories) {
|
|
366
|
+
const before = await inspectLumenConsumer(repository, options.targetVersion);
|
|
367
|
+
const commands = options.apply
|
|
368
|
+
? await upgradeConsumer(before, options.targetVersion ?? '', options.allowDirty ?? false, options.verify ?? true)
|
|
369
|
+
: [];
|
|
370
|
+
const after = options.apply
|
|
371
|
+
? await inspectLumenConsumer(repository, options.targetVersion)
|
|
372
|
+
: before;
|
|
373
|
+
if (options.apply) {
|
|
374
|
+
after.warnings = after.warnings.filter(warning => !warning.startsWith('Repository has uncommitted changes'));
|
|
375
|
+
after.valid = after.warnings.length === 0;
|
|
376
|
+
}
|
|
377
|
+
report.repositories.push({ ...after, commands });
|
|
378
|
+
if (commands.some(command => !command.ok))
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
if (options.report) {
|
|
382
|
+
await writeFile(resolve(options.report), `${JSON.stringify(report, undefined, 2)}\n`);
|
|
383
|
+
}
|
|
384
|
+
return report;
|
|
385
|
+
};
|
|
386
|
+
export const formatConsumerRollout = (report) => {
|
|
387
|
+
const lines = [
|
|
388
|
+
`Lumen consumer ${report.mode} (${report.repositories.length} repositories)`,
|
|
389
|
+
...(report.targetVersion ? [`Target: ${report.targetVersion}`] : [])
|
|
390
|
+
];
|
|
391
|
+
for (const repository of report.repositories) {
|
|
392
|
+
lines.push('', repository.repository, ` package manager: ${repository.packageManager ?? 'missing'}`, ` node engine: ${repository.nodeEngine ?? 'unspecified'}`, ` frameworks: ${repository.frameworks.join(', ') || 'none'}`, ` resolved graph: ${JSON.stringify(repository.resolvedVersions)}`, ` status: ${repository.valid && repository.commands.every(command => command.ok) ? 'ok' : 'attention required'}`);
|
|
393
|
+
lines.push(...repository.warnings.map(warning => ` warning: ${warning}`));
|
|
394
|
+
lines.push(...repository.commands.map(command => ` ${command.ok ? 'pass' : 'fail'}: ${command.command}`));
|
|
395
|
+
}
|
|
396
|
+
return lines.join('\n');
|
|
397
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { type ConsumerInventory, type ConsumerReference, type ConsumerRolloutOptions, type ConsumerRolloutReport, formatConsumerRollout, inspectLumenConsumer, type LumenFramework, runConsumerRollout, updateLumenManifestSource, updateLumenWorkspaceSource } from './consumer-rollout.js';
|
|
1
2
|
export { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, type LumenAddOptions, type LumenAddResult, type LumenAddTarget, type LumenMergeConflict, type LumenRegistry, lumenRegistry, type LumenRegistryComponent, type LumenRegistryEntry, type LumenRegistryFile, type LumenRegistryItem, type LumenRegistryLoadOptions } from './registry.js';
|
|
2
3
|
export { applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getScheduleConflicts, getVirtualRange, loadDataViewState, loadScheduleEvents, type LumenCodeToken, lumenCodeTokenClassNames, type LumenCodeTokenKind, lumenColors, type LumenColorTokenName, lumenColorTokenNames, type LumenComponentName, lumenComponentNames, type LumenContrastScore, lumenDarkTheme, type LumenDataRecord, type LumenDataViewServerRequest, type LumenDataViewState, lumenGlass, type LumenGlassColorTokenName, lumenGlassColorTokenNames, type LumenGlassEffectTokenName, lumenGlassEffectTokenNames, type LumenGlassTokenName, lumenGlassTokenNames, type LumenKeyValueReader, type LumenKeyValueStorage, type LumenKeyValueWriter, lumenLightTheme, lumenPackages, type LumenPackageTarget, type LumenScheduleConflict, type LumenScheduleEvent, type LumenScheduleKeyValueReader, type LumenScheduleKeyValueStorage, type LumenScheduleKeyValueWriter, type LumenScheduleResizeEdge, type LumenScheduleResizeOptions, type LumenScheduleResource, type LumenScheduleSlot, type LumenSemanticColorTokenName, lumenSemanticColorTokenNames, type LumenSortDirection, lumenThemeAttribute, type LumenThemeBuilderExportFormat, type LumenThemeBuilderMode, type LumenThemeBuilderOptions, type LumenThemeBuilderResult, type LumenThemeBuilderScheme, type LumenThemeContrastSuggestion, type LumenThemeTokens, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, saveDataViewState, saveScheduleEvents, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
|
|
3
4
|
export declare const lumen: {
|
|
@@ -5,4 +6,5 @@ export declare const lumen: {
|
|
|
5
6
|
readonly packageName: "@santi020k/lumen";
|
|
6
7
|
readonly scope: "@santi020k";
|
|
7
8
|
};
|
|
9
|
+
export { auditLumenTokenCss, type LumenTokenAuditFinding } from './token-audit.js';
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,aAAa,EACb,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,8BAA8B,EAC9B,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,cAAc,EACnB,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,WAAW,EACX,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACvB,UAAU,EACV,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,eAAe,EACf,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,EAChC,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,uBAAuB,CAAA;AAE9B,eAAO,MAAM,KAAK;;;;CAIR,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,oBAAoB,EACpB,KAAK,cAAc,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,aAAa,EACb,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,8BAA8B,EAC9B,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,cAAc,EACnB,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,WAAW,EACX,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACvB,UAAU,EACV,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,eAAe,EACf,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,EAChC,4BAA4B,EAC5B,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACjC,KAAK,gBAAgB,EACrB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,uBAAuB,CAAA;AAE9B,eAAO,MAAM,KAAK;;;;CAIR,CAAA;AAEV,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,EAC5B,MAAM,kBAAkB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { formatConsumerRollout, inspectLumenConsumer, runConsumerRollout, updateLumenManifestSource, updateLumenWorkspaceSource } from './consumer-rollout.js';
|
|
1
2
|
export { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, lumenRegistry } from './registry.js';
|
|
2
3
|
export { applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getScheduleConflicts, getVirtualRange, loadDataViewState, loadScheduleEvents, lumenCodeTokenClassNames, lumenColors, lumenColorTokenNames, lumenComponentNames, lumenDarkTheme, lumenGlass, lumenGlassColorTokenNames, lumenGlassEffectTokenNames, lumenGlassTokenNames, lumenLightTheme, lumenPackages, lumenSemanticColorTokenNames, lumenThemeAttribute, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, saveDataViewState, saveScheduleEvents, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
|
|
3
4
|
export const lumen = {
|
|
@@ -5,3 +6,4 @@ export const lumen = {
|
|
|
5
6
|
packageName: '@santi020k/lumen',
|
|
6
7
|
scope: '@santi020k'
|
|
7
8
|
};
|
|
9
|
+
export { auditLumenTokenCss } from './token-audit.js';
|
package/dist/registry-data.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export declare const lumenRegistry: {
|
|
|
39
39
|
readonly components: readonly [{
|
|
40
40
|
readonly name: "Accordion";
|
|
41
41
|
readonly type: "component";
|
|
42
|
-
readonly description: "Stacks collapsible content sections.";
|
|
42
|
+
readonly description: "Stacks collapsible content sections as cards or a compact flush list.";
|
|
43
43
|
readonly category: "Layout";
|
|
44
44
|
readonly files: readonly ["packages/astro/components/Accordion.astro", "packages/astro/styles/lumen.css"];
|
|
45
45
|
readonly dependencies: readonly ["styles"];
|
|
@@ -190,6 +190,13 @@ export declare const lumenRegistry: {
|
|
|
190
190
|
readonly category: "Data display";
|
|
191
191
|
readonly files: readonly ["packages/astro/components/Code.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
192
192
|
readonly dependencies: readonly ["styles", "runtime"];
|
|
193
|
+
}, {
|
|
194
|
+
readonly name: "CodeTabs";
|
|
195
|
+
readonly type: "component";
|
|
196
|
+
readonly description: "Groups related code examples into accessible, persistent tabs.";
|
|
197
|
+
readonly category: "Data display";
|
|
198
|
+
readonly files: readonly ["packages/astro/components/CodeTabs.astro", "packages/astro/components/Code.astro", "packages/astro/components/Tabs.astro", "packages/astro/styles/lumen.css", "packages/astro/runtime/UIPrimitives.astro"];
|
|
199
|
+
readonly dependencies: readonly ["Code", "Tabs", "styles", "runtime"];
|
|
193
200
|
}, {
|
|
194
201
|
readonly name: "Combobox";
|
|
195
202
|
readonly type: "component";
|
|
@@ -697,19 +704,22 @@ export declare const lumenRegistry: {
|
|
|
697
704
|
readonly type: "component";
|
|
698
705
|
readonly category: "Data display";
|
|
699
706
|
readonly description: "Animates a formatted metric while keeping one stable accessible value.";
|
|
700
|
-
readonly files: readonly ["packages/astro/components/AnimatedNumber.astro", "packages/react/src/components.tsx"];
|
|
707
|
+
readonly files: readonly ["packages/astro/components/AnimatedNumber.astro", "packages/astro/runtime/UIPrimitives.astro", "packages/astro/styles/lumen.css", "packages/react/src/components.tsx"];
|
|
708
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
701
709
|
}, {
|
|
702
710
|
readonly name: "RevealGroup";
|
|
703
711
|
readonly type: "component";
|
|
704
712
|
readonly category: "Layout";
|
|
705
713
|
readonly description: "Reveals a group of direct children with tokenized, reduced-motion-aware staggering.";
|
|
706
|
-
readonly files: readonly ["packages/astro/components/RevealGroup.astro", "packages/react/src/components.tsx"];
|
|
714
|
+
readonly files: readonly ["packages/astro/components/RevealGroup.astro", "packages/astro/runtime/UIPrimitives.astro", "packages/astro/styles/lumen.css", "packages/react/src/components.tsx"];
|
|
715
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
707
716
|
}, {
|
|
708
717
|
readonly name: "ScrollReveal";
|
|
709
718
|
readonly type: "component";
|
|
710
719
|
readonly category: "Layout";
|
|
711
|
-
readonly description: "
|
|
712
|
-
readonly files: readonly ["packages/astro/components/ScrollReveal.astro", "packages/react/src/components.tsx"];
|
|
720
|
+
readonly description: "Animates wrapped content as it first enters the viewport.";
|
|
721
|
+
readonly files: readonly ["packages/astro/components/ScrollReveal.astro", "packages/astro/runtime/UIPrimitives.astro", "packages/astro/styles/lumen.css", "packages/react/src/components.tsx"];
|
|
722
|
+
readonly dependencies: readonly ["styles", "runtime"];
|
|
713
723
|
}, {
|
|
714
724
|
readonly name: "Stat";
|
|
715
725
|
readonly type: "component";
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4sDQ,CAAA"}
|
package/dist/registry-data.js
CHANGED
|
@@ -98,7 +98,7 @@ export const lumenRegistry = {
|
|
|
98
98
|
{
|
|
99
99
|
"name": "Accordion",
|
|
100
100
|
"type": "component",
|
|
101
|
-
"description": "Stacks collapsible content sections.",
|
|
101
|
+
"description": "Stacks collapsible content sections as cards or a compact flush list.",
|
|
102
102
|
"category": "Layout",
|
|
103
103
|
"files": [
|
|
104
104
|
"packages/astro/components/Accordion.astro",
|
|
@@ -393,6 +393,25 @@ export const lumenRegistry = {
|
|
|
393
393
|
"runtime"
|
|
394
394
|
]
|
|
395
395
|
},
|
|
396
|
+
{
|
|
397
|
+
"name": "CodeTabs",
|
|
398
|
+
"type": "component",
|
|
399
|
+
"description": "Groups related code examples into accessible, persistent tabs.",
|
|
400
|
+
"category": "Data display",
|
|
401
|
+
"files": [
|
|
402
|
+
"packages/astro/components/CodeTabs.astro",
|
|
403
|
+
"packages/astro/components/Code.astro",
|
|
404
|
+
"packages/astro/components/Tabs.astro",
|
|
405
|
+
"packages/astro/styles/lumen.css",
|
|
406
|
+
"packages/astro/runtime/UIPrimitives.astro"
|
|
407
|
+
],
|
|
408
|
+
"dependencies": [
|
|
409
|
+
"Code",
|
|
410
|
+
"Tabs",
|
|
411
|
+
"styles",
|
|
412
|
+
"runtime"
|
|
413
|
+
]
|
|
414
|
+
},
|
|
396
415
|
{
|
|
397
416
|
"name": "Combobox",
|
|
398
417
|
"type": "component",
|
|
@@ -1417,7 +1436,13 @@ export const lumenRegistry = {
|
|
|
1417
1436
|
"description": "Animates a formatted metric while keeping one stable accessible value.",
|
|
1418
1437
|
"files": [
|
|
1419
1438
|
"packages/astro/components/AnimatedNumber.astro",
|
|
1439
|
+
"packages/astro/runtime/UIPrimitives.astro",
|
|
1440
|
+
"packages/astro/styles/lumen.css",
|
|
1420
1441
|
"packages/react/src/components.tsx"
|
|
1442
|
+
],
|
|
1443
|
+
"dependencies": [
|
|
1444
|
+
"styles",
|
|
1445
|
+
"runtime"
|
|
1421
1446
|
]
|
|
1422
1447
|
},
|
|
1423
1448
|
{
|
|
@@ -1427,17 +1452,29 @@ export const lumenRegistry = {
|
|
|
1427
1452
|
"description": "Reveals a group of direct children with tokenized, reduced-motion-aware staggering.",
|
|
1428
1453
|
"files": [
|
|
1429
1454
|
"packages/astro/components/RevealGroup.astro",
|
|
1455
|
+
"packages/astro/runtime/UIPrimitives.astro",
|
|
1456
|
+
"packages/astro/styles/lumen.css",
|
|
1430
1457
|
"packages/react/src/components.tsx"
|
|
1458
|
+
],
|
|
1459
|
+
"dependencies": [
|
|
1460
|
+
"styles",
|
|
1461
|
+
"runtime"
|
|
1431
1462
|
]
|
|
1432
1463
|
},
|
|
1433
1464
|
{
|
|
1434
1465
|
"name": "ScrollReveal",
|
|
1435
1466
|
"type": "component",
|
|
1436
1467
|
"category": "Layout",
|
|
1437
|
-
"description": "
|
|
1468
|
+
"description": "Animates wrapped content as it first enters the viewport.",
|
|
1438
1469
|
"files": [
|
|
1439
1470
|
"packages/astro/components/ScrollReveal.astro",
|
|
1471
|
+
"packages/astro/runtime/UIPrimitives.astro",
|
|
1472
|
+
"packages/astro/styles/lumen.css",
|
|
1440
1473
|
"packages/react/src/components.tsx"
|
|
1474
|
+
],
|
|
1475
|
+
"dependencies": [
|
|
1476
|
+
"styles",
|
|
1477
|
+
"runtime"
|
|
1441
1478
|
]
|
|
1442
1479
|
},
|
|
1443
1480
|
{
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface LumenTokenAuditFinding {
|
|
2
|
+
column: number;
|
|
3
|
+
file: string;
|
|
4
|
+
line: number;
|
|
5
|
+
token: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const auditLumenTokenCss: (source: string, file?: string) => LumenTokenAuditFinding[];
|
|
9
|
+
//# sourceMappingURL=token-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-audit.d.ts","sourceRoot":"","sources":["../src/token-audit.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,EAAE,aAAgB,KAAG,sBAAsB,EAwB3F,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { lumenSemanticColorTokenNames } from '@santi020k/lumen-core';
|
|
2
|
+
const declarationPattern = /--([a-z][\w-]*)\s*:\s*([^;}\n]+)/giu;
|
|
3
|
+
const channelPattern = /^(?:var\(.+\)|-?(?:\d+(?:\.\d+)?|\.\d+)(?:deg|grad|rad|turn)?\s+-?(?:\d+(?:\.\d+)?|\.\d+)%\s+-?(?:\d+(?:\.\d+)?|\.\d+)%(?:\s*\/\s*(?:\d+(?:\.\d+)?|\.\d+)%?)?)$/iu;
|
|
4
|
+
const semanticTokens = new Set(lumenSemanticColorTokenNames);
|
|
5
|
+
export const auditLumenTokenCss = (source, file = '<input>') => {
|
|
6
|
+
const findings = [];
|
|
7
|
+
for (const match of source.matchAll(declarationPattern)) {
|
|
8
|
+
const token = match[1];
|
|
9
|
+
const value = match[2]?.trim();
|
|
10
|
+
if (!token || !value || !semanticTokens.has(token) || channelPattern.test(value))
|
|
11
|
+
continue;
|
|
12
|
+
const index = match.index;
|
|
13
|
+
const before = source.slice(0, index);
|
|
14
|
+
const line = before.split('\n').length;
|
|
15
|
+
const lineStart = before.lastIndexOf('\n') + 1;
|
|
16
|
+
findings.push({
|
|
17
|
+
column: index - lineStart + 1,
|
|
18
|
+
file,
|
|
19
|
+
line,
|
|
20
|
+
token,
|
|
21
|
+
value
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return findings;
|
|
25
|
+
};
|
package/layers.css
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Import before Tailwind and Lumen so Tailwind base styles run before Lumen components while
|
|
3
|
+
* Tailwind utilities remain able to override component presentation.
|
|
4
|
+
*/
|
|
5
|
+
@layer theme, base, lumen.tokens, lumen.base, components, lumen.components, lumen.glass, utilities;
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@santi020k/lumen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"description": "Umbrella package for the Lumen multi-framework primitive UI system.",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"sideEffects": [
|
|
10
|
+
"./layers.css",
|
|
10
11
|
"./styles.css"
|
|
11
12
|
],
|
|
12
13
|
"main": "./dist/index.js",
|
|
@@ -22,11 +23,13 @@
|
|
|
22
23
|
"import": "./dist/registry.js"
|
|
23
24
|
},
|
|
24
25
|
"./styles.css": "./styles.css",
|
|
26
|
+
"./layers.css": "./layers.css",
|
|
25
27
|
"./package.json": "./package.json"
|
|
26
28
|
},
|
|
27
29
|
"files": [
|
|
28
30
|
"bin",
|
|
29
31
|
"dist",
|
|
32
|
+
"layers.css",
|
|
30
33
|
"styles.css",
|
|
31
34
|
"README.md",
|
|
32
35
|
"LICENSE"
|
|
@@ -35,16 +38,19 @@
|
|
|
35
38
|
"lumen": "./bin/lumen.mjs"
|
|
36
39
|
},
|
|
37
40
|
"dependencies": {
|
|
38
|
-
"
|
|
41
|
+
"semver": "^7.8.0",
|
|
42
|
+
"@santi020k/lumen-core": "^0.3.0"
|
|
39
43
|
},
|
|
40
44
|
"devDependencies": {
|
|
41
45
|
"@types/node": "^26.1.1",
|
|
46
|
+
"@types/semver": "^7.7.1",
|
|
42
47
|
"@vitest/coverage-v8": "^4.1.10",
|
|
43
48
|
"typescript": "^6.0.3",
|
|
49
|
+
"tailwindcss": "^4.3.3",
|
|
44
50
|
"vitest": "^4.1.10"
|
|
45
51
|
},
|
|
46
52
|
"engines": {
|
|
47
|
-
"node": ">=22.
|
|
53
|
+
"node": ">=22.12.0"
|
|
48
54
|
},
|
|
49
55
|
"repository": {
|
|
50
56
|
"type": "git",
|
package/styles.css
CHANGED
|
@@ -264,7 +264,7 @@
|
|
|
264
264
|
font-family: var(--ui-font);
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
:where(.ui-button, .ui-back-to-top, .ui-code__copy, .ui-input, .ui-language-toggle, .ui-link, .ui-select, .ui-skip-link, .ui-textarea, .ui-checkbox, .ui-switch, .ui-toggle, .ui-slider, .ui-color-picker, .ui-resizable__handle):focus-visible {
|
|
267
|
+
:where(.ui-button, .ui-back-to-top, .ui-code__copy, .ui-input, .ui-language-toggle, .ui-link, .ui-select, .ui-skip-link, .ui-textarea, .ui-checkbox, .ui-switch, .ui-toggle, .ui-theme-toggle, .ui-slider, .ui-color-picker, .ui-resizable__handle):focus-visible {
|
|
268
268
|
outline: 2px solid hsl(var(--brand));
|
|
269
269
|
outline-offset: 2px;
|
|
270
270
|
}
|
|
@@ -623,6 +623,11 @@
|
|
|
623
623
|
background: hsl(var(--surface-muted) / 0.72);
|
|
624
624
|
}
|
|
625
625
|
|
|
626
|
+
.ui-card--unstyled,
|
|
627
|
+
.ui-button-link--unstyled {
|
|
628
|
+
all: revert-layer;
|
|
629
|
+
}
|
|
630
|
+
|
|
626
631
|
.ui-card--glass.ui-card--interactive:hover,
|
|
627
632
|
.ui-card--glass.card-interactive:hover {
|
|
628
633
|
border-color: hsl(var(--glass-edge));
|
|
@@ -881,6 +886,15 @@
|
|
|
881
886
|
color: hsl(var(--brand-solid));
|
|
882
887
|
}
|
|
883
888
|
|
|
889
|
+
.ui-link--inherit {
|
|
890
|
+
color: inherit;
|
|
891
|
+
font-weight: inherit;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.ui-link--inherit:hover {
|
|
895
|
+
color: inherit;
|
|
896
|
+
}
|
|
897
|
+
|
|
884
898
|
.ui-prose {
|
|
885
899
|
max-width: 65ch;
|
|
886
900
|
color: hsl(var(--ink-soft));
|
|
@@ -1702,31 +1716,184 @@
|
|
|
1702
1716
|
|
|
1703
1717
|
.ui-accordion {
|
|
1704
1718
|
display: grid;
|
|
1705
|
-
gap: 0.
|
|
1719
|
+
gap: 0.75rem;
|
|
1706
1720
|
}
|
|
1707
1721
|
|
|
1708
1722
|
.ui-accordion details,
|
|
1709
1723
|
.ui-collapsible {
|
|
1724
|
+
overflow: clip;
|
|
1710
1725
|
border: 1px solid hsl(var(--line));
|
|
1711
|
-
border-radius: var(--ui-radius);
|
|
1726
|
+
border-radius: var(--ui-radius-lg);
|
|
1712
1727
|
background: hsl(var(--surface));
|
|
1713
1728
|
color: hsl(var(--ink-soft));
|
|
1714
|
-
|
|
1729
|
+
box-shadow: var(--ui-shadow-sm);
|
|
1730
|
+
transition:
|
|
1731
|
+
border-color var(--ui-duration-fast) var(--ui-ease),
|
|
1732
|
+
box-shadow var(--ui-duration-fast) var(--ui-ease);
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
.ui-accordion details[open],
|
|
1736
|
+
.ui-collapsible[open] {
|
|
1737
|
+
border-color: hsl(var(--brand) / 0.38);
|
|
1738
|
+
box-shadow:
|
|
1739
|
+
0 0 0 1px hsl(var(--brand) / 0.08),
|
|
1740
|
+
var(--ui-shadow-sm);
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
.ui-accordion--flush {
|
|
1744
|
+
gap: 0;
|
|
1745
|
+
border-top: 1px solid hsl(var(--line));
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
.ui-accordion--flush details {
|
|
1749
|
+
overflow: visible;
|
|
1750
|
+
border: 0;
|
|
1751
|
+
border-bottom: 1px solid hsl(var(--line));
|
|
1752
|
+
border-radius: 0;
|
|
1753
|
+
background: transparent;
|
|
1754
|
+
box-shadow: none;
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
.ui-accordion--flush details[open] {
|
|
1758
|
+
border-color: hsl(var(--line));
|
|
1759
|
+
background: transparent;
|
|
1760
|
+
box-shadow: none;
|
|
1715
1761
|
}
|
|
1716
1762
|
|
|
1717
1763
|
.ui-accordion summary,
|
|
1718
1764
|
.ui-collapsible summary {
|
|
1765
|
+
display: grid;
|
|
1766
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
1767
|
+
align-items: center;
|
|
1768
|
+
gap: 1rem;
|
|
1719
1769
|
cursor: pointer;
|
|
1770
|
+
list-style: none;
|
|
1720
1771
|
color: hsl(var(--ink));
|
|
1721
1772
|
font-weight: 650;
|
|
1773
|
+
line-height: 1.35;
|
|
1774
|
+
min-height: 3.5rem;
|
|
1775
|
+
padding: 1rem 1.125rem;
|
|
1776
|
+
transition:
|
|
1777
|
+
background-color var(--ui-duration-fast) var(--ui-ease),
|
|
1778
|
+
color var(--ui-duration-fast) var(--ui-ease);
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
.ui-accordion summary:hover,
|
|
1782
|
+
.ui-collapsible summary:hover {
|
|
1783
|
+
background: hsl(var(--surface-muted));
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
.ui-accordion details[open] > summary,
|
|
1787
|
+
.ui-collapsible[open] > summary {
|
|
1788
|
+
color: hsl(var(--brand));
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
.ui-accordion details[open],
|
|
1792
|
+
.ui-collapsible[open] {
|
|
1793
|
+
padding-block-end: 1rem;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
.ui-accordion details > :not(summary),
|
|
1797
|
+
.ui-collapsible > :not(summary) {
|
|
1798
|
+
margin-inline: 1.125rem;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
.ui-accordion summary::-webkit-details-marker,
|
|
1802
|
+
.ui-collapsible summary::-webkit-details-marker {
|
|
1803
|
+
display: none;
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
.ui-accordion summary::after,
|
|
1807
|
+
.ui-collapsible summary::after {
|
|
1808
|
+
width: 0.5rem;
|
|
1809
|
+
height: 0.5rem;
|
|
1810
|
+
border-right: 1.5px solid hsl(var(--ink-muted));
|
|
1811
|
+
border-bottom: 1.5px solid hsl(var(--ink-muted));
|
|
1812
|
+
content: "";
|
|
1813
|
+
border-radius: 1px;
|
|
1814
|
+
box-shadow: 0 0 0 0.45rem hsl(var(--surface-muted));
|
|
1815
|
+
transform: rotate(45deg) translate(-0.1rem, -0.1rem);
|
|
1816
|
+
transition:
|
|
1817
|
+
border-color var(--ui-duration-fast) var(--ui-ease),
|
|
1818
|
+
box-shadow var(--ui-duration-fast) var(--ui-ease),
|
|
1819
|
+
transform var(--ui-duration-fast) var(--ui-ease);
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
.ui-accordion details[open] > summary::after,
|
|
1823
|
+
.ui-collapsible[open] > summary::after {
|
|
1824
|
+
border-color: hsl(var(--brand));
|
|
1825
|
+
box-shadow: 0 0 0 0.45rem hsl(var(--brand-soft));
|
|
1826
|
+
transform: rotate(225deg) translate(-0.1rem, -0.1rem);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
.ui-accordion summary:hover::after,
|
|
1830
|
+
.ui-collapsible summary:hover::after {
|
|
1831
|
+
border-color: hsl(var(--brand));
|
|
1832
|
+
box-shadow: 0 0 0 0.45rem hsl(var(--brand-soft));
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
.ui-accordion summary:focus-visible,
|
|
1836
|
+
.ui-collapsible summary:focus-visible {
|
|
1837
|
+
border-radius: calc(var(--ui-radius-lg) - 1px);
|
|
1838
|
+
outline: 2px solid hsl(var(--brand));
|
|
1839
|
+
outline-offset: -3px;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
.ui-accordion--flush details[open] {
|
|
1843
|
+
padding-block-end: 1.25rem;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
.ui-accordion--flush summary {
|
|
1847
|
+
min-height: 4rem;
|
|
1848
|
+
padding: 1.125rem 0.25rem;
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
.ui-accordion--flush summary:hover {
|
|
1852
|
+
border-radius: var(--ui-radius);
|
|
1853
|
+
background: hsl(var(--surface-muted) / 0.72);
|
|
1854
|
+
box-shadow: 0 0 0 0.625rem hsl(var(--surface-muted) / 0.72);
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
.ui-accordion--flush details[open] > summary {
|
|
1858
|
+
color: hsl(var(--ink));
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
.ui-accordion--flush details > :not(summary) {
|
|
1862
|
+
margin-inline: 0.25rem;
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
.ui-accordion--flush details[open] > summary::before {
|
|
1866
|
+
width: 0.2rem;
|
|
1867
|
+
height: 1.25rem;
|
|
1868
|
+
border-radius: 999px;
|
|
1869
|
+
background: hsl(var(--brand));
|
|
1870
|
+
content: "";
|
|
1871
|
+
position: absolute;
|
|
1872
|
+
inset-inline-start: -0.875rem;
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
.ui-accordion--flush summary {
|
|
1876
|
+
position: relative;
|
|
1722
1877
|
}
|
|
1723
1878
|
|
|
1724
1879
|
.ui-accordion p,
|
|
1725
1880
|
.ui-collapsible p {
|
|
1881
|
+
color: hsl(var(--ink-soft));
|
|
1726
1882
|
margin-block-end: 0;
|
|
1727
1883
|
line-height: 1.6;
|
|
1728
1884
|
}
|
|
1729
1885
|
|
|
1886
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1887
|
+
.ui-accordion details,
|
|
1888
|
+
.ui-collapsible,
|
|
1889
|
+
.ui-accordion summary,
|
|
1890
|
+
.ui-collapsible summary,
|
|
1891
|
+
.ui-accordion summary::after,
|
|
1892
|
+
.ui-collapsible summary::after {
|
|
1893
|
+
transition: none;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1730
1897
|
.ui-dialog,
|
|
1731
1898
|
.ui-alert-dialog,
|
|
1732
1899
|
.ui-drawer,
|
|
@@ -1752,6 +1919,19 @@
|
|
|
1752
1919
|
transform: translate(-50%, -50%);
|
|
1753
1920
|
}
|
|
1754
1921
|
|
|
1922
|
+
.ui-dialog--fullscreen {
|
|
1923
|
+
inset: 0;
|
|
1924
|
+
width: 100%;
|
|
1925
|
+
max-width: none;
|
|
1926
|
+
height: 100dvh;
|
|
1927
|
+
max-height: none;
|
|
1928
|
+
margin: 0;
|
|
1929
|
+
border: 0;
|
|
1930
|
+
border-radius: 0;
|
|
1931
|
+
padding: 0;
|
|
1932
|
+
transform: none;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1755
1935
|
.ui-dialog::backdrop,
|
|
1756
1936
|
.ui-alert-dialog::backdrop,
|
|
1757
1937
|
.ui-drawer::backdrop,
|
|
@@ -1944,6 +2124,19 @@
|
|
|
1944
2124
|
color: hsl(var(--ink));
|
|
1945
2125
|
}
|
|
1946
2126
|
|
|
2127
|
+
.ui-navigation-menu--unstyled {
|
|
2128
|
+
all: revert-layer;
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
.ui-navigation-menu--unstyled :where(a, button) {
|
|
2132
|
+
all: revert-layer;
|
|
2133
|
+
}
|
|
2134
|
+
|
|
2135
|
+
.ui-navigation-menu--unstyled :where(a, button):hover,
|
|
2136
|
+
.ui-navigation-menu--unstyled :where(a, button)[aria-current="page"] {
|
|
2137
|
+
all: revert-layer;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
1947
2140
|
.ui-breadcrumb {
|
|
1948
2141
|
color: hsl(var(--ink-muted));
|
|
1949
2142
|
font-size: 0.875rem;
|
|
@@ -2100,6 +2293,96 @@
|
|
|
2100
2293
|
color: hsl(var(--ink-soft));
|
|
2101
2294
|
}
|
|
2102
2295
|
|
|
2296
|
+
.ui-code-tabs {
|
|
2297
|
+
display: block;
|
|
2298
|
+
overflow: hidden;
|
|
2299
|
+
border: 1px solid hsl(var(--line));
|
|
2300
|
+
border-radius: var(--ui-radius-lg);
|
|
2301
|
+
background: hsl(var(--surface-muted));
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
.ui-code-tabs .ui-code-tabs__list {
|
|
2305
|
+
display: flex;
|
|
2306
|
+
width: auto;
|
|
2307
|
+
gap: 0.25rem;
|
|
2308
|
+
border: 0;
|
|
2309
|
+
border-bottom: 1px solid hsl(var(--line));
|
|
2310
|
+
border-radius: 0;
|
|
2311
|
+
background: hsl(var(--surface));
|
|
2312
|
+
padding: 0.375rem;
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
.ui-code-tabs .ui-code-tabs__tab {
|
|
2316
|
+
min-width: 4.25rem;
|
|
2317
|
+
border: 0;
|
|
2318
|
+
border-radius: var(--ui-radius-sm);
|
|
2319
|
+
background: transparent;
|
|
2320
|
+
color: hsl(var(--ink-muted));
|
|
2321
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
|
2322
|
+
font-size: 0.8125rem;
|
|
2323
|
+
font-weight: 500;
|
|
2324
|
+
padding: 0.5rem 0.875rem;
|
|
2325
|
+
transition:
|
|
2326
|
+
background-color 150ms ease,
|
|
2327
|
+
color 150ms ease;
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
.ui-code-tabs .ui-code-tabs__tab:hover {
|
|
2331
|
+
background: hsl(var(--surface-muted));
|
|
2332
|
+
color: hsl(var(--ink));
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
.ui-code-tabs .ui-code-tabs__tab[aria-selected="true"] {
|
|
2336
|
+
background: hsl(var(--brand-soft));
|
|
2337
|
+
box-shadow: none;
|
|
2338
|
+
color: hsl(var(--brand));
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
.ui-code-tabs .ui-code-tabs__tab:focus-visible {
|
|
2342
|
+
outline: 2px solid hsl(var(--brand));
|
|
2343
|
+
outline-offset: 1px;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
.ui-code-tabs .ui-code-tabs__panel {
|
|
2347
|
+
color: hsl(var(--ink));
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
.ui-code-tabs .ui-code--block {
|
|
2351
|
+
margin: 0;
|
|
2352
|
+
border: 0;
|
|
2353
|
+
border-radius: 0;
|
|
2354
|
+
background: transparent;
|
|
2355
|
+
box-shadow: none;
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
.ui-code-tabs .ui-code__header {
|
|
2359
|
+
position: absolute;
|
|
2360
|
+
z-index: 1;
|
|
2361
|
+
inset-block-start: 0.75rem;
|
|
2362
|
+
inset-inline-end: 0.75rem;
|
|
2363
|
+
display: block;
|
|
2364
|
+
min-height: 0;
|
|
2365
|
+
border: 0;
|
|
2366
|
+
background: transparent;
|
|
2367
|
+
padding: 0;
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
.ui-code-tabs .ui-code__dots,
|
|
2371
|
+
.ui-code-tabs .ui-code__meta {
|
|
2372
|
+
display: none;
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
.ui-code-tabs .ui-code--block :where(pre) {
|
|
2376
|
+
min-height: 3.5rem;
|
|
2377
|
+
padding: 1rem 3.75rem 1rem 1.25rem;
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2381
|
+
.ui-code-tabs .ui-code-tabs__tab {
|
|
2382
|
+
transition: none;
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2103
2386
|
.ui-table-wrap,
|
|
2104
2387
|
.ui-data-table {
|
|
2105
2388
|
width: 100%;
|
|
@@ -2314,6 +2597,16 @@
|
|
|
2314
2597
|
color: hsl(var(--brand-solid));
|
|
2315
2598
|
}
|
|
2316
2599
|
|
|
2600
|
+
.ui-sidebar--unstyled {
|
|
2601
|
+
all: revert-layer;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
.ui-sidebar--unstyled a,
|
|
2605
|
+
.ui-sidebar--unstyled a:hover,
|
|
2606
|
+
.ui-sidebar--unstyled a[aria-current="page"] {
|
|
2607
|
+
all: revert-layer;
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2317
2610
|
.ui-empty {
|
|
2318
2611
|
display: grid;
|
|
2319
2612
|
place-items: center;
|
|
@@ -2452,6 +2745,9 @@
|
|
|
2452
2745
|
.ui-code--block {
|
|
2453
2746
|
position: relative;
|
|
2454
2747
|
overflow: hidden;
|
|
2748
|
+
width: 100%;
|
|
2749
|
+
max-width: 100%;
|
|
2750
|
+
min-width: 0;
|
|
2455
2751
|
margin: 0;
|
|
2456
2752
|
border: 1px solid var(--ui-code-border);
|
|
2457
2753
|
border-radius: var(--ui-radius-lg);
|
|
@@ -2601,6 +2897,16 @@
|
|
|
2601
2897
|
white-space: pre;
|
|
2602
2898
|
}
|
|
2603
2899
|
|
|
2900
|
+
.ui-code--wrap :where(pre) {
|
|
2901
|
+
overflow-x: hidden;
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
.ui-code--wrap :where(code) {
|
|
2905
|
+
min-width: 0;
|
|
2906
|
+
overflow-wrap: anywhere;
|
|
2907
|
+
white-space: pre-wrap;
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2604
2910
|
.ui-code--block :where(code span) {
|
|
2605
2911
|
color: var(--shiki-light, var(--ui-code-token, var(--ui-code-fg)));
|
|
2606
2912
|
font-style: var(--shiki-light-font-style, var(--ui-code-token-font-style, normal));
|
|
@@ -4009,6 +4315,16 @@
|
|
|
4009
4315
|
}
|
|
4010
4316
|
}
|
|
4011
4317
|
|
|
4318
|
+
.ui-dialog--fullscreen:not([open]) {
|
|
4319
|
+
transform: none;
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
@starting-style {
|
|
4323
|
+
.ui-dialog--fullscreen[open] {
|
|
4324
|
+
transform: none;
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4012
4328
|
.ui-drawer {
|
|
4013
4329
|
transition:
|
|
4014
4330
|
opacity var(--ui-duration) var(--ui-ease),
|
|
@@ -4584,6 +4900,16 @@
|
|
|
4584
4900
|
font-variant-numeric: tabular-nums;
|
|
4585
4901
|
}
|
|
4586
4902
|
|
|
4903
|
+
a.ui-pill {
|
|
4904
|
+
cursor: pointer;
|
|
4905
|
+
text-decoration: none;
|
|
4906
|
+
}
|
|
4907
|
+
|
|
4908
|
+
a.ui-pill:hover {
|
|
4909
|
+
border-color: hsl(var(--brand) / 0.42);
|
|
4910
|
+
color: hsl(var(--brand-solid));
|
|
4911
|
+
}
|
|
4912
|
+
|
|
4587
4913
|
/* CoverImage hover lift + bottom gradient overlay */
|
|
4588
4914
|
.ui-cover-image--hover {
|
|
4589
4915
|
transition: transform 300ms ease;
|