Skip to content

Commit

Permalink
feat(extractors): add missing typograph properties in Sketch extractor (
Browse files Browse the repository at this point in the history
  • Loading branch information
roperzh committed Jan 14, 2020
1 parent 830a84b commit aea53cf
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 22 deletions.
10 changes: 10 additions & 0 deletions .vscode/launch.json
Expand Up @@ -61,6 +61,16 @@
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/src/*/*/lib/**/*.js"]
},
{
"type": "node",
"request": "launch",
"name": "Diez extract - Lorem Ipsum",
"program": "${workspaceFolder}/node_modules/.bin/diez",
"args": ["extract"],
"cwd": "${workspaceFolder}/examples/lorem-ipsum/design-language",
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/src/*/*/lib/**/*.js"]
},
],
"compounds": [
{
Expand Down
6 changes: 4 additions & 2 deletions src/extractors/extractors/src/extractors/figma.ts
Expand Up @@ -356,8 +356,10 @@ const processFigmaNode = async (
spec.designLanguageName,
candidateFont,
node.style.fontPostScriptName,
node.style.fontSize,
getInitializerForTypographColorFromFigma(node),
{
fontSize: node.style.fontSize,
color: getInitializerForTypographColorFromFigma(node),
},
),
});
typographs.delete(node.styles.text);
Expand Down
39 changes: 35 additions & 4 deletions src/extractors/extractors/src/extractors/sketch.ts
Expand Up @@ -86,6 +86,7 @@ interface SketchSharedTypograph {
name: string;
value: {
textStyle: {
NSKern: number;
MSAttributedStringColorAttribute?: {
value: string;
};
Expand All @@ -96,6 +97,13 @@ interface SketchSharedTypograph {
};
family: string;
};
NSParagraphStyle: {
style: {
alignment: number;
maximumLineHeight: number;
},
}

};
};
}
Expand Down Expand Up @@ -181,6 +189,21 @@ const populateInitializerForSketchGradient = (gradient: SketchGradient, name: st
}
};

const mapNSTextAlignment = (aligment: number) => {
switch (aligment) {
case 0:
return 'TextAlignment.Left';
case 1:
return 'TextAlignment.Right';
case 2:
return 'TextAlignment.Center';
case 4:
return 'TextAlignment.Natural';
default:
return undefined;
}
};

class SketchExtractor implements Extractor {
/**
* ExtractorFactory interface method.
Expand Down Expand Up @@ -272,6 +295,9 @@ class SketchExtractor implements Extractor {

for (const {name, value: {textStyle}} of dump.layerTextStyles.objects) {
const fontSize = textStyle.NSFont.attributes.NSFontSizeAttribute;
const letterSpacing = textStyle.NSKern;
const lineHeight = textStyle.NSParagraphStyle.style.maximumLineHeight;
const alignment = mapNSTextAlignment(textStyle.NSParagraphStyle.style.alignment);
const candidateFont = await locateFont(
textStyle.NSFont.family,
{name: textStyle.NSFont.attributes.NSFontNameAttribute},
Expand All @@ -288,10 +314,15 @@ class SketchExtractor implements Extractor {
codegenSpec.designLanguageName,
candidateFont,
textStyle.NSFont.attributes.NSFontNameAttribute,
fontSize,
textStyle.MSAttributedStringColorAttribute ?
getColorInitializer(textStyle.MSAttributedStringColorAttribute.value) :
undefined,
{
fontSize,
letterSpacing,
lineHeight,
alignment,
color: textStyle.MSAttributedStringColorAttribute ?
getColorInitializer(textStyle.MSAttributedStringColorAttribute.value) :
undefined,
},
),
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/extractors/extractors/test/extractors/figma.test.ts
Expand Up @@ -467,11 +467,11 @@ describe('Figma', () => {
{
name: 'Foobar Typograph',
initializer:
'new Typograph({color: Color.rgba(100, 100, 100, 1), font: helloFonts.Foobar.BoldItalic, fontSize: 9001})',
'new Typograph({fontSize: 9001, color: Color.rgba(100, 100, 100, 1), font: helloFonts.Foobar.BoldItalic})',
},
{
name: 'Gradient Typograph',
initializer: 'new Typograph({color: Color.rgba(255, 0, 0, 1), font: helloFonts.Foobar.BoldItalic, fontSize: 9001})',
initializer: 'new Typograph({fontSize: 9001, color: Color.rgba(255, 0, 0, 1), font: helloFonts.Foobar.BoldItalic})',
},
],
});
Expand Down
9 changes: 8 additions & 1 deletion src/extractors/extractors/test/extractors/sketch.test.ts
Expand Up @@ -99,6 +99,13 @@ beforeEach(() => {
name: 'Heading 1',
value: {
textStyle: {
NSKern: 0,
NSParagraphStyle: {
style: {
maximumLineHeight: 22,
alignment: 2,
},
},
MSAttributedStringColorAttribute: {
value: '#333333',
},
Expand Down Expand Up @@ -231,7 +238,7 @@ describe('Sketch', () => {
projectRoot: '.',
typographs: [
{
initializer: 'new Typograph({color: Color.rgba(51, 51, 51, 1), font: testFonts.Foobar.BoldItalic, fontSize: 20})',
initializer: 'new Typograph({fontSize: 20, letterSpacing: 0, lineHeight: 22, alignment: TextAlignment.Center, color: Color.rgba(51, 51, 51, 1), font: testFonts.Foobar.BoldItalic})',
name: 'Heading 1',
},
],
Expand Down
11 changes: 11 additions & 0 deletions src/extractors/generation/src/api.ts
Expand Up @@ -58,3 +58,14 @@ export interface CodegenDesignLanguage {
fonts: GeneratedFonts;
assets: GeneratedAssets;
}

/**
* Describes typograph data serialized in a format useful to manipulate.
*/
export interface SerializedTypographData {
color: string;
fontSize: number;
letterSpacing: number;
lineHeight: number;
alignment: string;
}
13 changes: 5 additions & 8 deletions src/extractors/generation/src/typograph.ts
@@ -1,7 +1,8 @@
import {execAsync, isMacOS, Log} from '@diez/cli-core';
import {camelCase, pascalCase} from 'change-case';
import {join} from 'path';
import {GeneratedFont} from './api';
import {GeneratedFont, SerializedTypographData} from './api';
import {objectToSource} from './utils';

interface FontLookup {
name: string;
Expand Down Expand Up @@ -77,16 +78,12 @@ export const getTypographInitializer = (
designLanguageName: string,
candidateFont: GeneratedFont | undefined,
fontName: string,
fontSize: number,
colorInitializer?: string,
typographData: Partial<SerializedTypographData>,
) => {
const font = candidateFont ?
`${camelCase(`${designLanguageName} Fonts`)}.${pascalCase(candidateFont.family)}.${pascalCase(candidateFont.style)}` :
`new Font({name: "${fontName}"})`;

if (colorInitializer) {
return `new Typograph({color: ${colorInitializer}, font: ${font}, fontSize: ${fontSize}})`;
}

return `new Typograph({font: ${font}, fontSize: ${fontSize}})`;
Object.assign(typographData, {font});
return `new Typograph(${objectToSource(typographData)})`;
};
12 changes: 12 additions & 0 deletions src/extractors/generation/src/utils.ts
Expand Up @@ -270,6 +270,7 @@ export const codegenDesignLanguage = async (spec: CodegenDesignLanguage) => {
if (hasTypographs) {
designLanguageImports.add('Color');
designLanguageImports.add('Typograph');
designLanguageImports.add('TextAlignment');
sourceFile.addVariableStatement({
leadingTrivia: newLine,
declarationKind: VariableDeclarationKind.Const,
Expand Down Expand Up @@ -376,3 +377,14 @@ const addCommentHeader = (sourceFile: SourceFile) => {
*/
export const roundFloat = (value: number, decimals: number = 15) =>
Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);

/**
* Converts a record containing primitives into a string representing JavaScript source code.
*/
export const objectToSource = (obj: Record<string, string|number|undefined>) => {
const values = [];
for (const key in obj) {
values.push(`${key}: ${obj[key]}`);
}
return `{${values.join(', ')}}`;
};
13 changes: 9 additions & 4 deletions src/extractors/generation/test/typograph.test.ts
Expand Up @@ -74,8 +74,8 @@ describe('typograph', () => {
});

test('typograph initializer', () => {
expect(getTypographInitializer('DesignLanguage', undefined, 'Foobar-Regular', 20, 'new Color()')).toBe(
'new Typograph({color: new Color(), font: new Font({name: "Foobar-Regular"}), fontSize: 20})',
expect(getTypographInitializer('DesignLanguage', undefined, 'Foobar-Regular', {fontSize: 20, color: 'new Color()'})).toBe(
'new Typograph({fontSize: 20, color: new Color(), font: new Font({name: "Foobar-Regular"})})',
);
expect(getTypographInitializer(
'DesignLanguage',
Expand All @@ -86,9 +86,14 @@ describe('typograph', () => {
path: '/path/to/Foobar-Regular.ttf',
},
'Foobar-Regular',
20,
{
fontSize: 20,
letterSpacing: 33,
lineHeight: 12,
alignment: 'TextAlignment.Center',
},
)).toBe(
'new Typograph({font: designLanguageFonts.Foobar.Regular, fontSize: 20})',
'new Typograph({fontSize: 20, letterSpacing: 33, lineHeight: 12, alignment: TextAlignment.Center, font: designLanguageFonts.Foobar.Regular})',
);
});
});
9 changes: 8 additions & 1 deletion src/extractors/generation/test/utils.test.ts
Expand Up @@ -17,7 +17,7 @@ jest.doMock('@diez/compiler-core', () => {
});

import {VariableDeclarationKind} from 'ts-morph';
import {codegenDesignLanguage, UniqueNameResolver} from '../src/utils';
import {codegenDesignLanguage, UniqueNameResolver, objectToSource} from '../src/utils';

describe('UniqueNameResolver', () => {
test('provides conventional component names', () => {
Expand Down Expand Up @@ -109,3 +109,10 @@ describe('#codegenDesignLanguage', () => {
);
});
});

describe('objectToSource', () => {
test('converts an object to a string representation of JS source code', () => {
const obj = {str: 'a', numb: 2, undef: undefined};
expect(objectToSource(obj)).toEqual('{str: a, numb: 2, undef: undefined}');
});
});

0 comments on commit aea53cf

Please sign in to comment.