• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

marcomontalbano / figma-export / 7970372673

20 Feb 2024 08:16AM CUT coverage: 96.473% (-0.2%) from 96.693%
7970372673

Pull #157

github

marcomontalbano
deps: update other dependencies to latest
Pull Request #157: Update all dependencies – drop support for Node.js 12 and 14

236 of 258 branches covered (91.47%)

Branch coverage included in aggregate %.

612 of 621 relevant lines covered (98.55%)

17.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.69
/packages/core/src/lib/figmaStyles/paintStyle.ts
1
import * as Figma from 'figma-js';
2
import * as FigmaExport from '@figma-export/types';
3

4
import { notNullish } from '../utils';
1✔
5

6
const extractColor = ({ color, opacity = 1 }: FigmaExport.ExtractableColor): (FigmaExport.Color | undefined) => {
1✔
7
    if (!color) {
145!
8
        return undefined;
×
9
    }
10

11
    const toFixed = (number: number, fractionDigits: number) => parseFloat((number).toFixed(fractionDigits));
580✔
12
    const convert = (figmaColor: number) => toFixed(figmaColor * 255, 0);
435✔
13

14
    // eslint-disable-next-line object-curly-newline
15
    let { r = 0, g = 0, b = 0, a = 1 } = color;
145!
16

17
    r = convert(r);
145✔
18
    g = convert(g);
145✔
19
    b = convert(b);
145✔
20
    a = toFixed(opacity * a, 2);
145✔
21

22
    return {
145✔
23
        r,
24
        g,
25
        b,
26
        a,
27
        rgba: `rgba(${r}, ${g}, ${b}, ${a})`,
28
    };
29
};
30

31
const extractGradientLinear = (paint: Figma.Paint): (FigmaExport.LinearGradient | undefined) => {
1✔
32
    if (!paint.gradientStops || !paint.gradientHandlePositions) {
25!
33
        return undefined;
×
34
    }
35

36
    const getAngle = (figmaGradientHandlePositions: readonly Figma.Vector2[]): string => {
25✔
37
        const [startPoint, endPoint] = figmaGradientHandlePositions;
25✔
38
        const deltaY = (endPoint.y - startPoint.y);
25✔
39
        const deltaX = (endPoint.x - startPoint.x);
25✔
40
        const deg = ((Math.atan2(deltaY, deltaX) * 180) / Math.PI) + 90;
25✔
41
        return `${parseFloat(deg.toFixed(2))}deg`;
25✔
42
    };
43

44
    const getGradientStops = (figmaGradientStops: readonly Figma.ColorStop[], opacity?: number): FigmaExport.LinearColorStop[] => {
25✔
45
        const gradientStops: FigmaExport.LinearColorStop[] = [];
25✔
46

47
        figmaGradientStops.forEach((stop) => {
25✔
48
            const color = extractColor({ ...stop, opacity });
72✔
49
            const position = parseFloat((stop.position * 100).toFixed(3));
72✔
50

51
            if (color) {
72!
52
                gradientStops.push({ color, position });
72✔
53
            }
54
        });
55

56
        return gradientStops;
25✔
57
    };
58

59
    return {
25✔
60
        angle: getAngle(paint.gradientHandlePositions),
61
        gradientStops: getGradientStops(paint.gradientStops, paint.opacity),
62
    };
63
};
64

65
const createFillStyles = (fill: Figma.Paint): FigmaExport.FillStyle | undefined => {
1✔
66
    // eslint-disable-next-line default-case
67
    switch (fill.type) {
84✔
68
        case 'SOLID': {
69
            const color = extractColor(fill);
47✔
70
            if (color) {
47!
71
                return {
47✔
72
                    type: 'SOLID',
73
                    visible: fill.visible !== false,
74
                    color,
75
                    value: color.rgba,
76
                };
77
            }
78

79
            break;
×
80
        }
81

82
        case 'GRADIENT_LINEAR': {
83
            const gradient = extractGradientLinear(fill);
25✔
84
            if (gradient) {
25!
85
                return {
25✔
86
                    type: 'GRADIENT_LINEAR',
87
                    visible: fill.visible !== false,
88
                    ...gradient,
89
                    value: `linear-gradient(${gradient.angle}, ${gradient.gradientStops.map((stop) => {
90
                        return `${stop.color.rgba} ${stop.position}%`;
72✔
91
                    }).join(', ')})`,
92
                };
93
            }
94

95
            break;
×
96
        }
97
    }
98

99
    return undefined;
12✔
100
};
101

102
const parse = (node: FigmaExport.StyleNode): FigmaExport.StyleTypeFill | undefined => {
1✔
103
    if (node.styleType === 'FILL' && node.type === 'RECTANGLE') {
105✔
104
        return {
62✔
105
            styleType: 'FILL',
106
            fills: Array.from(node.fills)
107
                .reverse()
108
                .map(createFillStyles)
109
                .filter(notNullish),
110
        };
111
    }
112

113
    return undefined;
43✔
114
};
115

116
export {
117
    parse,
1✔
118
    extractColor,
1✔
119
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc