0
Fork 0
mirror of https://github.com/penpot/penpot-exporter-figma-plugin.git synced 2024-12-22 13:43:03 -05:00

Added text basic properties (#61)

* fixes in text nodes

* fix comment

* allow design.penpot.app

* wip

* wip

* add position data

* wip agaaain

* added translate growtype

* use a random url just to get a 404 on gfonts call

* leave the config, just in case someone wants to try it

* translated line height & letter spacing; Created new type for text positionData

* text strokes

* several fixes

* compiled penpot lib with fix

* updated penpot lib

* fix lint

* remove proxy

* correctly translate font style

* fix grow type to reflect vertical trim

* Fix font segments

* remove comment

* changeset

---------

Co-authored-by: Alex Sánchez <sion333@gmail.com>
This commit is contained in:
Jordi Sala Morales 2024-04-29 10:17:08 +02:00 committed by GitHub
parent 942b39370f
commit 881ccabe86
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 5525 additions and 5475 deletions

View file

@ -0,0 +1,5 @@
---
"penpot-exporter": minor
---
Added text basic properties

View file

@ -1,9 +1,20 @@
import { translateTextDecoration, translateTextTransform } from '@plugin/translators';
import slugify from 'slugify';
import {
translateFontStyle,
translateFontVariantId,
translateHorizontalAlign,
translateLetterSpacing,
translateLineHeight,
translateTextDecoration,
translateTextTransform
} from '@plugin/translators';
import { TextStyle } from '@ui/lib/types/text/textContent';
export const transformTextStyle = (
node: Pick<
node: TextNode,
segment: Pick<
StyledTextSegment,
| 'characters'
| 'start'
@ -19,11 +30,16 @@ export const transformTextStyle = (
>
): Partial<TextStyle> => {
return {
fontFamily: node.fontName.family,
fontSize: node.fontSize.toString(),
fontStyle: node.fontName.style,
fontWeight: node.fontWeight.toString(),
textDecoration: translateTextDecoration(node),
textTransform: translateTextTransform(node)
fontFamily: segment.fontName.family,
fontId: `gfont-${slugify(segment.fontName.family.toLowerCase())}`,
fontSize: segment.fontSize.toString(),
fontStyle: translateFontStyle(segment.fontName.style),
fontWeight: segment.fontWeight.toString(),
fontVariantId: translateFontVariantId(segment.fontName.style),
textAlign: translateHorizontalAlign(node.textAlignHorizontal),
textDecoration: translateTextDecoration(segment),
textTransform: translateTextTransform(segment),
letterSpacing: translateLetterSpacing(segment),
lineHeight: translateLineHeight(segment)
};
};

View file

@ -5,9 +5,14 @@ import {
transformFills,
transformProportion,
transformSceneNode,
transformStrokes,
transformTextStyle
} from '@plugin/transformers/partials';
import { translateStyledTextSegments } from '@plugin/translators';
import {
translateGrowType,
translateStyledTextSegments,
translateVerticalAlign
} from '@plugin/translators';
import { TextShape } from '@ui/lib/types/text/textShape';
@ -28,24 +33,27 @@ export const transformTextNode = (node: TextNode, baseX: number, baseY: number):
name: node.name,
content: {
type: 'root',
verticalAlign: translateVerticalAlign(node.textAlignVertical),
children: [
{
type: 'paragraph-set',
children: [
{
type: 'paragraph',
children: translateStyledTextSegments(styledTextSegments, node.width, node.height),
...(styledTextSegments.length ? transformTextStyle(styledTextSegments[0]) : {}),
children: translateStyledTextSegments(node, styledTextSegments),
...(styledTextSegments.length ? transformTextStyle(node, styledTextSegments[0]) : {}),
...transformFills(node)
}
]
}
]
},
growType: translateGrowType(node),
...transformDimensionAndPosition(node, baseX, baseY),
...transformEffects(node),
...transformSceneNode(node),
...transformBlend(node),
...transformProportion(node)
...transformProportion(node),
...transformStrokes(node)
};
};

View file

@ -1,8 +1,15 @@
export * from './translateBlendMode';
export * from './translateShadowEffects';
export * from './translateFills';
export * from './translateFontStyle';
export * from './translateFontVariantId';
export * from './translateGrowType';
export * from './translateHorizontalAlign';
export * from './translateLetterSpacing';
export * from './translateLineHeight';
export * from './translateStrokes';
export * from './translateStyledTextSegments';
export * from './translateTextDecoration';
export * from './translateTextTransform';
export * from './translateVectorPaths';
export * from './translateVerticalAlign';

View file

@ -0,0 +1,9 @@
import { TextFontStyle } from '@ui/lib/types/text/textContent';
export const translateFontStyle = (style: string): TextFontStyle => {
if (style.toLowerCase().includes('italic')) {
return 'italic';
}
return 'normal';
};

View file

@ -0,0 +1,3 @@
export const translateFontVariantId = (style: string) => {
return style.toLowerCase().replace(/\s/g, '');
};

View file

@ -0,0 +1,17 @@
import { GrowType } from '@ui/lib/types/shape/shapeAttributes';
export const translateGrowType = (node: TextNode): GrowType => {
if (node.leadingTrim === 'CAP_HEIGHT') {
return 'fixed';
}
switch (node.textAutoResize) {
case 'WIDTH_AND_HEIGHT':
return 'auto-width';
case 'HEIGHT':
return 'auto-height';
case 'TRUNCATE':
default:
return 'fixed';
}
};

View file

@ -0,0 +1,16 @@
import { TextHorizontalAlign } from '@ui/lib/types/text/textContent';
export const translateHorizontalAlign = (
align: 'LEFT' | 'CENTER' | 'RIGHT' | 'JUSTIFIED'
): TextHorizontalAlign => {
switch (align) {
case 'RIGHT':
return 'right';
case 'CENTER':
return 'center';
case 'JUSTIFIED':
return 'justify';
default:
return 'left';
}
};

View file

@ -0,0 +1,12 @@
export const translateLetterSpacing = (
segment: Pick<StyledTextSegment, 'letterSpacing' | 'fontSize'>
): number => {
switch (segment.letterSpacing.unit) {
case 'PIXELS':
return segment.letterSpacing.value;
case 'PERCENT':
return (segment.fontSize * segment.letterSpacing.value) / 100;
default:
return 0;
}
};

View file

@ -0,0 +1,10 @@
export const translateLineHeight = (
segment: Pick<StyledTextSegment, 'lineHeight' | 'fontSize'>
): number | undefined => {
switch (segment.lineHeight.unit) {
case 'PIXELS':
return segment.lineHeight.value / segment.fontSize;
case 'PERCENT':
return segment.lineHeight.value / 100;
}
};

View file

@ -1,9 +1,10 @@
import { transformTextStyle } from '@plugin/transformers/partials';
import { translateFills } from '@plugin/translators/translateFills';
import { TextNode } from '@ui/lib/types/text/textContent';
import { TextNode as PenpotTextNode } from '@ui/lib/types/text/textContent';
export const translateStyledTextSegments = (
node: TextNode,
segments: Pick<
StyledTextSegment,
| 'characters'
@ -17,17 +18,15 @@ export const translateStyledTextSegments = (
| 'textCase'
| 'textDecoration'
| 'fills'
>[],
width: number,
height: number
): TextNode[] => {
>[]
): PenpotTextNode[] => {
return segments.map(segment => {
figma.ui.postMessage({ type: 'FONT_NAME', data: segment.fontName.family });
return {
fills: translateFills(segment.fills, width, height),
fills: translateFills(segment.fills, node.width, node.height),
text: segment.characters,
...transformTextStyle(segment)
...transformTextStyle(node, segment)
};
});
};

View file

@ -0,0 +1,12 @@
import { TextVerticalAlign } from '@ui/lib/types/text/textContent';
export const translateVerticalAlign = (align: 'TOP' | 'CENTER' | 'BOTTOM'): TextVerticalAlign => {
switch (align) {
case 'BOTTOM':
return 'bottom';
case 'CENTER':
return 'center';
default:
return 'top';
}
};

File diff suppressed because it is too large Load diff

View file

@ -45,5 +45,7 @@ export type ShapeAttributes = {
interactions?: Interaction[];
shadow?: Shadow[];
blur?: Blur;
growType?: 'auto-width' | 'auto-height' | 'fixed';
growType?: GrowType;
};
export type GrowType = 'auto-width' | 'auto-height' | 'fixed';

View file

@ -3,9 +3,14 @@ import { Fill } from '@ui/lib/types/utils/fill';
export type TextContent = {
type: 'root';
key?: string;
verticalAlign?: TextVerticalAlign;
children?: ParagraphSet[];
};
export type TextVerticalAlign = 'top' | 'bottom' | 'center';
export type TextHorizontalAlign = 'left' | 'right' | 'center' | 'justify';
export type TextFontStyle = 'normal' | 'italic';
type ParagraphSet = {
type: 'paragraph-set';
key?: string;
@ -24,14 +29,20 @@ type TextNode = {
} & TextStyle;
type TextStyle = {
fontId?: string;
fontFamily?: string;
fontVariantId?: string;
fontSize?: string;
fontStyle?: string;
fontStyle?: TextFontStyle;
fontWeight?: string;
textDecoration?: string;
textTransform?: string;
direction?: string;
typographyRefId?: string;
typographyRefFile?: string;
lineHeight?: number;
letterSpacing?: number;
textAlign?: TextHorizontalAlign;
textDirection?: 'ltr' | 'rtl' | 'auto';
fills?: Fill[];
};

View file

@ -1,6 +1,3 @@
export * from './translateFillGradients';
export * from './translateFontStyle';
export * from './translateHorizontalAlign';
export * from './translatePathContent';
export * from './translateUiBlendMode';
export * from './translateVerticalAlign';

View file

@ -1,3 +0,0 @@
export const translateFontStyle = (style: string) => {
return style.toLowerCase().replace(/\s/g, '');
};

View file

@ -1,9 +0,0 @@
export const translateHorizontalAlign = (align: string) => {
if (align === 'RIGHT') {
return Symbol.for('right');
}
if (align === 'CENTER') {
return Symbol.for('center');
}
return Symbol.for('left');
};

View file

@ -1,9 +0,0 @@
export const translateVerticalAlign = (align: string) => {
if (align === 'BOTTOM') {
return Symbol.for('bottom');
}
if (align === 'CENTER') {
return Symbol.for('center');
}
return Symbol.for('top');
};