Spaces:
Runtime error
Runtime error
fix: Figma plugin SemiBold crash + robust font cascade
Browse filesVisual Spec:
- Remove ALL custom font loading from visual spec generator
- Typography section now uses only Inter Regular/Bold (always available)
- Font details (family, size, weight) shown as text labels instead
- Eliminates "Inter SemiBold could not be loaded" crash entirely
Create Styles:
- 3-level font cascade: exact match β same family Regular β Inter Regular
- Each level has its own try/catch β never crashes on missing font styles
- fontWeight "600" β "SemiBold" lookup still works but gracefully degrades
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
output_json/figma-plugin-extracted/figma-design-token-creator 5/src/code.js
CHANGED
|
@@ -562,14 +562,35 @@ figma.ui.onmessage = async function(msg) {
|
|
| 562 |
var lineHeight = value.lineHeight;
|
| 563 |
var fontStyle = getFontStyleFromWeight(fontWeight);
|
| 564 |
|
| 565 |
-
// Load and set font
|
|
|
|
|
|
|
| 566 |
try {
|
| 567 |
await figma.loadFontAsync({ family: fontFamily, style: fontStyle });
|
| 568 |
textStyle.fontName = { family: fontFamily, style: fontStyle };
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
}
|
| 574 |
|
| 575 |
textStyle.fontSize = fontSize;
|
|
@@ -866,6 +887,9 @@ figma.ui.onmessage = async function(msg) {
|
|
| 866 |
}
|
| 867 |
|
| 868 |
// === TYPOGRAPHY SECTION ===
|
|
|
|
|
|
|
|
|
|
| 869 |
if (tokens.typography.length > 0) {
|
| 870 |
var typoTitle = figma.createText();
|
| 871 |
typoTitle.characters = 'TYPOGRAPHY';
|
|
@@ -886,36 +910,28 @@ figma.ui.onmessage = async function(msg) {
|
|
| 886 |
}
|
| 887 |
var fontSize = parseNumericValue(value.fontSize) || 16;
|
| 888 |
var fontWeight = value.fontWeight || '400';
|
| 889 |
-
var
|
| 890 |
-
|
| 891 |
-
// Try to load the font
|
| 892 |
-
try {
|
| 893 |
-
await figma.loadFontAsync({ family: fontFamily, style: fontStyle });
|
| 894 |
-
} catch (e) {
|
| 895 |
-
fontFamily = 'Inter';
|
| 896 |
-
fontStyle = 'Regular';
|
| 897 |
-
}
|
| 898 |
|
| 899 |
-
// Sample text
|
| 900 |
var sampleText = figma.createText();
|
|
|
|
|
|
|
| 901 |
sampleText.characters = typoToken.name.split('/').pop() || 'Sample Text';
|
| 902 |
-
sampleText.fontName = { family: fontFamily, style: fontStyle };
|
| 903 |
-
sampleText.fontSize = Math.min(fontSize, 48); // Cap at 48 for display
|
| 904 |
sampleText.x = xOffset;
|
| 905 |
sampleText.y = yOffset;
|
| 906 |
specPage.appendChild(sampleText);
|
| 907 |
|
| 908 |
-
// Specs label
|
| 909 |
var specsLabel = figma.createText();
|
| 910 |
-
specsLabel.characters = fontSize + 'px / ' + fontWeight + ' / ' + fontFamily;
|
| 911 |
specsLabel.fontName = { family: 'Inter', style: 'Regular' };
|
| 912 |
specsLabel.fontSize = 11;
|
|
|
|
| 913 |
specsLabel.fills = [{ type: 'SOLID', color: { r: 0.5, g: 0.5, b: 0.5 } }];
|
| 914 |
specsLabel.x = xOffset + 300;
|
| 915 |
specsLabel.y = yOffset + 4;
|
| 916 |
specPage.appendChild(specsLabel);
|
| 917 |
|
| 918 |
-
yOffset += Math.max(
|
| 919 |
}
|
| 920 |
|
| 921 |
yOffset += sectionGap;
|
|
|
|
| 562 |
var lineHeight = value.lineHeight;
|
| 563 |
var fontStyle = getFontStyleFromWeight(fontWeight);
|
| 564 |
|
| 565 |
+
// Load and set font β cascade: exact match β same family Regular β Inter Regular
|
| 566 |
+
var fontLoaded = false;
|
| 567 |
+
// Try 1: exact family + weight style (e.g. "Open Sans" + "SemiBold")
|
| 568 |
try {
|
| 569 |
await figma.loadFontAsync({ family: fontFamily, style: fontStyle });
|
| 570 |
textStyle.fontName = { family: fontFamily, style: fontStyle };
|
| 571 |
+
fontLoaded = true;
|
| 572 |
+
} catch (e1) {
|
| 573 |
+
console.warn('Font ' + fontFamily + ' ' + fontStyle + ' not available');
|
| 574 |
+
}
|
| 575 |
+
// Try 2: same family + Regular
|
| 576 |
+
if (!fontLoaded && fontStyle !== 'Regular') {
|
| 577 |
+
try {
|
| 578 |
+
await figma.loadFontAsync({ family: fontFamily, style: 'Regular' });
|
| 579 |
+
textStyle.fontName = { family: fontFamily, style: 'Regular' };
|
| 580 |
+
fontLoaded = true;
|
| 581 |
+
} catch (e2) {
|
| 582 |
+
console.warn('Font ' + fontFamily + ' Regular not available either');
|
| 583 |
+
}
|
| 584 |
+
}
|
| 585 |
+
// Try 3: Inter Regular (always available in Figma)
|
| 586 |
+
if (!fontLoaded) {
|
| 587 |
+
try {
|
| 588 |
+
await figma.loadFontAsync({ family: 'Inter', style: 'Regular' });
|
| 589 |
+
textStyle.fontName = { family: 'Inter', style: 'Regular' };
|
| 590 |
+
} catch (e3) {
|
| 591 |
+
console.warn('Even Inter Regular failed β skipping style');
|
| 592 |
+
continue;
|
| 593 |
+
}
|
| 594 |
}
|
| 595 |
|
| 596 |
textStyle.fontSize = fontSize;
|
|
|
|
| 887 |
}
|
| 888 |
|
| 889 |
// === TYPOGRAPHY SECTION ===
|
| 890 |
+
// IMPORTANT: Only use already-loaded Inter Regular/Bold for ALL text in the spec.
|
| 891 |
+
// Never attempt to load custom fonts β they may not exist in the Figma environment
|
| 892 |
+
// and would crash the entire spec generation. Font details are shown as labels.
|
| 893 |
if (tokens.typography.length > 0) {
|
| 894 |
var typoTitle = figma.createText();
|
| 895 |
typoTitle.characters = 'TYPOGRAPHY';
|
|
|
|
| 910 |
}
|
| 911 |
var fontSize = parseNumericValue(value.fontSize) || 16;
|
| 912 |
var fontWeight = value.fontWeight || '400';
|
| 913 |
+
var displaySize = Math.min(fontSize, 48); // Cap display size
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 914 |
|
| 915 |
+
// Sample text β always use Inter (safe), size shows relative scale
|
| 916 |
var sampleText = figma.createText();
|
| 917 |
+
sampleText.fontName = { family: 'Inter', style: headingStyle };
|
| 918 |
+
sampleText.fontSize = displaySize;
|
| 919 |
sampleText.characters = typoToken.name.split('/').pop() || 'Sample Text';
|
|
|
|
|
|
|
| 920 |
sampleText.x = xOffset;
|
| 921 |
sampleText.y = yOffset;
|
| 922 |
specPage.appendChild(sampleText);
|
| 923 |
|
| 924 |
+
// Specs label β show the ACTUAL font specs as readable text
|
| 925 |
var specsLabel = figma.createText();
|
|
|
|
| 926 |
specsLabel.fontName = { family: 'Inter', style: 'Regular' };
|
| 927 |
specsLabel.fontSize = 11;
|
| 928 |
+
specsLabel.characters = fontFamily + ' Β· ' + fontSize + 'px Β· wt ' + fontWeight;
|
| 929 |
specsLabel.fills = [{ type: 'SOLID', color: { r: 0.5, g: 0.5, b: 0.5 } }];
|
| 930 |
specsLabel.x = xOffset + 300;
|
| 931 |
specsLabel.y = yOffset + 4;
|
| 932 |
specPage.appendChild(specsLabel);
|
| 933 |
|
| 934 |
+
yOffset += Math.max(displaySize, 24) + itemGap;
|
| 935 |
}
|
| 936 |
|
| 937 |
yOffset += sectionGap;
|