Files
HMDesign/examples/org-chart/prepare.mjs
shkim4 064517ec46 feat(org-chart): implement expandable layout and multi-company navigation
Integrate P5-1B through P5-4 shared Core layout, collapse, zoom/pan/fit, company roots and keyboard accessibility. Include React/HTML examples, virtual 20/100/300 employee fixtures, focused checks and the additive data contract.
2026-10-12 21:59:09 +09:00

43 lines
3.0 KiB
JavaScript

import { cp, mkdir, readFile, writeFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
const example = fileURLToPath(new URL('./', import.meta.url));
const root = path.resolve(example, '../..');
const output = path.join(example, 'dist');
await mkdir(path.join(output, 'assets'), { recursive: true });
// The host's theme is generated from the existing public CSS entry; no maintained theme fork.
async function flatten(file, seen = new Set()) {
const full = path.resolve(file);
if (seen.has(full)) throw new Error('Theme CSS import cycle');
const stack = new Set(seen).add(full);
const source = await readFile(full, 'utf8');
const matches = [...source.matchAll(/@import\s+["']([^"']+)["'];/g)];
let result = '', cursor = 0;
for (const match of matches) {
result += source.slice(cursor, match.index) + await flatten(path.resolve(path.dirname(full), match[1]), stack);
cursor = match.index + match[0].length;
}
return result + source.slice(cursor);
}
const theme = (await flatten(path.join(root, 'packages/ui/src/theme.css')))
.replace('/fonts/NotoSansKR-variable.ttf', './fonts/NotoSansKR-variable.ttf');
await writeFile(path.join(output, 'assets/hm-theme.css'), theme);
await cp(path.join(root, 'public/fonts'), path.join(output, 'assets/fonts'), { recursive: true });
for (const file of ['index.js', 'orgchart.browser.js', 'style.css', 'engine.css'])
await cp(path.join(root, 'packages/org-chart/dist', file), path.join(output, 'assets', file));
await cp(path.join(root, 'packages/org-chart/dist/licenses'), path.join(output, 'assets/licenses'), { recursive: true });
for (const file of ['index.html', 'classic.html', 'app.js', 'demo.css', 'data-v1.json', 'data-v2.json', 'data-p1.json', 'p1.html', 'p1-classic.html', 'p1-app.js', 'p1.css'])
await cp(path.join(example, file), path.join(output, file));
const initial = JSON.parse(await readFile(path.join(example, 'data-v1.json'), 'utf8'));
const changed = JSON.parse(await readFile(path.join(example, 'data-v2.json'), 'utf8'));
await writeFile(path.join(output, 'fixtures.js'), `window.OrgChartFixtures = ${JSON.stringify({initial, changed})};\n`);
const app = await readFile(path.join(example, 'app.js'), 'utf8');
await writeFile(path.join(output, 'app-classic.js'), app.replace('export function startDemo', 'function startDemo'));
const p1 = JSON.parse(await readFile(path.join(example, 'data-p1.json'), 'utf8'));
await writeFile(path.join(output, 'p1-fixture.js'), `window.OrgChartP1Fixture = ${JSON.stringify(p1)};\n`);
const p1App = await readFile(path.join(example, 'p1-app.js'), 'utf8');
await writeFile(path.join(output, 'p1-app-classic.js'), p1App.replace('export async function startP1', 'async function startP1'));
console.log(`OrgChart HTML example: ${output}`);
for (const file of ['expanded.html', 'expanded-app.js', 'expanded.css', 'data-expanded-small.json', 'data-expanded-medium.json', 'data-expanded-large.json'])
await cp(path.join(example, file), path.join(output, file));