mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 05:33:02 -05:00
✨ List out fonts not in Penpot's default list (#20)
Help users avoid a confusing import experience by warning of any fonts that will need to be added to Penpot since they aren't in the default gfont set. Signed-off-by: Ryan Breen <rbreen@zmags.com> Co-authored-by: Ryan Breen <rbreen@zmags.com>
This commit is contained in:
parent
14036905af
commit
70ffc7bb77
4 changed files with 1516 additions and 9 deletions
|
@ -5,7 +5,6 @@
|
|||
"description": "Penpot exporter",
|
||||
"main": "code.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "webpack",
|
||||
"watch": "webpack watch"
|
||||
},
|
||||
|
@ -31,7 +30,7 @@
|
|||
"crypto": "^1.0.1",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dev-utils": "^11.0.4",
|
||||
"react-dev-utils": "^12.0.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"slugify": "^1.6.5"
|
||||
}
|
||||
|
|
1434
src/gfonts.json
Normal file
1434
src/gfonts.json
Normal file
File diff suppressed because it is too large
Load diff
12
src/ui.css
12
src/ui.css
|
@ -92,6 +92,7 @@ section {
|
|||
justify-content: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
section > * + * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
@ -103,3 +104,14 @@ img {
|
|||
height: auto;
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.missing-fonts small {
|
||||
font-size: 0.5rem;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
72
src/ui.tsx
72
src/ui.tsx
|
@ -8,6 +8,9 @@ import slugify from "slugify";
|
|||
|
||||
declare function require(path: string): any;
|
||||
|
||||
// Open resources/gfonts.json and create a set of matched font names
|
||||
const gfonts = new Set();
|
||||
require("./gfonts.json").forEach((font) => gfonts.add(font));
|
||||
|
||||
type PenpotExporterProps = {
|
||||
}
|
||||
|
@ -21,6 +24,7 @@ type FigmaImageData = {
|
|||
type PenpotExporterState = {
|
||||
isDebug: boolean,
|
||||
penpotFileData: string
|
||||
missingFonts: Set<string>
|
||||
figmaFileData: string
|
||||
figmaRootNode: NodeData
|
||||
images: { [id: string] : FigmaImageData; };
|
||||
|
@ -31,6 +35,7 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
isDebug: false,
|
||||
penpotFileData: "",
|
||||
figmaFileData: "",
|
||||
missingFonts: new Set(),
|
||||
figmaRootNode: null,
|
||||
images: {}
|
||||
};
|
||||
|
@ -38,6 +43,11 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
componentDidMount = () => {
|
||||
window.addEventListener("message", this.onMessage);
|
||||
}
|
||||
|
||||
componentDidUpdate = () => {
|
||||
this.setDimensions();
|
||||
}
|
||||
|
||||
componentWillUnmount = () =>{
|
||||
window.removeEventListener('message', this.onMessage);
|
||||
}
|
||||
|
@ -113,6 +123,13 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
return penpotFills;
|
||||
}
|
||||
|
||||
addFontWarning(font){
|
||||
const newMissingFonts = this.state.missingFonts;
|
||||
newMissingFonts.add(font);
|
||||
|
||||
this.setState(_ => ({missingFonts: newMissingFonts }));
|
||||
}
|
||||
|
||||
createPenpotPage(file, node){
|
||||
file.addPage(node.name);
|
||||
for (var child of node.children){
|
||||
|
@ -200,9 +217,19 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
return "none";
|
||||
}
|
||||
|
||||
validateFont(fontName) {
|
||||
const name = slugify(fontName.family.toLowerCase());
|
||||
if (!gfonts.has(name)) {
|
||||
this.addFontWarning(name);
|
||||
}
|
||||
}
|
||||
|
||||
createPenpotText(file, node, baseX, baseY){
|
||||
|
||||
const children = node.children.map((val) => {
|
||||
|
||||
this.validateFont(val.fontName);
|
||||
|
||||
return {
|
||||
lineHeight: val.lineHeight,
|
||||
fontStyle: "normal",
|
||||
|
@ -219,6 +246,8 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
text: val.characters }
|
||||
});
|
||||
|
||||
this.validateFont(node.fontName);
|
||||
|
||||
file.createText({
|
||||
name: node.name,
|
||||
x: node.x + baseX,
|
||||
|
@ -367,18 +396,44 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
}
|
||||
}
|
||||
|
||||
setDimensions = () => {
|
||||
|
||||
const isMissingFonts = this.state.missingFonts.size > 0;
|
||||
|
||||
let width = 300;
|
||||
let height = 280;
|
||||
|
||||
if (isMissingFonts) {
|
||||
height += (this.state.missingFonts.size * 20);
|
||||
width = 400;
|
||||
}
|
||||
|
||||
if (this.state.isDebug){
|
||||
height += 600;
|
||||
width = 800;
|
||||
}
|
||||
|
||||
parent.postMessage({ pluginMessage: { type: "resize", width: width, height: height } }, "*");
|
||||
}
|
||||
|
||||
toggleDebug = (event) => {
|
||||
const isDebug = event.currentTarget.checked;
|
||||
this.setState (state => ({isDebug: isDebug}))
|
||||
if (isDebug){
|
||||
parent.postMessage({ pluginMessage: { type: "resize", width:800, height:800 } }, "*");
|
||||
} else {
|
||||
parent.postMessage({ pluginMessage: { type: "resize", width:300, height:200 } }, "*");
|
||||
this.setState (state => ({isDebug: isDebug}));
|
||||
}
|
||||
|
||||
renderFontWarnings = () => {
|
||||
return (
|
||||
<ul >
|
||||
{Array.from(this.state.missingFonts).map((font) => (
|
||||
<li key={font}>{font}</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
// Update the dimensions of the plugin window based on available data and selections
|
||||
return (
|
||||
<main>
|
||||
<header>
|
||||
|
@ -386,6 +441,13 @@ export default class PenpotExporter extends React.Component<PenpotExporterProps,
|
|||
<h2>Penpot Exporter</h2>
|
||||
</header>
|
||||
<section>
|
||||
<div style={{display:this.state.missingFonts.size > 0 ? "inline" : "none"}}>
|
||||
<div id="missing-fonts">{this.state.missingFonts.size} non-default font{this.state.missingFonts.size > 1 ? 's' : ''}: </div>
|
||||
<small>Ensure fonts are installed in Penpot before importing.</small>
|
||||
<div id="missing-fonts-list">
|
||||
{this.renderFontWarnings()}
|
||||
</div>
|
||||
</div>
|
||||
<div >
|
||||
<input type="checkbox" id="chkDebug" name="chkDebug" onChange={this.toggleDebug}/>
|
||||
<label htmlFor="chkDebug">Show debug data</label>
|
||||
|
|
Loading…
Reference in a new issue