for-humanity 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +16 -9
- package/dist/browser.js +16 -16
- package/dist/cli.css +2 -968
- package/dist/cli.js +92 -2318
- package/dist/config.js +1 -0
- package/dist/constant/copy.d.ts +100 -0
- package/dist/constant/site.d.ts +20 -0
- package/dist/constant/status.d.ts +19 -0
- package/dist/copy-C1uzvEnr.js +103 -0
- package/dist/group-path-XAThmzvC.js +10 -0
- package/dist/load-site-CbpLEhwu.js +2379 -0
- package/dist/logger-Dv1i9xSV.js +9 -0
- package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
- package/dist/mermaid/chunk--TN-qHgG.js +2 -0
- package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
- package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
- package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
- package/dist/mermaid/chunk-6HLei9i0.js +84 -0
- package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
- package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
- package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
- package/dist/mermaid/chunk-B--pNBQF.js +884 -0
- package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
- package/dist/mermaid/chunk-B58sEIY_.js +14 -0
- package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
- package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
- package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
- package/dist/mermaid/chunk-BKri0qr7.js +89 -0
- package/dist/mermaid/chunk-BL404pH5.js +26 -0
- package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
- package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
- package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
- package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
- package/dist/mermaid/chunk-BariMtWr.js +3020 -0
- package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
- package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
- package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
- package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
- package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
- package/dist/mermaid/chunk-BvVehae3.js +5069 -0
- package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
- package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
- package/dist/mermaid/chunk-CApNbSU9.js +6 -0
- package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
- package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
- package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
- package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
- package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
- package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
- package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
- package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
- package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
- package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
- package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
- package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
- package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
- package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
- package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
- package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
- package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
- package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
- package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
- package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
- package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
- package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
- package/dist/mermaid/chunk-CuYekbSv.js +2 -0
- package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
- package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
- package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
- package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
- package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
- package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
- package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
- package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
- package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
- package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
- package/dist/mermaid/chunk-DU69_VcF.js +363 -0
- package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
- package/dist/mermaid/chunk-DZe-4kde.js +20 -0
- package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
- package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
- package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
- package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
- package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
- package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
- package/dist/mermaid/chunk-DqGhppWe.js +2 -0
- package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
- package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
- package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
- package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
- package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
- package/dist/mermaid/chunk-KuPYb48V.js +275 -0
- package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
- package/dist/mermaid/chunk-MbInCS_6.js +28 -0
- package/dist/mermaid/chunk-MexOLyKV.js +355 -0
- package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
- package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
- package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
- package/dist/mermaid/chunk-TftHqGLg.js +490 -0
- package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
- package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
- package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
- package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
- package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
- package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
- package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
- package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
- package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
- package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
- package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
- package/dist/mermaid/chunk-yBz-vst0.js +976 -0
- package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
- package/dist/run-site-command-C80YoNOe.js +129 -0
- package/dist/site-config-bllORGpm.js +90 -0
- package/dist/site.js +1 -0
- package/dist/start-dev-server-C4_Lu1nZ.js +176 -0
- package/dist/to-change-queue-DbEnZGNK.js +34 -0
- package/dist/to-error-message-pF6_7wGK.js +16 -0
- package/dist/type/group-path.d.ts +7 -0
- package/dist/type/site-config.d.ts +57 -0
- package/package.json +34 -17
- package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
- package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
- package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
- package/src/component/widget/navigation/_constant/locale.ts +0 -9
- package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
- package/src/component/widget/navigation/_constant/navigation.ts +0 -9
- package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
- package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
- package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
- package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
- package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
- package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
- package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
- package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
- package/src/component/widget/navigation/_type/doc-group.ts +0 -24
- package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
- package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
- package/src/component/widget/navigation/_type/toc-group.ts +0 -39
- package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
- package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
- package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
- package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
- package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
- package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
- package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
- package/src/component/widget/navigation/wg-navigation.css +0 -282
- package/src/component/widget/navigation/wg-navigation.tsx +0 -420
- package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
- package/src/component/widget/prose/_constant/section.ts +0 -7
- package/src/component/widget/prose/_constant/status.ts +0 -9
- package/src/component/widget/prose/_function/has-block-content.ts +0 -30
- package/src/component/widget/prose/_function/rehype-head.ts +0 -31
- package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
- package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
- package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
- package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
- package/src/component/widget/prose/_function/remark-flow.ts +0 -26
- package/src/component/widget/prose/_function/remark-links.ts +0 -33
- package/src/component/widget/prose/_function/remark-parts.ts +0 -26
- package/src/component/widget/prose/_function/remark-status.ts +0 -59
- package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
- package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
- package/src/component/widget/prose/wg-prose.css +0 -484
- package/src/component/widget/prose/wg-prose.tsx +0 -43
- package/src/component/widget/shell/wg-shell.css +0 -63
- package/src/component/widget/shell/wg-shell.tsx +0 -88
- package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
- package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
- package/src/constant/asset.ts +0 -63
- package/src/constant/copy.ts +0 -133
- package/src/constant/doc.ts +0 -13
- package/src/constant/font.ts +0 -34
- package/src/constant/site.ts +0 -24
- package/src/constant/status.ts +0 -15
- package/src/entry/browser/browser.tsx +0 -22
- package/src/entry/cli/_constant/cli.ts +0 -19
- package/src/entry/cli/_constant/crawling.ts +0 -14
- package/src/entry/cli/_constant/snippet.ts +0 -21
- package/src/entry/cli/_function/create-app.tsx +0 -57
- package/src/entry/cli/_function/create-dev-app.ts +0 -87
- package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
- package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
- package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
- package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
- package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -91
- package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
- package/src/entry/cli/_function/read-docs.ts +0 -128
- package/src/entry/cli/_function/read-home.ts +0 -32
- package/src/entry/cli/_function/to-crawling-app.ts +0 -42
- package/src/entry/cli/cli.test.ts +0 -804
- package/src/entry/cli/cli.ts +0 -206
- package/src/env.d.ts +0 -6
- package/src/page/doc/pg-doc.tsx +0 -35
- package/src/page/home/pg-home.tsx +0 -40
- package/src/store/navigation/create-navigation-stores.test.ts +0 -74
- package/src/store/navigation/create-navigation-stores.ts +0 -59
- package/src/store/navigation/navigation-state.ts +0 -36
- package/src/store/navigation/navigation-storage.ts +0 -9
- package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
- package/src/style/base.css +0 -28
- package/src/style/token.css +0 -188
- package/src/type/doc-content.ts +0 -15
- package/src/type/doc-data.ts +0 -38
- package/src/type/doc-file-data.ts +0 -21
- package/src/type/doc-heading.ts +0 -17
- package/src/type/doc-outline.ts +0 -16
- package/src/type/doc-section.ts +0 -9
- package/src/type/doc.ts +0 -20
- package/src/type/group-path.ts +0 -7
- package/src/type/site-assets.ts +0 -25
- package/src/type/site-config.ts +0 -73
- package/src/type/vfile-data.d.ts +0 -10
- package/src/util/async/to-change-queue.test.ts +0 -58
- package/src/util/async/to-change-queue.ts +0 -43
- package/src/util/dom/find-hash-target.ts +0 -18
- package/src/util/dom/reveal-hash-target.ts +0 -15
- package/src/util/error/to-error-message.ts +0 -10
- package/src/util/file/to-asset-path.ts +0 -26
- package/src/util/font/to-font-css.test.ts +0 -41
- package/src/util/font/to-font-css.ts +0 -28
- package/src/util/mermaid/render-flow.js +0 -321
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 재귀 문서 목록 · 단계별 들여쓰기
|
|
3
|
-
*/
|
|
4
|
-
.wg_navigationNavList__root {
|
|
5
|
-
margin: 0;
|
|
6
|
-
padding: 0;
|
|
7
|
-
list-style: none;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.wg_navigationNavList__branch {
|
|
11
|
-
display: block;
|
|
12
|
-
padding: var(--app-space-tree-row) 0;
|
|
13
|
-
color: var(--app-color-text-muted);
|
|
14
|
-
font-size: var(--app-font-size-group);
|
|
15
|
-
line-height: calc(var(--app-font-size-dense) * var(--app-line-height-tight));
|
|
16
|
-
overflow-wrap: anywhere;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.wg_navigationNavList__link {
|
|
20
|
-
display: block;
|
|
21
|
-
padding: var(--app-space-tree-row) 0;
|
|
22
|
-
color: var(--app-color-link);
|
|
23
|
-
font-size: var(--app-font-size-dense);
|
|
24
|
-
line-height: var(--app-line-height-tight);
|
|
25
|
-
text-decoration: none;
|
|
26
|
-
overflow-wrap: anywhere;
|
|
27
|
-
|
|
28
|
-
&:where(:hover) {
|
|
29
|
-
text-decoration: underline;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/* hover와 같은 밑줄로 키보드 위치 표시 */
|
|
33
|
-
&:where(:focus-visible) {
|
|
34
|
-
outline: none;
|
|
35
|
-
text-decoration: underline;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.wg_navigationNavList__link--active {
|
|
40
|
-
color: var(--app-color-link);
|
|
41
|
-
font-weight: var(--app-font-weight-active);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.wg_navigationNavList__item {
|
|
45
|
-
& > .wg_navigationNavList__root {
|
|
46
|
-
margin-left: var(--app-space-tree-indent);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
import {Fragment} from "hono/jsx";
|
|
3
|
-
import type {NavigationGroup} from "@/component/widget/navigation/_type/navigation-data";
|
|
4
|
-
import "./_wg-navigation-nav-list.css";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 한 단계의 문서 목록과 하위 묶음 · 재귀에서도 같은 탐색 표현 유지
|
|
8
|
-
*/
|
|
9
|
-
export interface WgNavigationNavListProps {
|
|
10
|
-
/**
|
|
11
|
-
* 현재 단계의 문서와 하위 묶음
|
|
12
|
-
*/
|
|
13
|
-
group: NavigationGroup;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const WgNavigationNavList = (props: WgNavigationNavListProps) => {
|
|
17
|
-
const entries = [
|
|
18
|
-
...props.group.docs.map((doc) => ({kind: "document" as const, key: `doc:${doc.id}`, doc})),
|
|
19
|
-
...props.group.groups.map((group) => ({kind: "group" as const, key: `group:${JSON.stringify(group.path)}`, group})),
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<ul className={clsx("wg_navigationNavList__root")} aria-label={props.group.name}>
|
|
24
|
-
{/**
|
|
25
|
-
* 문서 링크는 원래 파일 URL 사용
|
|
26
|
-
*/}
|
|
27
|
-
{entries.map((entry) => (
|
|
28
|
-
<li className={clsx("wg_navigationNavList__item")} key={entry.key}>
|
|
29
|
-
{/**
|
|
30
|
-
* 문서 링크 · 부모도 독립 페이지, 현재 한 문서에만 페이지 상태 부여
|
|
31
|
-
*/}
|
|
32
|
-
{entry.kind === "document" && (
|
|
33
|
-
<Fragment>
|
|
34
|
-
<a
|
|
35
|
-
className={clsx("wg_navigationNavList__link", {"wg_navigationNavList__link--active": entry.doc.active})}
|
|
36
|
-
href={`/${entry.doc.id}/`}
|
|
37
|
-
title={entry.doc.label}
|
|
38
|
-
aria-current={entry.doc.active ? "page" : undefined}
|
|
39
|
-
>
|
|
40
|
-
{entry.doc.name}
|
|
41
|
-
</a>
|
|
42
|
-
{/**
|
|
43
|
-
* 하위 문서 · 부모 아래에서도 기존 목록의 들여쓰기와 키보드 이동 유지
|
|
44
|
-
*/}
|
|
45
|
-
{entry.doc.children.length > 0 && <WgNavigationNavList group={{name: entry.doc.name, path: props.group.path, docs: entry.doc.children, groups: []}} />}
|
|
46
|
-
</Fragment>
|
|
47
|
-
)}
|
|
48
|
-
{/**
|
|
49
|
-
* 하위 묶음 · 같은 목록을 재귀로 이어 깊이에 따라 들여쓰기
|
|
50
|
-
*/}
|
|
51
|
-
{entry.kind === "group" && (
|
|
52
|
-
<Fragment>
|
|
53
|
-
<span className={clsx("wg_navigationNavList__branch")}>{entry.group.name}</span>
|
|
54
|
-
<WgNavigationNavList group={entry.group} />
|
|
55
|
-
</Fragment>
|
|
56
|
-
)}
|
|
57
|
-
</li>
|
|
58
|
-
))}
|
|
59
|
-
</ul>
|
|
60
|
-
);
|
|
61
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 읽는 순서의 문서 목록 · 작은 회색 묶음과 링크색 문서
|
|
3
|
-
*/
|
|
4
|
-
.wg_navigationNav__root {
|
|
5
|
-
font-size: var(--app-font-size-dense);
|
|
6
|
-
line-height: var(--app-line-height-tight);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.wg_navigationNav__docs {
|
|
10
|
-
display: flex;
|
|
11
|
-
flex-direction: column;
|
|
12
|
-
gap: var(--app-space-tree-group);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.wg_navigationNav__group {
|
|
16
|
-
margin: 0 0 var(--app-space-tree-label);
|
|
17
|
-
color: var(--app-color-text-muted);
|
|
18
|
-
font-size: var(--app-font-size-group);
|
|
19
|
-
line-height: calc(var(--app-font-size-dense) * var(--app-line-height-tight));
|
|
20
|
-
text-box: trim-start cap alphabetic;
|
|
21
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
import type {NavigationGroup} from "@/component/widget/navigation/_type/navigation-data";
|
|
3
|
-
import {WgNavigationNavList} from "@/component/widget/navigation/_wg-navigation-nav-list";
|
|
4
|
-
import {copy_nav_aria_label} from "@/constant/copy";
|
|
5
|
-
import "./_wg-navigation-nav.css";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 서버·브라우저가 공유하는 문서 트리
|
|
9
|
-
*/
|
|
10
|
-
export interface WgNavigationNavProps {
|
|
11
|
-
/**
|
|
12
|
-
* 본문을 제외한 읽는 순서의 문서 묶음
|
|
13
|
-
*/
|
|
14
|
-
groups: NavigationGroup[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const WgNavigationNav = (props: WgNavigationNavProps) => {
|
|
18
|
-
return (
|
|
19
|
-
<nav className={clsx("wg_navigationNav__root")} aria-label={copy_nav_aria_label}>
|
|
20
|
-
{/**
|
|
21
|
-
* 문서 이동 · 클릭하지 않는 묶음과 독립 문서
|
|
22
|
-
*/}
|
|
23
|
-
<div className={clsx("wg_navigationNav__docs")}>
|
|
24
|
-
{props.groups.map((group) => (
|
|
25
|
-
<section className={clsx("wg_navigationNav__docGroup")} key={JSON.stringify(group.path)} aria-label={group.name}>
|
|
26
|
-
<div className={clsx("wg_navigationNav__group")}>{group.name}</div>
|
|
27
|
-
<WgNavigationNavList group={group} />
|
|
28
|
-
</section>
|
|
29
|
-
))}
|
|
30
|
-
</div>
|
|
31
|
-
</nav>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
import {type Child, type DOMAttributes, type RefObject, useLayoutEffect, useRef, useState} from "hono/jsx";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* 탐색 좌표를 제어하는 부모와 넘침 표시를 소유하는 스크롤 영역의 경계
|
|
6
|
-
*/
|
|
7
|
-
export interface WgNavigationScrollProps {
|
|
8
|
-
/**
|
|
9
|
-
* 배치별 좌표 복원과 저장에 필요한 실제 스크롤 요소
|
|
10
|
-
*/
|
|
11
|
-
portRef: RefObject<HTMLDivElement | null>;
|
|
12
|
-
/**
|
|
13
|
-
* 문서 목록과 현재 페이지 목차의 독립된 스크롤 수명
|
|
14
|
-
*/
|
|
15
|
-
kind: "documents" | "outline";
|
|
16
|
-
/**
|
|
17
|
-
* JavaScript가 연결된 뒤에만 손잡이를 넘침 표시로 대체
|
|
18
|
-
*/
|
|
19
|
-
ready: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* 탐색 링크를 포함한 영역 내용
|
|
22
|
-
*/
|
|
23
|
-
children: Child;
|
|
24
|
-
/**
|
|
25
|
-
* 이동 직전 좌표 보존과 모바일 모달 닫기
|
|
26
|
-
*/
|
|
27
|
-
onClick?: DOMAttributes["onClick"];
|
|
28
|
-
/**
|
|
29
|
-
* 실제 스크롤 좌표가 바뀔 때 부모 저장소에 반영
|
|
30
|
-
*/
|
|
31
|
-
onScroll?: () => void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const WgNavigationScroll = (props: WgNavigationScrollProps) => {
|
|
35
|
-
const [overflow, setOverflow] = useState({above: false, below: false});
|
|
36
|
-
const frameRef = useRef(0);
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 소수 픽셀 반올림을 제외한 실제 남은 내용만 위·아래 흐림으로 알림
|
|
40
|
-
*/
|
|
41
|
-
const updateOverflow = () => {
|
|
42
|
-
frameRef.current = 0;
|
|
43
|
-
if (props.portRef.current === null) return;
|
|
44
|
-
const above = props.portRef.current.scrollTop > 1;
|
|
45
|
-
const below = props.portRef.current.scrollHeight - props.portRef.current.clientHeight - props.portRef.current.scrollTop > 1;
|
|
46
|
-
setOverflow((state) => (state.above === above && state.below === below ? state : {above, below}));
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 연속 스크롤과 관찰자 알림은 프레임당 한 번 측정
|
|
51
|
-
*/
|
|
52
|
-
const scheduleOverflow = () => {
|
|
53
|
-
if (frameRef.current === 0) frameRef.current = requestAnimationFrame(updateOverflow);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* 네이티브 좌표는 바로 저장하고 시각적 넘침만 프레임에 맞춰 갱신
|
|
58
|
-
*/
|
|
59
|
-
const handlePortScroll: DOMAttributes["onScroll"] = (_event) => {
|
|
60
|
-
props.onScroll?.();
|
|
61
|
-
scheduleOverflow();
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 영역과 내용의 크기를 함께 추적 · Hono 최초 mount의 분리된 fragment 측정은 연결 직후 실행
|
|
66
|
-
*/
|
|
67
|
-
useLayoutEffect(() => {
|
|
68
|
-
if (!props.ready || props.portRef.current === null) return;
|
|
69
|
-
const observer = new ResizeObserver(scheduleOverflow);
|
|
70
|
-
observer.observe(props.portRef.current);
|
|
71
|
-
if (props.portRef.current.firstElementChild !== null) observer.observe(props.portRef.current.firstElementChild);
|
|
72
|
-
let active = true;
|
|
73
|
-
addEventListener("pageshow", scheduleOverflow);
|
|
74
|
-
if (props.portRef.current.isConnected) {
|
|
75
|
-
updateOverflow();
|
|
76
|
-
} else {
|
|
77
|
-
// Hono는 최초 layout effect를 fragment에서 실행하므로 같은 script의 paint 전 microtask에서 측정한다
|
|
78
|
-
queueMicrotask(() => {
|
|
79
|
-
if (active) updateOverflow();
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
return () => {
|
|
83
|
-
active = false;
|
|
84
|
-
observer.disconnect();
|
|
85
|
-
removeEventListener("pageshow", scheduleOverflow);
|
|
86
|
-
cancelAnimationFrame(frameRef.current);
|
|
87
|
-
frameRef.current = 0;
|
|
88
|
-
};
|
|
89
|
-
}, [props.portRef, props.ready]);
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 접힘 선택의 렌더가 바뀐 직후 측정 · 좌표 복원은 부모의 연결 후 처리보다 앞서 저장하지 않음
|
|
93
|
-
*/
|
|
94
|
-
useLayoutEffect(() => {
|
|
95
|
-
if (props.ready && props.portRef.current?.isConnected) updateOverflow();
|
|
96
|
-
}, [props.children, props.ready]);
|
|
97
|
-
|
|
98
|
-
return (
|
|
99
|
-
// biome-ignore lint/a11y/noStaticElementInteractions lint/a11y/useKeyWithClickEvents: 부모의 링크 이벤트 위임이며 자식 a·button의 네이티브 키보드 동작을 그대로 소비한다
|
|
100
|
-
<div
|
|
101
|
-
ref={props.ready ? props.portRef : undefined}
|
|
102
|
-
className={clsx(
|
|
103
|
-
"wg_navigation__scroll",
|
|
104
|
-
props.kind === "documents" && "wg_navigation__documents",
|
|
105
|
-
props.kind === "outline" && "wg_navigation__headings",
|
|
106
|
-
props.ready && "wg_navigation__scroll--ready",
|
|
107
|
-
props.ready && overflow.above && "wg_navigation__scroll--above",
|
|
108
|
-
props.ready && overflow.below && "wg_navigation__scroll--below",
|
|
109
|
-
)}
|
|
110
|
-
data-navigation-scroll={props.kind}
|
|
111
|
-
onClick={props.onClick}
|
|
112
|
-
onScroll={handlePortScroll}
|
|
113
|
-
>
|
|
114
|
-
{props.children}
|
|
115
|
-
</div>
|
|
116
|
-
);
|
|
117
|
-
};
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 와이드 화면의 오른쪽 목차 · 라벨·묶음은 문서 탐색의 묶음과 같은 표현
|
|
3
|
-
*/
|
|
4
|
-
.wg_navigationToc__root {
|
|
5
|
-
font-size: var(--app-font-size-dense);
|
|
6
|
-
line-height: var(--app-line-height-tight);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.wg_navigationToc__label {
|
|
10
|
-
margin: 0 0 var(--app-space-tree-label);
|
|
11
|
-
color: var(--app-color-text-muted);
|
|
12
|
-
font-size: var(--app-font-size-group);
|
|
13
|
-
line-height: calc(var(--app-font-size-dense) * var(--app-line-height-tight));
|
|
14
|
-
text-box: trim-start cap alphabetic;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.wg_navigationToc__group {
|
|
18
|
-
margin: 0 0 var(--app-space-tree-label);
|
|
19
|
-
color: var(--app-color-text-muted);
|
|
20
|
-
font-size: var(--app-font-size-group);
|
|
21
|
-
line-height: calc(var(--app-font-size-dense) * var(--app-line-height-tight));
|
|
22
|
-
text-box: trim-start cap alphabetic;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.wg_navigationToc__groupSection--named {
|
|
26
|
-
margin-top: var(--app-space-tree-group);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.wg_navigationToc__list {
|
|
30
|
-
margin: 0;
|
|
31
|
-
padding: 0;
|
|
32
|
-
list-style: none;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.wg_navigationToc__link {
|
|
36
|
-
display: block;
|
|
37
|
-
padding: var(--app-space-tree-row) 0;
|
|
38
|
-
color: var(--app-color-text);
|
|
39
|
-
font-size: var(--app-font-size-dense);
|
|
40
|
-
line-height: var(--app-line-height-tight);
|
|
41
|
-
text-decoration: none;
|
|
42
|
-
|
|
43
|
-
&:where(:hover) {
|
|
44
|
-
color: var(--app-color-text-strong);
|
|
45
|
-
text-decoration: underline;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/* 박스 대신 hover와 같은 진한 글·밑줄로 키보드 위치 표시 */
|
|
49
|
-
&:where(:focus-visible) {
|
|
50
|
-
outline: none;
|
|
51
|
-
color: var(--app-color-text-strong);
|
|
52
|
-
text-decoration: underline;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.wg_navigationToc__link--active {
|
|
57
|
-
color: var(--app-color-text-strong);
|
|
58
|
-
font-weight: var(--app-font-weight-active);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.wg_navigationToc__sub {
|
|
62
|
-
margin: var(--app-space-tree-row) 0 4px var(--app-space-tree-indent);
|
|
63
|
-
padding: 0;
|
|
64
|
-
list-style: none;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.wg_navigationToc__subLink {
|
|
68
|
-
display: block;
|
|
69
|
-
padding: var(--app-space-tree-row) 0;
|
|
70
|
-
color: var(--app-color-text);
|
|
71
|
-
font-size: var(--app-font-size-detail);
|
|
72
|
-
line-height: var(--app-line-height-tight);
|
|
73
|
-
text-decoration: none;
|
|
74
|
-
|
|
75
|
-
&:where(:hover) {
|
|
76
|
-
color: var(--app-color-text-strong);
|
|
77
|
-
text-decoration: underline;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* 상위 목차와 같은 키보드 표현 */
|
|
81
|
-
&:where(:focus-visible) {
|
|
82
|
-
outline: none;
|
|
83
|
-
color: var(--app-color-text-strong);
|
|
84
|
-
text-decoration: underline;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.wg_navigationToc__subLink--active {
|
|
89
|
-
color: var(--app-color-text-strong);
|
|
90
|
-
font-weight: var(--app-font-weight-active);
|
|
91
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import clsx from "clsx";
|
|
2
|
-
import {useLayoutEffect, useState} from "hono/jsx";
|
|
3
|
-
import {reading_line_slack_px} from "@/component/widget/navigation/_constant/reading-line";
|
|
4
|
-
import type {TocGroup} from "@/component/widget/navigation/_type/toc-group";
|
|
5
|
-
import {copy_nav_toc_label} from "@/constant/copy";
|
|
6
|
-
import {findHashTarget} from "@/util/dom/find-hash-target";
|
|
7
|
-
import "./_wg-navigation-toc.css";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 현재 문서의 목차 · 읽는 제목 한 항목만 강조
|
|
11
|
-
*/
|
|
12
|
-
export interface WgNavigationTocProps {
|
|
13
|
-
/**
|
|
14
|
-
* 본문 순서의 가름·절·소제목
|
|
15
|
-
*/
|
|
16
|
-
groups: TocGroup[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const WgNavigationToc = (props: WgNavigationTocProps) => {
|
|
20
|
-
const [currentSlug, setCurrentSlug] = useState<string>();
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 구독은 연결마다 한 번 설치 · 초기 갱신은 본문 파싱 이후로 미룸
|
|
24
|
-
*/
|
|
25
|
-
useLayoutEffect(() => {
|
|
26
|
-
const sections = props.groups.flatMap((group) => group.sections);
|
|
27
|
-
const headings = sections.flatMap((section) => [section.heading, ...section.subs.map((sub) => sub.heading)]);
|
|
28
|
-
const frame = {id: 0};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 접힌 본문 제목은 제외하고 읽는 선을 통과한 마지막 제목 선택
|
|
32
|
-
*/
|
|
33
|
-
const updateCurrentHeading = () => {
|
|
34
|
-
frame.id = 0;
|
|
35
|
-
const visible = headings.flatMap((heading) => {
|
|
36
|
-
const target = findHashTarget(`#${heading.slug}`);
|
|
37
|
-
return target?.checkVisibility()
|
|
38
|
-
? [{slug: heading.slug, top: target.getBoundingClientRect().top - Number.parseFloat(getComputedStyle(target).scrollMarginTop)}]
|
|
39
|
-
: [];
|
|
40
|
-
});
|
|
41
|
-
setCurrentSlug(visible.findLast((heading) => heading.top <= reading_line_slack_px)?.slug ?? visible[0]?.slug);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 연속 스크롤은 프레임당 한 번만 읽음
|
|
46
|
-
*/
|
|
47
|
-
const handleReadingPositionChange = () => {
|
|
48
|
-
if (frame.id === 0) frame.id = requestAnimationFrame(updateCurrentHeading);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
addEventListener("scroll", handleReadingPositionChange, {passive: true});
|
|
52
|
-
addEventListener("resize", handleReadingPositionChange);
|
|
53
|
-
addEventListener("toggle", handleReadingPositionChange, true);
|
|
54
|
-
addEventListener("pageshow", handleReadingPositionChange);
|
|
55
|
-
document.addEventListener("DOMContentLoaded", handleReadingPositionChange);
|
|
56
|
-
if (document.readyState !== "loading") updateCurrentHeading();
|
|
57
|
-
|
|
58
|
-
return () => {
|
|
59
|
-
cancelAnimationFrame(frame.id);
|
|
60
|
-
removeEventListener("scroll", handleReadingPositionChange);
|
|
61
|
-
removeEventListener("resize", handleReadingPositionChange);
|
|
62
|
-
removeEventListener("toggle", handleReadingPositionChange, true);
|
|
63
|
-
removeEventListener("pageshow", handleReadingPositionChange);
|
|
64
|
-
document.removeEventListener("DOMContentLoaded", handleReadingPositionChange);
|
|
65
|
-
};
|
|
66
|
-
}, [props.groups]);
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<nav className={clsx("wg_navigationToc__root")} aria-label={copy_nav_toc_label}>
|
|
70
|
-
<div className={clsx("wg_navigationToc__label")}>{copy_nav_toc_label}</div>
|
|
71
|
-
{/**
|
|
72
|
-
* 가름별 제목 이동 · 하위 제목이 현재 위치여도 부모 글씨는 강조하지 않음
|
|
73
|
-
*/}
|
|
74
|
-
{props.groups.map((group) => (
|
|
75
|
-
<div className={clsx("wg_navigationToc__groupSection", {"wg_navigationToc__groupSection--named": group.part !== undefined})} key={group.sections[0].heading.slug}>
|
|
76
|
-
{group.part !== undefined && <div className={clsx("wg_navigationToc__group")}>{group.part}</div>}
|
|
77
|
-
<ul className={clsx("wg_navigationToc__list")}>
|
|
78
|
-
{group.sections.map((section) => (
|
|
79
|
-
<li className={clsx("wg_navigationToc__item")} key={section.heading.slug}>
|
|
80
|
-
<a
|
|
81
|
-
className={clsx("wg_navigationToc__link", {"wg_navigationToc__link--active": section.heading.slug === currentSlug})}
|
|
82
|
-
href={`#${section.heading.slug}`}
|
|
83
|
-
data-toc-link=""
|
|
84
|
-
aria-current={section.heading.slug === currentSlug ? "location" : undefined}
|
|
85
|
-
>
|
|
86
|
-
{section.heading.text}
|
|
87
|
-
</a>
|
|
88
|
-
{/**
|
|
89
|
-
* 하위 제목 · 활성 링크는 한 제목만
|
|
90
|
-
*/}
|
|
91
|
-
{section.subs.length > 0 && (
|
|
92
|
-
<ul className={clsx("wg_navigationToc__sub")}>
|
|
93
|
-
{section.subs.map((sub) => (
|
|
94
|
-
<li className={clsx("wg_navigationToc__subItem")} key={sub.heading.slug}>
|
|
95
|
-
<a
|
|
96
|
-
className={clsx("wg_navigationToc__subLink", {"wg_navigationToc__subLink--active": sub.heading.slug === currentSlug})}
|
|
97
|
-
href={`#${sub.heading.slug}`}
|
|
98
|
-
data-toc-sub-link=""
|
|
99
|
-
aria-current={sub.heading.slug === currentSlug ? "location" : undefined}
|
|
100
|
-
>
|
|
101
|
-
{sub.heading.text}
|
|
102
|
-
</a>
|
|
103
|
-
</li>
|
|
104
|
-
))}
|
|
105
|
-
</ul>
|
|
106
|
-
)}
|
|
107
|
-
</li>
|
|
108
|
-
))}
|
|
109
|
-
</ul>
|
|
110
|
-
</div>
|
|
111
|
-
))}
|
|
112
|
-
</nav>
|
|
113
|
-
);
|
|
114
|
-
};
|