diff --git a/src/site.ts b/src/site.ts
index 231903c..7f43513 100644
--- a/src/site.ts
+++ b/src/site.ts
@@ -21,43 +21,125 @@ export const updateLatest = async (versionsDir: string, latestVersion: string):
await cp(join(versionsDir, latestVersion), latestDir, { recursive: true });
};
-const renderIndexPage = (versions: string[], latest?: string): string => {
- const latestLink = latest
- ? `
latest (${latest})\n `
- : '';
- const versionLinks = versions
- .map((version) => `${version}`)
- .join('\n ');
- return `
+const renderStylesheets = (styleBase?: string): string => {
+ if (styleBase === undefined) {
+ return '';
+ }
+ return `
+
+
+
+
+ `;
+};
+
+const renderLatestCard = (latest?: string): string => {
+ if (latest === undefined) {
+ return ``;
+ }
+ return ``;
+};
+
+const renderPrereleaseBadge = (version: string): string => {
+ if (semver.prerelease(version) === null) {
+ return '';
+ }
+ return 'pre-release';
+};
+
+const renderVersionItem = (version: string): string =>
+ `${version}${renderPrereleaseBadge(version)}`;
+
+const findStyleBase = (versions: string[], latest?: string): string | undefined => {
+ if (latest !== undefined) {
+ return `styles/${LATEST_DIR}`;
+ }
+ if (versions.length > 0) {
+ return `styles/${versions[0]}`;
+ }
+ return undefined;
+};
+
+const renderVersionList = (versions: string[]): string => {
+ if (versions.length === 0) {
+ return 'No versions have been published yet.
';
+ }
+ return `\n ${versions.map(renderVersionItem).join('\n ')}\n
`;
+};
+
+export const renderIndexPage = (versions: string[], latest?: string): string =>
+ `
Ippon UI Pattern Library
-
+
+ ${renderStylesheets(findStyleBase(versions, latest))}
- Ippon UI Pattern Library
- Published versions of @ippon-ui/styles:
-
- ${latestLink}${versionLinks}
-
- Versions are also listed in versions.json.
+
+
+
+
+
+
+
+
+
Styles
+
+ The Pattern Library — every published version of
+ @ippon-ui/styles, mirrored from npm.
+
+
+ ${renderLatestCard(latest)}
+
+ All versions
+ ${renderVersionList(versions)}
+
+
+
+
+
+
+
+
`;
-};
export const generateSitePages = async (
siteDir: string,
diff --git a/test/site.test.ts b/test/site.test.ts
index ce86b43..7d1730f 100644
--- a/test/site.test.ts
+++ b/test/site.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
-import { findLatestStable } from '../src/site.ts';
+import { findLatestStable, renderIndexPage } from '../src/site.ts';
describe('findLatestStable', () => {
it('should return the highest version', () => {
@@ -15,3 +15,55 @@ describe('findLatestStable', () => {
expect(findLatestStable([])).toBeUndefined();
});
});
+
+describe('renderIndexPage', () => {
+ it('should link every version', () => {
+ const html = renderIndexPage(['0.0.2', '0.0.1'], '0.0.2');
+ expect(html).toContain('href="styles/0.0.2/index.html"');
+ expect(html).toContain('href="styles/0.0.1/index.html"');
+ expect(html).toContain('href="versions.json"');
+ });
+
+ it('should feature the latest stable version', () => {
+ const html = renderIndexPage(['0.0.2'], '0.0.2');
+ expect(html).toContain('href="styles/latest/index.html"');
+ expect(html).toContain('v0.0.2');
+ });
+
+ it('should style the page with the pattern library of the latest stable version', () => {
+ const html = renderIndexPage(['0.0.2'], '0.0.2');
+ expect(html).toContain('href="styles/latest/tikui.css"');
+ });
+
+ it('should not link latest when there is no stable version', () => {
+ const html = renderIndexPage(['0.1.0-beta.1']);
+ expect(html).not.toContain('href="styles/latest/index.html"');
+ expect(html).toContain('No stable release yet');
+ });
+
+ it('should fall back to the highest version stylesheet when there is no stable version', () => {
+ const html = renderIndexPage(['0.1.0-beta.1']);
+ expect(html).toContain('href="styles/0.1.0-beta.1/tikui.css"');
+ });
+
+ it('should render without a stylesheet when no version is published', () => {
+ const html = renderIndexPage([]);
+ expect(html).not.toContain('tikui.css');
+ });
+
+ it('should tag prereleases', () => {
+ const html = renderIndexPage(['0.1.0-beta.1', '0.0.1'], '0.0.1');
+ expect(html.match(/pre-release/g)).toHaveLength(1);
+ });
+
+ it('should render an empty state when no version is published', () => {
+ const html = renderIndexPage([]);
+ expect(html).toContain('No versions have been published yet.');
+ });
+
+ it('should only use pattern library styles', () => {
+ const html = renderIndexPage(['0.0.2'], '0.0.2');
+ expect(html).not.toContain('