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
13 changes: 8 additions & 5 deletions apps/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ For a `/chart` build, preview the homepage image at

The `predev` and `prebuild` scripts compile the library and run
`scripts/prepare-demo.mjs`. It copies `apps/playground/index.html`,
`packages/chart/dist/`, and `packages/chart/assets/fonts/` from the repository
into the ignored `public/chart-demo/` directory. Both the homepage and the
`packages/chart/dist/`, and the Latin Bloxwap Sans/Mono faces from
`@bloxwap/font` into the ignored `public/chart-demo/` directory. Both the homepage and the
playground guide embed this same demo; edit the original instead of making a
separate docs implementation. Restart `docs:dev` after changing the demo or
library to refresh the copied assets. The export checker validates the iframe
Expand All @@ -88,7 +88,10 @@ documents building and installing its local tarball; update that note and the
homepage's release badge after the first public release.

The exact `@bloxwap/[email protected]` dependency supplies self-hosted Sans/Mono Next.js
loaders. The embedded playground copies the package stylesheet and fonts and
explicitly sets `theme.fontFamily` to Bloxwap Sans before drawing its canvas;
the standalone playground and SDK presets retain their existing font defaults.
loaders. The embedded playground copies a stylesheet trimmed to the Latin Sans
and Mono faces, replaces the playground's Geist faces with them, points the SDK
chrome's `--cts-font`/`--cts-mono` at Bloxwap Sans/Mono, and sets the canvas
`theme.fontFamily` to Bloxwap Sans and `monoFamily`/`scaleFontFamily` (status
line, drawing labels and scales) to Bloxwap Mono. The standalone playground and
SDK presets retain their existing font defaults.
Static social-image font provenance is recorded in `fonts/README.md`.
2 changes: 1 addition & 1 deletion apps/docs/scripts/check-export.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ for (const required of [
'index.html', '404.html', 'docs/index.html', 'developers/index.html', 'search.json', 'icon.svg',
'llms.txt', 'robots.txt', 'openapi.json', '404.md',
'chart-demo/demo/index.html', 'chart-demo/dist/index.js', 'chart-demo/dist/ui/index.js', 'chart-demo/dist/datafeed/index.js',
'chart-demo/assets/bloxwap-font/fonts/BloxwapSans/BloxwapSans-Variable.woff2', 'chart-demo/assets/bloxwap-font/bloxwap-font.css', 'chart-demo/assets/fonts/Geist-Regular.woff2', 'chart-demo/assets/fonts/GeistMono-Regular.woff2',
'chart-demo/assets/bloxwap-font/fonts/BloxwapSans/BloxwapSans-Variable.woff2', 'chart-demo/assets/bloxwap-font/fonts/BloxwapMono/BloxwapMono-Variable.woff2', 'chart-demo/assets/bloxwap-font/bloxwap-font.css',
]) {
if (!await exists(join(root, required))) failures.push(`Missing ${required}`);
}
Expand Down
38 changes: 28 additions & 10 deletions apps/docs/scripts/prepare-demo.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,47 @@ import { cp, mkdir, rm, readFile, writeFile } from 'node:fs/promises';
const repository = new URL('../../../', import.meta.url);
const output = new URL('../public/chart-demo/', import.meta.url);

// Preserve the demo's relative imports and fonts. There is only one playground
// Preserve the demo's relative imports. There is only one playground
// implementation: the same HTML served by `npm run demo` is published with docs.
// Its Geist assets are not copied: the docs copy below swaps every Geist
// reference for Bloxwap Sans/Mono.
await rm(output, { recursive: true, force: true });
await mkdir(new URL('demo/', output), { recursive: true });
await Promise.all([
cp(new URL('apps/playground/index.html', repository), new URL('demo/index.html', output)),
cp(new URL('packages/chart/dist/', repository), new URL('dist/', output), { recursive: true }),
cp(new URL('packages/chart/assets/fonts/', repository), new URL('assets/fonts/', output), { recursive: true }),
]);
console.log('Prepared the complete chart demo for the documentation site.');

// The embedded documentation example explicitly overrides the canvas preset's
// family; an iframe cannot inherit the parent's Next.js font variables.
// An iframe cannot inherit the parent's Next.js font variables, so the demo
// ships its own copy of the Latin Bloxwap Sans/Mono faces. The package's other
// script companions (CJK, Arabic, ...) are left out; the demo never shows them.
const fontPackage = new URL('../../../node_modules/@bloxwap/font/', import.meta.url);
await cp(new URL('fonts/', fontPackage), new URL('assets/bloxwap-font/fonts/', output), { recursive: true });
await cp(new URL('bloxwap-font.css', fontPackage), new URL('assets/bloxwap-font/bloxwap-font.css', output));
await cp(new URL('LICENSE', fontPackage), new URL('assets/bloxwap-font/LICENSE', output));
const fontOutput = new URL('assets/bloxwap-font/', output);
const families = ['BloxwapSans', 'BloxwapMono'];
await Promise.all([
...families.map((family) => cp(new URL(`fonts/${family}/`, fontPackage), new URL(`fonts/${family}/`, fontOutput), { recursive: true })),
cp(new URL('LICENSE', fontPackage), new URL('LICENSE', fontOutput)),
]);
const packageCss = await readFile(new URL('bloxwap-font.css', fontPackage), 'utf8');
const license = packageCss.split('\n').find((line) => line.includes('Open Font License'));
const faces = packageCss.match(/@font-face \{[^}]+\}/g)
.filter((face) => families.some((family) => face.includes(`./fonts/${family}/`)));
if (faces.length !== 4) throw new Error(`Expected 4 Latin Bloxwap Sans/Mono faces, found ${faces.length}.`);
await writeFile(new URL('bloxwap-font.css', fontOutput), `/*\n * Latin Bloxwap Sans and Mono, trimmed from @bloxwap/font/bloxwap-font.css by apps/docs/scripts/prepare-demo.mjs.\n${license}\n */\n${faces.join('\n')}\n`);

const SANS = '"Bloxwap Sans", system-ui, sans-serif';
const MONO = '"Bloxwap Mono", ui-monospace, monospace';
const demo = new URL('demo/index.html', output);
const html = (await readFile(demo, 'utf8'))
.replace('<style>', '<link rel="stylesheet" href="../assets/bloxwap-font/bloxwap-font.css" /><style>')
.replace('<style>', `<link rel="stylesheet" href="../assets/bloxwap-font/bloxwap-font.css" /><style>
/* SDK chrome (header, rails, menus, dialogs): doubled class outranks the injected TOOLBAR_CSS. */
.cts-theme.cts-theme { --cts-font: ${SANS}; --cts-mono: ${MONO}; }`)
.replace(/@font-face \{[^}]+\}/g, '')
.replaceAll("'Geist'", "'Bloxwap Sans'")
.replaceAll('12px "Geist"', '12px "Bloxwap Sans"')
.replaceAll('12px "Geist Mono"', '12px "Bloxwap Mono"')
.replace('config: defineConfig({', `config: defineConfig({ theme: { fontFamily: '"Bloxwap Sans", "Bloxwap Sans Scripts", system-ui, sans-serif' },`);
// Canvas text: the bloxwapDark preset uses system-ui for all three families.
.replace('config: defineConfig({', `config: defineConfig({ theme: { fontFamily: '${SANS}', monoFamily: '${MONO}', scaleFontFamily: '${MONO}' },`);
if (/Geist/.test(html)) throw new Error('The docs chart demo still references Geist.');
await writeFile(demo, html);
console.log('Prepared the complete chart demo for the documentation site.');
Loading