import { join } from "node:path"; import { fileExists } from "./fileExists.ts"; import { readFile } from "node:fs/promises"; export async function createPlaygroundIndex({ mode, rootDir, srcDir, indexFile, defaultDir, playgroundFile, title, repo, repoComponent, navigation, namespaces, }: any) { let indexContent = ''; if (await fileExists(join(rootDir, srcDir, indexFile))) { indexContent = await readFile(join(rootDir, srcDir, indexFile), 'utf8'); } else { indexContent = await readFile(join(defaultDir, playgroundFile), 'utf8'); } indexContent = indexContent.replace( 'Default', `${title ?? 'Default'}` ); indexContent = indexContent.replace( '

Default

', `

${title ?? 'Default'}

` ); const navItems = structuredClone(navigation ?? []); for (let navItem of navItems) { navItem.items = []; } let defaultItem; if (navItems.length === 0) { defaultItem = { label: 'Components', items: [] }; navItems.push(defaultItem); } else { defaultItem = navItems.find((x: any) => !x.extends && !x.components && !x.namespaces); if (!defaultItem) { defaultItem = { label: 'Other', items: [] }; navItems.push(defaultItem); } } const componentMap = new Map(); // Loop and organize into lists namespaces.forEach(({ components }: any) => { components.forEach(({ component, namespace, tag, readme, examples, className, classExtends }: any) => { // Front end data componentMap.set(className, { className, // MyComponent classExtends, // MyModal component, // component namespace, // my tag, // my-component readme, // # My Component examples: examples.map((example: any) => example.className), }); examples.forEach((example: any) => { componentMap.set(example.className, { className: example.className, // XMyComponentBasic classExtends: example.classExtends, // HtmlElement component: example.component, // myComponentBasic namespace: example.namespace, // x tag: example.tag, // x-my-component-basic example: example.example, // Basic }); }); // Quick insert any direct includes for (let navItem of navItems) { if (navItem.include && navItem.include.includes(className)) { navItem.items.push({ namespace, component, className, tag, }); return; } } // Move on to any other nav groups for (let navItem of navItems) { // skip default nav group if (navItem === defaultItem) { continue; } // ignore if excluded if (navItem.exclude && navItem.exclude.includes(className)) { continue; } // ignore if not in namespace if (navItem.namespaces && !navItem.namespaces.includes(namespace)) { continue; } // ignore if not extending the required class if (navItem.extends && !navItem.extends.includes(classExtends)) { continue; } navItem.items.push({ namespace, component, className, tag, }); return; } defaultItem.items.push({ namespace, component, examples, className, tag, }); }); }); // Replace left nav indexContent = indexContent.replace(/([ ]*)/, (match: any, indent: any) => { return navItems.map(({ label, items }: any) => { return [ indent, `
${label}
`, '' ].join(`\n${indent}`) }).join(`\n${indent}`); }); // Repo if (repo) { const github = 'M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z'; const generic = 'M6,2H18A2,2 0 0,1 20,4V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2M12.75,13.5C15.5,13.5 16.24,11.47 16.43,10.4C17.34,10.11 18,9.26 18,8.25C18,7 17,6 15.75,6C14.5,6 13.5,7 13.5,8.25C13.5,9.19 14.07,10 14.89,10.33C14.67,11 14,12 12,12C10.62,12 9.66,12.35 9,12.84V8.87C9.87,8.56 10.5,7.73 10.5,6.75C10.5,5.5 9.5,4.5 8.25,4.5C7,4.5 6,5.5 6,6.75C6,7.73 6.63,8.56 7.5,8.87V15.13C6.63,15.44 6,16.27 6,17.25C6,18.5 7,19.5 8.25,19.5C9.5,19.5 10.5,18.5 10.5,17.25C10.5,16.32 9.94,15.5 9.13,15.18C9.41,14.5 10.23,13.5 12.75,13.5M8.25,16.5A0.75,0.75 0 0,1 9,17.25A0.75,0.75 0 0,1 8.25,18A0.75,0.75 0 0,1 7.5,17.25A0.75,0.75 0 0,1 8.25,16.5M8.25,6A0.75,0.75 0 0,1 9,6.75A0.75,0.75 0 0,1 8.25,7.5A0.75,0.75 0 0,1 7.5,6.75A0.75,0.75 0 0,1 8.25,6M15.75,7.5A0.75,0.75 0 0,1 16.5,8.25A0.75,0.75 0 0,1 15.75,9A0.75,0.75 0 0,1 15,8.25A0.75,0.75 0 0,1 15.75,7.5Z'; const repoIcon = repo.includes('github.com') ? github : generic; indexContent = indexContent.replace(/([ ]*)/, (match: any, indent: any) => { return [ indent, ``, ' ', ` `, ' ', ' View Repo', '' ].join(`\n${indent}`) }); indexContent = indexContent.replace(/const repo = '';/, (match: any) => { return `const repo = '${repo}';`; }); indexContent = indexContent.replace(/const repoComponent = '';/, (match: any) => { return `const repoComponent = '${repoComponent.replace(/\$repo/g, repo)}';`; }); indexContent = indexContent.replace(/const repoIcon = '';/, (match: any) => { return `const repoIcon = '${repoIcon}';`; }); } // info message if (mode === 'dev') { indexContent = indexContent.replace(/([ ]*)/, (match: any, indent: any) => { return [ indent, '

This page is generated from npm start. To render only specific components use npm start c-button.

' ].join(`\n${indent}`) }); } // Components const classNames = [...componentMap.keys()]; indexContent = indexContent.replace(/([ ]*)const componentMap = new Map\(\);/, (match: any, indent: any) => { return [ `${indent}const componentMap = new Map();`, ...classNames.map((className: any) => { const data = componentMap.get(className); return `componentMap.set('${className}', ${JSON.stringify(data)});`; }) ].join(`${indent}\n`) }); // Components indexContent = indexContent.replace(/([ ]*)const navigation = \[\];/, (match: any, indent: any) => { return `${indent}const navigation = ${JSON.stringify(navItems, null, ' ')};`; }); return indexContent; }