for-humanity 0.11.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.
Files changed (226) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +16 -9
  3. package/dist/browser.js +16 -16
  4. package/dist/cli.css +2 -941
  5. package/dist/cli.js +92 -2290
  6. package/dist/config.js +1 -0
  7. package/dist/constant/copy.d.ts +100 -0
  8. package/dist/constant/site.d.ts +20 -0
  9. package/dist/constant/status.d.ts +19 -0
  10. package/dist/copy-C1uzvEnr.js +103 -0
  11. package/dist/group-path-XAThmzvC.js +10 -0
  12. package/dist/load-site-CbpLEhwu.js +2379 -0
  13. package/dist/logger-Dv1i9xSV.js +9 -0
  14. package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
  15. package/dist/mermaid/chunk--TN-qHgG.js +2 -0
  16. package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
  17. package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
  18. package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
  19. package/dist/mermaid/chunk-6HLei9i0.js +84 -0
  20. package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
  21. package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
  22. package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
  23. package/dist/mermaid/chunk-B--pNBQF.js +884 -0
  24. package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
  25. package/dist/mermaid/chunk-B58sEIY_.js +14 -0
  26. package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
  27. package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
  28. package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
  29. package/dist/mermaid/chunk-BKri0qr7.js +89 -0
  30. package/dist/mermaid/chunk-BL404pH5.js +26 -0
  31. package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
  32. package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
  33. package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
  34. package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
  35. package/dist/mermaid/chunk-BariMtWr.js +3020 -0
  36. package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
  37. package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
  38. package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
  39. package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
  40. package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
  41. package/dist/mermaid/chunk-BvVehae3.js +5069 -0
  42. package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
  43. package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
  44. package/dist/mermaid/chunk-CApNbSU9.js +6 -0
  45. package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
  46. package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
  47. package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
  48. package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
  49. package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
  50. package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
  51. package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
  52. package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
  53. package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
  54. package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
  55. package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
  56. package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
  57. package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
  58. package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
  59. package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
  60. package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
  61. package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
  62. package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
  63. package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
  64. package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
  65. package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
  66. package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
  67. package/dist/mermaid/chunk-CuYekbSv.js +2 -0
  68. package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
  69. package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
  70. package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
  71. package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
  72. package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
  73. package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
  74. package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
  75. package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
  76. package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
  77. package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
  78. package/dist/mermaid/chunk-DU69_VcF.js +363 -0
  79. package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
  80. package/dist/mermaid/chunk-DZe-4kde.js +20 -0
  81. package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
  82. package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
  83. package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
  84. package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
  85. package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
  86. package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
  87. package/dist/mermaid/chunk-DqGhppWe.js +2 -0
  88. package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
  89. package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
  90. package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
  91. package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
  92. package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
  93. package/dist/mermaid/chunk-KuPYb48V.js +275 -0
  94. package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
  95. package/dist/mermaid/chunk-MbInCS_6.js +28 -0
  96. package/dist/mermaid/chunk-MexOLyKV.js +355 -0
  97. package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
  98. package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
  99. package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
  100. package/dist/mermaid/chunk-TftHqGLg.js +490 -0
  101. package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
  102. package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
  103. package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
  104. package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
  105. package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
  106. package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
  107. package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
  108. package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
  109. package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
  110. package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
  111. package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
  112. package/dist/mermaid/chunk-yBz-vst0.js +976 -0
  113. package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
  114. package/dist/run-site-command-C80YoNOe.js +129 -0
  115. package/dist/site-config-bllORGpm.js +90 -0
  116. package/dist/site.js +1 -0
  117. package/dist/start-dev-server-C4_Lu1nZ.js +176 -0
  118. package/dist/to-change-queue-DbEnZGNK.js +34 -0
  119. package/dist/to-error-message-pF6_7wGK.js +16 -0
  120. package/dist/type/group-path.d.ts +7 -0
  121. package/dist/type/site-config.d.ts +57 -0
  122. package/package.json +34 -17
  123. package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
  124. package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
  125. package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
  126. package/src/component/widget/navigation/_constant/locale.ts +0 -9
  127. package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
  128. package/src/component/widget/navigation/_constant/navigation.ts +0 -9
  129. package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
  130. package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
  131. package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
  132. package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
  133. package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
  134. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
  135. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
  136. package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
  137. package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
  138. package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
  139. package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
  140. package/src/component/widget/navigation/_type/doc-group.ts +0 -24
  141. package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
  142. package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
  143. package/src/component/widget/navigation/_type/toc-group.ts +0 -39
  144. package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
  145. package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
  146. package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
  147. package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
  148. package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
  149. package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
  150. package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
  151. package/src/component/widget/navigation/wg-navigation.css +0 -282
  152. package/src/component/widget/navigation/wg-navigation.tsx +0 -420
  153. package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
  154. package/src/component/widget/prose/_constant/section.ts +0 -7
  155. package/src/component/widget/prose/_constant/status.ts +0 -9
  156. package/src/component/widget/prose/_function/has-block-content.ts +0 -30
  157. package/src/component/widget/prose/_function/rehype-head.ts +0 -31
  158. package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
  159. package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
  160. package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
  161. package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
  162. package/src/component/widget/prose/_function/remark-flow.ts +0 -26
  163. package/src/component/widget/prose/_function/remark-links.ts +0 -33
  164. package/src/component/widget/prose/_function/remark-parts.ts +0 -26
  165. package/src/component/widget/prose/_function/remark-status.ts +0 -59
  166. package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
  167. package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
  168. package/src/component/widget/prose/wg-prose.css +0 -454
  169. package/src/component/widget/prose/wg-prose.tsx +0 -43
  170. package/src/component/widget/shell/wg-shell.css +0 -63
  171. package/src/component/widget/shell/wg-shell.tsx +0 -88
  172. package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
  173. package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
  174. package/src/constant/asset.ts +0 -63
  175. package/src/constant/copy.ts +0 -133
  176. package/src/constant/doc.ts +0 -13
  177. package/src/constant/font.ts +0 -34
  178. package/src/constant/site.ts +0 -24
  179. package/src/constant/status.ts +0 -15
  180. package/src/entry/browser/browser.tsx +0 -22
  181. package/src/entry/cli/_constant/cli.ts +0 -19
  182. package/src/entry/cli/_constant/crawling.ts +0 -14
  183. package/src/entry/cli/_constant/snippet.ts +0 -21
  184. package/src/entry/cli/_function/create-app.tsx +0 -57
  185. package/src/entry/cli/_function/create-dev-app.ts +0 -87
  186. package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
  187. package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
  188. package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
  189. package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
  190. package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -55
  191. package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
  192. package/src/entry/cli/_function/read-docs.ts +0 -128
  193. package/src/entry/cli/_function/read-home.ts +0 -32
  194. package/src/entry/cli/_function/to-crawling-app.ts +0 -42
  195. package/src/entry/cli/cli.test.ts +0 -782
  196. package/src/entry/cli/cli.ts +0 -206
  197. package/src/env.d.ts +0 -6
  198. package/src/page/doc/pg-doc.tsx +0 -35
  199. package/src/page/home/pg-home.tsx +0 -40
  200. package/src/store/navigation/create-navigation-stores.test.ts +0 -74
  201. package/src/store/navigation/create-navigation-stores.ts +0 -59
  202. package/src/store/navigation/navigation-state.ts +0 -36
  203. package/src/store/navigation/navigation-storage.ts +0 -9
  204. package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
  205. package/src/style/base.css +0 -28
  206. package/src/style/token.css +0 -186
  207. package/src/type/doc-content.ts +0 -15
  208. package/src/type/doc-data.ts +0 -38
  209. package/src/type/doc-file-data.ts +0 -21
  210. package/src/type/doc-heading.ts +0 -17
  211. package/src/type/doc-outline.ts +0 -16
  212. package/src/type/doc-section.ts +0 -9
  213. package/src/type/doc.ts +0 -20
  214. package/src/type/group-path.ts +0 -7
  215. package/src/type/site-assets.ts +0 -25
  216. package/src/type/site-config.ts +0 -73
  217. package/src/type/vfile-data.d.ts +0 -10
  218. package/src/util/async/to-change-queue.test.ts +0 -58
  219. package/src/util/async/to-change-queue.ts +0 -43
  220. package/src/util/dom/find-hash-target.ts +0 -18
  221. package/src/util/dom/reveal-hash-target.ts +0 -15
  222. package/src/util/error/to-error-message.ts +0 -10
  223. package/src/util/file/to-asset-path.ts +0 -26
  224. package/src/util/font/to-font-css.test.ts +0 -41
  225. package/src/util/font/to-font-css.ts +0 -28
  226. package/src/util/mermaid/render-flow.js +0 -321
@@ -1,153 +0,0 @@
1
- import clsx from "clsx";
2
- import {useLayoutEffect, useRef} from "hono/jsx";
3
- import {cursor_face_offset_px, cursor_face_size_px, cursor_face_storage_key} from "@/component/widget/cursor-face/_constant/cursor-face";
4
- import {asset_favicon_path} from "@/constant/asset";
5
- import "./wg-cursor-face.css";
6
-
7
- /**
8
- * SSR 기본 장식과 브라우저 DOM 연결을 구분하는 입력
9
- */
10
- export interface WgCursorFaceProps {
11
- /**
12
- * 브라우저 셸이 준비한 DOM ref·이벤트 연결 활성화
13
- */
14
- ready: boolean;
15
- }
16
-
17
- export const WgCursorFace = (props: WgCursorFaceProps) => {
18
- const faceRef = useRef<HTMLImageElement | null>(null);
19
- const mediaRef = useRef<MediaQueryList | null>(null);
20
- const positionRef = useRef({x: 0, y: 0, frame: 0});
21
-
22
- /**
23
- * 화면 이탈·터치 전환에서 예약된 이동까지 취소
24
- */
25
- const handleCursorHide = () => {
26
- cancelAnimationFrame(positionRef.current.frame);
27
- positionRef.current.frame = 0;
28
- faceRef.current?.classList.remove("wg_cursorFace__root--visible");
29
- };
30
-
31
- /**
32
- * 비활성 전환에서만 숨겨 새 마우스 이동을 취소하지 않음
33
- */
34
- const handleCursorMediaChange = () => {
35
- if (!mediaRef.current?.matches) handleCursorHide();
36
- };
37
-
38
- /**
39
- * 화면 갱신마다 한 번만 반영 · transform으로 본문 재배치 방지
40
- */
41
- const renderCursorFace = () => {
42
- if (positionRef.current.frame !== 0) return;
43
- positionRef.current.frame = requestAnimationFrame(() => {
44
- positionRef.current.frame = 0;
45
- const face = faceRef.current;
46
- if (face === null) return;
47
- face.style.transform = `translate3d(
48
- ${Math.max(0, Math.min(positionRef.current.x + cursor_face_offset_px, document.documentElement.clientWidth - face.width - cursor_face_offset_px))}px,
49
- ${Math.max(0, Math.min(positionRef.current.y + cursor_face_offset_px, document.documentElement.clientHeight - face.height - cursor_face_offset_px))}px,
50
- 0
51
- )`;
52
- face.classList.add("wg_cursorFace__root--visible");
53
- });
54
- };
55
-
56
- /**
57
- * 클릭·텍스트 선택 중에도 장식 유지 · 실제 마우스 입력만 좌표 반영
58
- */
59
- const handleDocumentPointer = (event: PointerEvent) => {
60
- if (!mediaRef.current?.matches || event.pointerType !== "mouse") {
61
- handleCursorHide();
62
- return;
63
- }
64
- positionRef.current.x = event.clientX;
65
- positionRef.current.y = event.clientY;
66
- renderCursorFace();
67
- };
68
-
69
- /**
70
- * 새 마우스 이동 없이 화면 가장자리의 좌표 재계산
71
- */
72
- const handleCursorResize = () => {
73
- if (faceRef.current?.classList.contains("wg_cursorFace__root--visible")) renderCursorFace();
74
- };
75
-
76
- /**
77
- * 같은 탭의 문서 이동에서 마지막 좌표를 전달 · 저장 실패는 장식에만 영향
78
- */
79
- const handlePageHide = () => {
80
- if (!faceRef.current?.classList.contains("wg_cursorFace__root--visible")) return;
81
- try {
82
- sessionStorage.setItem(cursor_face_storage_key, JSON.stringify({x: positionRef.current.x, y: positionRef.current.y}));
83
- } catch {
84
- // 저장소 차단 시 현재 페이지의 포인터 동작 유지
85
- }
86
- };
87
-
88
- /**
89
- * 첫 진입·BFCache 복귀의 좌표를 한 번 소비 · 외부 저장 값은 검증 후 사용
90
- */
91
- const handlePageShow = () => {
92
- try {
93
- const stored = sessionStorage.getItem(cursor_face_storage_key);
94
- sessionStorage.removeItem(cursor_face_storage_key);
95
- if (stored === null || !mediaRef.current?.matches) return;
96
- const point: unknown = JSON.parse(stored);
97
- if (
98
- typeof point === "object" &&
99
- point !== null &&
100
- "x" in point &&
101
- "y" in point &&
102
- typeof point.x === "number" &&
103
- typeof point.y === "number" &&
104
- Number.isFinite(point.x) &&
105
- Number.isFinite(point.y)
106
- ) {
107
- positionRef.current.x = point.x;
108
- positionRef.current.y = point.y;
109
- renderCursorFace();
110
- }
111
- } catch {
112
- // 손상된 좌표는 다음 실제 마우스 입력으로 복구
113
- }
114
- };
115
-
116
- /**
117
- * 첫 paint 전 좌표 복원 · 해제 시 전역 이벤트와 예약 frame을 함께 정리
118
- */
119
- useLayoutEffect(() => {
120
- if (!props.ready) return;
121
- const lifetime = new AbortController();
122
- const media = matchMedia("(hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference)");
123
- mediaRef.current = media;
124
- handlePageShow();
125
- document.addEventListener("pointermove", handleDocumentPointer, {passive: true, signal: lifetime.signal});
126
- document.addEventListener("pointerdown", handleDocumentPointer, {passive: true, signal: lifetime.signal});
127
- document.documentElement.addEventListener("pointerleave", handleCursorHide, {signal: lifetime.signal});
128
- addEventListener("blur", handleCursorHide, {signal: lifetime.signal});
129
- addEventListener("resize", handleCursorResize, {signal: lifetime.signal});
130
- addEventListener("pagehide", handlePageHide, {signal: lifetime.signal});
131
- addEventListener("pageshow", handlePageShow, {signal: lifetime.signal});
132
- media.addEventListener("change", handleCursorMediaChange, {signal: lifetime.signal});
133
- return () => {
134
- lifetime.abort();
135
- mediaRef.current = null;
136
- handleCursorHide();
137
- };
138
- }, [props.ready]);
139
-
140
- return (
141
- <img
142
- ref={props.ready ? faceRef : undefined}
143
- className={clsx("wg_cursorFace__root")}
144
- src={asset_favicon_path}
145
- width={cursor_face_size_px}
146
- height={cursor_face_size_px}
147
- alt=""
148
- aria-hidden="true"
149
- draggable={false}
150
- data-cursor-face=""
151
- />
152
- );
153
- };
@@ -1,9 +0,0 @@
1
- /**
2
- * 영어 문서 이름의 정렬 locale
3
- */
4
- export const locale_doc_name = "en";
5
-
6
- /**
7
- * 한국어 문서 묶음의 정렬 locale
8
- */
9
- export const locale_doc_group = "ko";
@@ -1,33 +0,0 @@
1
- import {array, boolean, lazy, minLength, number, object, optional, string, type ZodMiniType} from "zod/mini";
2
- import type {NavigationData, NavigationDoc, NavigationGroup} from "@/component/widget/navigation/_type/navigation-data";
3
-
4
- const navigationDocSchema: ZodMiniType<NavigationDoc> = object({
5
- id: string(),
6
- name: string(),
7
- label: string(),
8
- active: boolean(),
9
- children: lazy(() => array(navigationDocSchema)),
10
- });
11
- const navigationGroupSchema: ZodMiniType<NavigationGroup> = object({
12
- name: string(),
13
- path: array(string()),
14
- docs: array(navigationDocSchema),
15
- groups: lazy(() => array(navigationGroupSchema)),
16
- });
17
- const headingSchema = object({depth: number(), slug: string(), text: string()});
18
-
19
- /**
20
- * HTML에 포함된 JSON을 읽는 브라우저 경계 · 손상된 자료에는 서버 HTML 유지
21
- */
22
- export const navigationDataSchema: ZodMiniType<NavigationData> = object({
23
- title: string(),
24
- groups: array(navigationGroupSchema),
25
- outline: array(
26
- object({
27
- part: optional(string()),
28
- sections: array(object({heading: headingSchema, part: optional(string()), subs: array(object({heading: headingSchema}))})).check(minLength(1)),
29
- }),
30
- ),
31
- home: boolean(),
32
- cursorFace: boolean(),
33
- });
@@ -1,9 +0,0 @@
1
- /**
2
- * 모바일 탐색 전환 · wg-shell.css의 폭 조건과 일치
3
- */
4
- export const navigation_mobile_query = "(width < 1024px)";
5
-
6
- /**
7
- * 양쪽 200px 탐색·간격 120px·최소 800px 본문과 스크롤바가 들어가는 3열 기준
8
- */
9
- export const navigation_wide_query = "(width >= 1360px)";
@@ -1,4 +0,0 @@
1
- /**
2
- * 읽는 선의 반올림 여유 · 경계의 제목을 현재 절에 포함
3
- */
4
- export const reading_line_slack_px = 1;
@@ -1,59 +0,0 @@
1
- import type {NavigationLayout} from "@/store/navigation/navigation-state";
2
- import type {toNavigationScrollState} from "@/store/navigation/to-navigation-scroll-state";
3
-
4
- /**
5
- * 초기 HTML과 저장 스토어가 같은 좌표 형태를 소비하는 복원 경계
6
- */
7
- interface RestoreNavigationScrollOptions {
8
- /**
9
- * persist 키 · 이전 배치별 키의 접두사도 동일
10
- */
11
- key: string;
12
- /**
13
- * 수용할 저장 형태 버전
14
- */
15
- version: number;
16
- /**
17
- * 현재 표시 중인 화면 배치
18
- */
19
- layout: NavigationLayout;
20
- /**
21
- * persist와 같은 저장 자료 검증
22
- */
23
- toState: typeof toNavigationScrollState;
24
- }
25
-
26
- /**
27
- * 탐색 진입점에서 첫 paint 전 복원 · 기존 배치별 저장 자료도 한 번 수용
28
- */
29
- export const restoreNavigationScroll = (options: RestoreNavigationScrollOptions) => {
30
- const navigation = document.querySelector<HTMLElement>("[data-navigation]");
31
- const documents = document.querySelector<HTMLElement>('[data-navigation-scroll="documents"]');
32
- const outline = document.querySelector<HTMLElement>('[data-navigation-scroll="outline"]');
33
- if (!navigation || !documents || !outline) return;
34
- // module을 기다리는 동안 breakpoint가 바뀌었는지 구분 · 자료가 없어도 적용 배치는 기록
35
- navigation.dataset.navigationLayout = options.layout;
36
-
37
- try {
38
- const value = sessionStorage.getItem(options.key);
39
- const stored: unknown = value === null ? undefined : JSON.parse(value);
40
- const state =
41
- typeof stored === "object" && stored !== null && "version" in stored && stored.version === options.version && "state" in stored
42
- ? options.toState(stored.state)
43
- : {positions: {}};
44
- const legacy = sessionStorage.getItem(`${options.key}:${options.layout === "drawer" ? "drawer" : "desktop"}`);
45
- const previous =
46
- state.positions[options.layout] === undefined && legacy !== null
47
- ? options.toState({positions: {[options.layout]: JSON.parse(legacy)}}).positions[options.layout]
48
- : undefined;
49
- const position = state.positions[options.layout] ?? previous;
50
- const signature = [...navigation.querySelectorAll<HTMLAnchorElement>(".wg_navigationNav__root a[href]")].map((link) => `${link.pathname}:${link.textContent}`).join("\n");
51
- if (position === undefined || position.navigation !== signature) return;
52
-
53
- documents.scrollTop = position.documents;
54
- // 공통 문서 목록은 페이지 간 공유 · 목차는 같은 페이지에서만 재사용
55
- if (position.pathname === location.pathname) outline.scrollTop = position.outline;
56
- } catch {
57
- // 차단·손상된 저장소는 복원만 생략 · 기본 링크와 스크롤 유지
58
- }
59
- };
@@ -1,15 +0,0 @@
1
- import {locale_doc_name} from "@/component/widget/navigation/_constant/locale";
2
- import type {DocBranch} from "@/component/widget/navigation/_type/doc-branch";
3
- import type {Doc} from "@/type/doc";
4
-
5
- /**
6
- * 검증된 부모 관계로 문서 가지를 재귀 구성 · 형제 순서와 URL 유지
7
- */
8
- export const toDocBranches = (options: {docs: readonly Doc[]; children: ReadonlyMap<Doc["data"]["parent"], Doc[]>}): DocBranch[] => {
9
- return options.docs
10
- .toSorted((a, b) => a.data.order - b.data.order || a.data.name.localeCompare(b.data.name, locale_doc_name) || a.id.localeCompare(b.id, locale_doc_name))
11
- .map((doc) => {
12
- const children = options.children.get(doc.id);
13
- return {...doc, children: children === undefined ? undefined : toDocBranches({docs: children, children: options.children})};
14
- });
15
- };
@@ -1,70 +0,0 @@
1
- import {locale_doc_group} from "@/component/widget/navigation/_constant/locale";
2
- import {toDocBranches} from "@/component/widget/navigation/_function/to-doc-groups/_to-doc-branches";
3
- import type {DocGroup} from "@/component/widget/navigation/_type/doc-group";
4
- import type {Doc} from "@/type/doc";
5
-
6
- /**
7
- * 같은 부모의 문서를 다음 경로 단계로 묶는 재귀 입력
8
- */
9
- interface DocGroupBranchesOptions {
10
- /**
11
- * 부모 경로에 속한 문서
12
- */
13
- docs: readonly Doc[];
14
- /**
15
- * 검증된 부모 id별 문서 · 자손을 각 단계에서 다시 수집하지 않음
16
- */
17
- children: ReadonlyMap<Doc["data"]["parent"], Doc[]>;
18
- /**
19
- * 부모까지의 경로 · 최상위는 빈 배열
20
- */
21
- path: DocGroup["path"];
22
- /**
23
- * 전체 경로의 JSON 키와 navigation 위치
24
- */
25
- positions: ReadonlyMap<string, number>;
26
- /**
27
- * 미지정 경로를 지정한 묶음 뒤에 놓는 위치
28
- */
29
- unlistedPosition: number;
30
- }
31
-
32
- /**
33
- * 각 단계의 직접 문서와 하위 묶음을 분리 · 고정된 깊이 제한 없이 구성
34
- */
35
- export const toDocGroupBranches = (options: DocGroupBranchesOptions): DocGroup[] => {
36
- return [
37
- ...Map.groupBy(
38
- options.docs.filter((doc) => doc.data.group.length > options.path.length),
39
- (doc) => doc.data.group[options.path.length],
40
- ),
41
- ]
42
- .map(([name, docs]) => {
43
- const path = [...options.path, name];
44
-
45
- return {
46
- name,
47
- path,
48
- docs,
49
- position: options.positions.get(JSON.stringify(path)) ?? options.unlistedPosition,
50
- };
51
- })
52
- .toSorted((a, b) => a.position - b.position || a.name.localeCompare(b.name, locale_doc_group))
53
- .map((group) => {
54
- return {
55
- name: group.name,
56
- path: group.path,
57
- docs: toDocBranches({
58
- docs: group.docs.filter((doc) => doc.data.group.length === group.path.length && doc.data.parent === undefined),
59
- children: options.children,
60
- }),
61
- groups: toDocGroupBranches({
62
- docs: group.docs,
63
- children: options.children,
64
- path: group.path,
65
- positions: options.positions,
66
- unlistedPosition: options.unlistedPosition,
67
- }),
68
- };
69
- });
70
- };
@@ -1,15 +0,0 @@
1
- import {toDocGroupBranches} from "@/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches";
2
- import type {Doc} from "@/type/doc";
3
- import type {SiteConfig} from "@/type/site-config";
4
-
5
- /**
6
- * 메타데이터 경로로 읽는 순서를 가진 문서 계층 구성
7
- * navigation의 첫 지정을 조상에도 적용 · 미지정 형제 묶음은 이름순
8
- */
9
- export const toDocGroups = (options: {docs: readonly Doc[]; navigation: SiteConfig["navigation"]}) => {
10
- // 같은 조상을 지정한 경로는 최초 navigation 위치를 우선
11
- const positions = new Map(options.navigation.flatMap((path, index) => path.map((_name, depth) => [JSON.stringify(path.slice(0, depth + 1)), index] as const)).toReversed());
12
-
13
- const children = Map.groupBy(options.docs, (doc) => doc.data.parent);
14
- return toDocGroupBranches({docs: options.docs, children, path: [], positions, unlistedPosition: options.navigation.length});
15
- };
@@ -1,13 +0,0 @@
1
- import type {DocBranch} from "@/component/widget/navigation/_type/doc-branch";
2
- import type {NavigationDoc} from "@/component/widget/navigation/_type/navigation-data";
3
-
4
- /**
5
- * 본문 없는 문서 가지 · 재귀에서도 현재 페이지 한 항목만 표시
6
- */
7
- export const toNavigationDocument = (options: {doc: DocBranch; current?: string}): NavigationDoc => ({
8
- id: options.doc.id,
9
- name: options.doc.data.name,
10
- label: options.doc.data.label,
11
- active: options.doc.id === options.current,
12
- children: options.doc.children === undefined ? [] : options.doc.children.map((doc) => toNavigationDocument({...options, doc})),
13
- });
@@ -1,13 +0,0 @@
1
- import {toNavigationDocument} from "@/component/widget/navigation/_function/to-navigation-data/_to-navigation-document";
2
- import type {DocGroup} from "@/component/widget/navigation/_type/doc-group";
3
- import type {NavigationGroup} from "@/component/widget/navigation/_type/navigation-data";
4
-
5
- /**
6
- * 전체 묶음 경로와 본문 없는 하위 가지
7
- */
8
- export const toNavigationGroup = (options: {group: DocGroup; current?: string}): NavigationGroup => ({
9
- name: options.group.name,
10
- path: options.group.path,
11
- docs: options.group.docs.map((doc) => toNavigationDocument({doc, current: options.current})),
12
- groups: options.group.groups.map((group) => toNavigationGroup({...options, group})),
13
- });
@@ -1,18 +0,0 @@
1
- import {toDocGroups} from "@/component/widget/navigation/_function/to-doc-groups/to-doc-groups";
2
- import {toNavigationGroup} from "@/component/widget/navigation/_function/to-navigation-data/_to-navigation-group";
3
- import {toTocGroups} from "@/component/widget/navigation/_function/to-toc-groups";
4
- import type {NavigationData} from "@/component/widget/navigation/_type/navigation-data";
5
- import type {Doc} from "@/type/doc";
6
- import type {DocOutline} from "@/type/doc-outline";
7
- import type {SiteConfig} from "@/type/site-config";
8
-
9
- /**
10
- * 현재 문서의 이름·계층·목차만 전송 · 다른 문서 본문은 브라우저 탐색 입력에서 제외
11
- */
12
- export const toNavigationData = (options: {site: SiteConfig; docs: Doc[]; current?: string; outline?: DocOutline}): NavigationData => ({
13
- title: options.site.title,
14
- groups: toDocGroups({docs: options.docs, navigation: options.site.navigation}).map((group) => toNavigationGroup({group, current: options.current})),
15
- outline: options.outline === undefined ? [] : toTocGroups(options.outline),
16
- home: options.current === undefined,
17
- cursorFace: options.site.cursorFace,
18
- });
@@ -1,8 +0,0 @@
1
- import type {NavigationData} from "@/component/widget/navigation/_type/navigation-data";
2
-
3
- /**
4
- * 작성한 이름이 script 종료 태그나 JavaScript 줄 구분자로 해석되지 않는 JSON
5
- */
6
- export const toNavigationJson = (data: NavigationData) => {
7
- return JSON.stringify(data).replaceAll("<", "\\u003c").replaceAll("\u2028", "\\u2028").replaceAll("\u2029", "\\u2029");
8
- };
@@ -1,38 +0,0 @@
1
- import {takeWhile} from "es-toolkit/array";
2
- import type {TocGroup, TocSection} from "@/component/widget/navigation/_type/toc-group";
3
- import {section_heading_depth} from "@/component/widget/prose/_constant/section";
4
- import type {DocOutline} from "@/type/doc-outline";
5
-
6
- /**
7
- * h2별 h3 수집 · 가름 시작 절에서 목차 묶음 분리
8
- * 첫 h2 앞의 h3은 목차 제외
9
- */
10
- export const toTocGroups = (outline: DocOutline): TocGroup[] => {
11
- const entries = outline.headings
12
- .filter((heading) => heading.depth === section_heading_depth.section || heading.depth === section_heading_depth.sub)
13
- .map((heading, index) => ({heading, section: outline.sections[index]}));
14
- const sections = entries.flatMap((entry, index): TocSection[] =>
15
- entry.heading.depth === section_heading_depth.section
16
- ? [
17
- {
18
- heading: entry.heading,
19
- part: entry.section.part,
20
- subs: takeWhile(entries.slice(index + 1), (sub) => sub.heading.depth !== section_heading_depth.section).map((sub) => ({
21
- heading: sub.heading,
22
- })),
23
- },
24
- ]
25
- : [],
26
- );
27
-
28
- return sections.flatMap((section, index) =>
29
- index === 0 || section.part !== undefined
30
- ? [
31
- {
32
- part: section.part,
33
- sections: [section, ...takeWhile(sections.slice(index + 1), (next) => next.part === undefined)],
34
- },
35
- ]
36
- : [],
37
- );
38
- };
@@ -1,11 +0,0 @@
1
- import type {Doc} from "@/type/doc";
2
-
3
- /**
4
- * 문서 탐색의 클릭 가능한 가지 · 원래 URL과 본문을 유지
5
- */
6
- export interface DocBranch extends Doc {
7
- /**
8
- * 같은 부모 아래의 문서 · order·제목·id 순, 말단 문서는 생략
9
- */
10
- children?: DocBranch[];
11
- }
@@ -1,24 +0,0 @@
1
- import type {DocBranch} from "@/component/widget/navigation/_type/doc-branch";
2
- import type {Doc} from "@/type/doc";
3
-
4
- /**
5
- * 사이드바의 문서 묶음 · 같은 이름도 전체 경로로 구분
6
- */
7
- export interface DocGroup {
8
- /**
9
- * 현재 단계의 표시 이름
10
- */
11
- name: string;
12
- /**
13
- * 최상위부터 현재 단계까지의 경로
14
- */
15
- path: Doc["data"]["group"];
16
- /**
17
- * 현재 묶음의 부모 없는 문서 · 하위 문서는 각 문서 가지에 포함
18
- */
19
- docs: DocBranch[];
20
- /**
21
- * 현재 묶음의 하위 묶음 · navigation·이름 순
22
- */
23
- groups: DocGroup[];
24
- }
@@ -1,75 +0,0 @@
1
- import type {TocGroup} from "@/component/widget/navigation/_type/toc-group";
2
-
3
- /**
4
- * 브라우저 문서 가지 · 본문·파일 경로를 포함하지 않는 탐색 전용 계약
5
- */
6
- export interface NavigationDoc {
7
- /**
8
- * 링크의 문서 id
9
- */
10
- id: string;
11
- /**
12
- * 표시 이름
13
- */
14
- name: string;
15
- /**
16
- * 링크의 보조 설명
17
- */
18
- label: string;
19
- /**
20
- * 현재 페이지 한 항목만 강조
21
- */
22
- active: boolean;
23
- /**
24
- * 클릭 가능한 하위 문서
25
- */
26
- children: NavigationDoc[];
27
- }
28
-
29
- /**
30
- * 클릭하지 않는 문서 묶음 · 같은 이름은 전체 경로로 구분
31
- */
32
- export interface NavigationGroup {
33
- /**
34
- * 묶음 이름
35
- */
36
- name: string;
37
- /**
38
- * 최상위부터 현재 묶음까지
39
- */
40
- path: string[];
41
- /**
42
- * 현재 단계의 문서
43
- */
44
- docs: NavigationDoc[];
45
- /**
46
- * 하위 묶음
47
- */
48
- groups: NavigationGroup[];
49
- }
50
-
51
- /**
52
- * 서버가 계산한 최소 탐색 자료 · 서버 출력과 클라이언트 JSX의 공통 입력
53
- */
54
- export interface NavigationData {
55
- /**
56
- * 브랜드 이름
57
- */
58
- title: string;
59
- /**
60
- * 읽는 순서의 문서 트리
61
- */
62
- groups: NavigationGroup[];
63
- /**
64
- * 현재 페이지의 목차
65
- */
66
- outline: TocGroup[];
67
- /**
68
- * README 홈 여부
69
- */
70
- home: boolean;
71
- /**
72
- * 커서 옆 픽셀 얼굴 표시 여부 · 사이트 설정 `cursorFace`
73
- */
74
- cursorFace: boolean;
75
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Hono가 배치 변경에서 이전 DOM의 자식을 분리하기 전에 기억하는 키보드 위치
3
- */
4
- export interface NavigationFocusSnapshot {
5
- /**
6
- * 문서 탐색 안에서 새 배치로 옮길 위치인지 구분
7
- */
8
- navigation: boolean;
9
- /**
10
- * 메뉴 진입·닫기 버튼에서 데스크톱 브랜드로 돌아갈 위치인지 구분
11
- */
12
- drawer: boolean;
13
- /**
14
- * 문서 이동 링크의 안정된 식별자
15
- */
16
- href: string | null;
17
- }
@@ -1,39 +0,0 @@
1
- import type {DocHeading} from "@/type/doc-heading";
2
-
3
- /**
4
- * 목차 소제목 항목
5
- */
6
- export interface TocSub {
7
- /**
8
- * 제목 id와 텍스트
9
- */
10
- heading: DocHeading;
11
- }
12
-
13
- /**
14
- * 목차 절과 소제목 목록
15
- */
16
- export interface TocSection extends TocSub {
17
- /**
18
- * 이 절에서 시작하는 가름 이름
19
- */
20
- part?: string;
21
- /**
22
- * 해당 절의 소제목 · 현재 위치와 무관하게 전체 표시
23
- */
24
- subs: TocSub[];
25
- }
26
-
27
- /**
28
- * 가름별 목차 묶음 · 첫 묶음 이름 생략 가능
29
- */
30
- export interface TocGroup {
31
- /**
32
- * 묶음 위의 가름 이름
33
- */
34
- part?: string;
35
- /**
36
- * 묶음의 절 목록
37
- */
38
- sections: TocSection[];
39
- }