22 * External dependencies
33 */
44import type { Plugin , TokenNormalized } from '@terrazzo/parser' ;
5+ import { kebabCase } from '@terrazzo/token-tools' ;
56import { transformCSSValue } from '@terrazzo/token-tools/css' ;
67import {
78 parse ,
@@ -16,80 +17,36 @@ import {
1617 */
1718import '../../src/color-ramps/lib/register-color-spaces' ;
1819import { FORMAT_JSON_ID } from './lib' ;
20+ import { publicTokenId } from '../../src/token-id' ;
1921
20- const TONES = new Set ( [
21- 'neutral' ,
22- 'brand' ,
23- 'success' ,
24- 'info' ,
25- 'warning' ,
26- 'caution' ,
27- 'error' ,
28- ] ) ;
29-
30- function titleCase ( str : string ) {
31- return str [ 0 ] . toUpperCase ( ) + str . slice ( 1 ) ;
32- }
33-
34- function kebabToCamel ( str : string ) {
35- return str . replace ( / - ( [ a - z ] ) / g, ( _ , letter ) => letter . toUpperCase ( ) ) ;
36- }
37-
38- function transformTokenName ( { id } : { id : string } ) {
39- return (
40- id
41- // Capitalize first segment
42- . replace ( / ^ ( \w + ) \. / g, ( _ , g1 ) => `${ titleCase ( g1 ) } /` )
43- // Capitalize
44- . replace ( / s e m a n t i c \. / g, '' )
45- // Transform tokens:
46- // - Add extra folder matching top-level grouping
47- // - Prefix property name with top-level grouping
48- // - Shift color tones to extra folder
49- // - Keep last part of the token name with dots (eg no folders)
50- . replace (
51- / ( D i m e n s i o n | C o l o r ) \/ ( \w + ) \. ( \w + ) \. ( .* ) / g,
52- ( _ , prefix , property , target , modifier ) => {
53- let extraFolder = '' ;
54- let propertyName = property + '-' + target ;
55-
56- switch ( property ) {
57- case 'bg' :
58- extraFolder = 'Background/' ;
59- break ;
60- case 'fg' :
61- extraFolder = 'Foreground/' ;
62- break ;
63- case 'stroke' :
64- extraFolder = 'Stroke/' ;
65- break ;
66- case 'padding' :
67- extraFolder = 'Padding/' ;
68- propertyName = 'pad-' + target ;
69- break ;
70- }
71-
72- const [ tone , ...remaining ] = modifier . split ( '.' ) ;
73- if ( tone && TONES . has ( tone ) ) {
74- extraFolder = extraFolder + titleCase ( tone ) + '/' ;
75- modifier = remaining . join ( '.' ) ;
76- }
77-
78- return `${ prefix } /${ extraFolder } ${ kebabToCamel (
79- propertyName
80- ) } .${ modifier } `;
81- }
82- )
83- // Remove default emphasis and state variants from variable name
84- . replace ( / n o r m a l \. / g, '' )
85- . replace ( / r e s t i n g / g, '' )
86- // Remove double dots
87- . replace ( / \. { 2 , } / g, '.' )
88- // Remove trailing dot
89- . replace ( / \. $ / g, '' )
90- // Replace remaining dots with dashes
91- . replace ( / \. / g, '-' )
92- ) ;
22+ /**
23+ * Transforms a token ID to a Figma variable name including folders.
24+ *
25+ * Token IDs are transformed to match the CSS variable naming convention
26+ * (`--wpds-<type>-<property>-<target>[-<modifier>]`) but using `/` as
27+ * folder separators for the first 3 segments (type, property, target),
28+ * with remaining segments joined by dashes.
29+ *
30+ * Examples:
31+ * - `color.bg.surface.info.weak` → `wpds-color/bg/surface/info-weak`
32+ * - `dimension.padding.surface.sm` → `wpds-dimension/padding/surface/sm`
33+ * - `font.lineHeight.small` → `wpds-font/line-height/small`
34+ *
35+ * @param options Options object.
36+ * @param options.id The token ID to transform.
37+ * @return The transformed token name.
38+ */
39+ function transformTokenName ( { id } : { id : string } ) : string {
40+ const [ type , property , target , ...modifiers ] =
41+ publicTokenId ( id ) . split ( '.' ) ;
42+
43+ return [
44+ `wpds-${ type } /${ kebabCase ( property ) } ` ,
45+ target && kebabCase ( target ) ,
46+ modifiers . map ( kebabCase ) . join ( '-' ) ,
47+ ]
48+ . filter ( Boolean )
49+ . join ( '/' ) ;
9350}
9451
9552function transformColorToken (
0 commit comments