@canopy-iiif/app 1.5.9 → 1.5.10
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/lib/build/iiif.js +7 -2
- package/lib/build/pages.js +20 -2
- package/lib/components/navigation.js +21 -0
- package/package.json +1 -1
- package/ui/dist/index.mjs +524 -204
- package/ui/dist/index.mjs.map +4 -4
- package/ui/dist/server.mjs +602 -309
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/components/_layout.scss +16 -2
- package/ui/styles/components/_nav-tree.scss +67 -0
- package/ui/styles/components/_sub-navigation.scss +38 -17
- package/ui/styles/components/header/_header.scss +3 -1
- package/ui/styles/components/header/_navbar.scss +65 -50
- package/ui/styles/components/index.scss +1 -0
- package/ui/styles/index.css +168 -67
- package/ui/styles/settings/_breakpoints.scss +7 -0
package/ui/dist/server.mjs
CHANGED
|
@@ -843,52 +843,140 @@ function Hero({
|
|
|
843
843
|
}
|
|
844
844
|
|
|
845
845
|
// ui/src/layout/SubNavigation.jsx
|
|
846
|
-
import
|
|
846
|
+
import React11 from "react";
|
|
847
847
|
import navigationHelpers2 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
if (typeof
|
|
853
|
-
return
|
|
848
|
+
|
|
849
|
+
// ui/src/layout/NavigationTree.jsx
|
|
850
|
+
import React10 from "react";
|
|
851
|
+
function normalizeDepth(depth) {
|
|
852
|
+
if (typeof depth !== "number") return 0;
|
|
853
|
+
return Math.max(0, Math.min(5, depth));
|
|
854
854
|
}
|
|
855
|
-
function
|
|
855
|
+
function NavigationTreeList({ nodes, depth, parentKey }) {
|
|
856
856
|
if (!Array.isArray(nodes) || !nodes.length) return null;
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
857
|
+
const listClasses = ["canopy-nav-tree__list"];
|
|
858
|
+
if (depth > 0) listClasses.push("canopy-nav-tree__list--nested");
|
|
859
|
+
return /* @__PURE__ */ React10.createElement("ul", { className: listClasses.join(" "), role: "list" }, nodes.map((node, index) => /* @__PURE__ */ React10.createElement(
|
|
860
|
+
NavigationTreeItem,
|
|
861
|
+
{
|
|
862
|
+
key: node.slug || node.href || node.title || `${parentKey}-${index}`,
|
|
863
|
+
node,
|
|
864
|
+
depth,
|
|
865
|
+
nodeKey: `${parentKey}-${index}`
|
|
866
|
+
}
|
|
867
|
+
)));
|
|
868
|
+
}
|
|
869
|
+
function NavigationTreeItem({ node, depth, nodeKey }) {
|
|
870
|
+
if (!node) return null;
|
|
871
|
+
const hasChildren = Array.isArray(node.children) && node.children.length > 0;
|
|
872
|
+
const isRoadmap = !!node.isRoadmap;
|
|
873
|
+
const isInteractive = !!(node.href && !isRoadmap);
|
|
874
|
+
const Tag = isInteractive ? "a" : "span";
|
|
875
|
+
const depthClass = `depth-${normalizeDepth(depth + 1)}`;
|
|
876
|
+
const classes = ["canopy-nav-tree__link", depthClass];
|
|
877
|
+
if (!isInteractive && !isRoadmap) classes.push("is-label");
|
|
878
|
+
if (isRoadmap) classes.push("is-disabled");
|
|
879
|
+
if (node.isActive) classes.push("is-active");
|
|
880
|
+
const isRootLevel = depth < 0;
|
|
881
|
+
const panelId = hasChildren ? `canopy-section-${nodeKey}` : null;
|
|
882
|
+
const allowToggle = hasChildren && !isRootLevel;
|
|
883
|
+
const defaultExpanded = allowToggle ? !!node.isExpanded : true;
|
|
884
|
+
const toggleLabel = node.title ? `Toggle ${node.title} menu` : "Toggle section menu";
|
|
885
|
+
return /* @__PURE__ */ React10.createElement(
|
|
886
|
+
"li",
|
|
887
|
+
{
|
|
888
|
+
className: "canopy-nav-tree__item",
|
|
889
|
+
"data-depth": depth,
|
|
890
|
+
"data-canopy-nav-item": allowToggle ? "true" : void 0,
|
|
891
|
+
"data-expanded": allowToggle ? defaultExpanded ? "true" : "false" : void 0,
|
|
892
|
+
"data-default-expanded": allowToggle && defaultExpanded ? "true" : void 0
|
|
893
|
+
},
|
|
894
|
+
/* @__PURE__ */ React10.createElement("div", { className: "canopy-nav-tree__row" }, /* @__PURE__ */ React10.createElement(
|
|
874
895
|
Tag,
|
|
875
896
|
{
|
|
876
|
-
className:
|
|
897
|
+
className: classes.join(" "),
|
|
877
898
|
href: isInteractive ? node.href : void 0,
|
|
878
899
|
"aria-current": node.isActive ? "page" : void 0,
|
|
879
900
|
tabIndex: isInteractive ? void 0 : -1
|
|
880
901
|
},
|
|
881
902
|
node.title || node.slug,
|
|
882
|
-
|
|
883
|
-
),
|
|
884
|
-
"
|
|
903
|
+
isRoadmap ? /* @__PURE__ */ React10.createElement("span", { className: "canopy-nav-tree__badge" }, "Roadmap") : null
|
|
904
|
+
), allowToggle ? /* @__PURE__ */ React10.createElement(
|
|
905
|
+
"button",
|
|
885
906
|
{
|
|
886
|
-
|
|
887
|
-
|
|
907
|
+
type: "button",
|
|
908
|
+
className: "canopy-nav-tree__toggle",
|
|
909
|
+
"aria-expanded": defaultExpanded ? "true" : "false",
|
|
910
|
+
"aria-controls": panelId || void 0,
|
|
911
|
+
"aria-label": toggleLabel,
|
|
912
|
+
"data-canopy-nav-item-toggle": panelId || void 0
|
|
888
913
|
},
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
914
|
+
/* @__PURE__ */ React10.createElement(
|
|
915
|
+
"svg",
|
|
916
|
+
{
|
|
917
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
918
|
+
viewBox: "0 0 24 24",
|
|
919
|
+
fill: "none",
|
|
920
|
+
stroke: "currentColor",
|
|
921
|
+
strokeWidth: "1.5",
|
|
922
|
+
className: "canopy-nav-tree__toggle-icon"
|
|
923
|
+
},
|
|
924
|
+
/* @__PURE__ */ React10.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 9l7 7 7-7" })
|
|
925
|
+
),
|
|
926
|
+
/* @__PURE__ */ React10.createElement("span", { className: "sr-only" }, toggleLabel)
|
|
927
|
+
) : null),
|
|
928
|
+
hasChildren ? /* @__PURE__ */ React10.createElement(
|
|
929
|
+
"div",
|
|
930
|
+
{
|
|
931
|
+
id: panelId || void 0,
|
|
932
|
+
className: "canopy-nav-tree__children",
|
|
933
|
+
"aria-hidden": allowToggle ? defaultExpanded ? "false" : "true" : "false",
|
|
934
|
+
hidden: allowToggle ? !defaultExpanded : void 0
|
|
935
|
+
},
|
|
936
|
+
/* @__PURE__ */ React10.createElement(
|
|
937
|
+
NavigationTreeList,
|
|
938
|
+
{
|
|
939
|
+
nodes: node.children,
|
|
940
|
+
depth: depth + 1,
|
|
941
|
+
parentKey: nodeKey
|
|
942
|
+
}
|
|
943
|
+
)
|
|
944
|
+
) : null
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
function NavigationTree({
|
|
948
|
+
root,
|
|
949
|
+
className = "",
|
|
950
|
+
parentKey = "nav",
|
|
951
|
+
includeRoot = false,
|
|
952
|
+
heading,
|
|
953
|
+
headingClassName = "canopy-nav-tree__heading",
|
|
954
|
+
component: Component = "div",
|
|
955
|
+
...rest
|
|
956
|
+
}) {
|
|
957
|
+
if (!root) return null;
|
|
958
|
+
const nodes = includeRoot ? [root] : root.children;
|
|
959
|
+
if (!Array.isArray(nodes) || !nodes.length) return null;
|
|
960
|
+
const combinedClassName = ["canopy-nav-tree", className].filter(Boolean).join(" ");
|
|
961
|
+
return /* @__PURE__ */ React10.createElement(
|
|
962
|
+
Component,
|
|
963
|
+
{
|
|
964
|
+
className: combinedClassName,
|
|
965
|
+
"data-canopy-nav-tree": "true",
|
|
966
|
+
...rest
|
|
967
|
+
},
|
|
968
|
+
heading ? /* @__PURE__ */ React10.createElement("div", { className: headingClassName }, heading) : null,
|
|
969
|
+
/* @__PURE__ */ React10.createElement(NavigationTreeList, { nodes, depth: includeRoot ? -1 : 0, parentKey })
|
|
970
|
+
);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// ui/src/layout/SubNavigation.jsx
|
|
974
|
+
function resolveRelativeCandidate(page, current) {
|
|
975
|
+
if (page && typeof page.relativePath === "string" && page.relativePath)
|
|
976
|
+
return page.relativePath;
|
|
977
|
+
if (page && typeof page.slug === "string" && page.slug) return page.slug;
|
|
978
|
+
if (typeof current === "string" && current) return current;
|
|
979
|
+
return "";
|
|
892
980
|
}
|
|
893
981
|
function SubNavigation({
|
|
894
982
|
navigation: navigationProp,
|
|
@@ -900,12 +988,12 @@ function SubNavigation({
|
|
|
900
988
|
ariaLabel
|
|
901
989
|
}) {
|
|
902
990
|
const PageContext = navigationHelpers2 && navigationHelpers2.getPageContext ? navigationHelpers2.getPageContext() : null;
|
|
903
|
-
const context = PageContext ?
|
|
991
|
+
const context = PageContext ? React11.useContext(PageContext) : null;
|
|
904
992
|
const contextNavigation = context && context.navigation ? context.navigation : null;
|
|
905
993
|
const contextPage = context && context.page ? context.page : null;
|
|
906
994
|
const effectiveNavigation = navigationProp || contextNavigation;
|
|
907
995
|
const effectivePage = page || contextPage;
|
|
908
|
-
const resolvedNavigation =
|
|
996
|
+
const resolvedNavigation = React11.useMemo(() => {
|
|
909
997
|
if (effectiveNavigation && effectiveNavigation.root)
|
|
910
998
|
return effectiveNavigation;
|
|
911
999
|
const candidate = resolveRelativeCandidate(effectivePage, current);
|
|
@@ -930,24 +1018,33 @@ function SubNavigation({
|
|
|
930
1018
|
if (!Object.prototype.hasOwnProperty.call(inlineStyle, "--sub-nav-indent")) {
|
|
931
1019
|
inlineStyle["--sub-nav-indent"] = "0.85rem";
|
|
932
1020
|
}
|
|
933
|
-
return /* @__PURE__ */
|
|
1021
|
+
return /* @__PURE__ */ React11.createElement(
|
|
934
1022
|
"nav",
|
|
935
1023
|
{
|
|
936
1024
|
className: combinedClassName,
|
|
937
1025
|
style: inlineStyle,
|
|
938
1026
|
"aria-label": navLabel
|
|
939
1027
|
},
|
|
940
|
-
|
|
941
|
-
|
|
1028
|
+
/* @__PURE__ */ React11.createElement(
|
|
1029
|
+
NavigationTree,
|
|
1030
|
+
{
|
|
1031
|
+
root: rootNode,
|
|
1032
|
+
includeRoot: true,
|
|
1033
|
+
component: "div",
|
|
1034
|
+
className: "canopy-sub-navigation__tree",
|
|
1035
|
+
parentKey: rootNode.slug || "root",
|
|
1036
|
+
heading: finalHeading || void 0
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
942
1039
|
);
|
|
943
1040
|
}
|
|
944
1041
|
|
|
945
1042
|
// ui/src/layout/Layout.jsx
|
|
946
|
-
import
|
|
1043
|
+
import React13 from "react";
|
|
947
1044
|
import navigationHelpers3 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
948
1045
|
|
|
949
1046
|
// ui/src/layout/ContentNavigation.jsx
|
|
950
|
-
import
|
|
1047
|
+
import React12 from "react";
|
|
951
1048
|
var SCROLL_OFFSET_REM = 1.618;
|
|
952
1049
|
var MAX_HEADING_DEPTH = 3;
|
|
953
1050
|
function depthIndex(depth) {
|
|
@@ -966,9 +1063,9 @@ function ContentNavigation({
|
|
|
966
1063
|
ariaLabel
|
|
967
1064
|
}) {
|
|
968
1065
|
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
969
|
-
const savedDepthsRef =
|
|
970
|
-
const [isExpanded, setIsExpanded] =
|
|
971
|
-
const handleToggle =
|
|
1066
|
+
const savedDepthsRef = React12.useRef(null);
|
|
1067
|
+
const [isExpanded, setIsExpanded] = React12.useState(false);
|
|
1068
|
+
const handleToggle = React12.useCallback(() => {
|
|
972
1069
|
setIsExpanded((prev) => !prev);
|
|
973
1070
|
}, []);
|
|
974
1071
|
if ((!items || !items.length) && !headingId) return null;
|
|
@@ -979,7 +1076,7 @@ function ContentNavigation({
|
|
|
979
1076
|
].filter(Boolean).join(" ");
|
|
980
1077
|
const effectiveHeading = heading || pageTitle || null;
|
|
981
1078
|
const navLabel = ariaLabel || (effectiveHeading ? `${effectiveHeading} navigation` : "Section navigation");
|
|
982
|
-
const getSavedDepth =
|
|
1079
|
+
const getSavedDepth = React12.useCallback(
|
|
983
1080
|
(id, fallback) => {
|
|
984
1081
|
if (!id) return fallback;
|
|
985
1082
|
if (!savedDepthsRef.current) savedDepthsRef.current = /* @__PURE__ */ new Map();
|
|
@@ -990,7 +1087,7 @@ function ContentNavigation({
|
|
|
990
1087
|
},
|
|
991
1088
|
[]
|
|
992
1089
|
);
|
|
993
|
-
const headingEntries =
|
|
1090
|
+
const headingEntries = React12.useMemo(() => {
|
|
994
1091
|
const entries = [];
|
|
995
1092
|
const seen = /* @__PURE__ */ new Set();
|
|
996
1093
|
if (headingId) {
|
|
@@ -1018,12 +1115,12 @@ function ContentNavigation({
|
|
|
1018
1115
|
return entries;
|
|
1019
1116
|
}, [headingId, items, getSavedDepth]);
|
|
1020
1117
|
const fallbackId = headingEntries.length ? headingEntries[0].id : headingId || null;
|
|
1021
|
-
const [activeId, setActiveId] =
|
|
1022
|
-
const activeIdRef =
|
|
1023
|
-
|
|
1118
|
+
const [activeId, setActiveId] = React12.useState(fallbackId);
|
|
1119
|
+
const activeIdRef = React12.useRef(activeId);
|
|
1120
|
+
React12.useEffect(() => {
|
|
1024
1121
|
activeIdRef.current = activeId;
|
|
1025
1122
|
}, [activeId]);
|
|
1026
|
-
|
|
1123
|
+
React12.useEffect(() => {
|
|
1027
1124
|
if (!headingEntries.length) return;
|
|
1028
1125
|
if (!headingEntries.some((entry) => entry.id === activeIdRef.current)) {
|
|
1029
1126
|
const next = headingEntries[0].id;
|
|
@@ -1031,7 +1128,7 @@ function ContentNavigation({
|
|
|
1031
1128
|
setActiveId(next);
|
|
1032
1129
|
}
|
|
1033
1130
|
}, [headingEntries]);
|
|
1034
|
-
const computeOffsetPx =
|
|
1131
|
+
const computeOffsetPx = React12.useCallback(() => {
|
|
1035
1132
|
if (!isBrowser) return 0;
|
|
1036
1133
|
try {
|
|
1037
1134
|
const root = document.documentElement;
|
|
@@ -1041,8 +1138,8 @@ function ContentNavigation({
|
|
|
1041
1138
|
return 0;
|
|
1042
1139
|
}
|
|
1043
1140
|
}, [isBrowser]);
|
|
1044
|
-
const headingElementsRef =
|
|
1045
|
-
const updateActiveFromElements =
|
|
1141
|
+
const headingElementsRef = React12.useRef([]);
|
|
1142
|
+
const updateActiveFromElements = React12.useCallback(
|
|
1046
1143
|
(elements) => {
|
|
1047
1144
|
if (!elements || !elements.length) return;
|
|
1048
1145
|
const offset = computeOffsetPx();
|
|
@@ -1062,7 +1159,7 @@ function ContentNavigation({
|
|
|
1062
1159
|
},
|
|
1063
1160
|
[computeOffsetPx]
|
|
1064
1161
|
);
|
|
1065
|
-
|
|
1162
|
+
React12.useEffect(() => {
|
|
1066
1163
|
if (!isBrowser) return void 0;
|
|
1067
1164
|
const elements = headingEntries.map((entry) => {
|
|
1068
1165
|
const element = document.getElementById(entry.id);
|
|
@@ -1088,7 +1185,7 @@ function ContentNavigation({
|
|
|
1088
1185
|
window.removeEventListener("resize", handle);
|
|
1089
1186
|
};
|
|
1090
1187
|
}, [headingEntries, isBrowser, updateActiveFromElements]);
|
|
1091
|
-
const handleAnchorClick =
|
|
1188
|
+
const handleAnchorClick = React12.useCallback(
|
|
1092
1189
|
(event, targetId, options = {}) => {
|
|
1093
1190
|
var _a;
|
|
1094
1191
|
try {
|
|
@@ -1119,7 +1216,7 @@ function ContentNavigation({
|
|
|
1119
1216
|
},
|
|
1120
1217
|
[computeOffsetPx, headingEntries, headingId, isBrowser]
|
|
1121
1218
|
);
|
|
1122
|
-
const
|
|
1219
|
+
const renderNodes = React12.useCallback(
|
|
1123
1220
|
(nodes) => {
|
|
1124
1221
|
if (!nodes || !nodes.length) return null;
|
|
1125
1222
|
return nodes.map((node) => {
|
|
@@ -1132,8 +1229,8 @@ function ContentNavigation({
|
|
|
1132
1229
|
if (depth > MAX_HEADING_DEPTH) return null;
|
|
1133
1230
|
const idx = depthIndex(depth);
|
|
1134
1231
|
const isActive = id && activeId === id;
|
|
1135
|
-
const childNodes = depth < MAX_HEADING_DEPTH ?
|
|
1136
|
-
return /* @__PURE__ */
|
|
1232
|
+
const childNodes = depth < MAX_HEADING_DEPTH ? renderNodes(node.children) : null;
|
|
1233
|
+
return /* @__PURE__ */ React12.createElement("li", { key: id || node.title, className: "canopy-sub-navigation__item", "data-depth": idx }, /* @__PURE__ */ React12.createElement(
|
|
1137
1234
|
"a",
|
|
1138
1235
|
{
|
|
1139
1236
|
className: `canopy-sub-navigation__link depth-${idx}${isActive ? " is-active" : ""}`,
|
|
@@ -1142,7 +1239,7 @@ function ContentNavigation({
|
|
|
1142
1239
|
"aria-current": isActive ? "location" : void 0
|
|
1143
1240
|
},
|
|
1144
1241
|
node.title
|
|
1145
|
-
), childNodes ? /* @__PURE__ */
|
|
1242
|
+
), childNodes ? /* @__PURE__ */ React12.createElement(
|
|
1146
1243
|
"ul",
|
|
1147
1244
|
{
|
|
1148
1245
|
className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested",
|
|
@@ -1154,8 +1251,8 @@ function ContentNavigation({
|
|
|
1154
1251
|
},
|
|
1155
1252
|
[handleAnchorClick, activeId, getSavedDepth]
|
|
1156
1253
|
);
|
|
1157
|
-
const nestedItems =
|
|
1158
|
-
const topLink = headingId ? /* @__PURE__ */
|
|
1254
|
+
const nestedItems = React12.useMemo(() => renderNodes(items), [items, renderNodes]);
|
|
1255
|
+
const topLink = headingId ? /* @__PURE__ */ React12.createElement("li", { className: "canopy-sub-navigation__item", "data-depth": 0 }, /* @__PURE__ */ React12.createElement(
|
|
1159
1256
|
"a",
|
|
1160
1257
|
{
|
|
1161
1258
|
className: `canopy-sub-navigation__link depth-0${activeId === headingId ? " is-active" : ""}`,
|
|
@@ -1164,7 +1261,7 @@ function ContentNavigation({
|
|
|
1164
1261
|
"aria-current": activeId === headingId ? "location" : void 0
|
|
1165
1262
|
},
|
|
1166
1263
|
effectiveHeading || pageTitle || headingId
|
|
1167
|
-
), nestedItems ? /* @__PURE__ */
|
|
1264
|
+
), nestedItems ? /* @__PURE__ */ React12.createElement(
|
|
1168
1265
|
"ul",
|
|
1169
1266
|
{
|
|
1170
1267
|
className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested",
|
|
@@ -1172,7 +1269,7 @@ function ContentNavigation({
|
|
|
1172
1269
|
},
|
|
1173
1270
|
nestedItems
|
|
1174
1271
|
) : null) : null;
|
|
1175
|
-
return /* @__PURE__ */
|
|
1272
|
+
return /* @__PURE__ */ React12.createElement(
|
|
1176
1273
|
"nav",
|
|
1177
1274
|
{
|
|
1178
1275
|
className: combinedClassName,
|
|
@@ -1180,7 +1277,7 @@ function ContentNavigation({
|
|
|
1180
1277
|
"aria-label": navLabel,
|
|
1181
1278
|
"data-canopy-content-nav": "true"
|
|
1182
1279
|
},
|
|
1183
|
-
/* @__PURE__ */
|
|
1280
|
+
/* @__PURE__ */ React12.createElement(
|
|
1184
1281
|
"button",
|
|
1185
1282
|
{
|
|
1186
1283
|
type: "button",
|
|
@@ -1197,7 +1294,7 @@ function ContentNavigation({
|
|
|
1197
1294
|
},
|
|
1198
1295
|
isExpanded ? "Hide" : "Show"
|
|
1199
1296
|
),
|
|
1200
|
-
/* @__PURE__ */
|
|
1297
|
+
/* @__PURE__ */ React12.createElement("ul", { className: "canopy-sub-navigation__list", role: "list" }, topLink || nestedItems)
|
|
1201
1298
|
);
|
|
1202
1299
|
}
|
|
1203
1300
|
|
|
@@ -1230,10 +1327,10 @@ function buildHeadingTree(headings) {
|
|
|
1230
1327
|
}
|
|
1231
1328
|
function buildNavigationAside(sidebar, className) {
|
|
1232
1329
|
if (!sidebar) {
|
|
1233
|
-
return /* @__PURE__ */
|
|
1330
|
+
return /* @__PURE__ */ React13.createElement(SubNavigation, { className });
|
|
1234
1331
|
}
|
|
1235
1332
|
if (typeof sidebar === "function") {
|
|
1236
|
-
return
|
|
1333
|
+
return React13.createElement(sidebar);
|
|
1237
1334
|
}
|
|
1238
1335
|
return sidebar;
|
|
1239
1336
|
}
|
|
@@ -1335,7 +1432,7 @@ function ContentNavigationScript() {
|
|
|
1335
1432
|
});
|
|
1336
1433
|
})();
|
|
1337
1434
|
`;
|
|
1338
|
-
return /* @__PURE__ */
|
|
1435
|
+
return /* @__PURE__ */ React13.createElement("script", { dangerouslySetInnerHTML: { __html: code } });
|
|
1339
1436
|
}
|
|
1340
1437
|
function Layout({
|
|
1341
1438
|
children,
|
|
@@ -1350,26 +1447,26 @@ function Layout({
|
|
|
1350
1447
|
...rest
|
|
1351
1448
|
}) {
|
|
1352
1449
|
const PageContext = navigationHelpers3 && typeof navigationHelpers3.getPageContext === "function" ? navigationHelpers3.getPageContext() : null;
|
|
1353
|
-
const context = PageContext ?
|
|
1354
|
-
const pageHeadings =
|
|
1450
|
+
const context = PageContext ? React13.useContext(PageContext) : null;
|
|
1451
|
+
const pageHeadings = React13.useMemo(() => {
|
|
1355
1452
|
const headings = context && context.page ? context.page.headings : null;
|
|
1356
1453
|
return Array.isArray(headings) ? headings : [];
|
|
1357
1454
|
}, [context]);
|
|
1358
|
-
const contentHeading =
|
|
1455
|
+
const contentHeading = React13.useMemo(() => {
|
|
1359
1456
|
const first = pageHeadings.find((heading) => {
|
|
1360
1457
|
const depth = heading && (heading.depth || heading.level);
|
|
1361
1458
|
return depth === 1;
|
|
1362
1459
|
});
|
|
1363
1460
|
return first && first.title ? first.title : null;
|
|
1364
1461
|
}, [pageHeadings]);
|
|
1365
|
-
const headingAnchorId =
|
|
1462
|
+
const headingAnchorId = React13.useMemo(() => {
|
|
1366
1463
|
const first = pageHeadings.find((heading) => {
|
|
1367
1464
|
const depth = heading && (heading.depth || heading.level);
|
|
1368
1465
|
return depth === 1;
|
|
1369
1466
|
});
|
|
1370
1467
|
return first && first.id ? first.id : null;
|
|
1371
1468
|
}, [pageHeadings]);
|
|
1372
|
-
const headingTree =
|
|
1469
|
+
const headingTree = React13.useMemo(
|
|
1373
1470
|
() => buildHeadingTree(pageHeadings),
|
|
1374
1471
|
[pageHeadings]
|
|
1375
1472
|
);
|
|
@@ -1394,13 +1491,13 @@ function Layout({
|
|
|
1394
1491
|
contentNavigationClassName
|
|
1395
1492
|
].filter(Boolean).join(" ");
|
|
1396
1493
|
const sidebarNode = showLeftColumn ? buildNavigationAside(sidebar, sidebarClassName) : null;
|
|
1397
|
-
return /* @__PURE__ */
|
|
1494
|
+
return /* @__PURE__ */ React13.createElement("div", { className: containerClassName, ...rest }, showLeftColumn ? /* @__PURE__ */ React13.createElement("aside", { className: leftAsideClassName }, sidebarNode) : null, /* @__PURE__ */ React13.createElement("div", { className: contentClassNames }, children), hasContentNavigation ? /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
|
|
1398
1495
|
"aside",
|
|
1399
1496
|
{
|
|
1400
1497
|
className: contentNavigationAsideClassName,
|
|
1401
1498
|
"data-canopy-content-nav-root": "true"
|
|
1402
1499
|
},
|
|
1403
|
-
/* @__PURE__ */
|
|
1500
|
+
/* @__PURE__ */ React13.createElement(
|
|
1404
1501
|
ContentNavigation,
|
|
1405
1502
|
{
|
|
1406
1503
|
items: headingTree,
|
|
@@ -1409,21 +1506,21 @@ function Layout({
|
|
|
1409
1506
|
pageTitle: context && context.page ? context.page.title : void 0
|
|
1410
1507
|
}
|
|
1411
1508
|
)
|
|
1412
|
-
), /* @__PURE__ */
|
|
1509
|
+
), /* @__PURE__ */ React13.createElement(ContentNavigationScript, null)) : null);
|
|
1413
1510
|
}
|
|
1414
1511
|
|
|
1415
1512
|
// ui/src/layout/CanopyHeader.jsx
|
|
1416
|
-
import
|
|
1513
|
+
import React20 from "react";
|
|
1417
1514
|
|
|
1418
1515
|
// ui/src/search/SearchPanel.jsx
|
|
1419
|
-
import
|
|
1516
|
+
import React17 from "react";
|
|
1420
1517
|
|
|
1421
1518
|
// ui/src/Icons.jsx
|
|
1422
|
-
import
|
|
1423
|
-
var MagnifyingGlassIcon = (props) => /* @__PURE__ */
|
|
1519
|
+
import React14 from "react";
|
|
1520
|
+
var MagnifyingGlassIcon = (props) => /* @__PURE__ */ React14.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", "aria-hidden": "true", focusable: "false", ...props }, /* @__PURE__ */ React14.createElement("path", { d: "M456.69 421.39L362.6 327.3a173.81 173.81 0 0034.84-104.58C397.44 126.38 319.06 48 222.72 48S48 126.38 48 222.72s78.38 174.72 174.72 174.72A173.81 173.81 0 00327.3 362.6l94.09 94.09a25 25 0 0035.3-35.3zM97.92 222.72a124.8 124.8 0 11124.8 124.8 124.95 124.95 0 01-124.8-124.8z" }));
|
|
1424
1521
|
|
|
1425
1522
|
// ui/src/search/SearchPanelForm.jsx
|
|
1426
|
-
import
|
|
1523
|
+
import React15 from "react";
|
|
1427
1524
|
function readBasePath() {
|
|
1428
1525
|
const normalize = (val) => {
|
|
1429
1526
|
const raw = typeof val === "string" ? val.trim() : "";
|
|
@@ -1486,18 +1583,18 @@ function SearchPanelForm(props = {}) {
|
|
|
1486
1583
|
clearLabel = "Clear search"
|
|
1487
1584
|
} = props || {};
|
|
1488
1585
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
1489
|
-
const action =
|
|
1586
|
+
const action = React15.useMemo(
|
|
1490
1587
|
() => resolveSearchPath(searchPath),
|
|
1491
1588
|
[searchPath]
|
|
1492
1589
|
);
|
|
1493
|
-
const autoId = typeof
|
|
1494
|
-
const [fallbackId] =
|
|
1590
|
+
const autoId = typeof React15.useId === "function" ? React15.useId() : void 0;
|
|
1591
|
+
const [fallbackId] = React15.useState(
|
|
1495
1592
|
() => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`
|
|
1496
1593
|
);
|
|
1497
1594
|
const inputId = inputIdProp || autoId || fallbackId;
|
|
1498
|
-
const inputRef =
|
|
1499
|
-
const [hasValue, setHasValue] =
|
|
1500
|
-
const focusInput =
|
|
1595
|
+
const inputRef = React15.useRef(null);
|
|
1596
|
+
const [hasValue, setHasValue] = React15.useState(false);
|
|
1597
|
+
const focusInput = React15.useCallback(() => {
|
|
1501
1598
|
const el = inputRef.current;
|
|
1502
1599
|
if (!el) return;
|
|
1503
1600
|
if (document.activeElement === el) return;
|
|
@@ -1510,7 +1607,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1510
1607
|
}
|
|
1511
1608
|
}
|
|
1512
1609
|
}, []);
|
|
1513
|
-
const handlePointerDown =
|
|
1610
|
+
const handlePointerDown = React15.useCallback(
|
|
1514
1611
|
(event) => {
|
|
1515
1612
|
const target = event.target;
|
|
1516
1613
|
if (target && typeof target.closest === "function") {
|
|
@@ -1522,23 +1619,23 @@ function SearchPanelForm(props = {}) {
|
|
|
1522
1619
|
},
|
|
1523
1620
|
[focusInput]
|
|
1524
1621
|
);
|
|
1525
|
-
|
|
1622
|
+
React15.useEffect(() => {
|
|
1526
1623
|
const el = inputRef.current;
|
|
1527
1624
|
if (!el) return;
|
|
1528
1625
|
if (el.value && el.value.trim()) {
|
|
1529
1626
|
setHasValue(true);
|
|
1530
1627
|
}
|
|
1531
1628
|
}, []);
|
|
1532
|
-
const handleInputChange =
|
|
1629
|
+
const handleInputChange = React15.useCallback((event) => {
|
|
1533
1630
|
var _a;
|
|
1534
1631
|
const nextHasValue = Boolean(
|
|
1535
1632
|
((_a = event == null ? void 0 : event.target) == null ? void 0 : _a.value) && event.target.value.trim()
|
|
1536
1633
|
);
|
|
1537
1634
|
setHasValue(nextHasValue);
|
|
1538
1635
|
}, []);
|
|
1539
|
-
const handleClear =
|
|
1636
|
+
const handleClear = React15.useCallback((event) => {
|
|
1540
1637
|
}, []);
|
|
1541
|
-
const handleClearKey =
|
|
1638
|
+
const handleClearKey = React15.useCallback(
|
|
1542
1639
|
(event) => {
|
|
1543
1640
|
if (event.key === "Enter" || event.key === " ") {
|
|
1544
1641
|
event.preventDefault();
|
|
@@ -1547,7 +1644,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1547
1644
|
},
|
|
1548
1645
|
[handleClear]
|
|
1549
1646
|
);
|
|
1550
|
-
return /* @__PURE__ */
|
|
1647
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1551
1648
|
"form",
|
|
1552
1649
|
{
|
|
1553
1650
|
action,
|
|
@@ -1559,7 +1656,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1559
1656
|
onPointerDown: handlePointerDown,
|
|
1560
1657
|
"data-has-value": hasValue ? "1" : "0"
|
|
1561
1658
|
},
|
|
1562
|
-
/* @__PURE__ */
|
|
1659
|
+
/* @__PURE__ */ React15.createElement("label", { htmlFor: inputId, className: "canopy-search-form__label" }, /* @__PURE__ */ React15.createElement(MagnifyingGlassIcon, { className: "canopy-search-form__icon" }), /* @__PURE__ */ React15.createElement("span", { className: "sr-only" }, "Search"), /* @__PURE__ */ React15.createElement(
|
|
1563
1660
|
"input",
|
|
1564
1661
|
{
|
|
1565
1662
|
id: inputId,
|
|
@@ -1574,7 +1671,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1574
1671
|
onInput: handleInputChange
|
|
1575
1672
|
}
|
|
1576
1673
|
)),
|
|
1577
|
-
hasValue ? /* @__PURE__ */
|
|
1674
|
+
hasValue ? /* @__PURE__ */ React15.createElement(
|
|
1578
1675
|
"button",
|
|
1579
1676
|
{
|
|
1580
1677
|
type: "button",
|
|
@@ -1587,7 +1684,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1587
1684
|
},
|
|
1588
1685
|
"\xD7"
|
|
1589
1686
|
) : null,
|
|
1590
|
-
/* @__PURE__ */
|
|
1687
|
+
/* @__PURE__ */ React15.createElement(
|
|
1591
1688
|
"button",
|
|
1592
1689
|
{
|
|
1593
1690
|
type: "submit",
|
|
@@ -1600,11 +1697,11 @@ function SearchPanelForm(props = {}) {
|
|
|
1600
1697
|
}
|
|
1601
1698
|
|
|
1602
1699
|
// ui/src/search/SearchPanelTeaserResults.jsx
|
|
1603
|
-
import
|
|
1700
|
+
import React16 from "react";
|
|
1604
1701
|
function SearchPanelTeaserResults(props = {}) {
|
|
1605
1702
|
const { style, className } = props || {};
|
|
1606
1703
|
const classes = ["canopy-search-teaser", "is-empty", className].filter(Boolean).join(" ");
|
|
1607
|
-
return /* @__PURE__ */
|
|
1704
|
+
return /* @__PURE__ */ React16.createElement(
|
|
1608
1705
|
"div",
|
|
1609
1706
|
{
|
|
1610
1707
|
"data-canopy-search-form-panel": true,
|
|
@@ -1612,7 +1709,7 @@ function SearchPanelTeaserResults(props = {}) {
|
|
|
1612
1709
|
className: classes || void 0,
|
|
1613
1710
|
style
|
|
1614
1711
|
},
|
|
1615
|
-
/* @__PURE__ */
|
|
1712
|
+
/* @__PURE__ */ React16.createElement("div", { id: "cplist", className: "canopy-search-teaser__list" })
|
|
1616
1713
|
);
|
|
1617
1714
|
}
|
|
1618
1715
|
|
|
@@ -1633,11 +1730,11 @@ function SearchPanel(props = {}) {
|
|
|
1633
1730
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
1634
1731
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
1635
1732
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
1636
|
-
return /* @__PURE__ */
|
|
1733
|
+
return /* @__PURE__ */ React17.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React17.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React17.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React17.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React17.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
|
|
1637
1734
|
}
|
|
1638
1735
|
|
|
1639
1736
|
// ui/src/layout/CanopyBrand.jsx
|
|
1640
|
-
import
|
|
1737
|
+
import React18 from "react";
|
|
1641
1738
|
function CanopyBrand(props = {}) {
|
|
1642
1739
|
const {
|
|
1643
1740
|
labelId,
|
|
@@ -1648,11 +1745,11 @@ function CanopyBrand(props = {}) {
|
|
|
1648
1745
|
} = props || {};
|
|
1649
1746
|
const spanProps = labelId ? { id: labelId } : {};
|
|
1650
1747
|
const classes = ["canopy-logo", className].filter(Boolean).join(" ");
|
|
1651
|
-
return /* @__PURE__ */
|
|
1748
|
+
return /* @__PURE__ */ React18.createElement("a", { href, className: classes }, typeof Logo === "function" ? /* @__PURE__ */ React18.createElement(Logo, null) : null, /* @__PURE__ */ React18.createElement("span", { ...spanProps }, label));
|
|
1652
1749
|
}
|
|
1653
1750
|
|
|
1654
1751
|
// ui/src/layout/CanopyModal.jsx
|
|
1655
|
-
import
|
|
1752
|
+
import React19 from "react";
|
|
1656
1753
|
function CanopyModal(props = {}) {
|
|
1657
1754
|
const {
|
|
1658
1755
|
id,
|
|
@@ -1703,7 +1800,7 @@ function CanopyModal(props = {}) {
|
|
|
1703
1800
|
if (padded) bodyClasses.push("canopy-modal__body--padded");
|
|
1704
1801
|
if (bodyClassName) bodyClasses.push(bodyClassName);
|
|
1705
1802
|
const bodyClassNameValue = bodyClasses.join(" ");
|
|
1706
|
-
return /* @__PURE__ */
|
|
1803
|
+
return /* @__PURE__ */ React19.createElement("div", { ...modalProps }, /* @__PURE__ */ React19.createElement("div", { className: "canopy-modal__panel" }, /* @__PURE__ */ React19.createElement("button", { ...closeButtonProps }, /* @__PURE__ */ React19.createElement(
|
|
1707
1804
|
"svg",
|
|
1708
1805
|
{
|
|
1709
1806
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -1713,8 +1810,8 @@ function CanopyModal(props = {}) {
|
|
|
1713
1810
|
strokeWidth: "1.5",
|
|
1714
1811
|
className: "canopy-modal__close-icon"
|
|
1715
1812
|
},
|
|
1716
|
-
/* @__PURE__ */
|
|
1717
|
-
), /* @__PURE__ */
|
|
1813
|
+
/* @__PURE__ */ React19.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M6 18L18 6" })
|
|
1814
|
+
), /* @__PURE__ */ React19.createElement("span", { className: "sr-only" }, closeLabel)), /* @__PURE__ */ React19.createElement("div", { className: bodyClassNameValue }, label ? /* @__PURE__ */ React19.createElement("div", { className: "canopy-modal__brand" }, /* @__PURE__ */ React19.createElement(
|
|
1718
1815
|
CanopyBrand,
|
|
1719
1816
|
{
|
|
1720
1817
|
labelId: resolvedLabelId,
|
|
@@ -1736,11 +1833,24 @@ function HeaderScript() {
|
|
|
1736
1833
|
var body = doc.body;
|
|
1737
1834
|
var root = doc.documentElement;
|
|
1738
1835
|
|
|
1836
|
+
function desktopBreakpointQuery() {
|
|
1837
|
+
if (typeof window === 'undefined') return '(min-width: 70rem)';
|
|
1838
|
+
try {
|
|
1839
|
+
var styles = window.getComputedStyle ? window.getComputedStyle(root) : null;
|
|
1840
|
+
var value = styles ? styles.getPropertyValue('--canopy-desktop-breakpoint') : '';
|
|
1841
|
+
if (typeof value === 'string') value = value.trim();
|
|
1842
|
+
if (!value) value = '70rem';
|
|
1843
|
+
return '(min-width: ' + value + ')';
|
|
1844
|
+
} catch (error) {
|
|
1845
|
+
return '(min-width: 70rem)';
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1739
1849
|
function ready(fn) {
|
|
1740
1850
|
if (doc.readyState === 'loading') {
|
|
1741
1851
|
doc.addEventListener('DOMContentLoaded', fn, { once: true });
|
|
1742
1852
|
} else {
|
|
1743
|
-
fn();
|
|
1853
|
+
fn();
|
|
1744
1854
|
}
|
|
1745
1855
|
}
|
|
1746
1856
|
|
|
@@ -1750,6 +1860,8 @@ function HeaderScript() {
|
|
|
1750
1860
|
|
|
1751
1861
|
var NAV_ATTR = 'data-mobile-nav';
|
|
1752
1862
|
var SEARCH_ATTR = 'data-mobile-search';
|
|
1863
|
+
var NAV_ITEM_ATTR = 'data-canopy-nav-item';
|
|
1864
|
+
var NAV_ITEM_TOGGLE_ATTR = 'data-canopy-nav-item-toggle';
|
|
1753
1865
|
|
|
1754
1866
|
function modalFor(type) {
|
|
1755
1867
|
return doc.querySelector('[data-canopy-modal="' + type + '"]');
|
|
@@ -1831,6 +1943,51 @@ function HeaderScript() {
|
|
|
1831
1943
|
});
|
|
1832
1944
|
}
|
|
1833
1945
|
|
|
1946
|
+
function forEachNavTree(scope, fn) {
|
|
1947
|
+
if (typeof fn !== 'function') return;
|
|
1948
|
+
var rootNode = scope || doc;
|
|
1949
|
+
var trees = rootNode.querySelectorAll('[data-canopy-nav-tree]');
|
|
1950
|
+
each(trees, function (tree) {
|
|
1951
|
+
fn(tree);
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
function resetNavItemToggles(scope) {
|
|
1956
|
+
forEachNavTree(scope, function (tree) {
|
|
1957
|
+
var toggles = tree.querySelectorAll('[' + NAV_ITEM_TOGGLE_ATTR + ']');
|
|
1958
|
+
each(toggles, function (btn) {
|
|
1959
|
+
btn.setAttribute('aria-expanded', 'false');
|
|
1960
|
+
var targetId = btn.getAttribute(NAV_ITEM_TOGGLE_ATTR);
|
|
1961
|
+
var panel = targetId ? doc.getElementById(targetId) : null;
|
|
1962
|
+
var parent = btn.closest('[' + NAV_ITEM_ATTR + ']');
|
|
1963
|
+
if (panel) {
|
|
1964
|
+
panel.hidden = true;
|
|
1965
|
+
panel.setAttribute('aria-hidden', 'true');
|
|
1966
|
+
panel.setAttribute('hidden', '');
|
|
1967
|
+
}
|
|
1968
|
+
if (parent) parent.setAttribute('data-expanded', 'false');
|
|
1969
|
+
});
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
function applyDefaultNavItemState(scope) {
|
|
1974
|
+
forEachNavTree(scope, function (tree) {
|
|
1975
|
+
var defaults = tree.querySelectorAll('[data-default-expanded="true"]');
|
|
1976
|
+
each(defaults, function (item) {
|
|
1977
|
+
var toggle = item.querySelector('[' + NAV_ITEM_TOGGLE_ATTR + ']');
|
|
1978
|
+
var targetId = toggle ? toggle.getAttribute(NAV_ITEM_TOGGLE_ATTR) : null;
|
|
1979
|
+
var panel = targetId ? doc.getElementById(targetId) : null;
|
|
1980
|
+
item.setAttribute('data-expanded', 'true');
|
|
1981
|
+
if (toggle) toggle.setAttribute('aria-expanded', 'true');
|
|
1982
|
+
if (panel) {
|
|
1983
|
+
panel.hidden = false;
|
|
1984
|
+
panel.removeAttribute('hidden');
|
|
1985
|
+
panel.setAttribute('aria-hidden', 'false');
|
|
1986
|
+
}
|
|
1987
|
+
});
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1834
1991
|
function setState(type, next) {
|
|
1835
1992
|
if (type === 'nav') header.setAttribute(NAV_ATTR, next);
|
|
1836
1993
|
if (type === 'search') header.setAttribute(SEARCH_ATTR, next);
|
|
@@ -1838,6 +1995,13 @@ function HeaderScript() {
|
|
|
1838
1995
|
var navOpen = header.getAttribute(NAV_ATTR) === 'open';
|
|
1839
1996
|
var searchOpen = header.getAttribute(SEARCH_ATTR) === 'open';
|
|
1840
1997
|
lockScroll(navOpen || searchOpen);
|
|
1998
|
+
if (type === 'nav') {
|
|
1999
|
+
if (next !== 'open') {
|
|
2000
|
+
resetNavItemToggles(modalFor('nav'));
|
|
2001
|
+
} else {
|
|
2002
|
+
applyDefaultNavItemState(modalFor('nav'));
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
1841
2005
|
}
|
|
1842
2006
|
|
|
1843
2007
|
function toggle(type, force) {
|
|
@@ -1850,6 +2014,35 @@ function HeaderScript() {
|
|
|
1850
2014
|
if (type === 'nav' && shouldOpen) focusNavMenu();
|
|
1851
2015
|
}
|
|
1852
2016
|
|
|
2017
|
+
function setupNavItemToggles() {
|
|
2018
|
+
var toggles = doc.querySelectorAll('[' + NAV_ITEM_TOGGLE_ATTR + ']');
|
|
2019
|
+
each(toggles, function (btn) {
|
|
2020
|
+
if (btn.__canopyNavReady) return;
|
|
2021
|
+
btn.__canopyNavReady = true;
|
|
2022
|
+
btn.addEventListener('click', function (event) {
|
|
2023
|
+
event.preventDefault();
|
|
2024
|
+
event.stopPropagation();
|
|
2025
|
+
var targetId = btn.getAttribute(NAV_ITEM_TOGGLE_ATTR);
|
|
2026
|
+
if (!targetId) return;
|
|
2027
|
+
var panel = doc.getElementById(targetId);
|
|
2028
|
+
var parent = btn.closest('[' + NAV_ITEM_ATTR + ']');
|
|
2029
|
+
var expanded = btn.getAttribute('aria-expanded') === 'true';
|
|
2030
|
+
var next = !expanded;
|
|
2031
|
+
btn.setAttribute('aria-expanded', next ? 'true' : 'false');
|
|
2032
|
+
if (panel) {
|
|
2033
|
+
panel.hidden = !next;
|
|
2034
|
+
panel.setAttribute('aria-hidden', next ? 'false' : 'true');
|
|
2035
|
+
if (next) {
|
|
2036
|
+
panel.removeAttribute('hidden');
|
|
2037
|
+
} else {
|
|
2038
|
+
panel.setAttribute('hidden', '');
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
if (parent) parent.setAttribute('data-expanded', next ? 'true' : 'false');
|
|
2042
|
+
});
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
2045
|
+
|
|
1853
2046
|
each(header.querySelectorAll('[data-canopy-header-toggle]'), function (btn) {
|
|
1854
2047
|
btn.addEventListener('click', function (event) {
|
|
1855
2048
|
event.preventDefault();
|
|
@@ -1897,7 +2090,7 @@ function HeaderScript() {
|
|
|
1897
2090
|
toggle('search', false);
|
|
1898
2091
|
});
|
|
1899
2092
|
|
|
1900
|
-
var mq = window.matchMedia(
|
|
2093
|
+
var mq = window.matchMedia(desktopBreakpointQuery());
|
|
1901
2094
|
function syncDesktopState() {
|
|
1902
2095
|
if (mq.matches) {
|
|
1903
2096
|
setState('nav', 'closed');
|
|
@@ -1914,11 +2107,13 @@ function HeaderScript() {
|
|
|
1914
2107
|
mq.addListener(syncDesktopState);
|
|
1915
2108
|
}
|
|
1916
2109
|
|
|
2110
|
+
setupNavItemToggles();
|
|
2111
|
+
applyDefaultNavItemState(null);
|
|
1917
2112
|
syncDesktopState();
|
|
1918
2113
|
});
|
|
1919
2114
|
})();
|
|
1920
2115
|
`;
|
|
1921
|
-
return /* @__PURE__ */
|
|
2116
|
+
return /* @__PURE__ */ React20.createElement(
|
|
1922
2117
|
"script",
|
|
1923
2118
|
{
|
|
1924
2119
|
dangerouslySetInnerHTML: {
|
|
@@ -1937,7 +2132,7 @@ function getSharedRoot() {
|
|
|
1937
2132
|
function getSafePageContext() {
|
|
1938
2133
|
const root = getSharedRoot();
|
|
1939
2134
|
if (root && root[CONTEXT_KEY]) return root[CONTEXT_KEY];
|
|
1940
|
-
const ctx =
|
|
2135
|
+
const ctx = React20.createContext({ navigation: null, page: null });
|
|
1941
2136
|
if (root) root[CONTEXT_KEY] = ctx;
|
|
1942
2137
|
return ctx;
|
|
1943
2138
|
}
|
|
@@ -1947,29 +2142,55 @@ function ensureArray(navLinks) {
|
|
|
1947
2142
|
(link) => link && typeof link === "object" && typeof link.href === "string"
|
|
1948
2143
|
);
|
|
1949
2144
|
}
|
|
1950
|
-
function
|
|
1951
|
-
if (
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
2145
|
+
function normalizeHref(href) {
|
|
2146
|
+
if (typeof href !== "string") return "";
|
|
2147
|
+
let next = href.trim();
|
|
2148
|
+
if (!next) return "";
|
|
2149
|
+
try {
|
|
2150
|
+
const parsed = new URL(next, "https://canopy.local");
|
|
2151
|
+
next = parsed.pathname || "/";
|
|
2152
|
+
} catch (_) {
|
|
2153
|
+
next = next.replace(/[?#].*$/, "");
|
|
2154
|
+
}
|
|
2155
|
+
next = next.replace(/[?#].*$/, "");
|
|
2156
|
+
if (next.length > 1) {
|
|
2157
|
+
next = next.replace(/\/+$/, "");
|
|
2158
|
+
}
|
|
2159
|
+
if (!next) return "/";
|
|
2160
|
+
return next;
|
|
2161
|
+
}
|
|
2162
|
+
function doesLinkMatchSection(linkHref, sectionNavigation) {
|
|
2163
|
+
if (!sectionNavigation || !sectionNavigation.root || !linkHref) return false;
|
|
2164
|
+
const normalizedLink = normalizeHref(linkHref);
|
|
2165
|
+
if (!normalizedLink) return false;
|
|
2166
|
+
const root = sectionNavigation.root;
|
|
2167
|
+
if (typeof root.href === "string" && normalizeHref(root.href) === normalizedLink) {
|
|
2168
|
+
return true;
|
|
2169
|
+
}
|
|
2170
|
+
if (root.slug) {
|
|
2171
|
+
const slugPath = normalizeHref(`/${root.slug}`);
|
|
2172
|
+
if (slugPath && normalizedLink === slugPath) {
|
|
2173
|
+
return true;
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
return false;
|
|
2177
|
+
}
|
|
2178
|
+
function rootSegmentFromHref(href) {
|
|
2179
|
+
const normalized = normalizeHref(href);
|
|
2180
|
+
if (!normalized || normalized === "/") return "";
|
|
2181
|
+
const trimmed = normalized.replace(/^\/+/, "");
|
|
2182
|
+
return trimmed.split("/")[0] || "";
|
|
2183
|
+
}
|
|
2184
|
+
function getLinkNavigationData(link, navigationRoots, sectionNavigation) {
|
|
2185
|
+
if (!link || typeof link.href !== "string") return null;
|
|
2186
|
+
const segment = rootSegmentFromHref(link.href);
|
|
2187
|
+
if (navigationRoots && segment && navigationRoots[segment]) {
|
|
2188
|
+
return navigationRoots[segment];
|
|
2189
|
+
}
|
|
2190
|
+
if (sectionNavigation && doesLinkMatchSection(link.href, sectionNavigation)) {
|
|
2191
|
+
return sectionNavigation;
|
|
2192
|
+
}
|
|
2193
|
+
return null;
|
|
1973
2194
|
}
|
|
1974
2195
|
function CanopyHeader(props = {}) {
|
|
1975
2196
|
const {
|
|
@@ -1983,20 +2204,34 @@ function CanopyHeader(props = {}) {
|
|
|
1983
2204
|
} = props;
|
|
1984
2205
|
const navLinks = ensureArray(navLinksProp);
|
|
1985
2206
|
const PageContext = getSafePageContext();
|
|
1986
|
-
const context =
|
|
1987
|
-
const
|
|
2207
|
+
const context = React20.useContext(PageContext);
|
|
2208
|
+
const contextNavigation = context && context.navigation ? context.navigation : null;
|
|
2209
|
+
const sectionNavigation = contextNavigation && contextNavigation.root ? contextNavigation : null;
|
|
2210
|
+
const navigationRoots = contextNavigation && contextNavigation.allRoots ? contextNavigation.allRoots : null;
|
|
1988
2211
|
const sectionHeading = sectionNavigation && sectionNavigation.title || (sectionNavigation && sectionNavigation.root ? sectionNavigation.root.title : "");
|
|
1989
2212
|
const hasSectionNav = !!(sectionNavigation && sectionNavigation.root && Array.isArray(sectionNavigation.root.children) && sectionNavigation.root.children.length);
|
|
1990
2213
|
const sectionLabel = sectionHeading ? `More in ${sectionHeading}` : "More in this section";
|
|
1991
2214
|
const sectionAriaLabel = sectionHeading ? `${sectionHeading} section navigation` : "Section navigation";
|
|
1992
|
-
|
|
2215
|
+
const defaultSectionLabel = sectionLabel;
|
|
2216
|
+
const defaultSectionAriaLabel = sectionAriaLabel;
|
|
2217
|
+
const shouldAttachSectionNav = (link) => {
|
|
2218
|
+
const navData = getLinkNavigationData(
|
|
2219
|
+
link,
|
|
2220
|
+
navigationRoots,
|
|
2221
|
+
sectionNavigation
|
|
2222
|
+
);
|
|
2223
|
+
const rootNode = navData && navData.root;
|
|
2224
|
+
return !!(rootNode && Array.isArray(rootNode.children) && rootNode.children.length);
|
|
2225
|
+
};
|
|
2226
|
+
const hasIntegratedSectionNav = navLinks.some(shouldAttachSectionNav);
|
|
2227
|
+
return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement(
|
|
1993
2228
|
"header",
|
|
1994
2229
|
{
|
|
1995
2230
|
className: "canopy-header",
|
|
1996
2231
|
"data-mobile-nav": "closed",
|
|
1997
2232
|
"data-mobile-search": "closed"
|
|
1998
2233
|
},
|
|
1999
|
-
/* @__PURE__ */
|
|
2234
|
+
/* @__PURE__ */ React20.createElement("div", { className: "canopy-header__brand" }, /* @__PURE__ */ React20.createElement(
|
|
2000
2235
|
CanopyBrand,
|
|
2001
2236
|
{
|
|
2002
2237
|
label: title,
|
|
@@ -2005,7 +2240,7 @@ function CanopyHeader(props = {}) {
|
|
|
2005
2240
|
Logo: SiteLogo
|
|
2006
2241
|
}
|
|
2007
2242
|
)),
|
|
2008
|
-
/* @__PURE__ */
|
|
2243
|
+
/* @__PURE__ */ React20.createElement("div", { className: "canopy-header__desktop-search" }, /* @__PURE__ */ React20.createElement(
|
|
2009
2244
|
SearchPanel,
|
|
2010
2245
|
{
|
|
2011
2246
|
label: searchLabel,
|
|
@@ -2013,13 +2248,13 @@ function CanopyHeader(props = {}) {
|
|
|
2013
2248
|
placeholder: searchPlaceholder
|
|
2014
2249
|
}
|
|
2015
2250
|
)),
|
|
2016
|
-
/* @__PURE__ */
|
|
2251
|
+
/* @__PURE__ */ React20.createElement(
|
|
2017
2252
|
"nav",
|
|
2018
2253
|
{
|
|
2019
2254
|
className: "canopy-nav-links canopy-header__desktop-nav",
|
|
2020
2255
|
"aria-label": "Primary navigation"
|
|
2021
2256
|
},
|
|
2022
|
-
navLinks.map((link) => /* @__PURE__ */
|
|
2257
|
+
navLinks.map((link) => /* @__PURE__ */ React20.createElement(
|
|
2023
2258
|
"a",
|
|
2024
2259
|
{
|
|
2025
2260
|
key: link.href,
|
|
@@ -2029,7 +2264,7 @@ function CanopyHeader(props = {}) {
|
|
|
2029
2264
|
link.label || link.href
|
|
2030
2265
|
))
|
|
2031
2266
|
),
|
|
2032
|
-
/* @__PURE__ */
|
|
2267
|
+
/* @__PURE__ */ React20.createElement("div", { className: "canopy-header__actions" }, /* @__PURE__ */ React20.createElement(
|
|
2033
2268
|
"button",
|
|
2034
2269
|
{
|
|
2035
2270
|
type: "button",
|
|
@@ -2039,7 +2274,7 @@ function CanopyHeader(props = {}) {
|
|
|
2039
2274
|
"aria-expanded": "false",
|
|
2040
2275
|
"data-canopy-header-toggle": "search"
|
|
2041
2276
|
},
|
|
2042
|
-
/* @__PURE__ */
|
|
2277
|
+
/* @__PURE__ */ React20.createElement(
|
|
2043
2278
|
"svg",
|
|
2044
2279
|
{
|
|
2045
2280
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2049,7 +2284,7 @@ function CanopyHeader(props = {}) {
|
|
|
2049
2284
|
strokeWidth: "1.5",
|
|
2050
2285
|
className: "canopy-header__search-icon"
|
|
2051
2286
|
},
|
|
2052
|
-
/* @__PURE__ */
|
|
2287
|
+
/* @__PURE__ */ React20.createElement(
|
|
2053
2288
|
"path",
|
|
2054
2289
|
{
|
|
2055
2290
|
strokeLinecap: "round",
|
|
@@ -2058,7 +2293,7 @@ function CanopyHeader(props = {}) {
|
|
|
2058
2293
|
}
|
|
2059
2294
|
)
|
|
2060
2295
|
)
|
|
2061
|
-
), /* @__PURE__ */
|
|
2296
|
+
), /* @__PURE__ */ React20.createElement(
|
|
2062
2297
|
"button",
|
|
2063
2298
|
{
|
|
2064
2299
|
type: "button",
|
|
@@ -2068,7 +2303,7 @@ function CanopyHeader(props = {}) {
|
|
|
2068
2303
|
"aria-expanded": "false",
|
|
2069
2304
|
"data-canopy-header-toggle": "nav"
|
|
2070
2305
|
},
|
|
2071
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ React20.createElement(
|
|
2072
2307
|
"svg",
|
|
2073
2308
|
{
|
|
2074
2309
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2078,7 +2313,7 @@ function CanopyHeader(props = {}) {
|
|
|
2078
2313
|
stroke: "currentColor",
|
|
2079
2314
|
className: "canopy-header__menu-icon"
|
|
2080
2315
|
},
|
|
2081
|
-
/* @__PURE__ */
|
|
2316
|
+
/* @__PURE__ */ React20.createElement(
|
|
2082
2317
|
"path",
|
|
2083
2318
|
{
|
|
2084
2319
|
strokeLinecap: "round",
|
|
@@ -2088,7 +2323,7 @@ function CanopyHeader(props = {}) {
|
|
|
2088
2323
|
)
|
|
2089
2324
|
)
|
|
2090
2325
|
))
|
|
2091
|
-
), /* @__PURE__ */
|
|
2326
|
+
), /* @__PURE__ */ React20.createElement(
|
|
2092
2327
|
CanopyModal,
|
|
2093
2328
|
{
|
|
2094
2329
|
id: "canopy-modal-nav",
|
|
@@ -2100,32 +2335,90 @@ function CanopyHeader(props = {}) {
|
|
|
2100
2335
|
closeLabel: "Close navigation",
|
|
2101
2336
|
closeDataAttr: "nav"
|
|
2102
2337
|
},
|
|
2103
|
-
/* @__PURE__ */
|
|
2338
|
+
/* @__PURE__ */ React20.createElement(
|
|
2104
2339
|
"nav",
|
|
2105
2340
|
{
|
|
2106
2341
|
className: "canopy-nav-links canopy-modal__nav",
|
|
2107
2342
|
"aria-label": "Primary navigation"
|
|
2108
2343
|
},
|
|
2109
|
-
navLinks.map((link) =>
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2344
|
+
/* @__PURE__ */ React20.createElement("ul", { className: "canopy-modal__nav-list", role: "list" }, navLinks.map((link, index) => {
|
|
2345
|
+
const navData = getLinkNavigationData(
|
|
2346
|
+
link,
|
|
2347
|
+
navigationRoots,
|
|
2348
|
+
sectionNavigation
|
|
2349
|
+
);
|
|
2350
|
+
const navRoot = navData && navData.root ? navData.root : null;
|
|
2351
|
+
const hasChildren = !!(navRoot && Array.isArray(navRoot.children) && navRoot.children.length);
|
|
2352
|
+
const nestedId = hasChildren ? `canopy-modal-section-${index}` : null;
|
|
2353
|
+
const toggleLabel = link.label ? `Toggle ${link.label} menu` : "Toggle section menu";
|
|
2354
|
+
const defaultExpanded = hasChildren && !!navRoot.isExpanded;
|
|
2355
|
+
return /* @__PURE__ */ React20.createElement(
|
|
2356
|
+
"li",
|
|
2357
|
+
{
|
|
2358
|
+
className: "canopy-modal__nav-item",
|
|
2359
|
+
key: link.href,
|
|
2360
|
+
"data-canopy-nav-item": hasChildren ? "true" : void 0,
|
|
2361
|
+
"data-expanded": defaultExpanded ? "true" : "false",
|
|
2362
|
+
"data-default-expanded": defaultExpanded ? "true" : void 0
|
|
2363
|
+
},
|
|
2364
|
+
/* @__PURE__ */ React20.createElement("div", { className: "canopy-modal__nav-row" }, /* @__PURE__ */ React20.createElement("a", { href: link.href }, link.label || link.href), hasChildren ? /* @__PURE__ */ React20.createElement(
|
|
2365
|
+
"button",
|
|
2366
|
+
{
|
|
2367
|
+
type: "button",
|
|
2368
|
+
className: "canopy-modal__nav-toggle",
|
|
2369
|
+
"aria-expanded": defaultExpanded ? "true" : "false",
|
|
2370
|
+
"aria-controls": nestedId || void 0,
|
|
2371
|
+
"aria-label": toggleLabel,
|
|
2372
|
+
"data-canopy-nav-item-toggle": nestedId || void 0
|
|
2373
|
+
},
|
|
2374
|
+
/* @__PURE__ */ React20.createElement(
|
|
2375
|
+
"svg",
|
|
2376
|
+
{
|
|
2377
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2378
|
+
viewBox: "0 0 24 24",
|
|
2379
|
+
fill: "none",
|
|
2380
|
+
stroke: "currentColor",
|
|
2381
|
+
strokeWidth: "1.5",
|
|
2382
|
+
className: "canopy-modal__nav-toggle-icon"
|
|
2383
|
+
},
|
|
2384
|
+
/* @__PURE__ */ React20.createElement(
|
|
2385
|
+
"path",
|
|
2386
|
+
{
|
|
2387
|
+
strokeLinecap: "round",
|
|
2388
|
+
strokeLinejoin: "round",
|
|
2389
|
+
d: "M5 9l7 7 7-7"
|
|
2390
|
+
}
|
|
2391
|
+
)
|
|
2392
|
+
),
|
|
2393
|
+
/* @__PURE__ */ React20.createElement("span", { className: "sr-only" }, toggleLabel)
|
|
2394
|
+
) : null),
|
|
2395
|
+
hasChildren ? /* @__PURE__ */ React20.createElement(
|
|
2396
|
+
NavigationTree,
|
|
2397
|
+
{
|
|
2398
|
+
root: navRoot,
|
|
2399
|
+
parentKey: navData && navData.rootSegment ? navData.rootSegment : `root-${index}`,
|
|
2400
|
+
component: "div",
|
|
2401
|
+
className: "canopy-modal__section-nav canopy-modal__section-nav--nested",
|
|
2402
|
+
"aria-label": navData && navData.title ? `${navData.title} section navigation` : defaultSectionAriaLabel,
|
|
2403
|
+
"aria-hidden": defaultExpanded ? "false" : "true",
|
|
2404
|
+
hidden: !defaultExpanded,
|
|
2405
|
+
id: nestedId || void 0
|
|
2406
|
+
}
|
|
2407
|
+
) : null
|
|
2408
|
+
);
|
|
2409
|
+
}))
|
|
2118
2410
|
),
|
|
2119
|
-
hasSectionNav ? /* @__PURE__ */
|
|
2120
|
-
|
|
2411
|
+
hasSectionNav && !hasIntegratedSectionNav ? /* @__PURE__ */ React20.createElement(
|
|
2412
|
+
NavigationTree,
|
|
2121
2413
|
{
|
|
2414
|
+
root: sectionNavigation.root,
|
|
2415
|
+
component: "nav",
|
|
2122
2416
|
className: "canopy-modal__section-nav",
|
|
2123
|
-
"aria-label":
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
/* @__PURE__ */ React19.createElement(SectionNavList, { root: sectionNavigation.root })
|
|
2417
|
+
"aria-label": defaultSectionAriaLabel,
|
|
2418
|
+
parentKey: "fallback-nav"
|
|
2419
|
+
}
|
|
2127
2420
|
) : null
|
|
2128
|
-
), /* @__PURE__ */
|
|
2421
|
+
), /* @__PURE__ */ React20.createElement(
|
|
2129
2422
|
CanopyModal,
|
|
2130
2423
|
{
|
|
2131
2424
|
id: "canopy-modal-search",
|
|
@@ -2138,7 +2431,7 @@ function CanopyHeader(props = {}) {
|
|
|
2138
2431
|
closeDataAttr: "search",
|
|
2139
2432
|
bodyClassName: "canopy-modal__body--search"
|
|
2140
2433
|
},
|
|
2141
|
-
/* @__PURE__ */
|
|
2434
|
+
/* @__PURE__ */ React20.createElement(
|
|
2142
2435
|
SearchPanel,
|
|
2143
2436
|
{
|
|
2144
2437
|
label: searchLabel,
|
|
@@ -2146,18 +2439,18 @@ function CanopyHeader(props = {}) {
|
|
|
2146
2439
|
placeholder: searchPlaceholder
|
|
2147
2440
|
}
|
|
2148
2441
|
)
|
|
2149
|
-
), /* @__PURE__ */
|
|
2442
|
+
), /* @__PURE__ */ React20.createElement(HeaderScript, null));
|
|
2150
2443
|
}
|
|
2151
2444
|
|
|
2152
2445
|
// ui/src/layout/CanopyFooter.jsx
|
|
2153
|
-
import
|
|
2446
|
+
import React21 from "react";
|
|
2154
2447
|
function CanopyFooter({ className = "", children }) {
|
|
2155
2448
|
const footerClassName = ["canopy-footer", className].filter(Boolean).join(" ");
|
|
2156
|
-
return /* @__PURE__ */
|
|
2449
|
+
return /* @__PURE__ */ React21.createElement("footer", { className: footerClassName }, /* @__PURE__ */ React21.createElement("div", { className: "canopy-footer__inner" }, children));
|
|
2157
2450
|
}
|
|
2158
2451
|
|
|
2159
2452
|
// ui/src/layout/TeaserCard.jsx
|
|
2160
|
-
import
|
|
2453
|
+
import React22 from "react";
|
|
2161
2454
|
function TeaserCard({
|
|
2162
2455
|
href = "",
|
|
2163
2456
|
title = "",
|
|
@@ -2178,7 +2471,7 @@ function TeaserCard({
|
|
|
2178
2471
|
].filter(Boolean).join(" ");
|
|
2179
2472
|
const showThumb = type === "work" && thumbnail;
|
|
2180
2473
|
const metaLine = (Array.isArray(metadata) && metadata.length ? metadata.filter(Boolean) : summary ? [summary] : []).filter(Boolean).slice(0, 2).join(" \u2022 ");
|
|
2181
|
-
return /* @__PURE__ */
|
|
2474
|
+
return /* @__PURE__ */ React22.createElement(
|
|
2182
2475
|
Tag,
|
|
2183
2476
|
{
|
|
2184
2477
|
className: classes,
|
|
@@ -2186,7 +2479,7 @@ function TeaserCard({
|
|
|
2186
2479
|
"data-canopy-item": href ? "" : void 0,
|
|
2187
2480
|
...rest
|
|
2188
2481
|
},
|
|
2189
|
-
showThumb ? /* @__PURE__ */
|
|
2482
|
+
showThumb ? /* @__PURE__ */ React22.createElement("div", { className: "canopy-search-teaser__thumb" }, /* @__PURE__ */ React22.createElement(
|
|
2190
2483
|
"img",
|
|
2191
2484
|
{
|
|
2192
2485
|
src: thumbnail,
|
|
@@ -2196,12 +2489,12 @@ function TeaserCard({
|
|
|
2196
2489
|
className: "canopy-search-teaser__thumb-img"
|
|
2197
2490
|
}
|
|
2198
2491
|
)) : null,
|
|
2199
|
-
/* @__PURE__ */
|
|
2492
|
+
/* @__PURE__ */ React22.createElement("div", { className: "canopy-search-teaser__text" }, /* @__PURE__ */ React22.createElement("span", { className: "canopy-search-teaser__title" }, title || href || "Untitled"), metaLine ? /* @__PURE__ */ React22.createElement("span", { className: "canopy-search-teaser__meta" }, metaLine) : null)
|
|
2200
2493
|
);
|
|
2201
2494
|
}
|
|
2202
2495
|
|
|
2203
2496
|
// ui/src/layout/GoogleAnalytics.jsx
|
|
2204
|
-
import
|
|
2497
|
+
import React23 from "react";
|
|
2205
2498
|
var GA_HOST = "https://www.googletagmanager.com/gtag/js";
|
|
2206
2499
|
function GoogleAnalytics({ id }) {
|
|
2207
2500
|
if (!id) return null;
|
|
@@ -2211,11 +2504,11 @@ function GoogleAnalytics({ id }) {
|
|
|
2211
2504
|
gtag('js', new Date());
|
|
2212
2505
|
gtag('config', '${id}');
|
|
2213
2506
|
`;
|
|
2214
|
-
return /* @__PURE__ */
|
|
2507
|
+
return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement("script", { async: true, src: `${GA_HOST}?id=${encodeURIComponent(id)}` }), /* @__PURE__ */ React23.createElement("script", { dangerouslySetInnerHTML: { __html: inlineConfig } }));
|
|
2215
2508
|
}
|
|
2216
2509
|
|
|
2217
2510
|
// ui/src/layout/Container.jsx
|
|
2218
|
-
import
|
|
2511
|
+
import React24 from "react";
|
|
2219
2512
|
function Container({
|
|
2220
2513
|
className = "",
|
|
2221
2514
|
variant = "content",
|
|
@@ -2224,7 +2517,7 @@ function Container({
|
|
|
2224
2517
|
}) {
|
|
2225
2518
|
const variantClass = variant === "wide" ? "max-w-wide" : "max-w-content";
|
|
2226
2519
|
const classes = ["mx-auto", variantClass, "w-full", className].filter(Boolean).join(" ");
|
|
2227
|
-
return /* @__PURE__ */
|
|
2520
|
+
return /* @__PURE__ */ React24.createElement(
|
|
2228
2521
|
"div",
|
|
2229
2522
|
{
|
|
2230
2523
|
className: classes,
|
|
@@ -2236,7 +2529,7 @@ function Container({
|
|
|
2236
2529
|
}
|
|
2237
2530
|
|
|
2238
2531
|
// ui/src/layout/Card.jsx
|
|
2239
|
-
import
|
|
2532
|
+
import React25, { useEffect as useEffect5, useRef, useState as useState5 } from "react";
|
|
2240
2533
|
var DEFAULT_CARD_ASPECT_RATIO = 4 / 3;
|
|
2241
2534
|
function Card({
|
|
2242
2535
|
href,
|
|
@@ -2300,8 +2593,8 @@ function Card({
|
|
|
2300
2593
|
const hasDimensions = Number.isFinite(w) && w > 0 && Number.isFinite(h) && h > 0;
|
|
2301
2594
|
const ratio = hasAspectRatio ? Number(aspectRatio) : hasDimensions ? w / h : src ? DEFAULT_CARD_ASPECT_RATIO : void 0;
|
|
2302
2595
|
const paddingPercent = ratio ? 100 / ratio : 100;
|
|
2303
|
-
const caption = /* @__PURE__ */
|
|
2304
|
-
return /* @__PURE__ */
|
|
2596
|
+
const caption = /* @__PURE__ */ React25.createElement("figcaption", null, title && /* @__PURE__ */ React25.createElement("span", null, title), subtitle && /* @__PURE__ */ React25.createElement("span", null, subtitle), children);
|
|
2597
|
+
return /* @__PURE__ */ React25.createElement(
|
|
2305
2598
|
"a",
|
|
2306
2599
|
{
|
|
2307
2600
|
href,
|
|
@@ -2313,13 +2606,13 @@ function Card({
|
|
|
2313
2606
|
"data-image-loaded": imageLoaded ? "true" : "false",
|
|
2314
2607
|
...rest
|
|
2315
2608
|
},
|
|
2316
|
-
/* @__PURE__ */
|
|
2609
|
+
/* @__PURE__ */ React25.createElement("figure", null, src ? ratio ? /* @__PURE__ */ React25.createElement(
|
|
2317
2610
|
"div",
|
|
2318
2611
|
{
|
|
2319
2612
|
className: "canopy-card-media",
|
|
2320
2613
|
style: { "--canopy-card-padding": `${paddingPercent}%` }
|
|
2321
2614
|
},
|
|
2322
|
-
inView ? /* @__PURE__ */
|
|
2615
|
+
inView ? /* @__PURE__ */ React25.createElement(
|
|
2323
2616
|
"img",
|
|
2324
2617
|
{
|
|
2325
2618
|
src,
|
|
@@ -2330,7 +2623,7 @@ function Card({
|
|
|
2330
2623
|
onError: () => setImageLoaded(true)
|
|
2331
2624
|
}
|
|
2332
2625
|
) : null
|
|
2333
|
-
) : /* @__PURE__ */
|
|
2626
|
+
) : /* @__PURE__ */ React25.createElement(
|
|
2334
2627
|
"img",
|
|
2335
2628
|
{
|
|
2336
2629
|
src,
|
|
@@ -2346,13 +2639,13 @@ function Card({
|
|
|
2346
2639
|
}
|
|
2347
2640
|
|
|
2348
2641
|
// ui/src/content/ReferencedItems.jsx
|
|
2349
|
-
import
|
|
2642
|
+
import React26 from "react";
|
|
2350
2643
|
import navigationHelpers4 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
2351
2644
|
function useReferencedItems(itemsProp) {
|
|
2352
2645
|
if (Array.isArray(itemsProp)) return itemsProp;
|
|
2353
2646
|
const PageContext = navigationHelpers4 && typeof navigationHelpers4.getPageContext === "function" ? navigationHelpers4.getPageContext() : null;
|
|
2354
2647
|
if (!PageContext) return [];
|
|
2355
|
-
const context =
|
|
2648
|
+
const context = React26.useContext(PageContext);
|
|
2356
2649
|
const items = context && context.page ? context.page.referencedItems : null;
|
|
2357
2650
|
return Array.isArray(items) ? items : [];
|
|
2358
2651
|
}
|
|
@@ -2372,13 +2665,13 @@ function ReferencedItems({
|
|
|
2372
2665
|
"referenced-items--empty",
|
|
2373
2666
|
className
|
|
2374
2667
|
].filter(Boolean).join(" ");
|
|
2375
|
-
return /* @__PURE__ */
|
|
2668
|
+
return /* @__PURE__ */ React26.createElement("div", { className: emptyClass, ...rest }, typeof emptyLabel === "function" ? emptyLabel() : emptyLabel);
|
|
2376
2669
|
}
|
|
2377
2670
|
const containerClassName = ["referenced-items", className].filter(Boolean).join(" ");
|
|
2378
|
-
return /* @__PURE__ */
|
|
2671
|
+
return /* @__PURE__ */ React26.createElement("section", { className: containerClassName, ...rest }, children, /* @__PURE__ */ React26.createElement("div", { className: "referenced-items__grid", role: "list" }, items.map((item) => {
|
|
2379
2672
|
if (!item) return null;
|
|
2380
2673
|
const key = item.href || item.slug || item.id;
|
|
2381
|
-
return /* @__PURE__ */
|
|
2674
|
+
return /* @__PURE__ */ React26.createElement("div", { className: "referenced-items__item", role: "listitem", key }, /* @__PURE__ */ React26.createElement(
|
|
2382
2675
|
Card,
|
|
2383
2676
|
{
|
|
2384
2677
|
href: item.href,
|
|
@@ -2395,7 +2688,7 @@ function ReferencedItems({
|
|
|
2395
2688
|
}
|
|
2396
2689
|
|
|
2397
2690
|
// ui/src/content/References.jsx
|
|
2398
|
-
import
|
|
2691
|
+
import React27 from "react";
|
|
2399
2692
|
import navigationHelpers5 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
2400
2693
|
import referenced from "@canopy-iiif/app/lib/components/referenced.js";
|
|
2401
2694
|
function getPageContext() {
|
|
@@ -2426,7 +2719,7 @@ function References({
|
|
|
2426
2719
|
...rest
|
|
2427
2720
|
}) {
|
|
2428
2721
|
const PageContext = getPageContext();
|
|
2429
|
-
const context = PageContext ?
|
|
2722
|
+
const context = PageContext ? React27.useContext(PageContext) : null;
|
|
2430
2723
|
const contextPage = context && context.page ? context.page : null;
|
|
2431
2724
|
const manifestId = id || contextPage && contextPage.manifestId || "";
|
|
2432
2725
|
const contextReferences = !id && contextPage && Array.isArray(contextPage.referencedBy) ? contextPage.referencedBy : null;
|
|
@@ -2435,11 +2728,11 @@ function References({
|
|
|
2435
2728
|
const entries = references && references.length ? references : null;
|
|
2436
2729
|
if (!entries || !entries.length) return null;
|
|
2437
2730
|
const containerClass = ["references", className].filter(Boolean).join(" ");
|
|
2438
|
-
return /* @__PURE__ */
|
|
2731
|
+
return /* @__PURE__ */ React27.createElement("dl", { className: containerClass, ...rest }, /* @__PURE__ */ React27.createElement("div", { className: "references__group" }, /* @__PURE__ */ React27.createElement("dt", null, title), entries.map((entry) => /* @__PURE__ */ React27.createElement("dd", { key: entry.href, className: "references__item" }, /* @__PURE__ */ React27.createElement("a", { href: entry.href }, entry.title || entry.href)))));
|
|
2439
2732
|
}
|
|
2440
2733
|
|
|
2441
2734
|
// ui/src/content/Bibliography.jsx
|
|
2442
|
-
import
|
|
2735
|
+
import React28 from "react";
|
|
2443
2736
|
import bibliography from "@canopy-iiif/app/lib/components/bibliography.js";
|
|
2444
2737
|
function resolveHeadingTag(tag, fallback) {
|
|
2445
2738
|
if (typeof tag === "string" && tag.trim()) return tag;
|
|
@@ -2449,7 +2742,7 @@ function resolveHeadingTag(tag, fallback) {
|
|
|
2449
2742
|
function NoteBody({ note }) {
|
|
2450
2743
|
if (!note) return null;
|
|
2451
2744
|
if (note.html) {
|
|
2452
|
-
return /* @__PURE__ */
|
|
2745
|
+
return /* @__PURE__ */ React28.createElement(
|
|
2453
2746
|
"div",
|
|
2454
2747
|
{
|
|
2455
2748
|
className: "bibliography__note-body",
|
|
@@ -2458,7 +2751,7 @@ function NoteBody({ note }) {
|
|
|
2458
2751
|
);
|
|
2459
2752
|
}
|
|
2460
2753
|
if (note.text) {
|
|
2461
|
-
return /* @__PURE__ */
|
|
2754
|
+
return /* @__PURE__ */ React28.createElement("div", { className: "bibliography__note-body" }, note.text);
|
|
2462
2755
|
}
|
|
2463
2756
|
return null;
|
|
2464
2757
|
}
|
|
@@ -2476,22 +2769,22 @@ function Bibliography({
|
|
|
2476
2769
|
if (!entries.length) return null;
|
|
2477
2770
|
const PageHeadingTag = resolveHeadingTag(pageHeadingTag, "h3");
|
|
2478
2771
|
const rootClass = ["bibliography", className].filter(Boolean).join(" ");
|
|
2479
|
-
return /* @__PURE__ */
|
|
2772
|
+
return /* @__PURE__ */ React28.createElement("section", { className: rootClass }, /* @__PURE__ */ React28.createElement("div", { className: "bibliography__pages" }, entries.map((entry) => {
|
|
2480
2773
|
const key = entry.href || entry.relativePath || entry.title;
|
|
2481
2774
|
const pageTitle = entry.title || entry.href;
|
|
2482
|
-
return /* @__PURE__ */
|
|
2775
|
+
return /* @__PURE__ */ React28.createElement("article", { key, className: "bibliography__page" }, /* @__PURE__ */ React28.createElement("header", { className: "bibliography__page-header" }, pageTitle ? /* @__PURE__ */ React28.createElement(PageHeadingTag, { className: "bibliography__page-title" }, pageTitle) : null, entry.href ? /* @__PURE__ */ React28.createElement("a", { className: "bibliography__page-link", href: entry.href }, entry.href) : null), /* @__PURE__ */ React28.createElement("ol", { className: "bibliography__notes" }, (entry.footnotes || []).map((note, idx) => {
|
|
2483
2776
|
const noteKey = `${key || "entry"}-${note.identifier || idx}`;
|
|
2484
|
-
return /* @__PURE__ */
|
|
2777
|
+
return /* @__PURE__ */ React28.createElement("li", { key: noteKey, className: "bibliography__note" }, note.identifier ? /* @__PURE__ */ React28.createElement("span", { className: "bibliography__note-label" }, note.identifier) : null, /* @__PURE__ */ React28.createElement(NoteBody, { note }));
|
|
2485
2778
|
})));
|
|
2486
2779
|
})));
|
|
2487
2780
|
}
|
|
2488
2781
|
|
|
2489
2782
|
// ui/src/content/timeline/MdxTimeline.jsx
|
|
2490
|
-
import
|
|
2783
|
+
import React32 from "react";
|
|
2491
2784
|
import ReactDOMServer from "react-dom/server";
|
|
2492
2785
|
|
|
2493
2786
|
// ui/src/content/timeline/Timeline.jsx
|
|
2494
|
-
import
|
|
2787
|
+
import React30 from "react";
|
|
2495
2788
|
|
|
2496
2789
|
// ui/src/content/timeline/date-utils.js
|
|
2497
2790
|
var FALLBACK_LOCALE = (() => {
|
|
@@ -2652,7 +2945,7 @@ function clampProgress(value) {
|
|
|
2652
2945
|
}
|
|
2653
2946
|
|
|
2654
2947
|
// ui/src/layout/ReferencedManifestCard.jsx
|
|
2655
|
-
import
|
|
2948
|
+
import React29 from "react";
|
|
2656
2949
|
function normalizeMetadata(metadata, summary) {
|
|
2657
2950
|
if (Array.isArray(metadata) && metadata.length) {
|
|
2658
2951
|
return metadata.filter(Boolean);
|
|
@@ -2686,7 +2979,7 @@ function ReferencedManifestCard({
|
|
|
2686
2979
|
"canopy-referenced-manifest-card",
|
|
2687
2980
|
className
|
|
2688
2981
|
].filter(Boolean).join(" ");
|
|
2689
|
-
return /* @__PURE__ */
|
|
2982
|
+
return /* @__PURE__ */ React29.createElement(
|
|
2690
2983
|
TeaserCard,
|
|
2691
2984
|
{
|
|
2692
2985
|
href: resolvedHref || void 0,
|
|
@@ -2868,14 +3161,14 @@ function TimelineConnector({ side, isActive, highlight }) {
|
|
|
2868
3161
|
"canopy-timeline__connector-dot",
|
|
2869
3162
|
highlight || isActive ? "is-active" : ""
|
|
2870
3163
|
].filter(Boolean).join(" ");
|
|
2871
|
-
return /* @__PURE__ */
|
|
3164
|
+
return /* @__PURE__ */ React30.createElement("span", { className: connectorClasses, "aria-hidden": "true" }, side === "left" ? /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__connector-line" }), /* @__PURE__ */ React30.createElement("span", { className: dotClasses })) : /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("span", { className: dotClasses }), /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__connector-line" })));
|
|
2872
3165
|
}
|
|
2873
3166
|
function renderResourceSection(point) {
|
|
2874
3167
|
if (!point) return null;
|
|
2875
3168
|
const manifestCards = Array.isArray(point.manifests) ? point.manifests.filter(Boolean) : [];
|
|
2876
3169
|
const legacyResources = Array.isArray(point.resources) ? point.resources.filter(Boolean) : [];
|
|
2877
3170
|
if (!manifestCards.length && !legacyResources.length) return null;
|
|
2878
|
-
return /* @__PURE__ */
|
|
3171
|
+
return /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__resources" }, /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__resources-list" }, manifestCards.map((manifest) => /* @__PURE__ */ React30.createElement("div", { key: manifest.id || manifest.href }, /* @__PURE__ */ React30.createElement(ReferencedManifestCard, { manifest }))), legacyResources.map((resource, idx) => /* @__PURE__ */ React30.createElement("div", { key: resource.id || resource.href || `legacy-${idx}` }, /* @__PURE__ */ React30.createElement(
|
|
2879
3172
|
TeaserCard,
|
|
2880
3173
|
{
|
|
2881
3174
|
href: resource.href,
|
|
@@ -2900,26 +3193,26 @@ function Timeline({
|
|
|
2900
3193
|
...rest
|
|
2901
3194
|
}) {
|
|
2902
3195
|
const payloadPoints = payload && Array.isArray(payload.points) ? payload.points : null;
|
|
2903
|
-
const rawPoints =
|
|
3196
|
+
const rawPoints = React30.useMemo(() => {
|
|
2904
3197
|
if (Array.isArray(pointsProp) && pointsProp.length) return pointsProp;
|
|
2905
3198
|
if (payloadPoints && payloadPoints.length) return payloadPoints;
|
|
2906
3199
|
return [];
|
|
2907
3200
|
}, [pointsProp, payloadPoints]);
|
|
2908
|
-
const sanitizedPoints =
|
|
3201
|
+
const sanitizedPoints = React30.useMemo(
|
|
2909
3202
|
() => sanitizePoints(rawPoints),
|
|
2910
3203
|
[rawPoints]
|
|
2911
3204
|
);
|
|
2912
3205
|
const localeValue = payload && payload.locale ? payload.locale : localeProp;
|
|
2913
|
-
const baseLocale =
|
|
3206
|
+
const baseLocale = React30.useMemo(
|
|
2914
3207
|
() => createLocale(localeValue),
|
|
2915
3208
|
[localeValue]
|
|
2916
3209
|
);
|
|
2917
3210
|
const rangeInput = payload && payload.range ? payload.range : rangeProp || {};
|
|
2918
|
-
const rangeOverrides =
|
|
3211
|
+
const rangeOverrides = React30.useMemo(
|
|
2919
3212
|
() => deriveRangeOverrides(sanitizedPoints, rangeInput),
|
|
2920
3213
|
[sanitizedPoints, rangeInput]
|
|
2921
3214
|
);
|
|
2922
|
-
const effectiveRange =
|
|
3215
|
+
const effectiveRange = React30.useMemo(
|
|
2923
3216
|
() => normalizeRange({
|
|
2924
3217
|
...rangeOverrides,
|
|
2925
3218
|
locale: baseLocale
|
|
@@ -2928,7 +3221,7 @@ function Timeline({
|
|
|
2928
3221
|
);
|
|
2929
3222
|
const spanStart = effectiveRange.startDate.getTime();
|
|
2930
3223
|
const span = effectiveRange.span;
|
|
2931
|
-
const pointsWithPosition =
|
|
3224
|
+
const pointsWithPosition = React30.useMemo(() => {
|
|
2932
3225
|
if (!sanitizedPoints.length) return [];
|
|
2933
3226
|
return sanitizedPoints.map((point, index) => {
|
|
2934
3227
|
const timestamp = point.meta.timestamp;
|
|
@@ -2942,29 +3235,29 @@ function Timeline({
|
|
|
2942
3235
|
};
|
|
2943
3236
|
});
|
|
2944
3237
|
}, [sanitizedPoints, spanStart, span]);
|
|
2945
|
-
const [activeId, setActiveId] =
|
|
3238
|
+
const [activeId, setActiveId] = React30.useState(
|
|
2946
3239
|
() => getActivePointId(pointsWithPosition)
|
|
2947
3240
|
);
|
|
2948
|
-
|
|
3241
|
+
React30.useEffect(() => {
|
|
2949
3242
|
setActiveId(getActivePointId(pointsWithPosition));
|
|
2950
3243
|
}, [pointsWithPosition]);
|
|
2951
3244
|
const thresholdValue = typeof thresholdProp === "number" ? thresholdProp : payload && payload.threshold != null ? payload.threshold : null;
|
|
2952
3245
|
const stepsValue = typeof steps === "number" ? Number(steps) : payload && typeof payload.steps === "number" ? Number(payload.steps) : null;
|
|
2953
|
-
const thresholdMs =
|
|
3246
|
+
const thresholdMs = React30.useMemo(
|
|
2954
3247
|
() => getThresholdMs(thresholdValue, effectiveRange.granularity),
|
|
2955
3248
|
[thresholdValue, effectiveRange.granularity]
|
|
2956
3249
|
);
|
|
2957
|
-
const groupedEntries =
|
|
3250
|
+
const groupedEntries = React30.useMemo(
|
|
2958
3251
|
() => buildGroupedEntries(pointsWithPosition, thresholdMs, {
|
|
2959
3252
|
granularity: effectiveRange.granularity,
|
|
2960
3253
|
locale: baseLocale
|
|
2961
3254
|
}),
|
|
2962
3255
|
[pointsWithPosition, thresholdMs, effectiveRange.granularity, baseLocale]
|
|
2963
3256
|
);
|
|
2964
|
-
const [expandedGroupIds, setExpandedGroupIds] =
|
|
3257
|
+
const [expandedGroupIds, setExpandedGroupIds] = React30.useState(
|
|
2965
3258
|
() => /* @__PURE__ */ new Set()
|
|
2966
3259
|
);
|
|
2967
|
-
|
|
3260
|
+
React30.useEffect(() => {
|
|
2968
3261
|
setExpandedGroupIds((prev) => {
|
|
2969
3262
|
if (!prev || prev.size === 0) return prev;
|
|
2970
3263
|
const validIds = new Set(
|
|
@@ -2979,7 +3272,7 @@ function Timeline({
|
|
|
2979
3272
|
return changed ? next : prev;
|
|
2980
3273
|
});
|
|
2981
3274
|
}, [groupedEntries]);
|
|
2982
|
-
const toggleGroup =
|
|
3275
|
+
const toggleGroup = React30.useCallback((groupId) => {
|
|
2983
3276
|
setExpandedGroupIds((prev) => {
|
|
2984
3277
|
const next = new Set(prev || []);
|
|
2985
3278
|
if (next.has(groupId)) next.delete(groupId);
|
|
@@ -3002,7 +3295,7 @@ function Timeline({
|
|
|
3002
3295
|
point.id === activeId ? "is-active" : "",
|
|
3003
3296
|
point.highlight ? "is-highlighted" : ""
|
|
3004
3297
|
].filter(Boolean).join(" ");
|
|
3005
|
-
const connector = /* @__PURE__ */
|
|
3298
|
+
const connector = /* @__PURE__ */ React30.createElement(
|
|
3006
3299
|
TimelineConnector,
|
|
3007
3300
|
{
|
|
3008
3301
|
side: point.side,
|
|
@@ -3010,9 +3303,9 @@ function Timeline({
|
|
|
3010
3303
|
highlight: point.highlight
|
|
3011
3304
|
}
|
|
3012
3305
|
);
|
|
3013
|
-
const body = /* @__PURE__ */
|
|
3306
|
+
const body = /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__point-body" }, /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__point-date" }, point.meta.label), /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__point-title" }, point.title), point.summary ? /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__point-summary" }, point.summary) : null);
|
|
3014
3307
|
const resourceSection = renderResourceSection(point);
|
|
3015
|
-
return /* @__PURE__ */
|
|
3308
|
+
return /* @__PURE__ */ React30.createElement(
|
|
3016
3309
|
"div",
|
|
3017
3310
|
{
|
|
3018
3311
|
key: point.id,
|
|
@@ -3020,7 +3313,7 @@ function Timeline({
|
|
|
3020
3313
|
style: wrapperStyle,
|
|
3021
3314
|
role: "listitem"
|
|
3022
3315
|
},
|
|
3023
|
-
point.side === "left" ? /* @__PURE__ */
|
|
3316
|
+
point.side === "left" ? /* @__PURE__ */ React30.createElement(React30.Fragment, null, /* @__PURE__ */ React30.createElement("div", { className: cardClasses }, body, resourceSection), connector) : /* @__PURE__ */ React30.createElement(React30.Fragment, null, connector, /* @__PURE__ */ React30.createElement("div", { className: cardClasses }, body, resourceSection))
|
|
3024
3317
|
);
|
|
3025
3318
|
}
|
|
3026
3319
|
function renderGroupEntry(entry) {
|
|
@@ -3031,7 +3324,7 @@ function Timeline({
|
|
|
3031
3324
|
const wrapperStyle = { top: `${entry.progress * 100}%` };
|
|
3032
3325
|
const isExpanded = expandedGroupIds.has(entry.id);
|
|
3033
3326
|
const hasActivePoint = entry.points.some((point) => point.id === activeId);
|
|
3034
|
-
const connector = /* @__PURE__ */
|
|
3327
|
+
const connector = /* @__PURE__ */ React30.createElement(
|
|
3035
3328
|
TimelineConnector,
|
|
3036
3329
|
{
|
|
3037
3330
|
side: entry.side,
|
|
@@ -3045,7 +3338,7 @@ function Timeline({
|
|
|
3045
3338
|
hasActivePoint ? "is-active" : ""
|
|
3046
3339
|
].filter(Boolean).join(" ");
|
|
3047
3340
|
const countLabel = `${entry.count} event${entry.count > 1 ? "s" : ""}`;
|
|
3048
|
-
const header = /* @__PURE__ */
|
|
3341
|
+
const header = /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__group-header" }, /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__group-summary" }, /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__point-date" }, entry.label), /* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__group-count" }, countLabel)), /* @__PURE__ */ React30.createElement(
|
|
3049
3342
|
"button",
|
|
3050
3343
|
{
|
|
3051
3344
|
type: "button",
|
|
@@ -3055,7 +3348,7 @@ function Timeline({
|
|
|
3055
3348
|
},
|
|
3056
3349
|
isExpanded ? "Hide details" : "Show details"
|
|
3057
3350
|
));
|
|
3058
|
-
const groupPoints = isExpanded ? /* @__PURE__ */
|
|
3351
|
+
const groupPoints = isExpanded ? /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__group-points" }, entry.points.map((point) => /* @__PURE__ */ React30.createElement(
|
|
3059
3352
|
"button",
|
|
3060
3353
|
{
|
|
3061
3354
|
key: point.id,
|
|
@@ -3066,11 +3359,11 @@ function Timeline({
|
|
|
3066
3359
|
].filter(Boolean).join(" "),
|
|
3067
3360
|
onClick: () => setActiveId(point.id)
|
|
3068
3361
|
},
|
|
3069
|
-
/* @__PURE__ */
|
|
3070
|
-
/* @__PURE__ */
|
|
3362
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__point-date" }, point.meta.label),
|
|
3363
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__group-point-title" }, point.title)
|
|
3071
3364
|
))) : null;
|
|
3072
|
-
const groupCard = /* @__PURE__ */
|
|
3073
|
-
return /* @__PURE__ */
|
|
3365
|
+
const groupCard = /* @__PURE__ */ React30.createElement("div", { className: groupClasses }, header, groupPoints);
|
|
3366
|
+
return /* @__PURE__ */ React30.createElement(
|
|
3074
3367
|
"div",
|
|
3075
3368
|
{
|
|
3076
3369
|
key: entry.id,
|
|
@@ -3078,17 +3371,17 @@ function Timeline({
|
|
|
3078
3371
|
style: wrapperStyle,
|
|
3079
3372
|
role: "listitem"
|
|
3080
3373
|
},
|
|
3081
|
-
entry.side === "left" ? /* @__PURE__ */
|
|
3374
|
+
entry.side === "left" ? /* @__PURE__ */ React30.createElement(React30.Fragment, null, groupCard, connector) : /* @__PURE__ */ React30.createElement(React30.Fragment, null, connector, groupCard)
|
|
3082
3375
|
);
|
|
3083
3376
|
}
|
|
3084
|
-
return /* @__PURE__ */
|
|
3377
|
+
return /* @__PURE__ */ React30.createElement("section", { className: containerClasses, ...rest }, title ? /* @__PURE__ */ React30.createElement("h2", { className: "canopy-timeline__title" }, title) : null, description ? /* @__PURE__ */ React30.createElement("p", { className: "canopy-timeline__description" }, description) : null, rangeLabel ? /* @__PURE__ */ React30.createElement("p", { className: "canopy-timeline__range", "aria-live": "polite" }, rangeLabel) : null, /* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__body" }, /* @__PURE__ */ React30.createElement(
|
|
3085
3378
|
"div",
|
|
3086
3379
|
{
|
|
3087
3380
|
className: "canopy-timeline__list",
|
|
3088
3381
|
role: "list",
|
|
3089
3382
|
style: { minHeight: trackHeight }
|
|
3090
3383
|
},
|
|
3091
|
-
/* @__PURE__ */
|
|
3384
|
+
/* @__PURE__ */ React30.createElement("div", { className: "canopy-timeline__spine", "aria-hidden": "true" }),
|
|
3092
3385
|
renderSteps(stepsValue, effectiveRange),
|
|
3093
3386
|
groupedEntries.map((entry) => {
|
|
3094
3387
|
if (entry.type === "group") return renderGroupEntry(entry);
|
|
@@ -3103,7 +3396,7 @@ function renderSteps(stepSize, range) {
|
|
|
3103
3396
|
const markers = [];
|
|
3104
3397
|
if (startYear < endYear) {
|
|
3105
3398
|
markers.push(
|
|
3106
|
-
/* @__PURE__ */
|
|
3399
|
+
/* @__PURE__ */ React30.createElement(
|
|
3107
3400
|
"span",
|
|
3108
3401
|
{
|
|
3109
3402
|
key: "timeline-step-start",
|
|
@@ -3111,12 +3404,12 @@ function renderSteps(stepSize, range) {
|
|
|
3111
3404
|
style: { top: "0%" },
|
|
3112
3405
|
"aria-hidden": "true"
|
|
3113
3406
|
},
|
|
3114
|
-
/* @__PURE__ */
|
|
3115
|
-
/* @__PURE__ */
|
|
3407
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__step-line" }),
|
|
3408
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__step-label" }, startYear)
|
|
3116
3409
|
)
|
|
3117
3410
|
);
|
|
3118
3411
|
markers.push(
|
|
3119
|
-
/* @__PURE__ */
|
|
3412
|
+
/* @__PURE__ */ React30.createElement(
|
|
3120
3413
|
"span",
|
|
3121
3414
|
{
|
|
3122
3415
|
key: "timeline-step-end",
|
|
@@ -3124,8 +3417,8 @@ function renderSteps(stepSize, range) {
|
|
|
3124
3417
|
style: { top: "100%" },
|
|
3125
3418
|
"aria-hidden": "true"
|
|
3126
3419
|
},
|
|
3127
|
-
/* @__PURE__ */
|
|
3128
|
-
/* @__PURE__ */
|
|
3420
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__step-line" }),
|
|
3421
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__step-label" }, endYear)
|
|
3129
3422
|
)
|
|
3130
3423
|
);
|
|
3131
3424
|
}
|
|
@@ -3135,7 +3428,7 @@ function renderSteps(stepSize, range) {
|
|
|
3135
3428
|
const progress = (timestamp - range.startDate.getTime()) / range.span;
|
|
3136
3429
|
if (progress <= 0 || progress >= 1) continue;
|
|
3137
3430
|
markers.push(
|
|
3138
|
-
/* @__PURE__ */
|
|
3431
|
+
/* @__PURE__ */ React30.createElement(
|
|
3139
3432
|
"span",
|
|
3140
3433
|
{
|
|
3141
3434
|
key: `timeline-step-${year}`,
|
|
@@ -3143,8 +3436,8 @@ function renderSteps(stepSize, range) {
|
|
|
3143
3436
|
style: { top: `calc(${progress * 100}% - 0.5px)` },
|
|
3144
3437
|
"aria-hidden": "true"
|
|
3145
3438
|
},
|
|
3146
|
-
/* @__PURE__ */
|
|
3147
|
-
/* @__PURE__ */
|
|
3439
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__step-line" }),
|
|
3440
|
+
/* @__PURE__ */ React30.createElement("span", { className: "canopy-timeline__step-label" }, year)
|
|
3148
3441
|
)
|
|
3149
3442
|
);
|
|
3150
3443
|
}
|
|
@@ -3158,7 +3451,7 @@ function TimelinePoint() {
|
|
|
3158
3451
|
TimelinePoint.displayName = "TimelinePoint";
|
|
3159
3452
|
|
|
3160
3453
|
// ui/src/utils/manifestReferences.js
|
|
3161
|
-
import
|
|
3454
|
+
import React31 from "react";
|
|
3162
3455
|
import navigationHelpers6 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
3163
3456
|
function normalizeManifestId(raw) {
|
|
3164
3457
|
if (!raw) return "";
|
|
@@ -3175,13 +3468,13 @@ function normalizeManifestId(raw) {
|
|
|
3175
3468
|
return String(raw || "").trim();
|
|
3176
3469
|
}
|
|
3177
3470
|
}
|
|
3178
|
-
var PageContextFallback =
|
|
3471
|
+
var PageContextFallback = React31.createContext(null);
|
|
3179
3472
|
function useReferencedManifestMap() {
|
|
3180
3473
|
var _a, _b;
|
|
3181
3474
|
const PageContext = ((_b = (_a = navigationHelpers6) == null ? void 0 : _a.getPageContext) == null ? void 0 : _b.call(_a)) || PageContextFallback;
|
|
3182
|
-
const pageContext =
|
|
3475
|
+
const pageContext = React31.useContext(PageContext);
|
|
3183
3476
|
const referencedItems = pageContext && pageContext.page && Array.isArray(pageContext.page.referencedItems) ? pageContext.page.referencedItems : [];
|
|
3184
|
-
return
|
|
3477
|
+
return React31.useMemo(() => {
|
|
3185
3478
|
const map = /* @__PURE__ */ new Map();
|
|
3186
3479
|
referencedItems.forEach((item) => {
|
|
3187
3480
|
if (!item) return;
|
|
@@ -3236,7 +3529,7 @@ function normalizeResource(resource, index) {
|
|
|
3236
3529
|
}
|
|
3237
3530
|
function normalizePoint(child, index, options) {
|
|
3238
3531
|
var _a, _b, _c, _d, _e, _f;
|
|
3239
|
-
if (!
|
|
3532
|
+
if (!React32.isValidElement(child)) return null;
|
|
3240
3533
|
if (child.type !== TimelinePoint && ((_a = child.type) == null ? void 0 : _a.displayName) !== "TimelinePoint")
|
|
3241
3534
|
return null;
|
|
3242
3535
|
const props = child.props || {};
|
|
@@ -3252,7 +3545,7 @@ function normalizePoint(child, index, options) {
|
|
|
3252
3545
|
try {
|
|
3253
3546
|
if (props.children) {
|
|
3254
3547
|
detailsHtml = ReactDOMServer.renderToStaticMarkup(
|
|
3255
|
-
|
|
3548
|
+
React32.createElement(React32.Fragment, null, props.children)
|
|
3256
3549
|
);
|
|
3257
3550
|
}
|
|
3258
3551
|
} catch (_) {
|
|
@@ -3301,7 +3594,7 @@ function MdxTimeline({ children, ...rest }) {
|
|
|
3301
3594
|
const localeObj = createLocale(localeValue);
|
|
3302
3595
|
const localeBase = typeof localeObj === "string" ? localeObj : localeObj.baseName || "en-US";
|
|
3303
3596
|
const manifestMap = useReferencedManifestMap();
|
|
3304
|
-
const childArray =
|
|
3597
|
+
const childArray = React32.Children.toArray(children);
|
|
3305
3598
|
const points = childArray.map(
|
|
3306
3599
|
(child, index) => normalizePoint(child, index, {
|
|
3307
3600
|
range: rest.range || {},
|
|
@@ -3317,7 +3610,7 @@ function MdxTimeline({ children, ...rest }) {
|
|
|
3317
3610
|
steps: rest.steps != null ? rest.steps : null
|
|
3318
3611
|
};
|
|
3319
3612
|
const json = serializeForScript(serializeProps(rest, payload, localeBase));
|
|
3320
|
-
return /* @__PURE__ */
|
|
3613
|
+
return /* @__PURE__ */ React32.createElement("div", { "data-canopy-timeline": "1" }, /* @__PURE__ */ React32.createElement(Timeline, { ...rest, __canopyTimeline: payload }), /* @__PURE__ */ React32.createElement(
|
|
3321
3614
|
"script",
|
|
3322
3615
|
{
|
|
3323
3616
|
type: "application/json",
|
|
@@ -3327,7 +3620,7 @@ function MdxTimeline({ children, ...rest }) {
|
|
|
3327
3620
|
}
|
|
3328
3621
|
|
|
3329
3622
|
// ui/src/content/map/MdxMap.jsx
|
|
3330
|
-
import
|
|
3623
|
+
import React33 from "react";
|
|
3331
3624
|
import ReactDOMServer2 from "react-dom/server";
|
|
3332
3625
|
|
|
3333
3626
|
// ui/src/content/map/MapPoint.jsx
|
|
@@ -3354,7 +3647,7 @@ function renderDetailsHtml(children) {
|
|
|
3354
3647
|
if (!children) return "";
|
|
3355
3648
|
try {
|
|
3356
3649
|
return ReactDOMServer2.renderToStaticMarkup(
|
|
3357
|
-
|
|
3650
|
+
React33.createElement(React33.Fragment, null, children)
|
|
3358
3651
|
);
|
|
3359
3652
|
} catch (_) {
|
|
3360
3653
|
return "";
|
|
@@ -3362,7 +3655,7 @@ function renderDetailsHtml(children) {
|
|
|
3362
3655
|
}
|
|
3363
3656
|
function normalizeCustomPoint(child, index, manifestMap) {
|
|
3364
3657
|
var _a;
|
|
3365
|
-
if (!
|
|
3658
|
+
if (!React33.isValidElement(child)) return null;
|
|
3366
3659
|
if (child.type !== MapPoint && ((_a = child.type) == null ? void 0 : _a.displayName) !== "MapPoint") return null;
|
|
3367
3660
|
const coords = normalizeCoordinates(child.props || {});
|
|
3368
3661
|
if (!coords) return null;
|
|
@@ -3407,7 +3700,7 @@ function normalizeCustomPoint(child, index, manifestMap) {
|
|
|
3407
3700
|
};
|
|
3408
3701
|
}
|
|
3409
3702
|
function normalizeCustomPoints(children, manifestMap) {
|
|
3410
|
-
return
|
|
3703
|
+
return React33.Children.toArray(children).map((child, index) => normalizeCustomPoint(child, index, manifestMap)).filter(Boolean);
|
|
3411
3704
|
}
|
|
3412
3705
|
function normalizeHeight(value) {
|
|
3413
3706
|
if (value == null) return "600px";
|
|
@@ -3545,11 +3838,11 @@ function MdxMap({ children, ...rest }) {
|
|
|
3545
3838
|
if (placeholderClass) placeholderProps.className = placeholderClass;
|
|
3546
3839
|
if (rest.id) placeholderProps.id = rest.id;
|
|
3547
3840
|
if (rest.style) placeholderProps.style = rest.style;
|
|
3548
|
-
return /* @__PURE__ */
|
|
3841
|
+
return /* @__PURE__ */ React33.createElement("div", { "data-canopy-map": "1" }, /* @__PURE__ */ React33.createElement("div", { ...placeholderProps, "aria-live": "polite" }, /* @__PURE__ */ React33.createElement("div", { className: "canopy-map__status" }, "Loading map\u2026")), /* @__PURE__ */ React33.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
3549
3842
|
}
|
|
3550
3843
|
|
|
3551
3844
|
// ui/src/search/MdxSearchResults.jsx
|
|
3552
|
-
import
|
|
3845
|
+
import React34 from "react";
|
|
3553
3846
|
function MdxSearchResults(props) {
|
|
3554
3847
|
let json = "{}";
|
|
3555
3848
|
try {
|
|
@@ -3557,11 +3850,11 @@ function MdxSearchResults(props) {
|
|
|
3557
3850
|
} catch (_) {
|
|
3558
3851
|
json = "{}";
|
|
3559
3852
|
}
|
|
3560
|
-
return /* @__PURE__ */
|
|
3853
|
+
return /* @__PURE__ */ React34.createElement("div", { "data-canopy-search-results": "1" }, /* @__PURE__ */ React34.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
3561
3854
|
}
|
|
3562
3855
|
|
|
3563
3856
|
// ui/src/search/SearchSummary.jsx
|
|
3564
|
-
import
|
|
3857
|
+
import React35 from "react";
|
|
3565
3858
|
function SearchSummary(props) {
|
|
3566
3859
|
let json = "{}";
|
|
3567
3860
|
try {
|
|
@@ -3569,11 +3862,11 @@ function SearchSummary(props) {
|
|
|
3569
3862
|
} catch (_) {
|
|
3570
3863
|
json = "{}";
|
|
3571
3864
|
}
|
|
3572
|
-
return /* @__PURE__ */
|
|
3865
|
+
return /* @__PURE__ */ React35.createElement("div", { "data-canopy-search-summary": "1" }, /* @__PURE__ */ React35.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
3573
3866
|
}
|
|
3574
3867
|
|
|
3575
3868
|
// ui/src/search/MdxSearchTabs.jsx
|
|
3576
|
-
import
|
|
3869
|
+
import React36 from "react";
|
|
3577
3870
|
function MdxSearchTabs(props) {
|
|
3578
3871
|
let json = "{}";
|
|
3579
3872
|
try {
|
|
@@ -3581,11 +3874,11 @@ function MdxSearchTabs(props) {
|
|
|
3581
3874
|
} catch (_) {
|
|
3582
3875
|
json = "{}";
|
|
3583
3876
|
}
|
|
3584
|
-
return /* @__PURE__ */
|
|
3877
|
+
return /* @__PURE__ */ React36.createElement("div", { "data-canopy-search-tabs": "1" }, /* @__PURE__ */ React36.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
3585
3878
|
}
|
|
3586
3879
|
|
|
3587
3880
|
// ui/src/search/MdxSearch.jsx
|
|
3588
|
-
import
|
|
3881
|
+
import React37 from "react";
|
|
3589
3882
|
function MdxSearch(props = {}) {
|
|
3590
3883
|
const {
|
|
3591
3884
|
layout,
|
|
@@ -3603,11 +3896,11 @@ function MdxSearch(props = {}) {
|
|
|
3603
3896
|
resultsPayload.layout = layout;
|
|
3604
3897
|
}
|
|
3605
3898
|
const classes = ["canopy-search", className].filter(Boolean).join(" ");
|
|
3606
|
-
return /* @__PURE__ */
|
|
3899
|
+
return /* @__PURE__ */ React37.createElement("section", { className: classes, "data-canopy-search": "1" }, showTabs ? /* @__PURE__ */ React37.createElement(MdxSearchTabs, { ...tabsProps }) : null, showSummary ? /* @__PURE__ */ React37.createElement(SearchSummary, { ...summaryProps }) : null, showResults ? /* @__PURE__ */ React37.createElement(MdxSearchResults, { ...resultsPayload }) : null, children || null);
|
|
3607
3900
|
}
|
|
3608
3901
|
|
|
3609
3902
|
// ui/src/search-form/MdxSearchFormModal.jsx
|
|
3610
|
-
import
|
|
3903
|
+
import React38 from "react";
|
|
3611
3904
|
function MdxSearchFormModal(props = {}) {
|
|
3612
3905
|
const {
|
|
3613
3906
|
placeholder = "Search\u2026",
|
|
@@ -3623,12 +3916,12 @@ function MdxSearchFormModal(props = {}) {
|
|
|
3623
3916
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
3624
3917
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
3625
3918
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
3626
|
-
return /* @__PURE__ */
|
|
3919
|
+
return /* @__PURE__ */ React38.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React38.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React38.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React38.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React38.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
|
|
3627
3920
|
}
|
|
3628
3921
|
|
|
3629
3922
|
// ui/src/iiif/ManifestPrimitives.jsx
|
|
3630
3923
|
var import_slugify = __toESM(require_slugify());
|
|
3631
|
-
import
|
|
3924
|
+
import React39 from "react";
|
|
3632
3925
|
import {
|
|
3633
3926
|
Label as CloverLabel,
|
|
3634
3927
|
Metadata as CloverMetadata,
|
|
@@ -3769,7 +4062,7 @@ function MetadataFacetLink(props) {
|
|
|
3769
4062
|
const valueSlug = facetSlug ? toValueSlug(text) : "";
|
|
3770
4063
|
const href = facetSlug && valueSlug ? buildFacetSearchHref(facetSlug, valueSlug) : "";
|
|
3771
4064
|
if (!href) return text;
|
|
3772
|
-
return /* @__PURE__ */
|
|
4065
|
+
return /* @__PURE__ */ React39.createElement(
|
|
3773
4066
|
"a",
|
|
3774
4067
|
{
|
|
3775
4068
|
href,
|
|
@@ -3795,7 +4088,7 @@ function buildFacetCustomValueContent(items, manifest) {
|
|
|
3795
4088
|
seen.add(normalized);
|
|
3796
4089
|
custom.push({
|
|
3797
4090
|
matchingLabel: item.label,
|
|
3798
|
-
Content: /* @__PURE__ */
|
|
4091
|
+
Content: /* @__PURE__ */ React39.createElement(MetadataFacetLink, { facetSlug: facet.slug })
|
|
3799
4092
|
});
|
|
3800
4093
|
}
|
|
3801
4094
|
return custom;
|
|
@@ -3827,12 +4120,12 @@ function mergeCustomValueContent(userContent, autoContent) {
|
|
|
3827
4120
|
function Label({ manifest, label, ...rest }) {
|
|
3828
4121
|
const intl = label || manifest && manifest.label;
|
|
3829
4122
|
if (!hasInternationalValue(intl)) return null;
|
|
3830
|
-
return /* @__PURE__ */
|
|
4123
|
+
return /* @__PURE__ */ React39.createElement(CloverLabel, { label: intl, ...rest });
|
|
3831
4124
|
}
|
|
3832
4125
|
function Summary({ manifest, summary, ...rest }) {
|
|
3833
4126
|
const intl = summary || manifest && manifest.summary;
|
|
3834
4127
|
if (!hasInternationalValue(intl)) return null;
|
|
3835
|
-
return /* @__PURE__ */
|
|
4128
|
+
return /* @__PURE__ */ React39.createElement(CloverSummary, { summary: intl, ...rest });
|
|
3836
4129
|
}
|
|
3837
4130
|
function Metadata({ manifest, metadata, customValueContent, ...rest }) {
|
|
3838
4131
|
const items = ensureMetadata(metadata || manifest && manifest.metadata);
|
|
@@ -3842,7 +4135,7 @@ function Metadata({ manifest, metadata, customValueContent, ...rest }) {
|
|
|
3842
4135
|
customValueContent,
|
|
3843
4136
|
autoCustomContent
|
|
3844
4137
|
);
|
|
3845
|
-
return /* @__PURE__ */
|
|
4138
|
+
return /* @__PURE__ */ React39.createElement(
|
|
3846
4139
|
CloverMetadata,
|
|
3847
4140
|
{
|
|
3848
4141
|
metadata: items,
|
|
@@ -3856,17 +4149,17 @@ function RequiredStatement({ manifest, requiredStatement, ...rest }) {
|
|
|
3856
4149
|
if (!stmt || !hasInternationalValue(stmt.label) || !hasInternationalValue(stmt.value)) {
|
|
3857
4150
|
return null;
|
|
3858
4151
|
}
|
|
3859
|
-
return /* @__PURE__ */
|
|
4152
|
+
return /* @__PURE__ */ React39.createElement(CloverRequiredStatement, { requiredStatement: stmt, ...rest });
|
|
3860
4153
|
}
|
|
3861
4154
|
|
|
3862
4155
|
// ui/src/iiif/Properties/Id.jsx
|
|
3863
|
-
import
|
|
4156
|
+
import React40 from "react";
|
|
3864
4157
|
function Id({ title = "IIIF Manifest", id, ...props }) {
|
|
3865
|
-
return /* @__PURE__ */
|
|
4158
|
+
return /* @__PURE__ */ React40.createElement("dl", null, /* @__PURE__ */ React40.createElement("dt", null, title), /* @__PURE__ */ React40.createElement("dd", null, /* @__PURE__ */ React40.createElement("a", { href: id }, id)));
|
|
3866
4159
|
}
|
|
3867
4160
|
|
|
3868
4161
|
// ui/src/docs/CodeBlock.jsx
|
|
3869
|
-
import
|
|
4162
|
+
import React41 from "react";
|
|
3870
4163
|
function parseHighlightAttr(attr) {
|
|
3871
4164
|
if (!attr) return /* @__PURE__ */ new Set();
|
|
3872
4165
|
const cleaned = String(attr || "").trim();
|
|
@@ -3912,10 +4205,10 @@ var highlightBaseStyle = {
|
|
|
3912
4205
|
};
|
|
3913
4206
|
function DocsCodeBlock(props = {}) {
|
|
3914
4207
|
const { children, ...rest } = props;
|
|
3915
|
-
const childArray =
|
|
3916
|
-
const codeElement = childArray.find((el) =>
|
|
4208
|
+
const childArray = React41.Children.toArray(children);
|
|
4209
|
+
const codeElement = childArray.find((el) => React41.isValidElement(el));
|
|
3917
4210
|
if (!codeElement || !codeElement.props) {
|
|
3918
|
-
return
|
|
4211
|
+
return React41.createElement("pre", props);
|
|
3919
4212
|
}
|
|
3920
4213
|
const {
|
|
3921
4214
|
className = "",
|
|
@@ -3930,8 +4223,8 @@ function DocsCodeBlock(props = {}) {
|
|
|
3930
4223
|
const highlightSet = parseHighlightAttr(highlightAttr);
|
|
3931
4224
|
const copyAttr = codeProps["data-copy"];
|
|
3932
4225
|
const enableCopy = copyAttr !== void 0 ? copyAttr === true || copyAttr === "true" || copyAttr === "" : false;
|
|
3933
|
-
const [copied, setCopied] =
|
|
3934
|
-
const handleCopy =
|
|
4226
|
+
const [copied, setCopied] = React41.useState(false);
|
|
4227
|
+
const handleCopy = React41.useCallback(async () => {
|
|
3935
4228
|
const text = rawCode;
|
|
3936
4229
|
try {
|
|
3937
4230
|
if (typeof navigator !== "undefined" && navigator.clipboard && navigator.clipboard.writeText) {
|
|
@@ -3996,20 +4289,20 @@ function DocsCodeBlock(props = {}) {
|
|
|
3996
4289
|
const highlight = highlightSet.has(lineNumber);
|
|
3997
4290
|
const style = highlight ? { ...baseLineStyle, ...highlightBaseStyle } : baseLineStyle;
|
|
3998
4291
|
const displayLine = line === "" ? " " : line;
|
|
3999
|
-
return
|
|
4292
|
+
return React41.createElement(
|
|
4000
4293
|
"span",
|
|
4001
4294
|
{ key: lineNumber, style },
|
|
4002
|
-
|
|
4295
|
+
React41.createElement("span", { style: lineContentStyle }, displayLine)
|
|
4003
4296
|
);
|
|
4004
4297
|
});
|
|
4005
|
-
return
|
|
4298
|
+
return React41.createElement(
|
|
4006
4299
|
"div",
|
|
4007
4300
|
{ style: containerStyle },
|
|
4008
|
-
showHeader ?
|
|
4301
|
+
showHeader ? React41.createElement(
|
|
4009
4302
|
"div",
|
|
4010
4303
|
{ style: headerStyle },
|
|
4011
|
-
|
|
4012
|
-
enableCopy ?
|
|
4304
|
+
React41.createElement("span", null, showFilename ? filename : null),
|
|
4305
|
+
enableCopy ? React41.createElement(
|
|
4013
4306
|
"button",
|
|
4014
4307
|
{
|
|
4015
4308
|
type: "button",
|
|
@@ -4029,29 +4322,29 @@ function DocsCodeBlock(props = {}) {
|
|
|
4029
4322
|
copied ? "Copied" : "Copy"
|
|
4030
4323
|
) : null
|
|
4031
4324
|
) : null,
|
|
4032
|
-
|
|
4325
|
+
React41.createElement(
|
|
4033
4326
|
"pre",
|
|
4034
4327
|
{ ...preRest, className: preClassName, style: mergedPreStyle },
|
|
4035
|
-
|
|
4328
|
+
React41.createElement("code", { style: codeStyle }, lineElements)
|
|
4036
4329
|
)
|
|
4037
4330
|
);
|
|
4038
4331
|
}
|
|
4039
4332
|
|
|
4040
4333
|
// ui/src/docs/MarkdownTable.jsx
|
|
4041
|
-
import
|
|
4334
|
+
import React42 from "react";
|
|
4042
4335
|
function MarkdownTable({ className = "", ...rest }) {
|
|
4043
4336
|
const merged = ["markdown-table", className].filter(Boolean).join(" ");
|
|
4044
|
-
return /* @__PURE__ */
|
|
4337
|
+
return /* @__PURE__ */ React42.createElement("div", { className: "markdown-table__frame" }, /* @__PURE__ */ React42.createElement("table", { className: merged, ...rest }));
|
|
4045
4338
|
}
|
|
4046
4339
|
|
|
4047
4340
|
// ui/src/docs/Diagram.jsx
|
|
4048
|
-
import
|
|
4341
|
+
import React43 from "react";
|
|
4049
4342
|
function CanopyDiagram() {
|
|
4050
|
-
return /* @__PURE__ */
|
|
4343
|
+
return /* @__PURE__ */ React43.createElement("div", { className: "canopy-diagram" }, /* @__PURE__ */ React43.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--collections" }, /* @__PURE__ */ React43.createElement("h3", null, "IIIF Collection(s)"), /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__section-summary" }, "Source collections contribute 105 total manifests that Canopy retrieves as-is via IIIF endpoints."), /* @__PURE__ */ React43.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Collection A"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "70 Manifests"), /* @__PURE__ */ React43.createElement("li", null, "IIIF Images + A/V"), /* @__PURE__ */ React43.createElement("li", null, "Textual Annotations"))), /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Collection B"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "35 Manifests"), /* @__PURE__ */ React43.createElement("li", null, "IIIF Images + A/V"), /* @__PURE__ */ React43.createElement("li", null, "Textual Annotations"))))), /* @__PURE__ */ React43.createElement("div", { className: "canopy-diagram__arrow", "aria-hidden": "true" }, /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__arrow-line" }), /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__arrow-head" })), /* @__PURE__ */ React43.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--build" }, /* @__PURE__ */ React43.createElement("h3", null, "Canopy Build Process"), /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__section-summary" }, "Canopy syncs manifests, page content, and annotations before bundling the site."), /* @__PURE__ */ React43.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Automated content"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "105 manifests \u2192 105 work pages"), /* @__PURE__ */ React43.createElement("li", null, "One page per manifest"), /* @__PURE__ */ React43.createElement("li", null, "Customize page layout"))), /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Contextual content"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "Markdown & MDX pages"), /* @__PURE__ */ React43.createElement("li", null, "Author narratives"), /* @__PURE__ */ React43.createElement("li", null, "Reference manifests inline"))), /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Search index"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "Combines works + pages"), /* @__PURE__ */ React43.createElement("li", null, "Customize result layout"), /* @__PURE__ */ React43.createElement("li", null, "Optional annotations"))))), /* @__PURE__ */ React43.createElement("div", { className: "canopy-diagram__arrow", "aria-hidden": "true" }, /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__arrow-line" }), /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__arrow-head" })), /* @__PURE__ */ React43.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--output" }, /* @__PURE__ */ React43.createElement("h3", null, "Static Digital Project"), /* @__PURE__ */ React43.createElement("span", { className: "canopy-diagram__section-summary" }, "The output is a lightweight bundle of HTML, CSS, JS, and JSON assets that can deploy anywhere."), /* @__PURE__ */ React43.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Work pages"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "105 generated HTML pages"), /* @__PURE__ */ React43.createElement("li", null, "Each links back to source manifests"), /* @__PURE__ */ React43.createElement("li", null, "Styled with Canopy components"))), /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Custom pages"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "Markdown & MDX-authored content"), /* @__PURE__ */ React43.createElement("li", null, "Reusable layouts for narratives"), /* @__PURE__ */ React43.createElement("li", null, "Embed IIIF media & interstitials"))), /* @__PURE__ */ React43.createElement("article", null, /* @__PURE__ */ React43.createElement("h4", null, "Search bundle"), /* @__PURE__ */ React43.createElement("ul", null, /* @__PURE__ */ React43.createElement("li", null, "Static FlexSearch index"), /* @__PURE__ */ React43.createElement("li", null, "Works + pages share records"), /* @__PURE__ */ React43.createElement("li", null, "Optional annotation dataset"))))));
|
|
4051
4344
|
}
|
|
4052
4345
|
|
|
4053
4346
|
// ui/src/docs/ThemeShowcase.jsx
|
|
4054
|
-
import
|
|
4347
|
+
import React44 from "react";
|
|
4055
4348
|
|
|
4056
4349
|
// ../../node_modules/@radix-ui/colors/index.mjs
|
|
4057
4350
|
var colors_exports = {};
|
|
@@ -7903,21 +8196,21 @@ var STEP_MAP = {
|
|
|
7903
8196
|
800: 11,
|
|
7904
8197
|
900: 12
|
|
7905
8198
|
};
|
|
7906
|
-
var Section = ({ title, description, children }) => /* @__PURE__ */
|
|
7907
|
-
var ColorScaleRow = ({ label, prefix }) => /* @__PURE__ */
|
|
8199
|
+
var Section = ({ title, description, children }) => /* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase__section" }, /* @__PURE__ */ React44.createElement("h3", { className: "canopy-theme-showcase__section-title" }, title), description ? /* @__PURE__ */ React44.createElement("p", { className: "canopy-theme-showcase__section-description" }, description) : null, children);
|
|
8200
|
+
var ColorScaleRow = ({ label, prefix }) => /* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase__scale-row" }, /* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase__scale-label" }, /* @__PURE__ */ React44.createElement("strong", null, label)), /* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase__scale-track" }, COLOR_STOPS.map((stop) => /* @__PURE__ */ React44.createElement(
|
|
7908
8201
|
"div",
|
|
7909
8202
|
{
|
|
7910
8203
|
key: `${label}-${stop}`,
|
|
7911
8204
|
className: "canopy-theme-showcase__scale-stop"
|
|
7912
8205
|
},
|
|
7913
|
-
/* @__PURE__ */
|
|
8206
|
+
/* @__PURE__ */ React44.createElement(
|
|
7914
8207
|
"span",
|
|
7915
8208
|
{
|
|
7916
8209
|
className: "canopy-theme-showcase__scale-chip",
|
|
7917
8210
|
style: { backgroundColor: `var(${prefix}-${stop})` }
|
|
7918
8211
|
}
|
|
7919
8212
|
),
|
|
7920
|
-
/* @__PURE__ */
|
|
8213
|
+
/* @__PURE__ */ React44.createElement("span", { className: "canopy-theme-showcase__scale-token" }, stop)
|
|
7921
8214
|
))));
|
|
7922
8215
|
var AVAILABLE = new Set(
|
|
7923
8216
|
Object.keys(colors_exports).filter(
|
|
@@ -7982,9 +8275,9 @@ var PREVIEW_DATA = buildPreviewData();
|
|
|
7982
8275
|
function encodeJson(value) {
|
|
7983
8276
|
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
7984
8277
|
}
|
|
7985
|
-
var ColorsLabeled = ({ colors, type, getRadixSwatch }) => /* @__PURE__ */
|
|
8278
|
+
var ColorsLabeled = ({ colors, type, getRadixSwatch }) => /* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase__swatch-grid" }, colors.map((name) => {
|
|
7986
8279
|
const colorValue = getRadixSwatch(name);
|
|
7987
|
-
return /* @__PURE__ */
|
|
8280
|
+
return /* @__PURE__ */ React44.createElement(
|
|
7988
8281
|
"button",
|
|
7989
8282
|
{
|
|
7990
8283
|
key: `${type}-${name}`,
|
|
@@ -7995,14 +8288,14 @@ var ColorsLabeled = ({ colors, type, getRadixSwatch }) => /* @__PURE__ */ React4
|
|
|
7995
8288
|
"data-theme-swatch-value": name,
|
|
7996
8289
|
"aria-pressed": "false"
|
|
7997
8290
|
},
|
|
7998
|
-
/* @__PURE__ */
|
|
8291
|
+
/* @__PURE__ */ React44.createElement(
|
|
7999
8292
|
"span",
|
|
8000
8293
|
{
|
|
8001
8294
|
className: "canopy-theme-showcase__swatch-chip",
|
|
8002
8295
|
style: { background: colorValue || "var(--color-gray-200)" }
|
|
8003
8296
|
}
|
|
8004
8297
|
),
|
|
8005
|
-
/* @__PURE__ */
|
|
8298
|
+
/* @__PURE__ */ React44.createElement("span", { className: "canopy-theme-showcase__swatch-label" }, name)
|
|
8006
8299
|
);
|
|
8007
8300
|
}));
|
|
8008
8301
|
function ThemeShowcase() {
|
|
@@ -8162,7 +8455,7 @@ function ThemeShowcase() {
|
|
|
8162
8455
|
.canopy-theme-showcase__swatch-controls { display: none; }
|
|
8163
8456
|
.canopy-theme-showcase__clear-button { display: none; }
|
|
8164
8457
|
`;
|
|
8165
|
-
return /* @__PURE__ */
|
|
8458
|
+
return /* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase", "data-theme-showcase": true }, /* @__PURE__ */ React44.createElement("style", { dangerouslySetInnerHTML: { __html: styles } }), /* @__PURE__ */ React44.createElement(
|
|
8166
8459
|
"div",
|
|
8167
8460
|
{
|
|
8168
8461
|
style: {
|
|
@@ -8173,18 +8466,18 @@ function ThemeShowcase() {
|
|
|
8173
8466
|
marginBottom: "1rem"
|
|
8174
8467
|
}
|
|
8175
8468
|
},
|
|
8176
|
-
/* @__PURE__ */
|
|
8469
|
+
/* @__PURE__ */ React44.createElement(
|
|
8177
8470
|
Section,
|
|
8178
8471
|
{
|
|
8179
8472
|
title: "Appearance",
|
|
8180
8473
|
description: "Pick the base light or dark mode for the theme preview."
|
|
8181
8474
|
},
|
|
8182
|
-
/* @__PURE__ */
|
|
8475
|
+
/* @__PURE__ */ React44.createElement("div", { className: "canopy-theme-showcase__appearance-buttons" }, ["light", "dark"].map((mode) => {
|
|
8183
8476
|
const label = `${mode.charAt(0).toUpperCase()}${mode.slice(1)}`;
|
|
8184
8477
|
const baseClass = "canopy-theme-showcase__appearance-button";
|
|
8185
8478
|
const isDefault = mode === DEFAULTS.appearance;
|
|
8186
8479
|
const className = isDefault ? `${baseClass} is-active` : baseClass;
|
|
8187
|
-
return /* @__PURE__ */
|
|
8480
|
+
return /* @__PURE__ */ React44.createElement(
|
|
8188
8481
|
"button",
|
|
8189
8482
|
{
|
|
8190
8483
|
key: mode,
|
|
@@ -8196,7 +8489,7 @@ function ThemeShowcase() {
|
|
|
8196
8489
|
);
|
|
8197
8490
|
}))
|
|
8198
8491
|
),
|
|
8199
|
-
/* @__PURE__ */
|
|
8492
|
+
/* @__PURE__ */ React44.createElement(
|
|
8200
8493
|
"button",
|
|
8201
8494
|
{
|
|
8202
8495
|
type: "button",
|
|
@@ -8205,13 +8498,13 @@ function ThemeShowcase() {
|
|
|
8205
8498
|
},
|
|
8206
8499
|
"Reset"
|
|
8207
8500
|
)
|
|
8208
|
-
), /* @__PURE__ */
|
|
8501
|
+
), /* @__PURE__ */ React44.createElement(
|
|
8209
8502
|
Section,
|
|
8210
8503
|
{
|
|
8211
8504
|
title: "Color scales",
|
|
8212
8505
|
description: "Accent and gray ramps from the active theme."
|
|
8213
8506
|
},
|
|
8214
|
-
/* @__PURE__ */
|
|
8507
|
+
/* @__PURE__ */ React44.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem" } }, COLOR_SCALES.map((scale) => /* @__PURE__ */ React44.createElement(
|
|
8215
8508
|
ColorScaleRow,
|
|
8216
8509
|
{
|
|
8217
8510
|
key: scale.label,
|
|
@@ -8219,13 +8512,13 @@ function ThemeShowcase() {
|
|
|
8219
8512
|
prefix: scale.prefix
|
|
8220
8513
|
}
|
|
8221
8514
|
)))
|
|
8222
|
-
), /* @__PURE__ */
|
|
8515
|
+
), /* @__PURE__ */ React44.createElement(
|
|
8223
8516
|
Section,
|
|
8224
8517
|
{
|
|
8225
8518
|
title: "Accent color palette options",
|
|
8226
8519
|
description: "Click a swatch to temporarily override the accent palette."
|
|
8227
8520
|
},
|
|
8228
|
-
/* @__PURE__ */
|
|
8521
|
+
/* @__PURE__ */ React44.createElement(
|
|
8229
8522
|
ColorsLabeled,
|
|
8230
8523
|
{
|
|
8231
8524
|
colors: accentColors,
|
|
@@ -8233,13 +8526,13 @@ function ThemeShowcase() {
|
|
|
8233
8526
|
getRadixSwatch
|
|
8234
8527
|
}
|
|
8235
8528
|
)
|
|
8236
|
-
), /* @__PURE__ */
|
|
8529
|
+
), /* @__PURE__ */ React44.createElement(
|
|
8237
8530
|
Section,
|
|
8238
8531
|
{
|
|
8239
8532
|
title: "Gray color palette options",
|
|
8240
8533
|
description: "Click a swatch to preview the neutral ramp for surfaces and text."
|
|
8241
8534
|
},
|
|
8242
|
-
/* @__PURE__ */
|
|
8535
|
+
/* @__PURE__ */ React44.createElement(
|
|
8243
8536
|
ColorsLabeled,
|
|
8244
8537
|
{
|
|
8245
8538
|
colors: grayColors,
|
|
@@ -8247,7 +8540,7 @@ function ThemeShowcase() {
|
|
|
8247
8540
|
getRadixSwatch
|
|
8248
8541
|
}
|
|
8249
8542
|
)
|
|
8250
|
-
), /* @__PURE__ */
|
|
8543
|
+
), /* @__PURE__ */ React44.createElement(
|
|
8251
8544
|
"script",
|
|
8252
8545
|
{
|
|
8253
8546
|
type: "application/json",
|