@tomehq/theme 0.3.1 → 0.3.3

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 (67) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{chunk-YXKONM3A.js → chunk-MSXVVBDW.js} +493 -143
  3. package/dist/entry.js +1 -1
  4. package/dist/index.d.ts +37 -1
  5. package/dist/index.js +1 -1
  6. package/package.json +5 -5
  7. package/src/Shell.test.tsx +405 -0
  8. package/src/Shell.tsx +248 -24
  9. package/src/__virtual_stubs/config.ts +2 -0
  10. package/src/__virtual_stubs/doc-context.ts +2 -0
  11. package/src/__virtual_stubs/overrides.ts +2 -0
  12. package/src/__virtual_stubs/page-loader.ts +4 -0
  13. package/src/__virtual_stubs/routes.ts +5 -0
  14. package/src/entry-helpers.test.ts +76 -0
  15. package/src/entry-helpers.ts +18 -1
  16. package/src/entry.test.tsx +695 -0
  17. package/src/entry.tsx +179 -4
  18. package/src/global.d.ts +11 -0
  19. package/vitest.config.ts +31 -1
  20. package/dist/chunk-2APCPR2Y.js +0 -2110
  21. package/dist/chunk-37JI6XGT.js +0 -1720
  22. package/dist/chunk-3A2LPGUL.js +0 -1991
  23. package/dist/chunk-3I2QTWTW.js +0 -1948
  24. package/dist/chunk-45M5UIAB.js +0 -2110
  25. package/dist/chunk-462AGU3S.js +0 -1959
  26. package/dist/chunk-7MUTU5D4.js +0 -1720
  27. package/dist/chunk-ABNPB6BB.js +0 -2133
  28. package/dist/chunk-BZGWSKT2.js +0 -573
  29. package/dist/chunk-CMQCNCSY.js +0 -2127
  30. package/dist/chunk-CTPOZMMK.js +0 -1703
  31. package/dist/chunk-DO544M3G.js +0 -1702
  32. package/dist/chunk-DPKZBFQP.js +0 -1777
  33. package/dist/chunk-EK7PZUEB.js +0 -2147
  34. package/dist/chunk-FMOLIHQF.js +0 -2182
  35. package/dist/chunk-FWBTK5TL.js +0 -1444
  36. package/dist/chunk-GDQIBNX5.js +0 -1962
  37. package/dist/chunk-GHQ2MODM.js +0 -2127
  38. package/dist/chunk-GR2WCRGK.js +0 -2182
  39. package/dist/chunk-HNLKDQ64.js +0 -2139
  40. package/dist/chunk-INUMUXN5.js +0 -2095
  41. package/dist/chunk-IW3NHNOQ.js +0 -2187
  42. package/dist/chunk-JA4PMX6M.js +0 -1500
  43. package/dist/chunk-JSPFS7G5.js +0 -2102
  44. package/dist/chunk-JZRT4WNC.js +0 -1441
  45. package/dist/chunk-KQBY2JDB.js +0 -2112
  46. package/dist/chunk-LIMYFTPC.js +0 -1468
  47. package/dist/chunk-MEP7P6A7.js +0 -1500
  48. package/dist/chunk-NOZBIES7.js +0 -1948
  49. package/dist/chunk-O4GH3KYX.js +0 -1712
  50. package/dist/chunk-OEXM3BEC.js +0 -1702
  51. package/dist/chunk-Q7PYTVW3.js +0 -1771
  52. package/dist/chunk-QCWZYABW.js +0 -1468
  53. package/dist/chunk-RDF25WB2.js +0 -2085
  54. package/dist/chunk-RKTT3ZEX.js +0 -1500
  55. package/dist/chunk-S47BRMNQ.js +0 -1715
  56. package/dist/chunk-S4ZH5F56.js +0 -1949
  57. package/dist/chunk-SRD7NJHS.js +0 -1949
  58. package/dist/chunk-SWFYJO5H.js +0 -2187
  59. package/dist/chunk-TQDWPSTO.js +0 -2087
  60. package/dist/chunk-TTRXRPP6.js +0 -1941
  61. package/dist/chunk-UKYFJSUA.js +0 -509
  62. package/dist/chunk-VKEQHP2E.js +0 -2133
  63. package/dist/chunk-VUT2FMSI.js +0 -1937
  64. package/dist/chunk-VVCC5JHK.js +0 -1949
  65. package/dist/chunk-W732TVBK.js +0 -1944
  66. package/dist/chunk-X4VQYPKO.js +0 -1768
  67. package/dist/chunk-YZ3P3TNS.js +0 -1760
@@ -3,7 +3,7 @@ import { useState as useState3, useEffect as useEffect3, useCallback as useCallb
3
3
  import { createRoot } from "react-dom/client";
4
4
 
5
5
  // src/Shell.tsx
6
- import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback as useCallback2 } from "react";
6
+ import React2, { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback as useCallback2 } from "react";
7
7
 
8
8
  // src/presets.ts
9
9
  var THEME_PRESETS = {
@@ -711,6 +711,20 @@ function AlgoliaSearchModal({
711
711
  var VersionIcon = () => /* @__PURE__ */ jsx2(Icon, { d: "M12 8v4l3 3m6-3a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z", size: 14 });
712
712
  var GlobeIcon = () => /* @__PURE__ */ jsx2(Icon, { d: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM3.6 9h16.8M3.6 15h16.8M12 3a15 15 0 0 1 4 9 15 15 0 0 1-4 9 15 15 0 0 1-4-9 15 15 0 0 1 4-9Z", size: 14 });
713
713
  var ExtLinkIcon = () => /* @__PURE__ */ jsx2(Icon, { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3", size: 11 });
714
+ var SOCIAL_ICON_PATHS = {
715
+ github: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z",
716
+ twitter: "M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865l8.875 11.633Z",
717
+ discord: "M13.545 2.907a13.227 13.227 0 00-3.257-1.011.05.05 0 00-.052.025c-.141.25-.297.577-.406.833a12.19 12.19 0 00-3.658 0 8.258 8.258 0 00-.412-.833.051.051 0 00-.052-.025c-1.125.194-2.22.534-3.257 1.011a.041.041 0 00-.021.018C.356 6.024-.213 9.047.066 12.032c.001.014.01.028.021.037a13.276 13.276 0 003.995 2.02.05.05 0 00.056-.019c.308-.42.582-.863.818-1.329a.05.05 0 00-.028-.07 8.735 8.735 0 01-1.248-.595.05.05 0 01-.005-.083c.084-.063.168-.129.248-.195a.05.05 0 01.051-.007c2.619 1.196 5.454 1.196 8.041 0a.052.052 0 01.053.007c.08.066.164.132.248.195a.051.051 0 01-.004.085c-.399.232-.813.431-1.249.594a.05.05 0 00-.03.07c.24.465.515.909.817 1.329a.05.05 0 00.056.019 13.235 13.235 0 004.001-2.02.049.049 0 00.021-.037c.334-3.451-.559-6.449-2.366-9.106a.034.034 0 00-.02-.019z",
718
+ linkedin: "M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 01.016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4z",
719
+ youtube: "M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 011.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.007 2.007 0 01-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.007 2.007 0 01-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31.4 31.4 0 010 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.007 2.007 0 011.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A99.788 99.788 0 017.858 2h.193zM6.4 5.209v4.818l4.157-2.408L6.4 5.209z",
720
+ mastodon: "M11.19 12.195c2.016-.24 3.77-1.475 3.99-2.603.348-1.778.32-4.339.32-4.339 0-3.47-2.286-4.488-2.286-4.488C12.062.238 10.083.017 8.027 0h-.05C5.92.017 3.942.238 2.79.765 2.79.765.504 1.783.504 5.253c-.005.995-.01 2.19.013 3.44.075 4.21.56 8.354 3.383 9.386 1.302.476 2.418.576 3.317.507 1.628-.125 2.541-.8 2.541-.8l-.054-1.182s-1.163.366-2.47.322c-1.293-.044-2.658-.138-2.867-1.716a3.23 3.23 0 01-.028-.465s1.27.31 2.879.384c.984.045 1.905-.058 2.842-.17zM13 8.59V5.319c0-.67-.17-1.2-.507-1.592-.348-.4-.806-.605-1.373-.605-.656 0-1.154.252-1.486.756L9.2 4.595l-.434-.717c-.332-.504-.83-.756-1.486-.756-.567 0-1.025.204-1.373.605-.338.392-.507.923-.507 1.592V8.59h1.69V5.468c0-.67.285-1.012.855-1.012.63 0 .946.404.946 1.204V7.11h1.682V5.66c0-.8.316-1.204.946-1.204.57 0 .855.342.855 1.012V8.59H13z",
721
+ bluesky: "M3.468 1.948C5.303 3.325 7.276 6.118 8 7.616c.724-1.498 2.697-4.29 4.532-5.668C13.855 1.013 16 .638 16 3.14c0 .5-.286 4.2-.454 4.8-.585 2.093-2.716 2.628-4.544 2.305 3.195.564 4.007 2.433 2.25 4.302-3.337 3.548-4.8-1.244-5.252-2.547 0 0-.116-.334-.166-.334h.332C8.166 11.666 8.05 12 8.05 12c-.452 1.303-1.916 6.095-5.252 2.547-1.756-1.869-.946-3.738 2.25-4.302-1.829.323-3.96-.212-4.544-2.305C.336 7.34.05 3.64.05 3.14.05.638 2.195 1.013 3.468 1.948z"
722
+ };
723
+ var SocialIcon = ({ platform, customIcon }) => {
724
+ const d = platform === "custom" && customIcon ? customIcon : SOCIAL_ICON_PATHS[platform];
725
+ if (!d) return null;
726
+ return /* @__PURE__ */ jsx2("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx2("path", { d }) });
727
+ };
714
728
  var CHANGELOG_SECTION_COLORS = {
715
729
  Added: "#22c55e",
716
730
  Changed: "#3b82f6",
@@ -773,6 +787,23 @@ function ChangelogView({ entries }) {
773
787
  ) })
774
788
  ] });
775
789
  }
790
+ function getBreadcrumbs(navigation2, currentPageId, pageTitle) {
791
+ if (currentPageId === "index") return [];
792
+ for (const section of navigation2) {
793
+ const found = section.pages.find((p) => p.id === currentPageId);
794
+ if (found) {
795
+ const crumbs = [];
796
+ const firstPage = section.pages[0];
797
+ crumbs.push({
798
+ label: section.section,
799
+ href: firstPage ? firstPage.urlPath : null
800
+ });
801
+ crumbs.push({ label: pageTitle, href: null });
802
+ return crumbs;
803
+ }
804
+ }
805
+ return [];
806
+ }
776
807
  function Shell({
777
808
  config: config2,
778
809
  navigation: navigation2,
@@ -787,15 +818,26 @@ function Shell({
787
818
  editUrl,
788
819
  lastUpdated,
789
820
  changelogEntries,
821
+ apiManifest,
822
+ apiBaseUrl,
823
+ apiPlayground,
824
+ apiAuth,
825
+ ApiReferenceComponent,
790
826
  onNavigate,
791
827
  allPages,
792
828
  versioning,
793
829
  currentVersion,
794
- i18n,
830
+ i18n: i18n2,
795
831
  currentLocale,
796
832
  docContext: docContext2,
797
- basePath: basePath2 = ""
833
+ basePath: basePath2 = "",
834
+ isDraft,
835
+ dir: dirProp,
836
+ overrides: overrides2
798
837
  }) {
838
+ const resolvedLocale = currentLocale || i18n2?.defaultLocale || "en";
839
+ const dir = dirProp || i18n2?.localeDirs?.[resolvedLocale] || "ltr";
840
+ const isRtl = dir === "rtl";
799
841
  const themeMode = config2.theme?.mode || "auto";
800
842
  const [isDark, setDark] = useState2(() => {
801
843
  if (themeMode === "dark") return true;
@@ -988,6 +1030,7 @@ function Shell({
988
1030
  const idx = allNavPages.findIndex((p) => p.id === currentPageId);
989
1031
  const prev = idx > 0 ? allNavPages[idx - 1] : null;
990
1032
  const next = idx < allNavPages.length - 1 ? allNavPages[idx + 1] : null;
1033
+ const breadcrumbs = getBreadcrumbs(navigation2, currentPageId, pageTitle);
991
1034
  const togSec = (s) => setExpanded((p) => p.includes(s) ? p.filter((x) => x !== s) : [...p, s]);
992
1035
  const cssVars = {
993
1036
  "--bg": t.bg,
@@ -1011,7 +1054,7 @@ function Shell({
1011
1054
  const PageComponent = pageComponent;
1012
1055
  const bannerLink = config2.banner?.link;
1013
1056
  const bannerIsInternal = bannerLink ? bannerLink.startsWith("#") || basePath2 && bannerLink.startsWith(basePath2 + "/") : false;
1014
- return /* @__PURE__ */ jsxs2("div", { className: "tome-grain", style: { ...cssVars, color: "var(--tx)", background: "var(--bg)", fontFamily: "var(--font-body)", minHeight: "100vh", overflow: "hidden" }, children: [
1057
+ return /* @__PURE__ */ jsxs2("div", { dir, className: "tome-grain", style: { ...cssVars, color: "var(--tx)", background: "var(--bg)", fontFamily: "var(--font-body)", minHeight: "100vh", overflow: "hidden" }, children: [
1015
1058
  config2.banner?.text && !bannerDismissed && /* @__PURE__ */ jsxs2("div", { style: {
1016
1059
  display: "flex",
1017
1060
  alignItems: "center",
@@ -1084,7 +1127,7 @@ function Shell({
1084
1127
  mobile
1085
1128
  }
1086
1129
  ) : null,
1087
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flex: 1, height: config2.banner?.text && !bannerDismissed ? "calc(100vh - 32px)" : "100vh" }, children: [
1130
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: isRtl ? "row-reverse" : "row", flex: 1, height: config2.banner?.text && !bannerDismissed ? "calc(100vh - 32px)" : "100vh" }, children: [
1088
1131
  mobile && sbOpen && /* @__PURE__ */ jsx2("div", { onClick: () => setSb(false), style: {
1089
1132
  position: "fixed",
1090
1133
  inset: 0,
@@ -1092,16 +1135,29 @@ function Shell({
1092
1135
  background: "rgba(0,0,0,0.4)",
1093
1136
  backdropFilter: "blur(2px)"
1094
1137
  } }),
1095
- /* @__PURE__ */ jsxs2("aside", { style: {
1138
+ overrides2?.Sidebar ? /* @__PURE__ */ jsx2(
1139
+ overrides2.Sidebar,
1140
+ {
1141
+ config: config2,
1142
+ navigation: navigation2,
1143
+ currentPageId,
1144
+ onNavigate,
1145
+ mobile,
1146
+ sbOpen,
1147
+ setSbOpen: setSb,
1148
+ versioning,
1149
+ currentVersion
1150
+ }
1151
+ ) : /* @__PURE__ */ jsxs2("aside", { style: {
1096
1152
  width: sbOpen ? 270 : 0,
1097
1153
  minWidth: sbOpen ? 270 : 0,
1098
1154
  background: "var(--sbBg)",
1099
- borderRight: "1px solid var(--bd)",
1155
+ [isRtl ? "borderLeft" : "borderRight"]: "1px solid var(--bd)",
1100
1156
  display: "flex",
1101
1157
  flexDirection: "column",
1102
1158
  transition: "width .2s, min-width .2s",
1103
1159
  overflow: "hidden",
1104
- ...mobile ? { position: "fixed", top: 0, left: 0, bottom: 0, zIndex: 201 } : {}
1160
+ ...mobile ? { position: "fixed", top: 0, [isRtl ? "right" : "left"]: 0, bottom: 0, zIndex: 201 } : {}
1105
1161
  }, children: [
1106
1162
  /* @__PURE__ */ jsxs2("a", { href: "/", style: { padding: "18px 20px", display: "flex", alignItems: "baseline", gap: 6, borderBottom: "1px solid var(--bd)", textDecoration: "none", color: "inherit" }, children: [
1107
1163
  /* @__PURE__ */ jsx2("span", { style: { fontFamily: "var(--font-heading)", fontSize: 22, fontWeight: 700, fontStyle: "italic" }, children: config2.name }),
@@ -1125,7 +1181,7 @@ function Shell({
1125
1181
  fontFamily: "var(--font-body)"
1126
1182
  }, children: [
1127
1183
  /* @__PURE__ */ jsx2(SearchIcon, {}),
1128
- /* @__PURE__ */ jsx2("span", { style: { flex: 1, textAlign: "left" }, children: "Search..." }),
1184
+ /* @__PURE__ */ jsx2("span", { style: { flex: 1, textAlign: isRtl ? "right" : "left" }, children: "Search..." }),
1129
1185
  /* @__PURE__ */ jsx2("kbd", { style: { fontFamily: "var(--font-code)", fontSize: 9, background: "var(--sf)", border: "1px solid var(--bd)", borderRadius: 2, padding: "2px 6px" }, children: "\u2318K" })
1130
1186
  ] }) }),
1131
1187
  /* @__PURE__ */ jsx2("nav", { style: { flex: 1, overflow: "auto", padding: "4px 10px 20px" }, children: navigation2.map((sec) => /* @__PURE__ */ jsxs2("div", { style: { marginBottom: 8 }, children: [
@@ -1149,9 +1205,9 @@ function Shell({
1149
1205
  expanded.includes(sec.section) ? /* @__PURE__ */ jsx2(ChevDown, {}) : /* @__PURE__ */ jsx2(ChevRight, {}),
1150
1206
  sec.section
1151
1207
  ] }),
1152
- expanded.includes(sec.section) && /* @__PURE__ */ jsx2("div", { style: { marginLeft: 8, borderLeft: "1px solid var(--bd)", paddingLeft: 0 }, children: sec.pages.map((p) => {
1208
+ expanded.includes(sec.section) && /* @__PURE__ */ jsx2("div", { style: { [isRtl ? "marginRight" : "marginLeft"]: 8, [isRtl ? "borderRight" : "borderLeft"]: "1px solid var(--bd)", [isRtl ? "paddingRight" : "paddingLeft"]: 0 }, children: sec.pages.map((p) => {
1153
1209
  const active = currentPageId === p.id;
1154
- return /* @__PURE__ */ jsx2("button", { onClick: () => {
1210
+ return /* @__PURE__ */ jsxs2("button", { onClick: () => {
1155
1211
  onNavigate(p.id);
1156
1212
  if (mobile) setSb(false);
1157
1213
  }, style: {
@@ -1159,11 +1215,11 @@ function Shell({
1159
1215
  alignItems: "center",
1160
1216
  gap: 10,
1161
1217
  width: "100%",
1162
- textAlign: "left",
1218
+ textAlign: isRtl ? "right" : "left",
1163
1219
  background: "none",
1164
1220
  border: "none",
1165
1221
  borderRadius: 0,
1166
- borderLeft: active ? "2px solid var(--ac)" : "2px solid transparent",
1222
+ [isRtl ? "borderRight" : "borderLeft"]: active ? "2px solid var(--ac)" : "2px solid transparent",
1167
1223
  padding: "7px 14px",
1168
1224
  cursor: "pointer",
1169
1225
  color: active ? "var(--ac)" : "var(--tx2)",
@@ -1171,7 +1227,29 @@ function Shell({
1171
1227
  fontWeight: active ? 500 : 400,
1172
1228
  fontFamily: "var(--font-body)",
1173
1229
  transition: "all .12s"
1174
- }, children: p.title }, p.id);
1230
+ }, children: [
1231
+ p.title,
1232
+ p.badge && (() => {
1233
+ const badgeColors = {
1234
+ default: { bg: "var(--sf)", text: "var(--tx2)" },
1235
+ info: { bg: "rgba(59,130,246,0.15)", text: "rgb(59,130,246)" },
1236
+ success: { bg: "rgba(34,197,94,0.15)", text: "rgb(34,197,94)" },
1237
+ warning: { bg: "rgba(234,179,8,0.15)", text: "rgb(202,138,4)" },
1238
+ danger: { bg: "rgba(239,68,68,0.15)", text: "rgb(239,68,68)" }
1239
+ };
1240
+ const bc = badgeColors[p.badge.variant || "default"] || badgeColors.default;
1241
+ return /* @__PURE__ */ jsx2("span", { style: {
1242
+ fontSize: 10,
1243
+ fontWeight: 600,
1244
+ padding: "2px 6px",
1245
+ borderRadius: 4,
1246
+ marginLeft: 6,
1247
+ whiteSpace: "nowrap",
1248
+ background: bc.bg,
1249
+ color: bc.text
1250
+ }, children: p.badge.text });
1251
+ })()
1252
+ ] }, p.id);
1175
1253
  }) })
1176
1254
  ] }, sec.section)) }),
1177
1255
  versioning && mobile && /* @__PURE__ */ jsx2("div", { style: { padding: "8px 16px", borderTop: "1px solid var(--bd)", display: "flex", gap: 6 }, children: versioning.versions.map((v) => /* @__PURE__ */ jsxs2(
@@ -1183,14 +1261,14 @@ function Shell({
1183
1261
  },
1184
1262
  style: {
1185
1263
  flex: 1,
1186
- padding: "6px 0",
1264
+ padding: "3px 0",
1187
1265
  textAlign: "center",
1188
1266
  background: v === (currentVersion || versioning.current) ? "var(--acD)" : "var(--sf)",
1189
1267
  border: "1px solid var(--bd)",
1190
1268
  borderRadius: 2,
1191
1269
  cursor: "pointer",
1192
1270
  color: v === (currentVersion || versioning.current) ? "var(--ac)" : "var(--tx2)",
1193
- fontSize: 12,
1271
+ fontSize: 11,
1194
1272
  fontFamily: "var(--font-code)",
1195
1273
  fontWeight: v === versioning.current ? 600 : 400
1196
1274
  },
@@ -1212,7 +1290,26 @@ function Shell({
1212
1290
  ] })
1213
1291
  ] }),
1214
1292
  /* @__PURE__ */ jsxs2("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
1215
- /* @__PURE__ */ jsxs2("header", { style: {
1293
+ overrides2?.Header ? /* @__PURE__ */ jsx2(
1294
+ overrides2.Header,
1295
+ {
1296
+ config: config2,
1297
+ navigation: navigation2,
1298
+ currentPageId,
1299
+ onNavigate,
1300
+ mobile,
1301
+ sbOpen,
1302
+ setSbOpen: setSb,
1303
+ isDark,
1304
+ setDark,
1305
+ versioning,
1306
+ currentVersion,
1307
+ i18n: i18n2,
1308
+ currentLocale,
1309
+ onSearchOpen: () => setSearch(true),
1310
+ basePath: basePath2
1311
+ }
1312
+ ) : /* @__PURE__ */ jsxs2("header", { style: {
1216
1313
  display: "flex",
1217
1314
  alignItems: "center",
1218
1315
  gap: mobile ? 8 : 12,
@@ -1272,6 +1369,28 @@ function Shell({
1272
1369
  }),
1273
1370
  /* @__PURE__ */ jsx2("span", { style: { width: 1, height: 16, background: "var(--bd)" } })
1274
1371
  ] }),
1372
+ config2.socialLinks && config2.socialLinks.length > 0 && !mobile && /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: config2.socialLinks.map((link) => /* @__PURE__ */ jsx2(
1373
+ "a",
1374
+ {
1375
+ href: link.url,
1376
+ target: "_blank",
1377
+ rel: "noopener noreferrer",
1378
+ "aria-label": link.label || link.platform,
1379
+ "data-testid": `social-link-${link.platform}`,
1380
+ style: {
1381
+ display: "flex",
1382
+ alignItems: "center",
1383
+ justifyContent: "center",
1384
+ color: "var(--tx2)",
1385
+ cursor: "pointer",
1386
+ transition: "color .15s"
1387
+ },
1388
+ onMouseOver: (e) => e.currentTarget.style.color = "var(--tx)",
1389
+ onMouseOut: (e) => e.currentTarget.style.color = "var(--tx2)",
1390
+ children: /* @__PURE__ */ jsx2(SocialIcon, { platform: link.platform, customIcon: link.icon })
1391
+ },
1392
+ link.url
1393
+ )) }),
1275
1394
  mobile && themeMode === "auto" && /* @__PURE__ */ jsx2("button", { "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", onClick: () => setDark((d) => !d), style: { background: "none", border: "none", color: "var(--txM)", cursor: "pointer", display: "flex", flexShrink: 0 }, children: isDark ? /* @__PURE__ */ jsx2(SunIcon, {}) : /* @__PURE__ */ jsx2(MoonIcon, {}) }),
1276
1395
  versioning && !mobile && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
1277
1396
  /* @__PURE__ */ jsxs2(
@@ -1347,7 +1466,7 @@ function Shell({
1347
1466
  }
1348
1467
  )
1349
1468
  ] }),
1350
- i18n && i18n.locales.length > 1 && !mobile && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
1469
+ i18n2 && i18n2.locales.length > 1 && !mobile && /* @__PURE__ */ jsxs2("div", { style: { position: "relative" }, children: [
1351
1470
  /* @__PURE__ */ jsxs2(
1352
1471
  "button",
1353
1472
  {
@@ -1368,7 +1487,7 @@ function Shell({
1368
1487
  },
1369
1488
  children: [
1370
1489
  /* @__PURE__ */ jsx2(GlobeIcon, {}),
1371
- i18n.localeNames?.[currentLocale || i18n.defaultLocale] || currentLocale || i18n.defaultLocale,
1490
+ i18n2.localeNames?.[currentLocale || i18n2.defaultLocale] || currentLocale || i18n2.defaultLocale,
1372
1491
  /* @__PURE__ */ jsx2(ChevDown, {})
1373
1492
  ]
1374
1493
  }
@@ -1390,15 +1509,15 @@ function Shell({
1390
1509
  zIndex: 100,
1391
1510
  minWidth: 120
1392
1511
  },
1393
- children: i18n.locales.map((locale) => {
1394
- const isActive = locale === (currentLocale || i18n.defaultLocale);
1395
- const displayName = i18n.localeNames?.[locale] || locale;
1396
- const activeLocale = currentLocale || i18n.defaultLocale;
1512
+ children: i18n2.locales.map((locale) => {
1513
+ const isActive = locale === (currentLocale || i18n2.defaultLocale);
1514
+ const displayName = i18n2.localeNames?.[locale] || locale;
1515
+ const activeLocale = currentLocale || i18n2.defaultLocale;
1397
1516
  let basePageId = currentPageId;
1398
- if (activeLocale !== i18n.defaultLocale && currentPageId.startsWith(`${activeLocale}/`)) {
1517
+ if (activeLocale !== i18n2.defaultLocale && currentPageId.startsWith(`${activeLocale}/`)) {
1399
1518
  basePageId = currentPageId.slice(activeLocale.length + 1);
1400
1519
  }
1401
- const targetId = locale === i18n.defaultLocale ? basePageId : `${locale}/${basePageId}`;
1520
+ const targetId = locale === i18n2.defaultLocale ? basePageId : `${locale}/${basePageId}`;
1402
1521
  return /* @__PURE__ */ jsx2(
1403
1522
  "button",
1404
1523
  {
@@ -1473,122 +1592,169 @@ function Shell({
1473
1592
  ),
1474
1593
  /* @__PURE__ */ jsxs2("div", { ref: contentRef, style: { flex: 1, overflow: "auto", display: "flex" }, children: [
1475
1594
  /* @__PURE__ */ jsxs2("main", { style: { flex: 1, maxWidth: mobile ? "100%" : 760, padding: mobile ? "24px 16px 60px" : "40px 48px 80px", margin: "0 auto", minWidth: 0 }, children: [
1476
- /* @__PURE__ */ jsx2("h1", { style: { fontFamily: "var(--font-heading)", fontSize: mobile ? 26 : 38, fontWeight: 400, fontStyle: "italic", lineHeight: 1.15, marginBottom: 8 }, children: pageTitle }),
1477
- pageDescription && /* @__PURE__ */ jsx2("p", { style: { fontSize: 16, color: "var(--tx2)", lineHeight: 1.6, marginBottom: 32 }, children: pageDescription }),
1478
- /* @__PURE__ */ jsx2("div", { style: { borderTop: "1px solid var(--bd)", paddingTop: 28 }, children: changelogEntries && changelogEntries.length > 0 ? /* @__PURE__ */ jsx2(ChangelogView, { entries: changelogEntries }) : PageComponent ? /* @__PURE__ */ jsx2("div", { className: "tome-content", children: /* @__PURE__ */ jsx2(PageComponent, { components: mdxComponents || {} }) }) : /* @__PURE__ */ jsx2(
1479
- "div",
1480
- {
1481
- className: "tome-content",
1482
- ref: htmlContentRef
1483
- }
1484
- ) }),
1485
- (editUrl || lastUpdated) && /* @__PURE__ */ jsxs2("div", { style: { marginTop: 40, display: "flex", flexDirection: mobile ? "column" : "row", alignItems: mobile ? "flex-start" : "center", justifyContent: "space-between", gap: mobile ? 8 : 16 }, children: [
1486
- editUrl && /* @__PURE__ */ jsx2("div", { "data-testid": "edit-page-link", children: /* @__PURE__ */ jsxs2(
1595
+ breadcrumbs.length > 0 && /* @__PURE__ */ jsx2("nav", { "aria-label": "Breadcrumbs", "data-testid": "breadcrumbs", style: {
1596
+ display: "flex",
1597
+ alignItems: "center",
1598
+ gap: 6,
1599
+ fontSize: 13,
1600
+ color: "var(--tx2)",
1601
+ marginBottom: 8
1602
+ }, children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxs2(React2.Fragment, { children: [
1603
+ i > 0 && /* @__PURE__ */ jsx2("span", { style: { color: "var(--tx2)", opacity: 0.5 }, children: "\u203A" }),
1604
+ i < breadcrumbs.length - 1 && crumb.href !== null ? /* @__PURE__ */ jsx2(
1487
1605
  "a",
1488
1606
  {
1489
- href: editUrl,
1490
- target: "_blank",
1491
- rel: "noopener noreferrer",
1492
- style: {
1493
- display: "inline-flex",
1494
- alignItems: "center",
1495
- gap: 6,
1496
- color: "var(--txM)",
1497
- textDecoration: "none",
1498
- fontSize: 13,
1499
- fontFamily: "var(--font-body)",
1500
- transition: "color .15s"
1607
+ href: crumb.href,
1608
+ onClick: (e) => {
1609
+ e.preventDefault();
1610
+ const page = navigation2.flatMap((s) => s.pages).find((p) => p.urlPath === crumb.href);
1611
+ if (page) onNavigate(page.id);
1501
1612
  },
1502
- onMouseOver: (e) => e.currentTarget.style.color = "var(--ac)",
1503
- onMouseOut: (e) => e.currentTarget.style.color = "var(--txM)",
1504
- children: [
1505
- /* @__PURE__ */ jsx2(PencilIcon, {}),
1506
- " Edit this page on GitHub"
1507
- ]
1508
- }
1509
- ) }),
1510
- lastUpdated && /* @__PURE__ */ jsxs2("div", { "data-testid": "last-updated", style: { fontSize: 12, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: [
1511
- "Last updated ",
1512
- formatRelativeDate(lastUpdated)
1513
- ] })
1514
- ] }),
1515
- /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 24, padding: "12px 0" }, children: feedbackGiven[currentPageId] ? /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Thanks for your feedback!" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1516
- /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Was this helpful?" }),
1517
- /* @__PURE__ */ jsx2("button", { onClick: () => {
1518
- setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1519
- try {
1520
- localStorage.setItem(`tome-feedback-${currentPageId}`, "up");
1521
- } catch {
1613
+ style: { color: "var(--tx2)", textDecoration: "none", cursor: "pointer" },
1614
+ children: crumb.label
1522
1615
  }
1523
- }, style: {
1524
- background: "none",
1525
- border: "1px solid var(--bd)",
1526
- borderRadius: 2,
1527
- padding: "4px 10px",
1528
- cursor: "pointer",
1529
- fontSize: 13,
1530
- color: "var(--txM)",
1531
- transition: "border-color .15s"
1532
- }, children: "\u{1F44D}" }),
1533
- /* @__PURE__ */ jsx2("button", { onClick: () => {
1534
- setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1535
- try {
1536
- localStorage.setItem(`tome-feedback-${currentPageId}`, "down");
1537
- } catch {
1616
+ ) : /* @__PURE__ */ jsx2("span", { style: i === breadcrumbs.length - 1 ? { color: "var(--tx)" } : void 0, children: crumb.label })
1617
+ ] }, i)) }),
1618
+ /* @__PURE__ */ jsx2("h1", { style: { fontFamily: "var(--font-heading)", fontSize: mobile ? 26 : 38, fontWeight: 400, fontStyle: "italic", lineHeight: 1.15, marginBottom: 8 }, children: pageTitle }),
1619
+ isDraft && /* @__PURE__ */ jsx2("div", { "data-testid": "draft-banner", style: { background: "#fef3c7", color: "#92400e", padding: "8px 16px", borderRadius: 6, fontSize: 13, marginBottom: 16 }, children: "Draft \u2014 This page is only visible in development" }),
1620
+ pageDescription && /* @__PURE__ */ jsx2("p", { style: { fontSize: 16, color: "var(--tx2)", lineHeight: 1.6, marginBottom: 32 }, children: pageDescription }),
1621
+ /* @__PURE__ */ jsx2("div", { style: { borderTop: "1px solid var(--bd)", paddingTop: 28 }, children: apiManifest && ApiReferenceComponent ? /* @__PURE__ */ jsx2(ApiReferenceComponent, { manifest: apiManifest, baseUrl: apiBaseUrl, showPlayground: apiPlayground, playgroundAuth: apiAuth }) : (
1622
+ /* TOM-49: Changelog page type */
1623
+ changelogEntries && changelogEntries.length > 0 ? /* @__PURE__ */ jsx2(ChangelogView, { entries: changelogEntries }) : PageComponent ? /* @__PURE__ */ jsx2("div", { className: "tome-content", children: /* @__PURE__ */ jsx2(PageComponent, { components: mdxComponents || {} }) }) : /* @__PURE__ */ jsx2(
1624
+ "div",
1625
+ {
1626
+ className: "tome-content",
1627
+ ref: htmlContentRef
1538
1628
  }
1539
- }, style: {
1540
- background: "none",
1541
- border: "1px solid var(--bd)",
1542
- borderRadius: 2,
1543
- padding: "4px 10px",
1544
- cursor: "pointer",
1545
- fontSize: 13,
1546
- color: "var(--txM)",
1547
- transition: "border-color .15s"
1548
- }, children: "\u{1F44E}" })
1549
- ] }) }),
1550
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: mobile ? "column" : "row", justifyContent: "space-between", marginTop: 16, paddingTop: 24, borderTop: "1px solid var(--bd)", gap: mobile ? 12 : 16 }, children: [
1551
- prev ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(prev.id), style: {
1552
- display: "flex",
1553
- alignItems: "center",
1554
- gap: 8,
1555
- background: "none",
1556
- border: "1px solid var(--bd)",
1557
- borderRadius: 2,
1558
- padding: "10px 16px",
1559
- cursor: "pointer",
1560
- color: "var(--tx2)",
1561
- fontSize: 13,
1562
- fontFamily: "var(--font-body)",
1563
- transition: "border-color .15s, color .15s"
1564
- }, children: [
1565
- /* @__PURE__ */ jsx2(ArrowLeft, {}),
1566
- " ",
1567
- prev.title
1568
- ] }) : /* @__PURE__ */ jsx2("div", {}),
1569
- next ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(next.id), style: {
1570
- display: "flex",
1571
- alignItems: "center",
1572
- gap: 8,
1573
- background: "none",
1574
- border: "1px solid var(--bd)",
1575
- borderRadius: 2,
1576
- padding: "10px 16px",
1577
- cursor: "pointer",
1578
- color: "var(--tx2)",
1579
- fontSize: 13,
1580
- fontFamily: "var(--font-body)",
1581
- transition: "border-color .15s, color .15s"
1582
- }, children: [
1583
- next.title,
1584
- " ",
1585
- /* @__PURE__ */ jsx2(ArrowRight, {})
1586
- ] }) : /* @__PURE__ */ jsx2("div", {})
1629
+ )
1630
+ ) }),
1631
+ overrides2?.PageFooter ? /* @__PURE__ */ jsx2(
1632
+ overrides2.PageFooter,
1633
+ {
1634
+ editUrl,
1635
+ lastUpdated,
1636
+ currentPageId,
1637
+ prev,
1638
+ next,
1639
+ onNavigate,
1640
+ mobile
1641
+ }
1642
+ ) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1643
+ (editUrl || lastUpdated) && /* @__PURE__ */ jsxs2("div", { style: { marginTop: 40, display: "flex", flexDirection: mobile ? "column" : "row", alignItems: mobile ? "flex-start" : "center", justifyContent: "space-between", gap: mobile ? 8 : 16 }, children: [
1644
+ editUrl && /* @__PURE__ */ jsx2("div", { "data-testid": "edit-page-link", children: /* @__PURE__ */ jsxs2(
1645
+ "a",
1646
+ {
1647
+ href: editUrl,
1648
+ target: "_blank",
1649
+ rel: "noopener noreferrer",
1650
+ style: {
1651
+ display: "inline-flex",
1652
+ alignItems: "center",
1653
+ gap: 6,
1654
+ color: "var(--txM)",
1655
+ textDecoration: "none",
1656
+ fontSize: 13,
1657
+ fontFamily: "var(--font-body)",
1658
+ transition: "color .15s"
1659
+ },
1660
+ onMouseOver: (e) => e.currentTarget.style.color = "var(--ac)",
1661
+ onMouseOut: (e) => e.currentTarget.style.color = "var(--txM)",
1662
+ children: [
1663
+ /* @__PURE__ */ jsx2(PencilIcon, {}),
1664
+ " Edit this page on GitHub"
1665
+ ]
1666
+ }
1667
+ ) }),
1668
+ lastUpdated && /* @__PURE__ */ jsxs2("div", { "data-testid": "last-updated", style: { fontSize: 12, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: [
1669
+ "Last updated ",
1670
+ formatRelativeDate(lastUpdated)
1671
+ ] })
1672
+ ] }),
1673
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", alignItems: "center", gap: 12, marginTop: 24, padding: "12px 0" }, children: feedbackGiven[currentPageId] ? /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Thanks for your feedback!" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
1674
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: 13, color: "var(--txM)", fontFamily: "var(--font-body)" }, children: "Was this helpful?" }),
1675
+ /* @__PURE__ */ jsx2("button", { onClick: () => {
1676
+ setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1677
+ try {
1678
+ localStorage.setItem(`tome-feedback-${currentPageId}`, "up");
1679
+ } catch {
1680
+ }
1681
+ }, style: {
1682
+ background: "none",
1683
+ border: "1px solid var(--bd)",
1684
+ borderRadius: 2,
1685
+ padding: "4px 10px",
1686
+ cursor: "pointer",
1687
+ fontSize: 13,
1688
+ color: "var(--txM)",
1689
+ transition: "border-color .15s"
1690
+ }, children: "\u{1F44D}" }),
1691
+ /* @__PURE__ */ jsx2("button", { onClick: () => {
1692
+ setFeedbackGiven((prev2) => ({ ...prev2, [currentPageId]: true }));
1693
+ try {
1694
+ localStorage.setItem(`tome-feedback-${currentPageId}`, "down");
1695
+ } catch {
1696
+ }
1697
+ }, style: {
1698
+ background: "none",
1699
+ border: "1px solid var(--bd)",
1700
+ borderRadius: 2,
1701
+ padding: "4px 10px",
1702
+ cursor: "pointer",
1703
+ fontSize: 13,
1704
+ color: "var(--txM)",
1705
+ transition: "border-color .15s"
1706
+ }, children: "\u{1F44E}" })
1707
+ ] }) }),
1708
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: mobile ? "column" : "row", justifyContent: "space-between", marginTop: 16, paddingTop: 24, borderTop: "1px solid var(--bd)", gap: mobile ? 12 : 16 }, children: [
1709
+ prev ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(prev.id), style: {
1710
+ display: "flex",
1711
+ alignItems: "center",
1712
+ gap: 8,
1713
+ background: "none",
1714
+ border: "1px solid var(--bd)",
1715
+ borderRadius: 2,
1716
+ padding: "10px 16px",
1717
+ cursor: "pointer",
1718
+ color: "var(--tx2)",
1719
+ fontSize: 13,
1720
+ fontFamily: "var(--font-body)",
1721
+ transition: "border-color .15s, color .15s"
1722
+ }, children: [
1723
+ isRtl ? /* @__PURE__ */ jsx2(ArrowRight, {}) : /* @__PURE__ */ jsx2(ArrowLeft, {}),
1724
+ " ",
1725
+ prev.title
1726
+ ] }) : /* @__PURE__ */ jsx2("div", {}),
1727
+ next ? /* @__PURE__ */ jsxs2("button", { onClick: () => onNavigate(next.id), style: {
1728
+ display: "flex",
1729
+ alignItems: "center",
1730
+ gap: 8,
1731
+ background: "none",
1732
+ border: "1px solid var(--bd)",
1733
+ borderRadius: 2,
1734
+ padding: "10px 16px",
1735
+ cursor: "pointer",
1736
+ color: "var(--tx2)",
1737
+ fontSize: 13,
1738
+ fontFamily: "var(--font-body)",
1739
+ transition: "border-color .15s, color .15s"
1740
+ }, children: [
1741
+ next.title,
1742
+ " ",
1743
+ isRtl ? /* @__PURE__ */ jsx2(ArrowLeft, {}) : /* @__PURE__ */ jsx2(ArrowRight, {})
1744
+ ] }) : /* @__PURE__ */ jsx2("div", {})
1745
+ ] })
1587
1746
  ] })
1588
1747
  ] }),
1589
- showToc && filteredHeadings.length >= 2 && wide && /* @__PURE__ */ jsxs2("aside", { "data-testid": "toc-sidebar", style: { width: 200, padding: "40px 16px 40px 0", position: "sticky", top: 0, alignSelf: "flex-start", flexShrink: 0 }, children: [
1748
+ overrides2?.Toc ? showToc && filteredHeadings.length >= 2 && wide && /* @__PURE__ */ jsx2(
1749
+ overrides2.Toc,
1750
+ {
1751
+ headings: filteredHeadings,
1752
+ activeHeadingId,
1753
+ onScrollToHeading: scrollToHeading
1754
+ }
1755
+ ) : showToc && filteredHeadings.length >= 2 && wide && /* @__PURE__ */ jsxs2("aside", { "data-testid": "toc-sidebar", style: { width: 200, padding: isRtl ? "40px 0 40px 16px" : "40px 16px 40px 0", position: "sticky", top: 0, alignSelf: "flex-start", flexShrink: 0 }, children: [
1590
1756
  /* @__PURE__ */ jsx2("div", { style: { fontSize: 10, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".1em", color: "var(--txM)", marginBottom: 12, fontFamily: "var(--font-code)" }, children: "On this page" }),
1591
- /* @__PURE__ */ jsx2("nav", { "aria-label": "Table of contents", style: { borderLeft: "1px solid var(--bd)", paddingLeft: 0 }, children: filteredHeadings.map((h, i) => {
1757
+ /* @__PURE__ */ jsx2("nav", { "aria-label": "Table of contents", style: { [isRtl ? "borderRight" : "borderLeft"]: "1px solid var(--bd)", [isRtl ? "paddingRight" : "paddingLeft"]: 0 }, children: filteredHeadings.map((h, i) => {
1592
1758
  const isActive = activeHeadingId === h.id;
1593
1759
  return /* @__PURE__ */ jsx2(
1594
1760
  "a",
@@ -1603,11 +1769,11 @@ function Shell({
1603
1769
  fontWeight: isActive ? 500 : 400,
1604
1770
  textDecoration: "none",
1605
1771
  padding: "4px 12px",
1606
- paddingLeft: 12 + (h.depth - 2) * 12,
1772
+ [isRtl ? "paddingRight" : "paddingLeft"]: 12 + (h.depth - 2) * 12,
1607
1773
  lineHeight: 1.4,
1608
1774
  transition: "color .15s, font-weight .15s",
1609
- borderLeft: isActive ? "2px solid var(--ac)" : "2px solid transparent",
1610
- marginLeft: -1
1775
+ [isRtl ? "borderRight" : "borderLeft"]: isActive ? "2px solid var(--ac)" : "2px solid transparent",
1776
+ [isRtl ? "marginRight" : "marginLeft"]: -1
1611
1777
  },
1612
1778
  children: h.text
1613
1779
  },
@@ -1618,6 +1784,15 @@ function Shell({
1618
1784
  ] })
1619
1785
  ] })
1620
1786
  ] }),
1787
+ overrides2?.Footer && /* @__PURE__ */ jsx2(
1788
+ overrides2.Footer,
1789
+ {
1790
+ config: config2,
1791
+ navigation: navigation2,
1792
+ currentPageId,
1793
+ onNavigate
1794
+ }
1795
+ ),
1621
1796
  config2.ai?.enabled && /* @__PURE__ */ jsx2(
1622
1797
  AiChat,
1623
1798
  {
@@ -1819,6 +1994,9 @@ async function loadPage(id, routes2, loadPageModule2) {
1819
1994
  };
1820
1995
  }
1821
1996
  if (!mod.default) return null;
1997
+ if (mod.isApiReference && mod.apiManifest) {
1998
+ return { isMdx: false, isApiReference: true, ...mod.default, apiManifest: mod.apiManifest };
1999
+ }
1822
2000
  if (mod.isChangelog && mod.changelogEntries) {
1823
2001
  return { isMdx: false, ...mod.default, changelogEntries: mod.changelogEntries };
1824
2002
  }
@@ -1834,9 +2012,10 @@ function detectCurrentVersion(currentRoute, versions2) {
1834
2012
 
1835
2013
  // src/entry.tsx
1836
2014
  import config from "virtual:tome/config";
1837
- import { routes, navigation, versions } from "virtual:tome/routes";
2015
+ import { routes, navigation, versions, i18n } from "virtual:tome/routes";
1838
2016
  import loadPageModule from "virtual:tome/page-loader";
1839
2017
  import docContext from "virtual:tome/doc-context";
2018
+ import overrides from "virtual:tome/overrides";
1840
2019
  import {
1841
2020
  Callout,
1842
2021
  Tabs,
@@ -1847,7 +2026,11 @@ import {
1847
2026
  ChangelogTimeline,
1848
2027
  PackageManager,
1849
2028
  TypeTable,
1850
- FileTree
2029
+ FileTree,
2030
+ CodeSamples,
2031
+ LinkCard,
2032
+ CardGrid,
2033
+ ApiReference
1851
2034
  } from "@tomehq/components";
1852
2035
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1853
2036
  var MDX_COMPONENTS = {
@@ -1860,8 +2043,11 @@ var MDX_COMPONENTS = {
1860
2043
  ChangelogTimeline,
1861
2044
  PackageManager,
1862
2045
  TypeTable,
1863
- FileTree
2046
+ FileTree,
1864
2047
  // Sub-components accessible as <FileTree.File /> and <FileTree.Folder /> in MDX
2048
+ CodeSamples,
2049
+ LinkCard,
2050
+ CardGrid
1865
2051
  };
1866
2052
  var contentStyles = `
1867
2053
  @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');
@@ -1875,15 +2061,15 @@ var contentStyles = `
1875
2061
  .tome-content a { color: var(--ac); text-decoration: none; }
1876
2062
  .tome-content a:hover { text-decoration: underline; }
1877
2063
  .tome-content .heading-anchor { display: none; }
1878
- .tome-content ul, .tome-content ol { color: var(--tx2); padding-left: 1.5em; margin-bottom: 1em; }
2064
+ .tome-content ul, .tome-content ol { color: var(--tx2); padding-inline-start: 1.5em; margin-bottom: 1em; }
1879
2065
  .tome-content li { margin-bottom: 0.3em; line-height: 1.7; }
1880
2066
  .tome-content code { font-family: var(--font-code); font-size: 0.88em; background: var(--cdBg); padding: 0.15em 0.4em; border-radius: 2px; color: var(--ac); }
1881
2067
  .tome-content pre { margin-bottom: 1.2em; border-radius: 2px; overflow-x: auto; border: 1px solid var(--bd); }
1882
2068
  .tome-content pre code { background: none; padding: 1em 1.2em; display: block; font-size: 12.5px; line-height: 1.7; color: var(--cdTx); }
1883
- .tome-content blockquote { border-left: 3px solid var(--ac); padding: 0.5em 1em; margin: 1em 0; background: var(--acD); border-radius: 0 2px 2px 0; }
2069
+ .tome-content blockquote { border-inline-start: 3px solid var(--ac); padding: 0.5em 1em; margin: 1em 0; background: var(--acD); border-radius: 0 2px 2px 0; }
1884
2070
  .tome-content blockquote p { color: var(--tx2); margin: 0; }
1885
2071
  .tome-content table { width: 100%; border-collapse: collapse; margin-bottom: 1em; }
1886
- .tome-content th, .tome-content td { padding: 0.5em 0.8em; border: 1px solid var(--bd); text-align: left; font-size: 0.9em; }
2072
+ .tome-content th, .tome-content td { padding: 0.5em 0.8em; border: 1px solid var(--bd); text-align: start; font-size: 0.9em; }
1887
2073
  .tome-content th { background: var(--sf); font-weight: 600; }
1888
2074
  .tome-content img { max-width: 100%; border-radius: 2px; cursor: zoom-in; }
1889
2075
  .tome-content hr { border: none; border-top: 1px solid var(--bd); margin: 2em 0; }
@@ -1937,6 +2123,74 @@ var contentStyles = `
1937
2123
  background-repeat: repeat; background-size: 256px;
1938
2124
  }
1939
2125
 
2126
+ /* \u2500\u2500 Expressive code blocks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
2127
+
2128
+ /* Code block wrapper (for titled blocks) */
2129
+ .tome-code-block-wrapper { position: relative; margin-bottom: 1.2em; border: 1px solid var(--bd); border-radius: 2px; overflow: hidden; }
2130
+ .tome-code-block-wrapper pre { margin-bottom: 0; border: none; border-radius: 0; }
2131
+ .tome-code-title {
2132
+ font-family: var(--font-code); font-size: 12px; color: var(--tx2);
2133
+ background: var(--sf); padding: 6px 12px; border-bottom: 1px solid var(--bd);
2134
+ letter-spacing: 0.01em; font-weight: 500;
2135
+ }
2136
+
2137
+ /* Line highlighting */
2138
+ .tome-content pre .line.tome-line-highlight {
2139
+ background: rgba(139, 148, 158, 0.1);
2140
+ display: inline-block; width: 100%; margin: 0 -1.2em; padding: 0 1.2em;
2141
+ }
2142
+ html.dark .tome-content pre .line.tome-line-highlight {
2143
+ background: rgba(200, 210, 220, 0.08);
2144
+ }
2145
+
2146
+ /* Diff lines */
2147
+ .tome-content pre .line.tome-line-added {
2148
+ background: rgba(34, 197, 94, 0.12);
2149
+ display: inline-block; width: 100%; margin: 0 -1.2em; padding: 0 1.2em;
2150
+ }
2151
+ .tome-content pre .line.tome-line-removed {
2152
+ background: rgba(239, 68, 68, 0.12);
2153
+ display: inline-block; width: 100%; margin: 0 -1.2em; padding: 0 1.2em;
2154
+ }
2155
+ html.dark .tome-content pre .line.tome-line-added { background: rgba(34, 197, 94, 0.15); }
2156
+ html.dark .tome-content pre .line.tome-line-removed { background: rgba(239, 68, 68, 0.15); }
2157
+
2158
+ /* Line numbers (CSS counter) */
2159
+ .tome-content pre[data-line-numbers] code {
2160
+ counter-reset: line;
2161
+ }
2162
+ .tome-content pre[data-line-numbers] .line::before {
2163
+ counter-increment: line;
2164
+ content: counter(line);
2165
+ display: inline-block; width: 2.5em; margin-inline-end: 1em;
2166
+ text-align: end; color: var(--txM); opacity: 0.4;
2167
+ font-size: 0.85em; user-select: none;
2168
+ border-inline-end: 1px solid var(--bd); padding-inline-end: 0.8em; margin-inline-end: 0.8em;
2169
+ }
2170
+
2171
+ /* Word highlighting */
2172
+ .tome-word-highlight {
2173
+ background: rgba(139, 148, 158, 0.2); border-radius: 2px;
2174
+ padding: 1px 3px; margin: 0 -1px;
2175
+ }
2176
+ html.dark .tome-word-highlight {
2177
+ background: rgba(200, 210, 220, 0.15);
2178
+ }
2179
+
2180
+ /* Copy button */
2181
+ .tome-content pre { position: relative; }
2182
+ .tome-copy-btn {
2183
+ position: absolute; top: 8px; inset-inline-end: 8px;
2184
+ font-family: var(--font-code); font-size: 11px;
2185
+ color: var(--tx2); background: var(--sf); border: 1px solid var(--bd);
2186
+ padding: 3px 8px; border-radius: 2px; cursor: pointer;
2187
+ opacity: 0; transition: opacity 0.15s;
2188
+ z-index: 2; line-height: 1.4;
2189
+ }
2190
+ .tome-content pre:hover .tome-copy-btn,
2191
+ .tome-copy-btn:focus { opacity: 1; }
2192
+ .tome-copy-btn:hover { background: var(--sfH); }
2193
+
1940
2194
  /* Shiki dual-theme support */
1941
2195
  .shiki { background: var(--cdBg) !important; }
1942
2196
 
@@ -1958,6 +2212,57 @@ var contentStyles = `
1958
2212
  html:not(.dark) .shiki span[style*="color:#22863A"] { color: #1a6e2e !important; }
1959
2213
  html:not(.dark) .shiki span[style*="color:#D73A49"] { color: #b62324 !important; }
1960
2214
  html:not(.dark) .shiki span[style*="color:#005CC5"] { color: #0349b4 !important; }
2215
+
2216
+ /* \u2500\u2500 Twoslash type hover tooltips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
2217
+ .twoslash-hover {
2218
+ position: relative;
2219
+ border-bottom: 1px dotted var(--tx2);
2220
+ cursor: help;
2221
+ }
2222
+ .twoslash-popup-container {
2223
+ position: absolute;
2224
+ opacity: 0;
2225
+ display: none;
2226
+ z-index: 10;
2227
+ left: 0;
2228
+ top: 100%;
2229
+ margin-top: 4px;
2230
+ padding: 6px 10px;
2231
+ background: var(--sf);
2232
+ border: 1px solid var(--bd);
2233
+ border-radius: 6px;
2234
+ font-size: 12px;
2235
+ font-family: var(--font-code);
2236
+ color: var(--tx);
2237
+ white-space: pre-wrap;
2238
+ max-width: 500px;
2239
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
2240
+ pointer-events: none;
2241
+ }
2242
+ .twoslash-hover:hover .twoslash-popup-container {
2243
+ opacity: 1;
2244
+ display: block;
2245
+ }
2246
+ /* Twoslash error/warning underlines */
2247
+ .twoslash-error {
2248
+ position: relative;
2249
+ background: rgba(239, 68, 68, 0.1);
2250
+ border-bottom: 2px wavy rgba(239, 68, 68, 0.6);
2251
+ }
2252
+ /* Twoslash highlighted identifiers */
2253
+ .twoslash-highlighted {
2254
+ background: rgba(139, 148, 158, 0.15);
2255
+ border-radius: 2px;
2256
+ padding: 1px 2px;
2257
+ }
2258
+ /* Twoslash type annotation line (^?) */
2259
+ .twoslash-popup-code .shiki { background: transparent !important; padding: 0; margin: 0; }
2260
+ .twoslash-popup-code .shiki code { padding: 0; font-size: 12px; }
2261
+ html.dark .twoslash-popup-container {
2262
+ background: var(--sf);
2263
+ border-color: var(--bd);
2264
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
2265
+ }
1961
2266
  `;
1962
2267
  var basePath = (config.basePath || "/").replace(/\/$/, "");
1963
2268
  function pathnameToPageId2(pathname) {
@@ -2095,6 +2400,39 @@ function App() {
2095
2400
  cancelled = true;
2096
2401
  };
2097
2402
  }, [pageData, loading, mermaidTheme]);
2403
+ useEffect3(() => {
2404
+ if (loading) return;
2405
+ const preBlocks = document.querySelectorAll(".tome-content pre");
2406
+ const buttons = [];
2407
+ preBlocks.forEach((pre) => {
2408
+ if (pre.querySelector(".tome-copy-btn")) return;
2409
+ const btn = document.createElement("button");
2410
+ btn.className = "tome-copy-btn";
2411
+ btn.textContent = "Copy";
2412
+ btn.addEventListener("click", async () => {
2413
+ const code = pre.querySelector("code");
2414
+ if (code) {
2415
+ try {
2416
+ await navigator.clipboard.writeText(code.textContent || "");
2417
+ btn.textContent = "Copied!";
2418
+ setTimeout(() => {
2419
+ btn.textContent = "Copy";
2420
+ }, 2e3);
2421
+ } catch {
2422
+ btn.textContent = "Failed";
2423
+ setTimeout(() => {
2424
+ btn.textContent = "Copy";
2425
+ }, 2e3);
2426
+ }
2427
+ }
2428
+ });
2429
+ pre.appendChild(btn);
2430
+ buttons.push(btn);
2431
+ });
2432
+ return () => {
2433
+ buttons.forEach((btn) => btn.remove());
2434
+ };
2435
+ }, [pageData, loading]);
2098
2436
  const allPages = routes.map((r) => ({
2099
2437
  id: r.id,
2100
2438
  title: r.frontmatter.title,
@@ -2103,6 +2441,8 @@ function App() {
2103
2441
  const currentRoute = routes.find((r) => r.id === currentPageId);
2104
2442
  const currentVersion = detectCurrentVersion(currentRoute, versions);
2105
2443
  const editUrl = computeEditUrl(config.editLink, currentRoute?.filePath);
2444
+ const currentLocale = currentRoute?.locale || i18n?.defaultLocale || "en";
2445
+ const dir = i18n?.localeDirs?.[currentLocale] || "ltr";
2106
2446
  useEffect3(() => {
2107
2447
  const hasMathPlaceholders = document.querySelectorAll(".tome-math[data-math]").length > 0;
2108
2448
  if (!config.math && !hasMathPlaceholders) return;
@@ -2167,12 +2507,22 @@ function App() {
2167
2507
  editUrl,
2168
2508
  lastUpdated: currentRoute?.lastUpdated,
2169
2509
  changelogEntries: !pageData?.isMdx ? pageData?.changelogEntries : void 0,
2510
+ apiManifest: !pageData?.isMdx && pageData?.isApiReference ? pageData.apiManifest : void 0,
2511
+ apiBaseUrl: config.api?.baseUrl,
2512
+ apiPlayground: config.api?.playground,
2513
+ apiAuth: config.api?.auth,
2514
+ ApiReferenceComponent: ApiReference,
2170
2515
  onNavigate: navigateTo,
2171
2516
  allPages,
2172
2517
  docContext,
2173
2518
  versioning: versions || void 0,
2174
2519
  currentVersion,
2175
- basePath
2520
+ basePath,
2521
+ isDraft: currentRoute?.frontmatter?.draft === true,
2522
+ dir,
2523
+ i18n: i18n || void 0,
2524
+ currentLocale,
2525
+ overrides
2176
2526
  }
2177
2527
  )
2178
2528
  ] });