@tomehq/theme 0.4.0 → 0.6.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 +1 -96
- package/dist/{chunk-DKSQZLWR.js → chunk-NIWVZJLG.js} +150 -45
- package/dist/entry.js +1 -1
- package/dist/index.d.ts +78 -0
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/src/Shell.test.tsx +30 -0
- package/src/Shell.tsx +35 -17
- package/src/entry.tsx +2 -3
- package/src/presets.test.ts +4 -2
- package/src/presets.ts +30 -0
- package/dist/chunk-2APCPR2Y.js +0 -2110
- package/dist/chunk-2AXAEADQ.js +0 -2525
- package/dist/chunk-2WNOJXK3.js +0 -2581
- package/dist/chunk-37JI6XGT.js +0 -1720
- package/dist/chunk-3A2LPGUL.js +0 -1991
- package/dist/chunk-3I2QTWTW.js +0 -1948
- package/dist/chunk-3I4SJMER.js +0 -2538
- package/dist/chunk-45M5UIAB.js +0 -2110
- package/dist/chunk-462AGU3S.js +0 -1959
- package/dist/chunk-5GVQFIPI.js +0 -2581
- package/dist/chunk-7MUTU5D4.js +0 -1720
- package/dist/chunk-7NQ4IMDY.js +0 -2294
- package/dist/chunk-ABNPB6BB.js +0 -2133
- package/dist/chunk-BZGWSKT2.js +0 -573
- package/dist/chunk-BZIB2LMI.js +0 -2519
- package/dist/chunk-CMQCNCSY.js +0 -2127
- package/dist/chunk-CTPOZMMK.js +0 -1703
- package/dist/chunk-DO544M3G.js +0 -1702
- package/dist/chunk-DPKZBFQP.js +0 -1777
- package/dist/chunk-EK7PZUEB.js +0 -2147
- package/dist/chunk-FMOLIHQF.js +0 -2182
- package/dist/chunk-FWBTK5TL.js +0 -1444
- package/dist/chunk-GDQIBNX5.js +0 -1962
- package/dist/chunk-GHQ2MODM.js +0 -2127
- package/dist/chunk-GR2WCRGK.js +0 -2182
- package/dist/chunk-H5XZVNBW.js +0 -2291
- package/dist/chunk-HNLKDQ64.js +0 -2139
- package/dist/chunk-INUMUXN5.js +0 -2095
- package/dist/chunk-IW3NHNOQ.js +0 -2187
- package/dist/chunk-JA4PMX6M.js +0 -1500
- package/dist/chunk-JSPFS7G5.js +0 -2102
- package/dist/chunk-JZRT4WNC.js +0 -1441
- package/dist/chunk-KQBY2JDB.js +0 -2112
- package/dist/chunk-LIMYFTPC.js +0 -1468
- package/dist/chunk-LIY62BGC.js +0 -2519
- package/dist/chunk-MEP7P6A7.js +0 -1500
- package/dist/chunk-MHYKO7KM.js +0 -2570
- package/dist/chunk-MSXVVBDW.js +0 -2542
- package/dist/chunk-NOZBIES7.js +0 -1948
- package/dist/chunk-O4GH3KYX.js +0 -1712
- package/dist/chunk-OEDJTH5F.js +0 -2569
- package/dist/chunk-OEXM3BEC.js +0 -1702
- package/dist/chunk-PGKSFQ7A.js +0 -2459
- package/dist/chunk-PIV6CPY2.js +0 -2395
- package/dist/chunk-Q7PYTVW3.js +0 -1771
- package/dist/chunk-QCWZYABW.js +0 -1468
- package/dist/chunk-QYINBNMJ.js +0 -2545
- package/dist/chunk-RDF25WB2.js +0 -2085
- package/dist/chunk-RKTT3ZEX.js +0 -1500
- package/dist/chunk-S47BRMNQ.js +0 -1715
- package/dist/chunk-S4ZH5F56.js +0 -1949
- package/dist/chunk-SRD7NJHS.js +0 -1949
- package/dist/chunk-SWFYJO5H.js +0 -2187
- package/dist/chunk-TQDWPSTO.js +0 -2087
- package/dist/chunk-TTRXRPP6.js +0 -1941
- package/dist/chunk-UKYFJSUA.js +0 -509
- package/dist/chunk-VKEQHP2E.js +0 -2133
- package/dist/chunk-VUT2FMSI.js +0 -1937
- package/dist/chunk-VVCC5JHK.js +0 -1949
- package/dist/chunk-W732TVBK.js +0 -1944
- package/dist/chunk-X4VQYPKO.js +0 -1768
- package/dist/chunk-YX7HV4EP.js +0 -2568
- package/dist/chunk-YXKONM3A.js +0 -2192
- package/dist/chunk-YZ3P3TNS.js +0 -1760
- package/dist/chunk-ZVZ7JN3V.js +0 -2568
- package/dist/chunk-ZXW4STTN.js +0 -2568
package/CHANGELOG.md
CHANGED
|
@@ -1,96 +1 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
## 0.4.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- c4eae3b: Fix client-side navigation race conditions, content flash, and feedback section disappearing
|
|
8
|
-
|
|
9
|
-
**Theme:**
|
|
10
|
-
|
|
11
|
-
- Replace AbortController with navigation counter pattern for reliable race condition protection during rapid sidebar navigation
|
|
12
|
-
- Switch content innerHTML update from `useEffect` to `useLayoutEffect` to prevent visual flash artifacts (thumbs up/down flicker)
|
|
13
|
-
- Add `key={currentPageId}` on content div to force DOM recreation on page change
|
|
14
|
-
- Change `overflow: hidden` to `overflow: clip` on root container to prevent feedback section from disappearing on scroll
|
|
15
|
-
- Move `setCurrentPageId` after page load completes (load-before-push) so sidebar highlighting stays correct during navigation
|
|
16
|
-
- Remove stale HTML comparison guard that prevented content updates during rapid navigation
|
|
17
|
-
- Add error classes (PageNotFoundError, PageLoadError, NavigationCancelledError) for better error handling
|
|
18
|
-
|
|
19
|
-
**Core:**
|
|
20
|
-
|
|
21
|
-
- Page loader virtual module now throws `Error("Unknown page: " + id)` for unknown page IDs instead of silently returning null
|
|
22
|
-
|
|
23
|
-
**CLI:**
|
|
24
|
-
|
|
25
|
-
- Restructure `tome init` scaffolding to use Diataxis framework (tutorials, guides, reference, concepts)
|
|
26
|
-
- Add comprehensive starter pages for each Diataxis category
|
|
27
|
-
- Add create-tome template with same Diataxis structure
|
|
28
|
-
|
|
29
|
-
### Patch Changes
|
|
30
|
-
|
|
31
|
-
- Updated dependencies [c4eae3b]
|
|
32
|
-
- @tomehq/core@0.3.4
|
|
33
|
-
|
|
34
|
-
## 0.3.4
|
|
35
|
-
|
|
36
|
-
### Patch Changes
|
|
37
|
-
|
|
38
|
-
- f03e6c2: Fix page scrolling beyond viewport bounds in all directions. Lock layout to 100vh with overflow hidden on html, body, and root container.
|
|
39
|
-
|
|
40
|
-
## 0.3.3
|
|
41
|
-
|
|
42
|
-
### Patch Changes
|
|
43
|
-
|
|
44
|
-
- 062349c: Fix MCP server stdout corruption, add dashboard mobile responsiveness, improve test coverage, and update docs.
|
|
45
|
-
|
|
46
|
-
- Fix: MCP CLI banner no longer writes to stdout, preventing JSON-RPC protocol corruption
|
|
47
|
-
- Fix: API Playground prop wiring and githubSource route crash
|
|
48
|
-
- Feat: MCP server `createMcpServer()` exported for programmatic use with graceful shutdown
|
|
49
|
-
- Feat: Dashboard mobile-responsive layout with media query breakpoints
|
|
50
|
-
- Feat: 13 MCP server integration tests using InMemoryTransport
|
|
51
|
-
- Docs: Add missing typedoc CLI command, fix social link examples, update package list
|
|
52
|
-
|
|
53
|
-
- Updated dependencies [062349c]
|
|
54
|
-
- @tomehq/core@0.3.3
|
|
55
|
-
- @tomehq/components@0.3.3
|
|
56
|
-
|
|
57
|
-
## 0.2.8
|
|
58
|
-
|
|
59
|
-
### Minor Changes
|
|
60
|
-
|
|
61
|
-
- Replace hash-based SPA routing with History API (pushState + popstate + pathname parsing)
|
|
62
|
-
- Content link interception: in-content markdown links navigate via SPA instead of full page reload
|
|
63
|
-
- Banner link internal navigation support
|
|
64
|
-
- Algolia search basePath stripping for correct page ID extraction
|
|
65
|
-
- Extract routing helpers (`pathnameToPageId`, `pageIdToPath`) into testable `routing.ts` module
|
|
66
|
-
- Extract entry helpers (`loadPage`, `computeEditUrl`, `resolveInitialPageId`, `detectCurrentVersion`) into testable `entry-helpers.ts` module
|
|
67
|
-
- Pass `basePath` prop through Shell for correct URL construction
|
|
68
|
-
- Updated dependencies
|
|
69
|
-
- @tomehq/core@0.2.8
|
|
70
|
-
- @tomehq/components@0.2.8
|
|
71
|
-
|
|
72
|
-
## 0.2.0
|
|
73
|
-
|
|
74
|
-
### Minor Changes
|
|
75
|
-
|
|
76
|
-
- Shell: logo links back to landing page, dynamic version in sidebar footer
|
|
77
|
-
- Shell: edit link support, table of contents depth config, changelog page layout
|
|
78
|
-
- Entry: pass new config fields (editLink, tableOfContents, plugins) to Shell
|
|
79
|
-
- Updated dependencies
|
|
80
|
-
- @tomehq/core@0.2.0
|
|
81
|
-
- @tomehq/components@0.2.0
|
|
82
|
-
|
|
83
|
-
## 0.1.2
|
|
84
|
-
|
|
85
|
-
### Patch Changes
|
|
86
|
-
|
|
87
|
-
- Updated dependencies
|
|
88
|
-
- @tomehq/components@0.1.1
|
|
89
|
-
|
|
90
|
-
## 0.1.1
|
|
91
|
-
|
|
92
|
-
### Patch Changes
|
|
93
|
-
|
|
94
|
-
- Fix bugs found in functionality audit: invalid search provider, AI key naming mismatch, hardcoded version. Remove dead billing stubs. Add 57 API route tests.
|
|
95
|
-
- Updated dependencies
|
|
96
|
-
- @tomehq/core@0.1.1
|
|
1
|
+
# Changelog
|
|
@@ -76,6 +76,76 @@ var THEME_PRESETS = {
|
|
|
76
76
|
hdBg: "rgba(246,244,240,0.92)"
|
|
77
77
|
},
|
|
78
78
|
fonts: { heading: "Cormorant Garamond", body: "Bricolage Grotesque", code: "Fira Code" }
|
|
79
|
+
},
|
|
80
|
+
cipher: {
|
|
81
|
+
dark: {
|
|
82
|
+
bg: "#050508",
|
|
83
|
+
sf: "#0c0c12",
|
|
84
|
+
sfH: "#12121a",
|
|
85
|
+
bd: "#1a1a25",
|
|
86
|
+
tx: "#d4ff00",
|
|
87
|
+
tx2: "#8a90a0",
|
|
88
|
+
txM: "#6a7080",
|
|
89
|
+
ac: "#6666ff",
|
|
90
|
+
acD: "rgba(102,102,255,0.10)",
|
|
91
|
+
acT: "#8080ff",
|
|
92
|
+
cdBg: "#08080e",
|
|
93
|
+
cdTx: "#b0c870",
|
|
94
|
+
sbBg: "#08080d",
|
|
95
|
+
hdBg: "rgba(5,5,8,0.88)"
|
|
96
|
+
},
|
|
97
|
+
light: {
|
|
98
|
+
bg: "#f0f2f5",
|
|
99
|
+
sf: "#ffffff",
|
|
100
|
+
sfH: "#e8eaef",
|
|
101
|
+
bd: "#d0d4db",
|
|
102
|
+
tx: "#0f1219",
|
|
103
|
+
tx2: "#4a5060",
|
|
104
|
+
txM: "#6a7080",
|
|
105
|
+
ac: "#2020cc",
|
|
106
|
+
acD: "rgba(32,32,204,0.08)",
|
|
107
|
+
acT: "#1a1aa8",
|
|
108
|
+
cdBg: "#e6e9ef",
|
|
109
|
+
cdTx: "#2a3520",
|
|
110
|
+
sbBg: "#ebedf2",
|
|
111
|
+
hdBg: "rgba(240,242,245,0.90)"
|
|
112
|
+
},
|
|
113
|
+
fonts: { heading: "Bodoni Moda", body: "Space Grotesk", code: "Source Code Pro" }
|
|
114
|
+
},
|
|
115
|
+
mint: {
|
|
116
|
+
dark: {
|
|
117
|
+
bg: "#0d1117",
|
|
118
|
+
sf: "#161b22",
|
|
119
|
+
sfH: "#1c2129",
|
|
120
|
+
bd: "#21262d",
|
|
121
|
+
tx: "#e6edf3",
|
|
122
|
+
tx2: "#8b949e",
|
|
123
|
+
txM: "#6e7681",
|
|
124
|
+
ac: "#0ea371",
|
|
125
|
+
acD: "rgba(14,163,113,0.10)",
|
|
126
|
+
acT: "#2dd4a0",
|
|
127
|
+
cdBg: "#0a0e14",
|
|
128
|
+
cdTx: "#adbac7",
|
|
129
|
+
sbBg: "#0d1117",
|
|
130
|
+
hdBg: "rgba(13,17,23,0.88)"
|
|
131
|
+
},
|
|
132
|
+
light: {
|
|
133
|
+
bg: "#ffffff",
|
|
134
|
+
sf: "#f6f8fa",
|
|
135
|
+
sfH: "#eef1f5",
|
|
136
|
+
bd: "#d8dee4",
|
|
137
|
+
tx: "#1f2328",
|
|
138
|
+
tx2: "#59636e",
|
|
139
|
+
txM: "#6e7681",
|
|
140
|
+
ac: "#0a7b53",
|
|
141
|
+
acD: "rgba(10,123,83,0.07)",
|
|
142
|
+
acT: "#087a50",
|
|
143
|
+
cdBg: "#f0f3f6",
|
|
144
|
+
cdTx: "#24292f",
|
|
145
|
+
sbBg: "#f6f8fa",
|
|
146
|
+
hdBg: "rgba(255,255,255,0.90)"
|
|
147
|
+
},
|
|
148
|
+
fonts: { heading: "Inter", body: "Inter", code: "Fira Code" }
|
|
79
149
|
}
|
|
80
150
|
};
|
|
81
151
|
|
|
@@ -842,7 +912,7 @@ function Shell({
|
|
|
842
912
|
const [isDark, setDark] = useState2(() => {
|
|
843
913
|
if (themeMode === "dark") return true;
|
|
844
914
|
if (themeMode === "light") return false;
|
|
845
|
-
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ??
|
|
915
|
+
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false;
|
|
846
916
|
});
|
|
847
917
|
const [mobile, setMobile] = useState2(() => typeof window !== "undefined" && window.innerWidth < 768);
|
|
848
918
|
const [sbOpen, setSb] = useState2(() => typeof window !== "undefined" && window.innerWidth >= 768);
|
|
@@ -1026,8 +1096,8 @@ function Shell({
|
|
|
1026
1096
|
}, []);
|
|
1027
1097
|
const allNavPages = navigation2.flatMap((g) => g.pages);
|
|
1028
1098
|
const idx = allNavPages.findIndex((p) => p.id === currentPageId);
|
|
1029
|
-
const prev = idx > 0 ? allNavPages[idx - 1] : null;
|
|
1030
|
-
const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : null;
|
|
1099
|
+
const prev = idx > 0 ? allNavPages[idx - 1] : allNavPages[allNavPages.length - 1] ?? null;
|
|
1100
|
+
const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : allNavPages[0] ?? null;
|
|
1031
1101
|
const breadcrumbs = getBreadcrumbs(navigation2, currentPageId, pageTitle);
|
|
1032
1102
|
const togSec = (s) => setExpanded((p) => p.includes(s) ? p.filter((x) => x !== s) : [...p, s]);
|
|
1033
1103
|
const cssVars = {
|
|
@@ -1589,7 +1659,7 @@ function Shell({
|
|
|
1589
1659
|
}
|
|
1590
1660
|
),
|
|
1591
1661
|
/* @__PURE__ */ jsxs2("div", { ref: contentRef, style: { flex: 1, overflow: "auto", display: "flex" }, children: [
|
|
1592
|
-
/* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
|
|
1662
|
+
/* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : apiManifest ? 1100 : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
|
|
1593
1663
|
breadcrumbs.length > 0 && /* @__PURE__ */ jsx2("nav", { "aria-label": "Breadcrumbs", "data-testid": "breadcrumbs", style: {
|
|
1594
1664
|
display: "flex",
|
|
1595
1665
|
alignItems: "center",
|
|
@@ -1627,7 +1697,7 @@ function Shell({
|
|
|
1627
1697
|
currentPageId
|
|
1628
1698
|
)
|
|
1629
1699
|
) }),
|
|
1630
|
-
overrides2?.PageFooter ? /* @__PURE__ */ jsx2(
|
|
1700
|
+
!pageHtml && !pageComponent ? null : overrides2?.PageFooter ? /* @__PURE__ */ jsx2(
|
|
1631
1701
|
overrides2.PageFooter,
|
|
1632
1702
|
{
|
|
1633
1703
|
editUrl,
|
|
@@ -1704,43 +1774,79 @@ function Shell({
|
|
|
1704
1774
|
transition: "border-color .15s"
|
|
1705
1775
|
}, children: "\u{1F44E}" })
|
|
1706
1776
|
] }) }),
|
|
1707
|
-
/* @__PURE__ */ jsxs2("div", { style: { display: "
|
|
1708
|
-
prev ? /* @__PURE__ */ jsxs2(
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1777
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "grid", gridTemplateColumns: mobile ? "1fr" : "1fr 1fr", marginTop: 24, paddingTop: 32, paddingBottom: 40, borderTop: "1px solid var(--bd)", gap: 16 }, children: [
|
|
1778
|
+
prev ? /* @__PURE__ */ jsxs2(
|
|
1779
|
+
"button",
|
|
1780
|
+
{
|
|
1781
|
+
onClick: () => onNavigate(prev.id),
|
|
1782
|
+
style: {
|
|
1783
|
+
display: "flex",
|
|
1784
|
+
flexDirection: "column",
|
|
1785
|
+
alignItems: "flex-start",
|
|
1786
|
+
gap: 6,
|
|
1787
|
+
background: "var(--sf)",
|
|
1788
|
+
border: "1px solid var(--bd)",
|
|
1789
|
+
borderRadius: 8,
|
|
1790
|
+
padding: "16px 20px",
|
|
1791
|
+
cursor: "pointer",
|
|
1792
|
+
textAlign: "left",
|
|
1793
|
+
fontFamily: "var(--font-body)",
|
|
1794
|
+
transition: "all .3s ease",
|
|
1795
|
+
boxShadow: "0 2px 8px rgba(0,0,0,0.06)"
|
|
1796
|
+
},
|
|
1797
|
+
onMouseOver: (e) => {
|
|
1798
|
+
e.currentTarget.style.borderColor = "var(--ac)";
|
|
1799
|
+
e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.1)";
|
|
1800
|
+
},
|
|
1801
|
+
onMouseOut: (e) => {
|
|
1802
|
+
e.currentTarget.style.borderColor = "var(--bd)";
|
|
1803
|
+
e.currentTarget.style.boxShadow = "0 2px 8px rgba(0,0,0,0.06)";
|
|
1804
|
+
},
|
|
1805
|
+
children: [
|
|
1806
|
+
/* @__PURE__ */ jsxs2("span", { style: { fontSize: 11, color: "var(--txM)", textTransform: "uppercase", letterSpacing: "0.5px", display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
1807
|
+
isRtl ? /* @__PURE__ */ jsx2(ArrowRight, {}) : /* @__PURE__ */ jsx2(ArrowLeft, {}),
|
|
1808
|
+
" Previous"
|
|
1809
|
+
] }),
|
|
1810
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 14, fontWeight: 500, color: "var(--tx)" }, children: prev.title })
|
|
1811
|
+
]
|
|
1812
|
+
}
|
|
1813
|
+
) : /* @__PURE__ */ jsx2("div", {}),
|
|
1814
|
+
next ? /* @__PURE__ */ jsxs2(
|
|
1815
|
+
"button",
|
|
1816
|
+
{
|
|
1817
|
+
onClick: () => onNavigate(next.id),
|
|
1818
|
+
style: {
|
|
1819
|
+
display: "flex",
|
|
1820
|
+
flexDirection: "column",
|
|
1821
|
+
alignItems: "flex-end",
|
|
1822
|
+
gap: 6,
|
|
1823
|
+
background: "var(--sf)",
|
|
1824
|
+
border: "1px solid var(--bd)",
|
|
1825
|
+
borderRadius: 8,
|
|
1826
|
+
padding: "16px 20px",
|
|
1827
|
+
cursor: "pointer",
|
|
1828
|
+
textAlign: "right",
|
|
1829
|
+
fontFamily: "var(--font-body)",
|
|
1830
|
+
transition: "all .3s ease",
|
|
1831
|
+
boxShadow: "0 2px 8px rgba(0,0,0,0.06)"
|
|
1832
|
+
},
|
|
1833
|
+
onMouseOver: (e) => {
|
|
1834
|
+
e.currentTarget.style.borderColor = "var(--ac)";
|
|
1835
|
+
e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.1)";
|
|
1836
|
+
},
|
|
1837
|
+
onMouseOut: (e) => {
|
|
1838
|
+
e.currentTarget.style.borderColor = "var(--bd)";
|
|
1839
|
+
e.currentTarget.style.boxShadow = "0 2px 8px rgba(0,0,0,0.06)";
|
|
1840
|
+
},
|
|
1841
|
+
children: [
|
|
1842
|
+
/* @__PURE__ */ jsxs2("span", { style: { fontSize: 11, color: "var(--txM)", textTransform: "uppercase", letterSpacing: "0.5px", display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
1843
|
+
"Next ",
|
|
1844
|
+
isRtl ? /* @__PURE__ */ jsx2(ArrowLeft, {}) : /* @__PURE__ */ jsx2(ArrowRight, {})
|
|
1845
|
+
] }),
|
|
1846
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 14, fontWeight: 500, color: "var(--tx)" }, children: next.title })
|
|
1847
|
+
]
|
|
1848
|
+
}
|
|
1849
|
+
) : /* @__PURE__ */ jsx2("div", {})
|
|
1744
1850
|
] })
|
|
1745
1851
|
] })
|
|
1746
1852
|
] }),
|
|
@@ -2064,14 +2170,13 @@ var MDX_COMPONENTS = {
|
|
|
2064
2170
|
CardGrid
|
|
2065
2171
|
};
|
|
2066
2172
|
var contentStyles = `
|
|
2067
|
-
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@300;400;500;600;700&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,700&family=Fira+Code:wght@400;500;600&display=swap');
|
|
2173
|
+
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Bricolage+Grotesque:wght@300;400;500;600;700&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,700&family=Fira+Code:wght@400;500;600&family=Bodoni+Moda:ital,wght@0,400;0,700;0,900;1,400&family=Space+Grotesk:wght@400;500;600;700&family=Source+Code+Pro:wght@400;500;600&family=Inter:wght@300;400;500;600;700&display=swap');
|
|
2068
2174
|
|
|
2069
2175
|
html, body { margin: 0; padding: 0; height: 100%; overflow: clip; }
|
|
2070
2176
|
#tome-root { height: 100%; overflow: clip; }
|
|
2071
2177
|
|
|
2072
2178
|
.tome-content h1 { display: none; }
|
|
2073
|
-
.tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em;
|
|
2074
|
-
.tome-content h2::before { content: "#"; font-family: var(--font-heading); font-size: 1.2em; font-weight: 300; font-style: italic; color: var(--ac); opacity: 0.5; }
|
|
2179
|
+
.tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; letter-spacing: 0.01em; }
|
|
2075
2180
|
.tome-content h3 { font-family: var(--font-body); font-size: 1.15em; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; }
|
|
2076
2181
|
.tome-content h4 { font-family: var(--font-body); font-size: 1.05em; font-weight: 600; margin-top: 1.2em; margin-bottom: 0.5em; }
|
|
2077
2182
|
.tome-content p { color: var(--tx2); line-height: 1.8; margin-bottom: 1em; font-size: 14.5px; }
|
package/dist/entry.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -252,6 +252,84 @@ declare const THEME_PRESETS: {
|
|
|
252
252
|
readonly code: "Fira Code";
|
|
253
253
|
};
|
|
254
254
|
};
|
|
255
|
+
readonly cipher: {
|
|
256
|
+
readonly dark: {
|
|
257
|
+
readonly bg: "#050508";
|
|
258
|
+
readonly sf: "#0c0c12";
|
|
259
|
+
readonly sfH: "#12121a";
|
|
260
|
+
readonly bd: "#1a1a25";
|
|
261
|
+
readonly tx: "#d4ff00";
|
|
262
|
+
readonly tx2: "#8a90a0";
|
|
263
|
+
readonly txM: "#6a7080";
|
|
264
|
+
readonly ac: "#6666ff";
|
|
265
|
+
readonly acD: "rgba(102,102,255,0.10)";
|
|
266
|
+
readonly acT: "#8080ff";
|
|
267
|
+
readonly cdBg: "#08080e";
|
|
268
|
+
readonly cdTx: "#b0c870";
|
|
269
|
+
readonly sbBg: "#08080d";
|
|
270
|
+
readonly hdBg: "rgba(5,5,8,0.88)";
|
|
271
|
+
};
|
|
272
|
+
readonly light: {
|
|
273
|
+
readonly bg: "#f0f2f5";
|
|
274
|
+
readonly sf: "#ffffff";
|
|
275
|
+
readonly sfH: "#e8eaef";
|
|
276
|
+
readonly bd: "#d0d4db";
|
|
277
|
+
readonly tx: "#0f1219";
|
|
278
|
+
readonly tx2: "#4a5060";
|
|
279
|
+
readonly txM: "#6a7080";
|
|
280
|
+
readonly ac: "#2020cc";
|
|
281
|
+
readonly acD: "rgba(32,32,204,0.08)";
|
|
282
|
+
readonly acT: "#1a1aa8";
|
|
283
|
+
readonly cdBg: "#e6e9ef";
|
|
284
|
+
readonly cdTx: "#2a3520";
|
|
285
|
+
readonly sbBg: "#ebedf2";
|
|
286
|
+
readonly hdBg: "rgba(240,242,245,0.90)";
|
|
287
|
+
};
|
|
288
|
+
readonly fonts: {
|
|
289
|
+
readonly heading: "Bodoni Moda";
|
|
290
|
+
readonly body: "Space Grotesk";
|
|
291
|
+
readonly code: "Source Code Pro";
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
readonly mint: {
|
|
295
|
+
readonly dark: {
|
|
296
|
+
readonly bg: "#0d1117";
|
|
297
|
+
readonly sf: "#161b22";
|
|
298
|
+
readonly sfH: "#1c2129";
|
|
299
|
+
readonly bd: "#21262d";
|
|
300
|
+
readonly tx: "#e6edf3";
|
|
301
|
+
readonly tx2: "#8b949e";
|
|
302
|
+
readonly txM: "#6e7681";
|
|
303
|
+
readonly ac: "#0ea371";
|
|
304
|
+
readonly acD: "rgba(14,163,113,0.10)";
|
|
305
|
+
readonly acT: "#2dd4a0";
|
|
306
|
+
readonly cdBg: "#0a0e14";
|
|
307
|
+
readonly cdTx: "#adbac7";
|
|
308
|
+
readonly sbBg: "#0d1117";
|
|
309
|
+
readonly hdBg: "rgba(13,17,23,0.88)";
|
|
310
|
+
};
|
|
311
|
+
readonly light: {
|
|
312
|
+
readonly bg: "#ffffff";
|
|
313
|
+
readonly sf: "#f6f8fa";
|
|
314
|
+
readonly sfH: "#eef1f5";
|
|
315
|
+
readonly bd: "#d8dee4";
|
|
316
|
+
readonly tx: "#1f2328";
|
|
317
|
+
readonly tx2: "#59636e";
|
|
318
|
+
readonly txM: "#6e7681";
|
|
319
|
+
readonly ac: "#0a7b53";
|
|
320
|
+
readonly acD: "rgba(10,123,83,0.07)";
|
|
321
|
+
readonly acT: "#087a50";
|
|
322
|
+
readonly cdBg: "#f0f3f6";
|
|
323
|
+
readonly cdTx: "#24292f";
|
|
324
|
+
readonly sbBg: "#f6f8fa";
|
|
325
|
+
readonly hdBg: "rgba(255,255,255,0.90)";
|
|
326
|
+
};
|
|
327
|
+
readonly fonts: {
|
|
328
|
+
readonly heading: "Inter";
|
|
329
|
+
readonly body: "Inter";
|
|
330
|
+
readonly code: "Fira Code";
|
|
331
|
+
};
|
|
332
|
+
};
|
|
255
333
|
};
|
|
256
334
|
type PresetName = keyof typeof THEME_PRESETS;
|
|
257
335
|
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomehq/theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Tome default theme and React app shell",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.tsx",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"./entry": "./src/entry.tsx"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@tomehq/
|
|
13
|
-
"@tomehq/
|
|
12
|
+
"@tomehq/components": "0.6.0",
|
|
13
|
+
"@tomehq/core": "0.6.0"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
16
|
"react": "^18.0.0 || ^19.0.0",
|
package/src/Shell.test.tsx
CHANGED
|
@@ -180,6 +180,18 @@ describe("Shell theme mode", () => {
|
|
|
180
180
|
const buttons = footer?.querySelectorAll("button");
|
|
181
181
|
expect(buttons?.length).toBeGreaterThan(0);
|
|
182
182
|
});
|
|
183
|
+
|
|
184
|
+
it("defaults to light mode when mode is 'auto' and system preference is unavailable", () => {
|
|
185
|
+
const { container } = renderShell({
|
|
186
|
+
config: { ...baseConfig, theme: { preset: "amber", mode: "auto" } },
|
|
187
|
+
});
|
|
188
|
+
// matchMedia mock returns matches: false → light mode
|
|
189
|
+
// In light mode, the root container uses light theme background
|
|
190
|
+
const root = container.firstElementChild as HTMLElement;
|
|
191
|
+
const bg = root?.style.getPropertyValue("--bg");
|
|
192
|
+
// Amber light bg is #fafaf9 (not dark bg #09090b)
|
|
193
|
+
expect(bg).toBe("#fafaf9");
|
|
194
|
+
});
|
|
183
195
|
});
|
|
184
196
|
|
|
185
197
|
// ── TOC (TOM-52) ──────────────────────────────────────────
|
|
@@ -1211,6 +1223,24 @@ describe("Shell API reference rendering", () => {
|
|
|
1211
1223
|
expect(screen.queryByTestId("api-playground")).not.toBeInTheDocument();
|
|
1212
1224
|
expect(screen.queryByTestId("api-auth")).not.toBeInTheDocument();
|
|
1213
1225
|
});
|
|
1226
|
+
|
|
1227
|
+
it("uses wider max-width for API reference pages", () => {
|
|
1228
|
+
const { container } = renderShell({
|
|
1229
|
+
apiManifest: mockManifest,
|
|
1230
|
+
ApiReferenceComponent: MockApiRef,
|
|
1231
|
+
pageHtml: undefined,
|
|
1232
|
+
});
|
|
1233
|
+
const main = container.querySelector("main") as HTMLElement;
|
|
1234
|
+
expect(main.style.maxWidth).toBe("1100px");
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
it("uses standard max-width for non-API pages", () => {
|
|
1238
|
+
const { container } = renderShell({
|
|
1239
|
+
pageHtml: "<p>Regular prose content</p>",
|
|
1240
|
+
});
|
|
1241
|
+
const main = container.querySelector("main") as HTMLElement;
|
|
1242
|
+
expect(main.style.maxWidth).toBe("760px");
|
|
1243
|
+
});
|
|
1214
1244
|
});
|
|
1215
1245
|
|
|
1216
1246
|
// ── Content link interception ───────────────────────────────
|
package/src/Shell.tsx
CHANGED
|
@@ -413,7 +413,7 @@ export function Shell({
|
|
|
413
413
|
const [isDark, setDark] = useState(() => {
|
|
414
414
|
if (themeMode === "dark") return true;
|
|
415
415
|
if (themeMode === "light") return false;
|
|
416
|
-
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ??
|
|
416
|
+
return window.matchMedia?.("(prefers-color-scheme: dark)").matches ?? false;
|
|
417
417
|
});
|
|
418
418
|
|
|
419
419
|
const [mobile, setMobile] = useState(() => typeof window !== "undefined" && window.innerWidth < 768);
|
|
@@ -643,8 +643,8 @@ export function Shell({
|
|
|
643
643
|
// Prev / Next
|
|
644
644
|
const allNavPages = navigation.flatMap(g => g.pages);
|
|
645
645
|
const idx = allNavPages.findIndex(p => p.id === currentPageId);
|
|
646
|
-
const prev = idx > 0 ? allNavPages[idx - 1] : null;
|
|
647
|
-
const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : null;
|
|
646
|
+
const prev = idx > 0 ? allNavPages[idx - 1] : allNavPages[allNavPages.length - 1] ?? null;
|
|
647
|
+
const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : allNavPages[0] ?? null;
|
|
648
648
|
|
|
649
649
|
// Breadcrumbs
|
|
650
650
|
const breadcrumbs = getBreadcrumbs(navigation, currentPageId, pageTitle);
|
|
@@ -1127,7 +1127,7 @@ export function Shell({
|
|
|
1127
1127
|
|
|
1128
1128
|
{/* Content + TOC */}
|
|
1129
1129
|
<div ref={contentRef} style={{ flex: 1, overflow: "auto", display: "flex" }}>
|
|
1130
|
-
<main style={{ flex: 1, maxWidth: mobile ? "100%" : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }}>
|
|
1130
|
+
<main style={{ flex: 1, maxWidth: mobile ? "100%" : apiManifest ? 1100 : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }}>
|
|
1131
1131
|
{breadcrumbs.length > 0 && (
|
|
1132
1132
|
<nav aria-label="Breadcrumbs" data-testid="breadcrumbs" style={{
|
|
1133
1133
|
display: "flex", alignItems: "center", gap: 6,
|
|
@@ -1186,7 +1186,7 @@ export function Shell({
|
|
|
1186
1186
|
</div>
|
|
1187
1187
|
|
|
1188
1188
|
{/* TOM-48: Edit this page link + TOM-54: Last updated + Feedback + Prev/Next */}
|
|
1189
|
-
{overrides?.PageFooter ? (
|
|
1189
|
+
{!pageHtml && !pageComponent ? null : overrides?.PageFooter ? (
|
|
1190
1190
|
<overrides.PageFooter
|
|
1191
1191
|
editUrl={editUrl}
|
|
1192
1192
|
lastUpdated={lastUpdated}
|
|
@@ -1243,23 +1243,41 @@ export function Shell({
|
|
|
1243
1243
|
)}
|
|
1244
1244
|
</div>
|
|
1245
1245
|
|
|
1246
|
-
{/* Prev / Next */}
|
|
1247
|
-
<div style={{ display: "
|
|
1246
|
+
{/* Prev / Next link cards */}
|
|
1247
|
+
<div style={{ display: "grid", gridTemplateColumns: mobile ? "1fr" : "1fr 1fr", marginTop: 24, paddingTop: 32, paddingBottom: 40, borderTop: "1px solid var(--bd)", gap: 16 }}>
|
|
1248
1248
|
{prev ? (
|
|
1249
1249
|
<button onClick={() => onNavigate(prev.id)} style={{
|
|
1250
|
-
display: "flex",
|
|
1251
|
-
border: "1px solid var(--bd)", borderRadius:
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1250
|
+
display: "flex", flexDirection: "column", alignItems: "flex-start", gap: 6,
|
|
1251
|
+
background: "var(--sf)", border: "1px solid var(--bd)", borderRadius: 8,
|
|
1252
|
+
padding: "16px 20px", cursor: "pointer", textAlign: "left",
|
|
1253
|
+
fontFamily: "var(--font-body)", transition: "all .3s ease",
|
|
1254
|
+
boxShadow: "0 2px 8px rgba(0,0,0,0.06)",
|
|
1255
|
+
}}
|
|
1256
|
+
onMouseOver={(e) => { e.currentTarget.style.borderColor = "var(--ac)"; e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.1)"; }}
|
|
1257
|
+
onMouseOut={(e) => { e.currentTarget.style.borderColor = "var(--bd)"; e.currentTarget.style.boxShadow = "0 2px 8px rgba(0,0,0,0.06)"; }}
|
|
1258
|
+
>
|
|
1259
|
+
<span style={{ fontSize: 11, color: "var(--txM)", textTransform: "uppercase", letterSpacing: "0.5px", display: "flex", alignItems: "center", gap: 4 }}>
|
|
1260
|
+
{isRtl ? <ArrowRight /> : <ArrowLeft />} Previous
|
|
1261
|
+
</span>
|
|
1262
|
+
<span style={{ fontSize: 14, fontWeight: 500, color: "var(--tx)" }}>{prev.title}</span>
|
|
1263
|
+
</button>
|
|
1255
1264
|
) : <div />}
|
|
1256
1265
|
{next ? (
|
|
1257
1266
|
<button onClick={() => onNavigate(next.id)} style={{
|
|
1258
|
-
display: "flex",
|
|
1259
|
-
border: "1px solid var(--bd)", borderRadius:
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1267
|
+
display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 6,
|
|
1268
|
+
background: "var(--sf)", border: "1px solid var(--bd)", borderRadius: 8,
|
|
1269
|
+
padding: "16px 20px", cursor: "pointer", textAlign: "right",
|
|
1270
|
+
fontFamily: "var(--font-body)", transition: "all .3s ease",
|
|
1271
|
+
boxShadow: "0 2px 8px rgba(0,0,0,0.06)",
|
|
1272
|
+
}}
|
|
1273
|
+
onMouseOver={(e) => { e.currentTarget.style.borderColor = "var(--ac)"; e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.1)"; }}
|
|
1274
|
+
onMouseOut={(e) => { e.currentTarget.style.borderColor = "var(--bd)"; e.currentTarget.style.boxShadow = "0 2px 8px rgba(0,0,0,0.06)"; }}
|
|
1275
|
+
>
|
|
1276
|
+
<span style={{ fontSize: 11, color: "var(--txM)", textTransform: "uppercase", letterSpacing: "0.5px", display: "flex", alignItems: "center", gap: 4 }}>
|
|
1277
|
+
Next {isRtl ? <ArrowLeft /> : <ArrowRight />}
|
|
1278
|
+
</span>
|
|
1279
|
+
<span style={{ fontSize: 14, fontWeight: 500, color: "var(--tx)" }}>{next.title}</span>
|
|
1280
|
+
</button>
|
|
1263
1281
|
) : <div />}
|
|
1264
1282
|
</div>
|
|
1265
1283
|
</>
|
package/src/entry.tsx
CHANGED
|
@@ -59,14 +59,13 @@ const MDX_COMPONENTS: Record<string, React.ComponentType<any>> = {
|
|
|
59
59
|
|
|
60
60
|
// ── CONTENT STYLES ───────────────────────────────────────
|
|
61
61
|
const contentStyles = `
|
|
62
|
-
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@300;400;500;600;700&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,700&family=Fira+Code:wght@400;500;600&display=swap');
|
|
62
|
+
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=DM+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Bricolage+Grotesque:wght@300;400;500;600;700&family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,700&family=Fira+Code:wght@400;500;600&family=Bodoni+Moda:ital,wght@0,400;0,700;0,900;1,400&family=Space+Grotesk:wght@400;500;600;700&family=Source+Code+Pro:wght@400;500;600&family=Inter:wght@300;400;500;600;700&display=swap');
|
|
63
63
|
|
|
64
64
|
html, body { margin: 0; padding: 0; height: 100%; overflow: clip; }
|
|
65
65
|
#tome-root { height: 100%; overflow: clip; }
|
|
66
66
|
|
|
67
67
|
.tome-content h1 { display: none; }
|
|
68
|
-
.tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em;
|
|
69
|
-
.tome-content h2::before { content: "#"; font-family: var(--font-heading); font-size: 1.2em; font-weight: 300; font-style: italic; color: var(--ac); opacity: 0.5; }
|
|
68
|
+
.tome-content h2 { font-family: var(--font-body); font-size: 1.35em; font-weight: 600; margin-top: 2em; margin-bottom: 0.5em; letter-spacing: 0.01em; }
|
|
70
69
|
.tome-content h3 { font-family: var(--font-body); font-size: 1.15em; font-weight: 600; margin-top: 1.5em; margin-bottom: 0.5em; }
|
|
71
70
|
.tome-content h4 { font-family: var(--font-body); font-size: 1.05em; font-weight: 600; margin-top: 1.2em; margin-bottom: 0.5em; }
|
|
72
71
|
.tome-content p { color: var(--tx2); line-height: 1.8; margin-bottom: 1em; font-size: 14.5px; }
|
package/src/presets.test.ts
CHANGED
|
@@ -11,12 +11,14 @@ const TOKEN_KEYS = [
|
|
|
11
11
|
|
|
12
12
|
const FONT_KEYS = ["heading", "body", "code"] as const;
|
|
13
13
|
|
|
14
|
-
const PRESET_NAMES: PresetName[] = ["amber", "editorial"];
|
|
14
|
+
const PRESET_NAMES: PresetName[] = ["amber", "editorial", "cipher", "mint"];
|
|
15
15
|
|
|
16
16
|
describe("THEME_PRESETS", () => {
|
|
17
|
-
it("contains
|
|
17
|
+
it("contains all presets", () => {
|
|
18
18
|
expect(THEME_PRESETS).toHaveProperty("amber");
|
|
19
19
|
expect(THEME_PRESETS).toHaveProperty("editorial");
|
|
20
|
+
expect(THEME_PRESETS).toHaveProperty("cipher");
|
|
21
|
+
expect(THEME_PRESETS).toHaveProperty("mint");
|
|
20
22
|
});
|
|
21
23
|
|
|
22
24
|
for (const name of PRESET_NAMES) {
|