From d1014de68415df8f0a5dc3389332e086119c6198 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Thu, 27 Nov 2025 04:02:06 +0900 Subject: refactor(nuldoc): eliminate JSX --- .../nuldoc-src/components/AboutGlobalHeader.ts | 18 ++++ .../nuldoc-src/components/AboutGlobalHeader.tsx | 13 --- .../nuldoc-src/components/BlogGlobalHeader.ts | 34 +++++++ .../nuldoc-src/components/BlogGlobalHeader.tsx | 29 ------ .../nuldoc-src/components/DefaultGlobalHeader.ts | 18 ++++ .../nuldoc-src/components/DefaultGlobalHeader.tsx | 13 --- .../nuldoc/nuldoc-src/components/GlobalFooter.ts | 10 ++ .../nuldoc/nuldoc-src/components/GlobalFooter.tsx | 9 -- .../nuldoc/nuldoc-src/components/PageLayout.ts | 76 +++++++++++++++ .../nuldoc/nuldoc-src/components/PageLayout.tsx | 65 ------------- .../nuldoc/nuldoc-src/components/Pagination.ts | 98 +++++++++++++++++++ .../nuldoc/nuldoc-src/components/Pagination.tsx | 104 --------------------- .../nuldoc/nuldoc-src/components/PostPageEntry.ts | 49 ++++++++++ .../nuldoc/nuldoc-src/components/PostPageEntry.tsx | 46 --------- .../nuldoc/nuldoc-src/components/SlidePageEntry.ts | 49 ++++++++++ .../nuldoc-src/components/SlidePageEntry.tsx | 46 --------- .../nuldoc-src/components/SlidesGlobalHeader.ts | 33 +++++++ .../nuldoc-src/components/SlidesGlobalHeader.tsx | 26 ------ .../nuldoc/nuldoc-src/components/StaticScript.ts | 20 ++++ .../nuldoc/nuldoc-src/components/StaticScript.tsx | 18 ---- .../nuldoc-src/components/StaticStylesheet.ts | 12 +++ .../nuldoc-src/components/StaticStylesheet.tsx | 11 --- .../nuldoc-src/components/TableOfContents.ts | 34 +++++++ .../nuldoc-src/components/TableOfContents.tsx | 33 ------- services/nuldoc/nuldoc-src/components/TagList.ts | 17 ++++ services/nuldoc/nuldoc-src/components/TagList.tsx | 18 ---- 26 files changed, 468 insertions(+), 431 deletions(-) create mode 100644 services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts delete mode 100644 services/nuldoc/nuldoc-src/components/AboutGlobalHeader.tsx create mode 100644 services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts delete mode 100644 services/nuldoc/nuldoc-src/components/BlogGlobalHeader.tsx create mode 100644 services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts delete mode 100644 services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.tsx create mode 100644 services/nuldoc/nuldoc-src/components/GlobalFooter.ts delete mode 100644 services/nuldoc/nuldoc-src/components/GlobalFooter.tsx create mode 100644 services/nuldoc/nuldoc-src/components/PageLayout.ts delete mode 100644 services/nuldoc/nuldoc-src/components/PageLayout.tsx create mode 100644 services/nuldoc/nuldoc-src/components/Pagination.ts delete mode 100644 services/nuldoc/nuldoc-src/components/Pagination.tsx create mode 100644 services/nuldoc/nuldoc-src/components/PostPageEntry.ts delete mode 100644 services/nuldoc/nuldoc-src/components/PostPageEntry.tsx create mode 100644 services/nuldoc/nuldoc-src/components/SlidePageEntry.ts delete mode 100644 services/nuldoc/nuldoc-src/components/SlidePageEntry.tsx create mode 100644 services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts delete mode 100644 services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.tsx create mode 100644 services/nuldoc/nuldoc-src/components/StaticScript.ts delete mode 100644 services/nuldoc/nuldoc-src/components/StaticScript.tsx create mode 100644 services/nuldoc/nuldoc-src/components/StaticStylesheet.ts delete mode 100644 services/nuldoc/nuldoc-src/components/StaticStylesheet.tsx create mode 100644 services/nuldoc/nuldoc-src/components/TableOfContents.ts delete mode 100644 services/nuldoc/nuldoc-src/components/TableOfContents.tsx create mode 100644 services/nuldoc/nuldoc-src/components/TagList.ts delete mode 100644 services/nuldoc/nuldoc-src/components/TagList.tsx (limited to 'services/nuldoc/nuldoc-src/components') diff --git a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts new file mode 100644 index 0000000..b6ef84c --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.ts @@ -0,0 +1,18 @@ +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; + +export default function GlobalHeader({ config }: { config: Config }): Element { + return elem( + "header", + { class: "header" }, + elem( + "div", + { class: "site-logo" }, + elem( + "a", + { href: `https://${config.sites.default.fqdn}/` }, + "nsfisis.dev", + ), + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.tsx b/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.tsx deleted file mode 100644 index 2df7296..0000000 --- a/services/nuldoc/nuldoc-src/components/AboutGlobalHeader.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Config } from "../config.ts"; - -export default function GlobalHeader({ config }: { config: Config }) { - return ( -
-
- - nsfisis.dev - -
-
- ); -} diff --git a/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts new file mode 100644 index 0000000..034c2ab --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.ts @@ -0,0 +1,34 @@ +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; + +export default function GlobalHeader({ config }: { config: Config }): Element { + return elem( + "header", + { class: "header" }, + elem( + "div", + { class: "site-logo" }, + elem( + "a", + { href: `https://${config.sites.default.fqdn}/` }, + "nsfisis.dev", + ), + ), + elem("div", { class: "site-name" }, config.sites.blog.siteName), + elem( + "nav", + { class: "nav" }, + elem( + "ul", + {}, + elem( + "li", + {}, + elem("a", { href: `https://${config.sites.about.fqdn}/` }, "About"), + ), + elem("li", {}, elem("a", { href: "/posts/" }, "Posts")), + elem("li", {}, elem("a", { href: "/tags/" }, "Tags")), + ), + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.tsx b/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.tsx deleted file mode 100644 index 1f7fe6e..0000000 --- a/services/nuldoc/nuldoc-src/components/BlogGlobalHeader.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Config } from "../config.ts"; - -export default function GlobalHeader({ config }: { config: Config }) { - return ( -
-
- - nsfisis.dev - -
-
- {config.sites.blog.siteName} -
- -
- ); -} diff --git a/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts new file mode 100644 index 0000000..b6ef84c --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.ts @@ -0,0 +1,18 @@ +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; + +export default function GlobalHeader({ config }: { config: Config }): Element { + return elem( + "header", + { class: "header" }, + elem( + "div", + { class: "site-logo" }, + elem( + "a", + { href: `https://${config.sites.default.fqdn}/` }, + "nsfisis.dev", + ), + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.tsx b/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.tsx deleted file mode 100644 index 2df7296..0000000 --- a/services/nuldoc/nuldoc-src/components/DefaultGlobalHeader.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Config } from "../config.ts"; - -export default function GlobalHeader({ config }: { config: Config }) { - return ( -
-
- - nsfisis.dev - -
-
- ); -} diff --git a/services/nuldoc/nuldoc-src/components/GlobalFooter.ts b/services/nuldoc/nuldoc-src/components/GlobalFooter.ts new file mode 100644 index 0000000..835d73f --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/GlobalFooter.ts @@ -0,0 +1,10 @@ +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; + +export default function GlobalFooter({ config }: { config: Config }): Element { + return elem( + "footer", + { class: "footer" }, + `© ${config.site.copyrightYear} ${config.site.author}`, + ); +} diff --git a/services/nuldoc/nuldoc-src/components/GlobalFooter.tsx b/services/nuldoc/nuldoc-src/components/GlobalFooter.tsx deleted file mode 100644 index 9374aa7..0000000 --- a/services/nuldoc/nuldoc-src/components/GlobalFooter.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Config } from "../config.ts"; - -export default function GlobalFooter({ config }: { config: Config }) { - return ( - - ); -} diff --git a/services/nuldoc/nuldoc-src/components/PageLayout.ts b/services/nuldoc/nuldoc-src/components/PageLayout.ts new file mode 100644 index 0000000..19a8e86 --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/PageLayout.ts @@ -0,0 +1,76 @@ +import { Config } from "../config.ts"; +import { elem, Element, Node } from "../dom.ts"; +import StaticStylesheet from "./StaticStylesheet.ts"; + +type Props = { + metaCopyrightYear: number; + metaDescription: string; + metaKeywords?: string[]; + metaTitle: string; + metaAtomFeedHref?: string; + requiresSyntaxHighlight?: boolean; + site: "default" | "about" | "blog" | "slides"; + config: Config; + children: Node; +}; + +export default async function PageLayout( + { + metaCopyrightYear, + metaDescription, + metaKeywords, + metaTitle, + metaAtomFeedHref, + requiresSyntaxHighlight: _, + site, + config, + children, + }: Props, +): Promise { + return elem( + "html", + { lang: "ja-JP" }, + elem( + "head", + {}, + elem("meta", { charset: "UTF-8" }), + elem("meta", { + name: "viewport", + content: "width=device-width, initial-scale=1.0", + }), + elem("meta", { name: "author", content: config.site.author }), + elem("meta", { + name: "copyright", + content: `© ${metaCopyrightYear} ${config.site.author}`, + }), + elem("meta", { name: "description", content: metaDescription }), + metaKeywords && metaKeywords.length !== 0 + ? elem("meta", { name: "keywords", content: metaKeywords.join(",") }) + : null, + elem("meta", { property: "og:type", content: "article" }), + elem("meta", { property: "og:title", content: metaTitle }), + elem("meta", { property: "og:description", content: metaDescription }), + elem("meta", { + property: "og:site_name", + content: config.sites[site].siteName, + }), + elem("meta", { property: "og:locale", content: "ja_JP" }), + elem("meta", { name: "Hatena::Bookmark", content: "nocomment" }), + metaAtomFeedHref + ? elem("link", { + rel: "alternate", + href: metaAtomFeedHref, + type: "application/atom+xml", + }) + : null, + elem("link", { + rel: "icon", + href: "/favicon.svg", + type: "image/svg+xml", + }), + elem("title", {}, metaTitle), + await StaticStylesheet({ fileName: "/style.css", config }), + ), + children, + ); +} diff --git a/services/nuldoc/nuldoc-src/components/PageLayout.tsx b/services/nuldoc/nuldoc-src/components/PageLayout.tsx deleted file mode 100644 index b32f229..0000000 --- a/services/nuldoc/nuldoc-src/components/PageLayout.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import { Config } from "../config.ts"; -import { JSXNode } from "myjsx/jsx-runtime"; -import StaticStylesheet from "./StaticStylesheet.tsx"; - -type Props = { - metaCopyrightYear: number; - metaDescription: string; - metaKeywords?: string[]; - metaTitle: string; - metaAtomFeedHref?: string; - requiresSyntaxHighlight?: boolean; - site: "default" | "about" | "blog" | "slides"; - config: Config; - children: JSXNode; -}; - -export default function PageLayout( - { - metaCopyrightYear, - metaDescription, - metaKeywords, - metaTitle, - metaAtomFeedHref, - requiresSyntaxHighlight: _, - site, - config, - children, - }: Props, -) { - return ( - - - - - - - - {metaKeywords && metaKeywords.length !== 0 && - } - - - - - - {/* https://b.hatena.ne.jp/help/entry/nocomment */} - - {metaAtomFeedHref && - ( - - )} - - {metaTitle} - - - {children} - - ); -} diff --git a/services/nuldoc/nuldoc-src/components/Pagination.ts b/services/nuldoc/nuldoc-src/components/Pagination.ts new file mode 100644 index 0000000..62e796b --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/Pagination.ts @@ -0,0 +1,98 @@ +import { elem, Element } from "../dom.ts"; + +type Props = { + currentPage: number; + totalPages: number; + basePath: string; +}; + +export default function Pagination( + { currentPage, totalPages, basePath }: Props, +): Element { + if (totalPages <= 1) { + return elem("div", {}); + } + + const pages = generatePageNumbers(currentPage, totalPages); + + return elem( + "nav", + { class: "pagination" }, + elem( + "div", + { class: "pagination-prev" }, + currentPage > 1 + ? elem("a", { href: pageUrlAt(basePath, currentPage - 1) }, "前へ") + : null, + ), + ...pages.map((page) => { + if (page === "...") { + return elem("div", { class: "pagination-elipsis" }, "…"); + } else if (page === currentPage) { + return elem( + "div", + { class: "pagination-page pagination-page-current" }, + elem("span", {}, String(page)), + ); + } else { + return elem( + "div", + { class: "pagination-page" }, + elem("a", { href: pageUrlAt(basePath, page) }, String(page)), + ); + } + }), + elem( + "div", + { class: "pagination-next" }, + currentPage < totalPages + ? elem("a", { href: pageUrlAt(basePath, currentPage + 1) }, "次へ") + : null, + ), + ); +} + +type PageItem = number | "..."; + +/** + * Generates page numbers for pagination display. + * + * - Always show the first page + * - Always show the last page + * - Always show the current page + * - Always show the page before and after the current page + * - If there's only one page gap between displayed pages, fill it + * - If there are two or more pages gap between displayed pages, show ellipsis + */ +function generatePageNumbers( + currentPage: number, + totalPages: number, +): PageItem[] { + const pages = new Set(); + pages.add(1); + pages.add(Math.max(1, currentPage - 1)); + pages.add(currentPage); + pages.add(Math.min(totalPages, currentPage + 1)); + pages.add(totalPages); + + const sorted = Array.from(pages).sort((a, b) => a - b); + + const result: PageItem[] = []; + for (let i = 0; i < sorted.length; i++) { + if (i > 0) { + const gap = sorted[i] - sorted[i - 1]; + if (gap === 2) { + result.push(sorted[i - 1] + 1); + } else if (gap > 2) { + result.push("..."); + } + } + result.push(sorted[i]); + } + + return result; +} + +function pageUrlAt(basePath: string, page: number): string { + return page === 1 ? basePath : `${basePath}${page}/`; +} diff --git a/services/nuldoc/nuldoc-src/components/Pagination.tsx b/services/nuldoc/nuldoc-src/components/Pagination.tsx deleted file mode 100644 index 84752c5..0000000 --- a/services/nuldoc/nuldoc-src/components/Pagination.tsx +++ /dev/null @@ -1,104 +0,0 @@ -type Props = { - currentPage: number; - totalPages: number; - basePath: string; -}; - -export default function Pagination( - { currentPage, totalPages, basePath }: Props, -) { - if (totalPages <= 1) { - return
; - } - - const pages = generatePageNumbers(currentPage, totalPages); - - return ( - - ); -} - -type PageItem = number | "..."; - -/** - * Generates page numbers for pagination display. - * - * - Always show the first page - * - Always show the last page - * - Always show the current page - * - Always show the page before and after the current page - * - If there's only one page gap between displayed pages, fill it - * - If there are two or more pages gap between displayed pages, show ellipsis - */ -function generatePageNumbers( - currentPage: number, - totalPages: number, -): PageItem[] { - const pages = new Set(); - pages.add(1); - pages.add(Math.max(1, currentPage - 1)); - pages.add(currentPage); - pages.add(Math.min(totalPages, currentPage + 1)); - pages.add(totalPages); - - const sorted = Array.from(pages).sort((a, b) => a - b); - - const result: PageItem[] = []; - for (let i = 0; i < sorted.length; i++) { - if (i > 0) { - const gap = sorted[i] - sorted[i - 1]; - if (gap === 2) { - result.push(sorted[i - 1] + 1); - } else if (gap > 2) { - result.push("..."); - } - } - result.push(sorted[i]); - } - - return result; -} - -function pageUrlAt(basePath: string, page: number): string { - return page === 1 ? basePath : `${basePath}${page}/`; -} diff --git a/services/nuldoc/nuldoc-src/components/PostPageEntry.ts b/services/nuldoc/nuldoc-src/components/PostPageEntry.ts new file mode 100644 index 0000000..75ad11c --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/PostPageEntry.ts @@ -0,0 +1,49 @@ +import { + getPostPublishedDate, + getPostUpdatedDate, + postHasAnyUpdates, + PostPage, +} from "../generators/post.ts"; +import { dateToString } from "../revision.ts"; +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; +import TagList from "./TagList.ts"; + +type Props = { post: PostPage; config: Config }; + +export default function PostPageEntry({ post, config }: Props): Element { + return elem( + "article", + { class: "post-entry" }, + elem( + "a", + { href: post.href }, + elem("header", { class: "entry-header" }, elem("h2", {}, post.title)), + elem( + "section", + { class: "entry-content" }, + elem("p", {}, post.description), + ), + elem( + "footer", + { class: "entry-footer" }, + elem( + "time", + { datetime: dateToString(getPostPublishedDate(post)) }, + dateToString(getPostPublishedDate(post)), + ), + " 投稿", + postHasAnyUpdates(post) ? "、" : null, + postHasAnyUpdates(post) + ? elem( + "time", + { datetime: dateToString(getPostUpdatedDate(post)) }, + dateToString(getPostUpdatedDate(post)), + ) + : null, + postHasAnyUpdates(post) ? " 更新" : null, + post.tags.length !== 0 ? TagList({ tags: post.tags, config }) : null, + ), + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/PostPageEntry.tsx b/services/nuldoc/nuldoc-src/components/PostPageEntry.tsx deleted file mode 100644 index 23ca88a..0000000 --- a/services/nuldoc/nuldoc-src/components/PostPageEntry.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { - getPostPublishedDate, - getPostUpdatedDate, - postHasAnyUpdates, - PostPage, -} from "../generators/post.ts"; -import { dateToString } from "../revision.ts"; -import { Config } from "../config.ts"; -import TagList from "./TagList.tsx"; - -type Props = { post: PostPage; config: Config }; - -export default function PostPageEntry({ post, config }: Props) { - return ( - - ); -} diff --git a/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts b/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts new file mode 100644 index 0000000..1dc5f1a --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/SlidePageEntry.ts @@ -0,0 +1,49 @@ +import { + getPostPublishedDate, + getPostUpdatedDate, + postHasAnyUpdates, +} from "../generators/post.ts"; +import { SlidePage } from "../generators/slide.ts"; +import { dateToString } from "../revision.ts"; +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; +import TagList from "./TagList.ts"; + +type Props = { slide: SlidePage; config: Config }; + +export default function SlidePageEntry({ slide, config }: Props): Element { + return elem( + "article", + { class: "post-entry" }, + elem( + "a", + { href: slide.href }, + elem( + "header", + { class: "entry-header" }, + elem("h2", {}, slide.description), + ), + elem("section", { class: "entry-content" }, elem("p", {}, slide.title)), + elem( + "footer", + { class: "entry-footer" }, + elem( + "time", + { datetime: dateToString(getPostPublishedDate(slide)) }, + dateToString(getPostPublishedDate(slide)), + ), + " 登壇", + postHasAnyUpdates(slide) ? "、" : null, + postHasAnyUpdates(slide) + ? elem( + "time", + { datetime: dateToString(getPostUpdatedDate(slide)) }, + dateToString(getPostUpdatedDate(slide)), + ) + : null, + postHasAnyUpdates(slide) ? " 更新" : null, + slide.tags.length !== 0 ? TagList({ tags: slide.tags, config }) : null, + ), + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/SlidePageEntry.tsx b/services/nuldoc/nuldoc-src/components/SlidePageEntry.tsx deleted file mode 100644 index 2401765..0000000 --- a/services/nuldoc/nuldoc-src/components/SlidePageEntry.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { - getPostPublishedDate, - getPostUpdatedDate, - postHasAnyUpdates, -} from "../generators/post.ts"; -import { SlidePage } from "../generators/slide.ts"; -import { dateToString } from "../revision.ts"; -import { Config } from "../config.ts"; -import TagList from "./TagList.tsx"; - -type Props = { slide: SlidePage; config: Config }; - -export default function SlidePageEntry({ slide, config }: Props) { - return ( - - ); -} diff --git a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts b/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts new file mode 100644 index 0000000..902e12f --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.ts @@ -0,0 +1,33 @@ +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; + +export default function GlobalHeader({ config }: { config: Config }): Element { + return elem( + "header", + { class: "header" }, + elem( + "div", + { class: "site-logo" }, + elem( + "a", + { href: `https://${config.sites.default.fqdn}/` }, + "nsfisis.dev", + ), + ), + elem( + "nav", + { class: "nav" }, + elem( + "ul", + {}, + elem( + "li", + {}, + elem("a", { href: `https://${config.sites.about.fqdn}/` }, "About"), + ), + elem("li", {}, elem("a", { href: "/slides/" }, "Slides")), + elem("li", {}, elem("a", { href: "/tags/" }, "Tags")), + ), + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.tsx b/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.tsx deleted file mode 100644 index 4d93240..0000000 --- a/services/nuldoc/nuldoc-src/components/SlidesGlobalHeader.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Config } from "../config.ts"; - -export default function GlobalHeader({ config }: { config: Config }) { - return ( -
- - -
- ); -} diff --git a/services/nuldoc/nuldoc-src/components/StaticScript.ts b/services/nuldoc/nuldoc-src/components/StaticScript.ts new file mode 100644 index 0000000..7df40fd --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/StaticScript.ts @@ -0,0 +1,20 @@ +import { join } from "@std/path"; +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; +import { calculateFileHash } from "./utils.ts"; + +export default async function StaticScript( + { fileName, type, defer, config }: { + fileName: string; + type?: string; + defer?: "true"; + config: Config; + }, +): Promise { + const filePath = join(Deno.cwd(), config.locations.staticDir, fileName); + const hash = await calculateFileHash(filePath); + const attrs: Record = { src: `${fileName}?h=${hash}` }; + if (type) attrs.type = type; + if (defer) attrs.defer = defer; + return elem("script", attrs); +} diff --git a/services/nuldoc/nuldoc-src/components/StaticScript.tsx b/services/nuldoc/nuldoc-src/components/StaticScript.tsx deleted file mode 100644 index 0e3ab19..0000000 --- a/services/nuldoc/nuldoc-src/components/StaticScript.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { join } from "@std/path"; -import { Config } from "../config.ts"; -import { calculateFileHash } from "./utils.ts"; - -export default async function StaticScript( - { fileName, type, defer, config }: { - fileName: string; - type?: string; - defer?: "true"; - config: Config; - }, -) { - const filePath = join(Deno.cwd(), config.locations.staticDir, fileName); - const hash = await calculateFileHash(filePath); - return ( - - ); -} diff --git a/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts b/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts new file mode 100644 index 0000000..43802d2 --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/StaticStylesheet.ts @@ -0,0 +1,12 @@ +import { join } from "@std/path"; +import { Config } from "../config.ts"; +import { elem, Element } from "../dom.ts"; +import { calculateFileHash } from "./utils.ts"; + +export default async function StaticStylesheet( + { fileName, config }: { fileName: string; config: Config }, +): Promise { + const filePath = join(Deno.cwd(), config.locations.staticDir, fileName); + const hash = await calculateFileHash(filePath); + return elem("link", { rel: "stylesheet", href: `${fileName}?h=${hash}` }); +} diff --git a/services/nuldoc/nuldoc-src/components/StaticStylesheet.tsx b/services/nuldoc/nuldoc-src/components/StaticStylesheet.tsx deleted file mode 100644 index 52b695e..0000000 --- a/services/nuldoc/nuldoc-src/components/StaticStylesheet.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { join } from "@std/path"; -import { Config } from "../config.ts"; -import { calculateFileHash } from "./utils.ts"; - -export default async function StaticStylesheet( - { fileName, config }: { fileName: string; config: Config }, -) { - const filePath = join(Deno.cwd(), config.locations.staticDir, fileName); - const hash = await calculateFileHash(filePath); - return ; -} diff --git a/services/nuldoc/nuldoc-src/components/TableOfContents.ts b/services/nuldoc/nuldoc-src/components/TableOfContents.ts new file mode 100644 index 0000000..ac4205a --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/TableOfContents.ts @@ -0,0 +1,34 @@ +import { TocEntry, TocRoot } from "../djot/document.ts"; +import { elem, Element } from "../dom.ts"; + +type Props = { + toc: TocRoot; +}; + +export default function TableOfContents({ toc }: Props): Element { + return elem( + "nav", + { class: "toc" }, + elem("h2", {}, "目次"), + elem( + "ul", + {}, + ...toc.entries.map((entry) => TocEntryComponent({ entry })), + ), + ); +} + +function TocEntryComponent({ entry }: { entry: TocEntry }): Element { + return elem( + "li", + {}, + elem("a", { href: `#${entry.id}` }, entry.text), + entry.children.length > 0 + ? elem( + "ul", + {}, + ...entry.children.map((child) => TocEntryComponent({ entry: child })), + ) + : null, + ); +} diff --git a/services/nuldoc/nuldoc-src/components/TableOfContents.tsx b/services/nuldoc/nuldoc-src/components/TableOfContents.tsx deleted file mode 100644 index 29907d0..0000000 --- a/services/nuldoc/nuldoc-src/components/TableOfContents.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { TocEntry, TocRoot } from "../djot/document.ts"; - -type Props = { - toc: TocRoot; -}; - -export default function TableOfContents({ toc }: Props) { - return ( - - ); -} - -function TocEntryComponent({ entry }: { entry: TocEntry }) { - return ( -
  • - {entry.text} - {entry.children.length > 0 && ( -
      - {entry.children.map((child, index) => ( - - ))} -
    - )} -
  • - ); -} diff --git a/services/nuldoc/nuldoc-src/components/TagList.ts b/services/nuldoc/nuldoc-src/components/TagList.ts new file mode 100644 index 0000000..540abe6 --- /dev/null +++ b/services/nuldoc/nuldoc-src/components/TagList.ts @@ -0,0 +1,17 @@ +import { Config, getTagLabel } from "../config.ts"; +import { elem, Element, text } from "../dom.ts"; + +type Props = { + tags: string[]; + config: Config; +}; + +export default function TagList({ tags, config }: Props): Element { + return elem( + "ul", + { class: "entry-tags" }, + ...tags.map((slug) => + elem("li", { class: "tag" }, text(getTagLabel(config, slug))) + ), + ); +} diff --git a/services/nuldoc/nuldoc-src/components/TagList.tsx b/services/nuldoc/nuldoc-src/components/TagList.tsx deleted file mode 100644 index 86ee70b..0000000 --- a/services/nuldoc/nuldoc-src/components/TagList.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Config, getTagLabel } from "../config.ts"; - -type Props = { - tags: string[]; - config: Config; -}; - -export default function TagList({ tags, config }: Props) { - return ( -
      - {tags.map((slug) => ( -
    • - {getTagLabel(config, slug)} -
    • - ))} -
    - ); -} -- cgit v1.2.3-70-g09d2