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

glideapps / glide-data-grid / 7455656024

09 Jan 2024 01:59AM CUT coverage: 92.126% (+5.7%) from 86.42%
7455656024

Pull #810

github

jassmith
Fix jitter with freeze rows. Still inefficient
Pull Request #810: 6.0.0

2722 of 3335 branches covered (0.0%)

16509 of 17920 relevant lines covered (92.13%)

3197.67 hits per line

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

83.18
/packages/core/src/internal/data-grid/data-grid-sprites.ts
1
import type { Theme } from "../../common/styles.js";
1✔
2
import type { SpriteProps } from "../../common/utils.js";
1✔
3
import { type HeaderIconMap } from "./sprites.js";
1✔
4

1✔
5
/**
1✔
6
 * A known icon identifier
1✔
7
 *
1✔
8
 * @category Columns
1✔
9
 */
1✔
10
export type HeaderIcon = keyof HeaderIconMap;
1✔
11

1✔
12
/**
1✔
13
 * A method that produces an SVG array from
1✔
14
 * an SVG icon configuration.
1✔
15
 *
1✔
16
 * @category Columns
1✔
17
 */
1✔
18
export type Sprite = (props: SpriteProps) => string;
1✔
19

1✔
20
/**
1✔
21
 * A method that maps from icon names to functions
1✔
22
 * that return SVG strings.
1✔
23
 *
1✔
24
 * @category Columns
1✔
25
 */
1✔
26
export type SpriteMap = Record<string | HeaderIcon, Sprite>;
1✔
27

1✔
28
/** @category Columns */
1✔
29
export type SpriteVariant = "normal" | "selected" | "special";
1✔
30

1✔
31
function getColors(variant: SpriteVariant, theme: Theme): readonly [string, string] {
4,145✔
32
    if (variant === "normal") {
4,145✔
33
        return [theme.bgIconHeader, theme.fgIconHeader];
4,080✔
34
    } else if (variant === "selected") {
4,145✔
35
        return ["white", theme.accentColor];
65✔
36
    } else {
65!
37
        return [theme.accentColor, theme.bgHeader];
×
38
    }
×
39
}
4,145✔
40

1✔
41
/** @category Columns */
1✔
42
export class SpriteManager {
1✔
43
    private spriteMap: Map<string, HTMLCanvasElement> = new Map();
1✔
44
    private headerIcons: SpriteMap;
1✔
45
    private inFlight = 0;
1✔
46

1✔
47
    constructor(
1✔
48
        headerIcons: SpriteMap | undefined,
159✔
49
        private onSettled: () => void
159✔
50
    ) {
159✔
51
        this.headerIcons = headerIcons ?? {};
159✔
52
    }
159✔
53

1✔
54
    public drawSprite(
1✔
55
        sprite: HeaderIcon | string,
4,145✔
56
        variant: SpriteVariant,
4,145✔
57
        ctx: CanvasRenderingContext2D,
4,145✔
58
        x: number,
4,145✔
59
        y: number,
4,145✔
60
        size: number,
4,145✔
61
        theme: Theme,
4,145✔
62
        alpha: number = 1
4,145✔
63
    ) {
4,145✔
64
        const [bgColor, fgColor] = getColors(variant, theme);
4,145✔
65
        const rSize = size * Math.ceil(window.devicePixelRatio);
4,145✔
66
        const key = `${bgColor}_${fgColor}_${rSize}_${sprite}`;
4,145✔
67

4,145✔
68
        let spriteCanvas = this.spriteMap.get(key);
4,145✔
69
        if (spriteCanvas === undefined) {
4,145✔
70
            const spriteCb = this.headerIcons[sprite];
1,463✔
71

1,463✔
72
            if (spriteCb === undefined) return;
1,463!
73

1,463✔
74
            spriteCanvas = document.createElement("canvas");
1,463✔
75
            const spriteCtx = spriteCanvas.getContext("2d");
1,463✔
76

1,463✔
77
            if (spriteCtx === null) return;
1,463!
78

1,463✔
79
            const imgSource = new Image();
1,463✔
80
            imgSource.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(spriteCb({ fgColor, bgColor }))}`;
1,463✔
81
            this.spriteMap.set(key, spriteCanvas);
1,463✔
82
            const promise: Promise<void> | undefined = imgSource.decode();
1,463✔
83

1,463✔
84
            if (promise === undefined) return;
1,463!
85

×
86
            this.inFlight++;
×
87
            promise
×
88
                .then(() => {
×
89
                    spriteCtx.drawImage(imgSource, 0, 0, rSize, rSize);
×
90
                })
×
91
                .finally(() => {
×
92
                    this.inFlight--;
×
93
                    if (this.inFlight === 0) {
×
94
                        this.onSettled();
×
95
                    }
×
96
                });
×
97
        } else {
4,145✔
98
            if (alpha < 1) {
2,682!
99
                ctx.globalAlpha = alpha;
×
100
            }
×
101
            ctx.drawImage(spriteCanvas, 0, 0, rSize, rSize, x, y, size, size);
2,682✔
102
            if (alpha < 1) {
2,682!
103
                ctx.globalAlpha = 1;
×
104
            }
×
105
        }
2,682✔
106
    }
4,145✔
107
}
1✔
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