11---
2+ import { readFileSync } from ' node:fs' ;
3+ import { fileURLToPath } from ' node:url' ;
4+ import { dirname , join } from ' node:path' ;
5+
26interface ReferenceItem {
37 class: string ;
4- styles: string | string [] | Record <string , string >;
8+ styles? : string | string [] | Record <string , string >;
9+ description? : string ;
10+ comment? : string ; // Optional manual comment to append
511 [key : string ]: any ; // Allow additional properties
612}
713
@@ -22,6 +28,68 @@ const {
2228// Use explicit reference prop or data prop
2329const referenceData = reference || data || [];
2430
31+ // Parse CSS variables from _root.scss at build time
32+ function parseCSSVariables(): Record <string , string > {
33+ try {
34+ const __filename = fileURLToPath (import .meta .url );
35+ const __dirname = dirname (__filename );
36+ const rootScssPath = join (__dirname , ' ../../../scss/_root.scss' );
37+ const scssContent = readFileSync (rootScssPath , ' utf-8' );
38+
39+ const cssVarValues: Record <string , string > = {};
40+
41+ // Match CSS variable declarations: --#{$prefix}variable-name: value;
42+ // This regex captures the variable name and its value
43+ const varRegex = / --#\{\$ prefix\} ([a-z0-9 -] + ):\s * ([^ ;] + );/ gi ;
44+ let match;
45+
46+ while ((match = varRegex .exec (scssContent )) !== null ) {
47+ const varName = ` --bs-${match [1 ]} ` ;
48+ let value = match [2 ].trim ();
49+
50+ // Clean up SCSS interpolation syntax (e.g., #{$variable})
51+ value = value .replace (/ #\{ [^ }] + \} / g , ' ' ).trim ();
52+
53+ // Remove inline comments
54+ value = value .replace (/ \/\/ . * $ / gm , ' ' ).trim ();
55+
56+ // Only store if we have a clean value (not empty after removing interpolations)
57+ if (value ) {
58+ cssVarValues [varName ] = value ;
59+ }
60+ }
61+
62+ return cssVarValues ;
63+ } catch (error ) {
64+ console .warn (' Could not parse CSS variables from _root.scss:' , error );
65+ return {};
66+ }
67+ }
68+
69+ const cssVarValues = parseCSSVariables ();
70+
71+ // Function to add CSS variable value comments
72+ function addVarComments(cssValue : string ): string {
73+ const comments: string [] = [];
74+
75+ // Collect resolved values for all CSS variables
76+ cssValue .replace (/ var\( (--[a-z0-9 -] + )\) / gi , (match , varName ) => {
77+ const resolvedValue = cssVarValues [varName ];
78+ if (resolvedValue ) {
79+ comments .push (` <span class="color-3">/* ${resolvedValue } */</span> ` );
80+ }
81+ return match ;
82+ });
83+
84+ // Append comments after the last semicolon or at the end
85+ if (comments .length > 0 ) {
86+ const hasSemicolon = cssValue .trimEnd ().endsWith (' ;' );
87+ return ` ${cssValue }${hasSemicolon ? ' ' : ' ;' } ${comments .join (' ' )} ` ;
88+ }
89+
90+ return cssValue ;
91+ }
92+
2593// If no explicit columns provided, infer from the first data item
2694const inferredColumns = columns || (() => {
2795 if (referenceData .length === 0 ) {
@@ -32,10 +100,12 @@ const inferredColumns = columns || (() => {
32100 }
33101
34102 const firstItem = referenceData [0 ];
35- return Object .keys (firstItem ).map (key => ({
36- label: key .charAt (0 ).toUpperCase () + key .slice (1 ), // Capitalize first letter
37- key: key
38- }));
103+ return Object .keys (firstItem )
104+ .filter (key => key !== ' comment' ) // Exclude comment field from columns
105+ .map (key => ({
106+ label: key .charAt (0 ).toUpperCase () + key .slice (1 ),
107+ key: key
108+ }));
39109})();
40110
41111// Transform frontmatter format to table format
@@ -51,26 +121,40 @@ const tableData = referenceData.map((item: ReferenceItem) => {
51121 }
52122
53123 if (key === ' styles' ) {
124+ let processedStyles = ' ' ;
125+
54126 if (typeof value === ' string' ) {
55- transformedItem [ key ] = value ;
127+ processedStyles = addVarComments ( value ) ;
56128 } else if (typeof value === ' object' && ! Array .isArray (value )) {
57129 // Handle object syntax: { prop: value, prop2: value2 }
58- transformedItem [key ] = Object .entries (value )
59- .map (([prop , val ]) => ` ${prop }: ${val }; ` )
130+ processedStyles = Object .entries (value )
131+ .map (([prop , val ]) => {
132+ const cssLine = ` ${prop }: ${val }; ` ;
133+ return addVarComments (cssLine );
134+ })
60135 .join (' <br/>' );
61136 } else if (Array .isArray (value )) {
62- transformedItem [ key ] = value .map ((style : any ) => {
137+ processedStyles = value .map ((style : any ) => {
63138 if (typeof style === ' string' ) {
64- return style .includes (' :' ) ? style + (style .endsWith (' ;' ) ? ' ' : ' ;' ) : style ;
139+ const formattedStyle = style .includes (' :' ) ? style + (style .endsWith (' ;' ) ? ' ' : ' ;' ) : style ;
140+ return addVarComments (formattedStyle );
65141 }
66142 if (typeof style === ' object' ) {
67- return Object .entries (style ).map (([prop , val ]) => ` ${prop }: ${val }; ` ).join (' ' );
143+ const cssLine = Object .entries (style ).map (([prop , val ]) => ` ${prop }: ${val }; ` ).join (' ' );
144+ return addVarComments (cssLine );
68145 }
69146 return style ;
70147 }).join (' <br/>' );
71148 } else {
72- transformedItem [ key ] = value || ' ' ;
149+ processedStyles = value || ' ' ;
73150 }
151+
152+ // Append manual comment if provided in frontmatter
153+ if (item .comment ) {
154+ processedStyles += ` <br/><span class="color-3">/* ${item .comment } */</span> ` ;
155+ }
156+
157+ transformedItem [key ] = processedStyles ;
74158 } else {
75159 transformedItem [key ] = value ;
76160 }
0 commit comments