@nexub/tokens 8.3.0 → 8.4.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/bin/nexub-migrate.mjs +39 -1
- package/package.json +1 -1
package/bin/nexub-migrate.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import path from 'node:path';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { parseArgs } from 'node:util';
|
|
8
8
|
|
|
9
|
-
export const RULES = ['legacy-tokens', 'logical-classes', 'tw-animate', 'opacity-modifier', 'deprecated-components', 'tailwind-3-preset', 'keep-5-defaults', 'removed-in-7', 'changes-in-8'];
|
|
9
|
+
export const RULES = ['legacy-tokens', 'logical-classes', 'tw-animate', 'opacity-modifier', 'deprecated-components', 'tailwind-3-preset', 'keep-5-defaults', 'removed-in-7', 'changes-in-8', 'button-aliases'];
|
|
10
10
|
// Run only when asked for by --rules: they keep old behaviour instead of moving code forward.
|
|
11
11
|
const OPT_IN = new Set(['keep-5-defaults']);
|
|
12
12
|
export const DEFAULT_RULES = RULES.filter((r) => !OPT_IN.has(r));
|
|
@@ -450,6 +450,36 @@ function changesIn8(src, ext, report) {
|
|
|
450
450
|
if (themes && !/data-style/.test(src)) report(themes.index, SIGNATURE_NOTE);
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
+
// ─── button-aliases: Button's legacy variant names (deprecated 8.4, removed 9.0) ─
|
|
454
|
+
export const BUTTON_ALIASES = { primary: 'filled', secondary: 'tonal', outline: 'outlined', ghost: 'text' };
|
|
455
|
+
const ALIAS_RE = Object.keys(BUTTON_ALIASES).join('|');
|
|
456
|
+
|
|
457
|
+
function buttonAliases(src) {
|
|
458
|
+
const edits = [];
|
|
459
|
+
const items = [];
|
|
460
|
+
const report = (at, message) => items.push({ line: src.slice(0, at).split('\n').length, rule: 'button-aliases', message });
|
|
461
|
+
const locals = [];
|
|
462
|
+
for (const m of src.matchAll(/\bimport\s+\{([^}]*)\}\s*from\s*(['"])@nexub\/react(?:\/\w+)?\2/g))
|
|
463
|
+
for (const [, name, alias] of m[1].matchAll(/\b(\w+)(?:\s+as\s+(\w+))?/g)) if (name === 'Button') locals.push(alias ?? name);
|
|
464
|
+
for (const local of locals) {
|
|
465
|
+
for (const m of src.matchAll(new RegExp(`<${local}(?![\\w.$-])`, 'g'))) {
|
|
466
|
+
const variant = readTag(src, m.index + m[0].length)?.attrs.find((a) => a.name === 'variant');
|
|
467
|
+
if (!variant?.value) continue;
|
|
468
|
+
const lit = /^(?:\{\s*)?(["'])(\w+)\1(?:\s*\})?$/.exec(variant.value);
|
|
469
|
+
if (lit && BUTTON_ALIASES[lit[2]]) edits.push({ start: variant.end - variant.value.length, end: variant.end, text: `"${BUTTON_ALIASES[lit[2]]}"` });
|
|
470
|
+
else if (!lit && new RegExp(`['"](${ALIAS_RE})['"]`).test(variant.value)) report(m.index, `<${local} variant={…}> may pass a legacy alias (removed in 9.0): use ${Object.entries(BUTTON_ALIASES).map(([a, b]) => `${a} -> ${b}`).join(', ')}`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// buttonVariants({ variant: 'primary' }) for links styled as buttons.
|
|
474
|
+
for (const m of src.matchAll(new RegExp(`\\bbuttonVariants\\(\\{[^}]*?\\bvariant:\\s*(['"])(${ALIAS_RE})\\1`, 'g'))) {
|
|
475
|
+
const at = m.index + m[0].length - m[2].length - 1;
|
|
476
|
+
edits.push({ start: at, end: at + m[2].length, text: BUTTON_ALIASES[m[2]] });
|
|
477
|
+
}
|
|
478
|
+
let output = src;
|
|
479
|
+
for (const e of edits.sort((a, b) => b.start - a.start)) output = output.slice(0, e.start) + e.text + output.slice(e.end);
|
|
480
|
+
return { output, items };
|
|
481
|
+
}
|
|
482
|
+
|
|
453
483
|
// ─── per-file migration ──────────────────────────────────────────────────────
|
|
454
484
|
/**
|
|
455
485
|
* Migrate one file's text. Returns { output, manual: [{ line, rule, message }] }.
|
|
@@ -481,6 +511,11 @@ export function migrateSource(src, { ext, rules = new Set(DEFAULT_RULES), fix =
|
|
|
481
511
|
text = r.output;
|
|
482
512
|
items.push(...r.items);
|
|
483
513
|
}
|
|
514
|
+
if (rules.has('button-aliases') && COMPONENT_EXTS.has(ext) && /@nexub\/react['"/]/.test(text)) {
|
|
515
|
+
const r = buttonAliases(text);
|
|
516
|
+
text = r.output;
|
|
517
|
+
items.push(...r.items);
|
|
518
|
+
}
|
|
484
519
|
if (rules.has('keep-5-defaults') && COMPONENT_EXTS.has(ext) && /@nexub\/react['"/]/.test(text)) {
|
|
485
520
|
const r = pinDefaults(text);
|
|
486
521
|
text = r.output;
|
|
@@ -571,6 +606,9 @@ Rules:
|
|
|
571
606
|
changes-in-8 report what 8.0 removes and flips: legacy --duration-*/--ease-* tokens,
|
|
572
607
|
the Motion easing prop, the default scrollLock (becomes "class"),
|
|
573
608
|
non-strict safeHref and custom-scheme links, and the Signature look
|
|
609
|
+
button-aliases Button's legacy variants (deprecated 8.4, removed 9.0): primary -> filled,
|
|
610
|
+
secondary -> tonal, outline -> outlined, ghost -> text (JSX literals and
|
|
611
|
+
buttonVariants({ variant })); variant={expressions} reported
|
|
574
612
|
|
|
575
613
|
Ignored: node_modules, dist, build, .next, out, coverage, files over 1 MB.
|
|
576
614
|
Exit codes: 0 ok, 1 --check found something, 2 usage error.`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexub/tokens",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.4.0",
|
|
4
4
|
"description": "Design tokens for Nexub Design System — colours, typography, spacing, radii, shadows, and motion as CSS variables, a Tailwind 4 theme, Figma variables and native (React Native, SwiftUI, Compose) tokens.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|