Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 22 additions & 47 deletions assets/packs/data_table/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,36 @@ import { createTableSkeleton } from "./Skeleton";
export async function init(ctx, data) {
ctx.root.appendChild(createTableSkeleton());

try {
await loadStyles(ctx);
} finally {
const root = createRoot(ctx.root);
root.render(<App ctx={ctx} data={data} />);
}
}

async function loadStyles(ctx) {
const cssPromises = [
await Promise.all([
ctx.importCSS(
"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap",
),
ctx.importCSS(
"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap",
),
ctx.importCSS("main.css"),
];
]);

// We force all fonts to be loaded by adding an invisible element,
// and then we explicitly wait for the fonts to finish loading.
// We force all fonts to be loaded before rendering the table.
// This is important on first uncached render. If we don't wait
// and render the table with fallback fonts, the columns get wrong
// default widths. Also, on Firefox ans Safari, once the font is
// loaded, the table only updates on hover, which is bad UX.

const fontPreloader = document.createElement("div");
fontPreloader.setAttribute("aria-hidden", "true");
fontPreloader.style.cssText = `
position: absolute;
visibility: hidden;
left: -9999px;
`;
fontPreloader.innerHTML = `
<span style="font-family: 'JetBrains Mono'">
<span style="font-weight: 400">preload</span>"
<span style="font-weight: 500">preload</span>"
<span style="font-weight: 600">preload</span>"
</span>"
<span style="font-family: 'Inter'">
<span style="font-weight: 400">preload</span>"
<span style="font-weight: 500">preload</span>"
<span style="font-weight: 600">preload</span>"
</span>"
`;

document.body.appendChild(fontPreloader);

try {
await Promise.all(cssPromises);

if (document.fonts && document.fonts.ready) {
await document.fonts.ready;
}
} finally {
document.body.removeChild(fontPreloader);
}
// default widths. Also, in Firefox ans Safari, once the font is
// loaded, the table only updates on hover, which is bad UX. That
// said, in Firefox, this doesn't help 100% of the time either.
await Promise.race([
Promise.all([
document.fonts.load("400 16px 'JetBrains Mono'"),
document.fonts.load("500 16px 'JetBrains Mono'"),
document.fonts.load("600 16px 'JetBrains Mono'"),
document.fonts.load("400 16px Inter"),
document.fonts.load("500 16px Inter"),
document.fonts.load("600 16px Inter"),
]),
// If a font request fails, the promises may not be resolved, so
// we add a timeout just to make sure this finishes at some point.
new Promise((resolve) => setTimeout(resolve, 5000)),
]);

const root = createRoot(ctx.root);
root.render(<App ctx={ctx} data={data} />);
}
Loading