@@ -41,13 +41,35 @@ const SPACING_LAYOUT_MAP = {
4141 96 : '150' , 128 : '200' ,
4242} ;
4343
44- // Helper: build regex that matches class names with word boundaries
45- // Sorted by descending key length to avoid partial matches (d-h1024 before d-h102)
44+ // Border-radius: legacy pixel value → new radius token stop
45+ // MUST STAY IN SYNC with RADIUS_STOPS in dialtone-css/postcss/constants.cjs.
46+ const RADIUS_MAP = {
47+ 0 : '0' , 1 : '100' , 2 : '200' , 4 : '300' , 6 : '350' ,
48+ 8 : '400' , 12 : '450' , 16 : '500' , 24 : '550' , 32 : '600' ,
49+ } ;
50+
51+ // Border-radius: legacy physical-side prefix → new logical prefix.
52+ const RADIUS_PAIR_PREFIX_MAP = {
53+ btr : 'bbsr' , // top → block-start pair
54+ bbr : 'bber' , // bottom → block-end pair
55+ blr : 'bisr' , // left → inline-start pair
56+ brr : 'bier' , // right → inline-end pair
57+ } ;
58+
59+ // Class-name boundary: preceded by space, quote, or start; followed by space, quote, or end.
60+ const CLASS_BOUNDARY_LEFT = `((?:^|["'\\s]))` ;
61+ const CLASS_BOUNDARY_RIGHT = `((?:["'\\s]|$))` ;
62+
63+ // Build regex that matches class names ending in any key from `map`, with boundaries.
64+ // Keys sorted by descending length to avoid partial matches (d-h1024 before d-h102).
4665function buildClassRegex ( prefix , map ) {
4766 const keys = Object . keys ( map ) . sort ( ( a , b ) => b . length - a . length || Number ( b ) - Number ( a ) ) ;
48- const pattern = keys . join ( '|' ) ;
49- // Match class name boundary: preceded by space, quote, or start; followed by space, quote, or end
50- return new RegExp ( `((?:^|["'\\s]))${ prefix } (${ pattern } )((?:["'\\s]|$))` , 'gm' ) ;
67+ return new RegExp ( `${ CLASS_BOUNDARY_LEFT } ${ prefix } (${ keys . join ( '|' ) } )${ CLASS_BOUNDARY_RIGHT } ` , 'gm' ) ;
68+ }
69+
70+ // Variant for fixed-keyword suffixes (e.g. `-pill`, `-circle`).
71+ function buildKeywordClassRegex ( prefix , keyword ) {
72+ return new RegExp ( `${ CLASS_BOUNDARY_LEFT } ${ prefix } -${ keyword } ${ CLASS_BOUNDARY_RIGHT } ` , 'gm' ) ;
5173}
5274
5375export default {
@@ -59,10 +81,42 @@ export default {
5981 '- Padding: d-p8 → d-p-100, d-pt16 → d-pt-200\n' +
6082 '- Gap: d-g8 → d-g-100, d-rg16 → d-rg-200\n' +
6183 '- Position: d-t8 → d-t-100, d-tn8 → d-t-n100\n' +
84+ '- Border-radius all: d-bar6 → d-bar-350, d-bar24 → d-bar-550\n' +
85+ '- Border-radius pair (physical → logical): d-btr6 → d-bbsr-350, d-bbr8 → d-bber-400, d-blr12 → d-bisr-450, d-brr16 → d-bier-500\n' +
86+ '- Border-radius pair keyword: d-btr-pill → d-bbsr-pill, d-brr-circle → d-bier-circle\n' +
6287 '- Old deprecated sizes (d-h72, d-w332, etc.) are left unchanged for manual review.\n' ,
63- patterns : [ '**/*.{vue,html,js,ts,jsx,tsx,md,less,css}' ] ,
88+ patterns : [ '**/*.{vue,html,js,ts,jsx,tsx,md,mdx, less,css}' ] ,
6489 globbyConfig : {
65- ignore : [ '**/dialtone_migration_helper/tests/**' , '**/node_modules/**' ] ,
90+ // Include dotfiles/dotdirs so tooling directories like `.vuepress/baseComponents/`,
91+ // `.storybook/`, and per-repo docs folders are scanned. Dotted build-output caches are
92+ // explicitly excluded below.
93+ dot : true ,
94+ ignore : [
95+ '**/node_modules/**' ,
96+ // `dot: true` makes dot-dirs globbable; explicitly exclude the git directory.
97+ '**/.git/**' ,
98+ // Built outputs: regenerated on next build; rewriting selectors in co-selected rules
99+ // (`.d-bar-350, .d-bar6 { ... }`) would corrupt them since the leading whitespace
100+ // before the legacy selector looks like a class boundary to the regex.
101+ '**/dist/**' ,
102+ '**/build/**' ,
103+ '**/lib/dist/**' ,
104+ // Framework caches
105+ '**/.cache/**' ,
106+ '**/.vite/**' ,
107+ '**/.vuepress/.cache/**' ,
108+ '**/.vuepress/.temp/**' ,
109+ '**/.vuepress/dist/**' ,
110+ '**/.next/**' ,
111+ '**/.nuxt/**' ,
112+ '**/.turbo/**' ,
113+ '**/.nx/**' ,
114+ // Migration-helper test fixtures intentionally contain legacy class names.
115+ '**/dialtone_migration_helper/tests/**' ,
116+ // ESLint-plugin rules and tests inherently contain legacy class names as regex patterns
117+ // and test inputs — they're the tool that detects the legacy classes, don't rewrite them.
118+ '**/eslint-plugin-dialtone/**' ,
119+ ] ,
66120 } ,
67121 expressions : [
68122 // ── Sizing: d-h{px} → d-h-{layout-stop} ──────────────────────────────
@@ -135,5 +189,27 @@ export default {
135189 from : buildClassRegex ( `d-${ prefix } n` , NEGATIVE_SPACING_MAP ) ,
136190 to : ( match , pre , px , post ) => `${ pre } d-${ prefix } -n${ NEGATIVE_SPACING_MAP [ px ] } ${ post } ` ,
137191 } ) ) ,
192+
193+ // ── Border-radius all-corners numeric: d-bar{px} → d-bar-{stop} ──────
194+ {
195+ from : buildClassRegex ( 'd-bar' , RADIUS_MAP ) ,
196+ to : ( match , pre , px , post ) => `${ pre } d-bar-${ RADIUS_MAP [ px ] } ${ post } ` ,
197+ } ,
198+
199+ // ── Border-radius side-pair numeric: d-{legacy}{px} → d-{logical}-{stop}
200+ // Physical pair prefixes (btr/bbr/blr/brr) rewrite to their logical siblings (bbsr/bber/bisr/bier).
201+ ...Object . entries ( RADIUS_PAIR_PREFIX_MAP ) . map ( ( [ legacy , logical ] ) => ( {
202+ from : buildClassRegex ( `d-${ legacy } ` , RADIUS_MAP ) ,
203+ to : ( match , pre , px , post ) => `${ pre } d-${ logical } -${ RADIUS_MAP [ px ] } ${ post } ` ,
204+ } ) ) ,
205+
206+ // ── Border-radius side-pair keyword: d-{legacy}-{pill|circle} → d-{logical}-{pill|circle}
207+ // Legacy `.d-bar-pill` / `.d-bar-circle` stay as-is (same name in the new scheme).
208+ ...Object . entries ( RADIUS_PAIR_PREFIX_MAP ) . flatMap ( ( [ legacy , logical ] ) =>
209+ [ 'pill' , 'circle' ] . map ( keyword => ( {
210+ from : buildKeywordClassRegex ( `d-${ legacy } ` , keyword ) ,
211+ to : ( match , pre , post ) => `${ pre } d-${ logical } -${ keyword } ${ post } ` ,
212+ } ) ) ,
213+ ) ,
138214 ] ,
139215} ;
0 commit comments