lildocs 0.1.15 → 0.1.16

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.
@@ -0,0 +1,98 @@
1
+ let activeDialog: HTMLDialogElement | undefined;
2
+
3
+ export function initTableViewer() {
4
+ enhanceTables();
5
+ document.addEventListener("lildocs:page-view", () => {
6
+ activeDialog?.close();
7
+ enhanceTables();
8
+ });
9
+ }
10
+
11
+ function enhanceTables() {
12
+ const tables = document.querySelectorAll<HTMLTableElement>(
13
+ ".content article table",
14
+ );
15
+ for (const table of Array.from(tables)) {
16
+ if (table.closest(".tableFrame")) {
17
+ continue;
18
+ }
19
+
20
+ const frame = document.createElement("div");
21
+ frame.className = "tableFrame";
22
+ const toolbar = document.createElement("div");
23
+ toolbar.className = "tableToolbar";
24
+ const button = document.createElement("button");
25
+ button.type = "button";
26
+ button.className = "tableExpandButton";
27
+ button.title = "Expand table";
28
+ button.setAttribute("aria-label", "View table in full screen");
29
+ button.innerHTML =
30
+ '<span class="ti ti-arrows-maximize" aria-hidden="true"></span>';
31
+ const viewport = document.createElement("div");
32
+ viewport.className = "tableViewport";
33
+
34
+ button.addEventListener("click", () => openTableDialog(table, button));
35
+ table.before(frame);
36
+ toolbar.append(button);
37
+ viewport.append(table);
38
+ frame.append(viewport, toolbar);
39
+ }
40
+ }
41
+
42
+ function openTableDialog(table: HTMLTableElement, opener: HTMLButtonElement) {
43
+ activeDialog?.close();
44
+
45
+ const dialog = document.createElement("dialog");
46
+ dialog.className = "tableFullscreenDialog";
47
+ dialog.setAttribute("aria-label", "Full screen table");
48
+ const content = document.createElement("div");
49
+ content.className = "tableFullscreenContent";
50
+ const header = document.createElement("header");
51
+ header.className = "tableFullscreenHeader";
52
+ const title = document.createElement("strong");
53
+ title.textContent =
54
+ table.querySelector("caption")?.textContent?.trim() || "Table";
55
+ const closeButton = document.createElement("button");
56
+ closeButton.type = "button";
57
+ closeButton.className = "tableFullscreenClose";
58
+ closeButton.title = "Minimize table";
59
+ closeButton.setAttribute("aria-label", "Minimize table");
60
+ closeButton.innerHTML =
61
+ '<span class="ti ti-arrows-minimize" aria-hidden="true"></span>';
62
+ const viewport = document.createElement("div");
63
+ viewport.className = "tableFullscreenViewport content";
64
+ viewport.append(table.cloneNode(true));
65
+
66
+ closeButton.addEventListener("click", () => dialog.close());
67
+ dialog.addEventListener("cancel", (event) => {
68
+ event.preventDefault();
69
+ dialog.close();
70
+ });
71
+ dialog.addEventListener("click", (event) => {
72
+ if (event.target === dialog) {
73
+ dialog.close();
74
+ }
75
+ });
76
+ dialog.addEventListener(
77
+ "close",
78
+ () => {
79
+ document.documentElement.classList.remove("tableFullscreenOpen");
80
+ dialog.remove();
81
+ if (activeDialog === dialog) {
82
+ activeDialog = undefined;
83
+ }
84
+ if (opener.isConnected) {
85
+ opener.focus();
86
+ }
87
+ },
88
+ { once: true },
89
+ );
90
+
91
+ header.append(title, closeButton);
92
+ content.append(header, viewport);
93
+ dialog.append(content);
94
+ document.body.append(dialog);
95
+ document.documentElement.classList.add("tableFullscreenOpen");
96
+ activeDialog = dialog;
97
+ dialog.showModal();
98
+ }
@@ -17,6 +17,22 @@
17
17
  --ld-tabler-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20%3E%3Cpath%20stroke%3D%22none%22%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%20%2F%3E%3Cpath%20d%3D%22M3%2010a7%207%200%201%200%2014%200a7%207%200%201%200%20-14%200%22%20%2F%3E%3Cpath%20d%3D%22M21%2021l-6%20-6%22%20%2F%3E%3C%2Fsvg%3E");
18
18
  }
19
19
 
20
+ .ti-arrows-maximize {
21
+ --ld-tabler-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M16%204l4%200l0%204%22%2F%3E%3Cpath%20d%3D%22M14%2010l6%20-6%22%2F%3E%3Cpath%20d%3D%22M8%2020l-4%200l0%20-4%22%2F%3E%3Cpath%20d%3D%22M4%2020l6%20-6%22%2F%3E%3Cpath%20d%3D%22M16%2020l4%200l0%20-4%22%2F%3E%3Cpath%20d%3D%22M14%2014l6%206%22%2F%3E%3Cpath%20d%3D%22M8%204l-4%200l0%204%22%2F%3E%3Cpath%20d%3D%22M4%204l6%206%22%2F%3E%3C%2Fsvg%3E");
22
+ }
23
+
24
+ .ti-arrows-minimize {
25
+ --ld-tabler-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M5%209l4%200l0%20-4%22%2F%3E%3Cpath%20d%3D%22M3%203l6%206%22%2F%3E%3Cpath%20d%3D%22M5%2015l4%200l0%204%22%2F%3E%3Cpath%20d%3D%22M3%2021l6%20-6%22%2F%3E%3Cpath%20d%3D%22M19%209l-4%200l0%20-4%22%2F%3E%3Cpath%20d%3D%22M15%209l6%20-6%22%2F%3E%3Cpath%20d%3D%22M19%2015l-4%200l0%204%22%2F%3E%3Cpath%20d%3D%22M15%2015l6%206%22%2F%3E%3C%2Fsvg%3E");
26
+ }
27
+
28
+ .ti-layout-sidebar-left-collapse {
29
+ --ld-tabler-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20stroke%3D%22none%22%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%3Cpath%20d%3D%22M4%206a2%202%200%200%201%202%20-2h12a2%202%200%200%201%202%202v12a2%202%200%200%201%20-2%202h-12a2%202%200%200%201%20-2%20-2l0%20-12%22%2F%3E%3Cpath%20d%3D%22M9%204v16%22%2F%3E%3Cpath%20d%3D%22M15%2010l-2%202l2%202%22%2F%3E%3C%2Fsvg%3E");
30
+ }
31
+
32
+ .ti-layout-sidebar-left-expand {
33
+ --ld-tabler-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20stroke%3D%22none%22%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%3Cpath%20d%3D%22M4%206a2%202%200%200%201%202%20-2h12a2%202%200%200%201%202%202v12a2%202%200%200%201%20-2%202h-12a2%202%200%200%201%20-2%20-2l0%20-12%22%2F%3E%3Cpath%20d%3D%22M9%204v16%22%2F%3E%3Cpath%20d%3D%22M14%2010l2%202l-2%202%22%2F%3E%3C%2Fsvg%3E");
34
+ }
35
+
20
36
  .ti-copy {
21
37
  --ld-tabler-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20%3E%3Cpath%20stroke%3D%22none%22%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%20%2F%3E%3Cpath%20d%3D%22M7%209.667a2.667%202.667%200%200%201%202.667%20-2.667h8.666a2.667%202.667%200%200%201%202.667%202.667v8.666a2.667%202.667%200%200%201%20-2.667%202.667h-8.666a2.667%202.667%200%200%201%20-2.667%20-2.667l0%20-8.666%22%20%2F%3E%3Cpath%20d%3D%22M4.012%2016.737a2.005%202.005%200%200%201%20-1.012%20-1.737v-10c0%20-1.1%20.9%20-2%202%20-2h10c.75%200%201.158%20.385%201.5%201%22%20%2F%3E%3C%2Fsvg%3E");
22
38
  }
@@ -0,0 +1,9 @@
1
+ export type AdjacentPageLink = {
2
+ title: string;
3
+ href: string;
4
+ };
5
+
6
+ export type PageNavigation = {
7
+ previous?: AdjacentPageLink;
8
+ next?: AdjacentPageLink;
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lildocs",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "A lightweight CLI that turns Markdown docs into a static searchable documentation site.",
5
5
  "homepage": "https://aleclarson.github.io/lildocs/",
6
6
  "repository": {
@@ -17,35 +17,39 @@
17
17
  "scripts": {
18
18
  "build": "tsdown",
19
19
  "docs:serve": "pnpm run build && node dist/cli.mjs build ./docs --out ./dist/docs && sirv ./dist/docs",
20
- "format": "oxfmt --write src schemas package.json tsconfig.json tsdown.config.ts .oxlintrc.json .oxfmtrc.json .vscode/settings.json",
21
- "format:check": "oxfmt --check src schemas package.json tsconfig.json tsdown.config.ts .oxlintrc.json .oxfmtrc.json .vscode/settings.json",
22
- "lint": "oxlint src tsdown.config.ts",
23
- "test": "pnpm run build && node --test test/*.test.mjs",
20
+ "format": "prettier --write src schemas package.json tsconfig.json tsdown.config.ts vitest.config.ts .oxlintrc.json .prettierrc.json .vscode/settings.json",
21
+ "format:check": "prettier --check src schemas package.json tsconfig.json tsdown.config.ts vitest.config.ts .oxlintrc.json .prettierrc.json .vscode/settings.json",
22
+ "lint": "oxlint src tsdown.config.ts vitest.config.ts",
23
+ "test": "pnpm run build && vitest run",
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@goddard-ai/ui-primitives": "^0.1.1",
28
- "@preact/signals": "^2.9.2",
29
27
  "beautiful-mermaid": "^1.1.3",
30
28
  "cmd-ts": "^0.15.0",
31
29
  "culori": "^4.0.2",
30
+ "entities": "^8.0.0",
32
31
  "exports-md": "^0.2.5",
33
32
  "gray-matter": "^4.0.3",
34
33
  "marked": "^18.0.3",
35
34
  "marked-shiki": "^1.2.1",
36
- "preact": "^10.29.2",
37
- "preact-render-to-string": "^6.7.0",
35
+ "octane": "^0.1.3",
38
36
  "shiki": "^4.0.2",
39
37
  "swup": "^4.9.0"
40
38
  },
39
+ "peerDependencies": {
40
+ "vite": "^8.0.0"
41
+ },
41
42
  "devDependencies": {
43
+ "@tsrx/prettier-plugin": "^0.3.93",
42
44
  "@types/culori": "^4.0.1",
43
45
  "@types/node": "^24.0.0",
44
- "oxfmt": "^0.50.0",
45
46
  "oxlint": "^1.65.0",
47
+ "prettier": "^3.9.5",
46
48
  "sirv": "^3.0.2",
47
49
  "tsdown": "^0.22.0",
48
- "typescript": "^5.9.0"
50
+ "typescript": "^5.9.0",
51
+ "vite": "^8.0.0",
52
+ "vitest": "^4.1.10"
49
53
  },
50
54
  "engines": {
51
55
  "node": "^22.18.0 || >=24.3.0"
@@ -1,54 +0,0 @@
1
- (() => {
2
- const icons = {
3
- copy: '<span class="ti ti-copy copyCodeIcon" aria-hidden="true"></span>',
4
- check: '<span class="ti ti-copy-check copyCodeIcon" aria-hidden="true"></span>',
5
- error: '<span class="ti ti-alert-circle copyCodeIcon" aria-hidden="true"></span>',
6
- };
7
-
8
- initCopyCode();
9
- document.addEventListener("lildocs:page-view", initCopyCode);
10
-
11
- function initCopyCode() {
12
- const blocks = document.querySelectorAll(".content article pre");
13
- if (!blocks.length || !navigator.clipboard?.writeText) {
14
- return;
15
- }
16
-
17
- for (const block of blocks) {
18
- if (block.parentElement?.classList.contains("copyCodeBlock")) {
19
- continue;
20
- }
21
-
22
- const copyText = block.textContent ?? "";
23
- const wrapper = document.createElement("div");
24
- wrapper.className = "copyCodeBlock";
25
- const button = document.createElement("button");
26
- button.type = "button";
27
- button.className = "copyCodeButton";
28
- button.setAttribute("aria-label", "Copy code");
29
- button.title = "Copy code";
30
- button.innerHTML = icons.copy;
31
-
32
- button.addEventListener("click", async () => {
33
- try {
34
- await navigator.clipboard.writeText(copyText);
35
- button.innerHTML = icons.check;
36
- button.setAttribute("aria-label", "Copied");
37
- button.title = "Copied";
38
- window.setTimeout(() => {
39
- button.innerHTML = icons.copy;
40
- button.setAttribute("aria-label", "Copy code");
41
- button.title = "Copy code";
42
- }, 1600);
43
- } catch {
44
- button.innerHTML = icons.error;
45
- button.setAttribute("aria-label", "Copy failed");
46
- button.title = "Copy failed";
47
- }
48
- });
49
-
50
- block.before(wrapper);
51
- wrapper.append(block, button);
52
- }
53
- }
54
- })();
@@ -1,14 +0,0 @@
1
- (() => {
2
- if (!window.Swup || window.location.protocol === "file:") {
3
- return;
4
- }
5
-
6
- const swup = new window.Swup({
7
- containers: ["#swup"],
8
- animationSelector: '[class*="transition-"]',
9
- });
10
-
11
- swup.hooks.on("page:view", () => {
12
- document.dispatchEvent(new CustomEvent("lildocs:page-view"));
13
- });
14
- })();