@canopy-iiif/app 0.9.14 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/AGENTS.md +1 -0
- package/lib/build/build.js +1 -0
- package/lib/build/dev.js +17 -4
- package/lib/build/iiif.js +234 -12
- package/lib/build/mdx.js +2 -0
- package/lib/build/pages.js +17 -1
- package/lib/build/styles.js +4 -8
- package/lib/components/featured.js +6 -0
- package/lib/components/hero-slider-runtime.js +9 -2
- package/lib/iiif/thumbnail.js +262 -4
- package/package.json +14 -1
- package/ui/dist/index.mjs +191 -99
- package/ui/dist/index.mjs.map +4 -4
- package/ui/dist/server.mjs +295 -187
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/base/_common.scss +33 -33
- package/ui/styles/base/_heading.scss +26 -19
- package/ui/styles/base/index.scss +0 -1
- package/ui/styles/components/_buttons.scss +53 -46
- package/ui/styles/components/_interstitial-hero.scss +13 -18
- package/ui/styles/components/_sub-navigation.scss +1 -0
- package/ui/styles/components/header/_header.scss +10 -3
- package/ui/styles/components/header/_logo.scss +32 -33
- package/ui/styles/components/search/_form.scss +4 -9
- package/ui/styles/index.css +161 -171
- package/ui/tailwind-canopy-iiif-preset.js +5 -15
- package/ui/tailwind-config.d.ts +21 -0
- package/ui/tailwind-config.js +134 -0
- package/ui/tailwind-default.config.mjs +3 -0
- package/ui/theme.js +4 -4
- package/ui/styles/_variables.scss +0 -1
package/ui/dist/server.mjs
CHANGED
|
@@ -153,8 +153,45 @@ var Scroll = (props) => {
|
|
|
153
153
|
return /* @__PURE__ */ React4.createElement(CloverScroll, { ...props });
|
|
154
154
|
};
|
|
155
155
|
|
|
156
|
+
// ui/src/iiif/Image.jsx
|
|
157
|
+
import React5, { useEffect as useEffect4, useState as useState4 } from "react";
|
|
158
|
+
var Image = (props) => {
|
|
159
|
+
const [CloverImage, setCloverImage] = useState4(null);
|
|
160
|
+
useEffect4(() => {
|
|
161
|
+
let mounted = true;
|
|
162
|
+
const canUseDom = typeof window !== "undefined" && typeof document !== "undefined";
|
|
163
|
+
if (canUseDom) {
|
|
164
|
+
import("@samvera/clover-iiif/image").then((mod) => {
|
|
165
|
+
if (!mounted) return;
|
|
166
|
+
const Comp = mod && (mod.default || mod.Image || mod);
|
|
167
|
+
setCloverImage(() => Comp);
|
|
168
|
+
}).catch(() => {
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return () => {
|
|
172
|
+
mounted = false;
|
|
173
|
+
};
|
|
174
|
+
}, []);
|
|
175
|
+
if (!CloverImage) {
|
|
176
|
+
let json = "{}";
|
|
177
|
+
try {
|
|
178
|
+
json = JSON.stringify(props || {});
|
|
179
|
+
} catch (_) {
|
|
180
|
+
json = "{}";
|
|
181
|
+
}
|
|
182
|
+
return /* @__PURE__ */ React5.createElement("div", { "data-canopy-image": "1", className: "not-prose" }, /* @__PURE__ */ React5.createElement(
|
|
183
|
+
"script",
|
|
184
|
+
{
|
|
185
|
+
type: "application/json",
|
|
186
|
+
dangerouslySetInnerHTML: { __html: json }
|
|
187
|
+
}
|
|
188
|
+
));
|
|
189
|
+
}
|
|
190
|
+
return /* @__PURE__ */ React5.createElement(CloverImage, { ...props });
|
|
191
|
+
};
|
|
192
|
+
|
|
156
193
|
// ui/src/iiif/MdxRelatedItems.jsx
|
|
157
|
-
import
|
|
194
|
+
import React6 from "react";
|
|
158
195
|
function MdxRelatedItems(props) {
|
|
159
196
|
let json = "{}";
|
|
160
197
|
try {
|
|
@@ -162,7 +199,7 @@ function MdxRelatedItems(props) {
|
|
|
162
199
|
} catch (_) {
|
|
163
200
|
json = "{}";
|
|
164
201
|
}
|
|
165
|
-
return /* @__PURE__ */
|
|
202
|
+
return /* @__PURE__ */ React6.createElement("div", { "data-canopy-related-items": "1", className: "not-prose" }, /* @__PURE__ */ React6.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
166
203
|
}
|
|
167
204
|
|
|
168
205
|
// ui/src/interstitials/index.js
|
|
@@ -173,7 +210,7 @@ __export(interstitials_exports, {
|
|
|
173
210
|
});
|
|
174
211
|
|
|
175
212
|
// ui/src/interstitials/Hero.jsx
|
|
176
|
-
import
|
|
213
|
+
import React9 from "react";
|
|
177
214
|
import helpers from "@canopy-iiif/app/lib/components/featured.js";
|
|
178
215
|
|
|
179
216
|
// ui/src/interstitials/hero-utils.js
|
|
@@ -184,7 +221,7 @@ function computeHeroHeightStyle(height) {
|
|
|
184
221
|
}
|
|
185
222
|
|
|
186
223
|
// ui/src/layout/Button.jsx
|
|
187
|
-
import
|
|
224
|
+
import React7 from "react";
|
|
188
225
|
var VARIANTS = /* @__PURE__ */ new Set(["primary", "secondary"]);
|
|
189
226
|
function Button({
|
|
190
227
|
label,
|
|
@@ -205,7 +242,7 @@ function Button({
|
|
|
205
242
|
`canopy-button--${resolvedVariant}`,
|
|
206
243
|
className
|
|
207
244
|
].filter(Boolean).join(" ");
|
|
208
|
-
return /* @__PURE__ */
|
|
245
|
+
return /* @__PURE__ */ React7.createElement(
|
|
209
246
|
"a",
|
|
210
247
|
{
|
|
211
248
|
href,
|
|
@@ -219,13 +256,14 @@ function Button({
|
|
|
219
256
|
}
|
|
220
257
|
|
|
221
258
|
// ui/src/layout/ButtonWrapper.jsx
|
|
222
|
-
import
|
|
259
|
+
import React8 from "react";
|
|
223
260
|
function ButtonWrapper({ className = "", children, ...rest }) {
|
|
224
261
|
const classes = ["canopy-button-group", className].filter(Boolean).join(" ");
|
|
225
|
-
return /* @__PURE__ */
|
|
262
|
+
return /* @__PURE__ */ React8.createElement("div", { className: classes, ...rest }, children);
|
|
226
263
|
}
|
|
227
264
|
|
|
228
265
|
// ui/src/interstitials/Hero.jsx
|
|
266
|
+
var HERO_DEFAULT_SIZES_ATTR = "(min-width: 1024px) 1280px, 100vw";
|
|
229
267
|
var basePath = (() => {
|
|
230
268
|
try {
|
|
231
269
|
const raw = typeof process !== "undefined" && process && process.env ? String(process.env.CANOPY_BASE_PATH || "") : "";
|
|
@@ -300,6 +338,7 @@ function Hero({
|
|
|
300
338
|
item,
|
|
301
339
|
index,
|
|
302
340
|
random = true,
|
|
341
|
+
transition = "fade",
|
|
303
342
|
headline,
|
|
304
343
|
description,
|
|
305
344
|
links = [],
|
|
@@ -366,6 +405,15 @@ function Hero({
|
|
|
366
405
|
backgroundClassName,
|
|
367
406
|
className
|
|
368
407
|
].filter(Boolean).join(" ");
|
|
408
|
+
const normalizedTransition = (() => {
|
|
409
|
+
try {
|
|
410
|
+
const raw = transition == null ? "" : String(transition);
|
|
411
|
+
const normalized = raw.trim().toLowerCase();
|
|
412
|
+
return normalized === "slide" ? "slide" : "fade";
|
|
413
|
+
} catch (_) {
|
|
414
|
+
return "fade";
|
|
415
|
+
}
|
|
416
|
+
})();
|
|
369
417
|
const renderSlide = (slide, idx, { showVeil = true, captionVariant = "overlay" } = {}) => {
|
|
370
418
|
const safeHref = applyBasePath(slide.href || "#");
|
|
371
419
|
const isStaticCaption = captionVariant === "static";
|
|
@@ -374,45 +422,53 @@ function Hero({
|
|
|
374
422
|
showVeil ? "" : "canopy-interstitial__pane--flat",
|
|
375
423
|
isStaticCaption ? "canopy-interstitial__pane--static" : ""
|
|
376
424
|
].filter(Boolean).join(" ");
|
|
425
|
+
const buildImageProps = (className2) => {
|
|
426
|
+
if (!slide.thumbnail) return null;
|
|
427
|
+
const props = {
|
|
428
|
+
src: slide.thumbnail,
|
|
429
|
+
alt: "",
|
|
430
|
+
"aria-hidden": true,
|
|
431
|
+
className: className2,
|
|
432
|
+
loading: idx === 0 ? "eager" : "lazy"
|
|
433
|
+
};
|
|
434
|
+
if (slide.srcset) props.srcSet = slide.srcset;
|
|
435
|
+
if (slide.srcset)
|
|
436
|
+
props.sizes = slide.sizes || HERO_DEFAULT_SIZES_ATTR;
|
|
437
|
+
return props;
|
|
438
|
+
};
|
|
377
439
|
if (isStaticCaption) {
|
|
378
|
-
return /* @__PURE__ */
|
|
440
|
+
return /* @__PURE__ */ React9.createElement("div", { className: "swiper-slide", key: safeHref || idx }, /* @__PURE__ */ React9.createElement("article", { className: paneClassName }, slide.thumbnail ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__media-frame" }, /* @__PURE__ */ React9.createElement(
|
|
379
441
|
"img",
|
|
380
442
|
{
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
className: "canopy-interstitial__media canopy-interstitial__media--static",
|
|
385
|
-
loading: idx === 0 ? "eager" : "lazy"
|
|
443
|
+
...buildImageProps(
|
|
444
|
+
"canopy-interstitial__media canopy-interstitial__media--static"
|
|
445
|
+
)
|
|
386
446
|
}
|
|
387
|
-
)) : null, slide.title ? /* @__PURE__ */
|
|
447
|
+
)) : null, slide.title ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__caption canopy-interstitial__caption--static" }, /* @__PURE__ */ React9.createElement("a", { href: safeHref, className: "canopy-interstitial__caption-link" }, slide.title)) : null));
|
|
388
448
|
}
|
|
389
|
-
return /* @__PURE__ */
|
|
449
|
+
return /* @__PURE__ */ React9.createElement("div", { className: "swiper-slide", key: safeHref || idx }, /* @__PURE__ */ React9.createElement("article", { className: paneClassName }, slide.thumbnail ? /* @__PURE__ */ React9.createElement(
|
|
390
450
|
"img",
|
|
391
451
|
{
|
|
392
|
-
|
|
393
|
-
alt: "",
|
|
394
|
-
"aria-hidden": "true",
|
|
395
|
-
className: "canopy-interstitial__media",
|
|
396
|
-
loading: idx === 0 ? "eager" : "lazy"
|
|
452
|
+
...buildImageProps("canopy-interstitial__media")
|
|
397
453
|
}
|
|
398
|
-
) : null, showVeil ? /* @__PURE__ */
|
|
454
|
+
) : null, showVeil ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__veil", "aria-hidden": "true" }) : null, slide.title ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__caption" }, /* @__PURE__ */ React9.createElement("a", { href: safeHref, className: "canopy-interstitial__caption-link" }, slide.title)) : null));
|
|
399
455
|
};
|
|
400
|
-
const renderSlider = (options = {}) => /* @__PURE__ */
|
|
456
|
+
const renderSlider = (options = {}) => /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__slider swiper" }, /* @__PURE__ */ React9.createElement("div", { className: "swiper-wrapper" }, orderedSlides.map((slide, idx) => renderSlide(slide, idx, options))), /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__nav" }, /* @__PURE__ */ React9.createElement(
|
|
401
457
|
"button",
|
|
402
458
|
{
|
|
403
459
|
type: "button",
|
|
404
460
|
"aria-label": "Previous slide",
|
|
405
461
|
className: "canopy-interstitial__nav-btn canopy-interstitial__nav-btn--prev swiper-button-prev"
|
|
406
462
|
}
|
|
407
|
-
), /* @__PURE__ */
|
|
463
|
+
), /* @__PURE__ */ React9.createElement(
|
|
408
464
|
"button",
|
|
409
465
|
{
|
|
410
466
|
type: "button",
|
|
411
467
|
"aria-label": "Next slide",
|
|
412
468
|
className: "canopy-interstitial__nav-btn canopy-interstitial__nav-btn--next swiper-button-next"
|
|
413
469
|
}
|
|
414
|
-
)), /* @__PURE__ */
|
|
415
|
-
const overlayContent = /* @__PURE__ */
|
|
470
|
+
)), /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__pagination swiper-pagination" }));
|
|
471
|
+
const overlayContent = /* @__PURE__ */ React9.createElement(React9.Fragment, null, overlayTitle ? /* @__PURE__ */ React9.createElement("h1", { className: "canopy-interstitial__headline" }, overlayTitle) : null, derivedDescription ? /* @__PURE__ */ React9.createElement("p", { className: "canopy-interstitial__description" }, derivedDescription) : null, overlayLinks.length ? /* @__PURE__ */ React9.createElement(ButtonWrapper, { className: "canopy-interstitial__actions" }, overlayLinks.map((link) => /* @__PURE__ */ React9.createElement(
|
|
416
472
|
Button,
|
|
417
473
|
{
|
|
418
474
|
key: `${link.href}-${link.title}`,
|
|
@@ -423,20 +479,21 @@ function Hero({
|
|
|
423
479
|
}
|
|
424
480
|
))) : null);
|
|
425
481
|
const cleanedProps = sanitizeRest(rest);
|
|
426
|
-
return /* @__PURE__ */
|
|
482
|
+
return /* @__PURE__ */ React9.createElement(
|
|
427
483
|
"section",
|
|
428
484
|
{
|
|
429
485
|
className: containerClassName,
|
|
430
486
|
"data-canopy-hero-slider": "1",
|
|
487
|
+
"data-transition": normalizedTransition,
|
|
431
488
|
style: heroStyles,
|
|
432
489
|
...cleanedProps
|
|
433
490
|
},
|
|
434
|
-
/* @__PURE__ */
|
|
491
|
+
/* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__layout" }, /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__panel" }, /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__body" }, overlayContent)), /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__media-group" }, renderSlider({ showVeil: false, captionVariant: "static" })))
|
|
435
492
|
);
|
|
436
493
|
}
|
|
437
494
|
|
|
438
495
|
// ui/src/layout/SubNavigation.jsx
|
|
439
|
-
import
|
|
496
|
+
import React10 from "react";
|
|
440
497
|
import navigationHelpers from "@canopy-iiif/app/lib/components/navigation.js";
|
|
441
498
|
function resolveRelativeCandidate(page, current) {
|
|
442
499
|
if (page && typeof page.relativePath === "string" && page.relativePath) return page.relativePath;
|
|
@@ -461,14 +518,14 @@ function renderNodes(nodes, parentKey = "node") {
|
|
|
461
518
|
if (node.isActive) classes.push("is-active");
|
|
462
519
|
const linkClass = classes.join(" ");
|
|
463
520
|
const Tag = node.href ? "a" : "span";
|
|
464
|
-
return /* @__PURE__ */
|
|
521
|
+
return /* @__PURE__ */ React10.createElement(
|
|
465
522
|
"li",
|
|
466
523
|
{
|
|
467
524
|
key,
|
|
468
525
|
className: "canopy-sub-navigation__item",
|
|
469
526
|
"data-depth": depth
|
|
470
527
|
},
|
|
471
|
-
/* @__PURE__ */
|
|
528
|
+
/* @__PURE__ */ React10.createElement(
|
|
472
529
|
Tag,
|
|
473
530
|
{
|
|
474
531
|
className: linkClass,
|
|
@@ -477,7 +534,7 @@ function renderNodes(nodes, parentKey = "node") {
|
|
|
477
534
|
},
|
|
478
535
|
node.title || node.slug
|
|
479
536
|
),
|
|
480
|
-
showChildren ? /* @__PURE__ */
|
|
537
|
+
showChildren ? /* @__PURE__ */ React10.createElement("ul", { className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested", role: "list" }, renderNodes(node.children, key)) : null
|
|
481
538
|
);
|
|
482
539
|
});
|
|
483
540
|
}
|
|
@@ -491,12 +548,12 @@ function SubNavigation({
|
|
|
491
548
|
ariaLabel
|
|
492
549
|
}) {
|
|
493
550
|
const PageContext = navigationHelpers && navigationHelpers.getPageContext ? navigationHelpers.getPageContext() : null;
|
|
494
|
-
const context = PageContext ?
|
|
551
|
+
const context = PageContext ? React10.useContext(PageContext) : null;
|
|
495
552
|
const contextNavigation = context && context.navigation ? context.navigation : null;
|
|
496
553
|
const contextPage = context && context.page ? context.page : null;
|
|
497
554
|
const effectiveNavigation = navigationProp || contextNavigation;
|
|
498
555
|
const effectivePage = page || contextPage;
|
|
499
|
-
const resolvedNavigation =
|
|
556
|
+
const resolvedNavigation = React10.useMemo(() => {
|
|
500
557
|
if (effectiveNavigation && effectiveNavigation.root) return effectiveNavigation;
|
|
501
558
|
const candidate = resolveRelativeCandidate(effectivePage, current);
|
|
502
559
|
if (!candidate) return effectiveNavigation || null;
|
|
@@ -520,15 +577,15 @@ function SubNavigation({
|
|
|
520
577
|
if (!Object.prototype.hasOwnProperty.call(inlineStyle, "--sub-nav-indent")) {
|
|
521
578
|
inlineStyle["--sub-nav-indent"] = "0.85rem";
|
|
522
579
|
}
|
|
523
|
-
return /* @__PURE__ */
|
|
580
|
+
return /* @__PURE__ */ React10.createElement("nav", { className: combinedClassName, style: inlineStyle, "aria-label": navLabel }, finalHeading ? /* @__PURE__ */ React10.createElement("div", { className: "canopy-sub-navigation__heading" }, finalHeading) : null, /* @__PURE__ */ React10.createElement("ul", { className: "canopy-sub-navigation__list", role: "list" }, renderNodes([rootNode], rootNode.slug || "root")));
|
|
524
581
|
}
|
|
525
582
|
|
|
526
583
|
// ui/src/layout/Layout.jsx
|
|
527
|
-
import
|
|
584
|
+
import React12 from "react";
|
|
528
585
|
import navigationHelpers2 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
529
586
|
|
|
530
587
|
// ui/src/layout/ContentNavigation.jsx
|
|
531
|
-
import
|
|
588
|
+
import React11 from "react";
|
|
532
589
|
var SCROLL_OFFSET_REM = 1.618;
|
|
533
590
|
function depthIndex(depth) {
|
|
534
591
|
return Math.max(0, Math.min(5, (depth || 1) - 1));
|
|
@@ -543,12 +600,12 @@ function ContentNavigation({
|
|
|
543
600
|
ariaLabel
|
|
544
601
|
}) {
|
|
545
602
|
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
546
|
-
const savedDepthsRef =
|
|
603
|
+
const savedDepthsRef = React11.useRef(null);
|
|
547
604
|
if ((!items || !items.length) && !headingId) return null;
|
|
548
605
|
const combinedClassName = ["canopy-sub-navigation canopy-content-navigation", className].filter(Boolean).join(" ");
|
|
549
606
|
const effectiveHeading = heading || pageTitle || null;
|
|
550
607
|
const navLabel = ariaLabel || (effectiveHeading ? `${effectiveHeading} navigation` : "Section navigation");
|
|
551
|
-
const getSavedDepth =
|
|
608
|
+
const getSavedDepth = React11.useCallback(
|
|
552
609
|
(id, fallback) => {
|
|
553
610
|
if (!id) return fallback;
|
|
554
611
|
if (!savedDepthsRef.current) savedDepthsRef.current = /* @__PURE__ */ new Map();
|
|
@@ -559,7 +616,7 @@ function ContentNavigation({
|
|
|
559
616
|
},
|
|
560
617
|
[]
|
|
561
618
|
);
|
|
562
|
-
const headingEntries =
|
|
619
|
+
const headingEntries = React11.useMemo(() => {
|
|
563
620
|
const entries = [];
|
|
564
621
|
const seen = /* @__PURE__ */ new Set();
|
|
565
622
|
if (headingId) {
|
|
@@ -583,12 +640,12 @@ function ContentNavigation({
|
|
|
583
640
|
return entries;
|
|
584
641
|
}, [headingId, items, getSavedDepth]);
|
|
585
642
|
const fallbackId = headingEntries.length ? headingEntries[0].id : headingId || null;
|
|
586
|
-
const [activeId, setActiveId] =
|
|
587
|
-
const activeIdRef =
|
|
588
|
-
|
|
643
|
+
const [activeId, setActiveId] = React11.useState(fallbackId);
|
|
644
|
+
const activeIdRef = React11.useRef(activeId);
|
|
645
|
+
React11.useEffect(() => {
|
|
589
646
|
activeIdRef.current = activeId;
|
|
590
647
|
}, [activeId]);
|
|
591
|
-
|
|
648
|
+
React11.useEffect(() => {
|
|
592
649
|
if (!headingEntries.length) return;
|
|
593
650
|
if (!headingEntries.some((entry) => entry.id === activeIdRef.current)) {
|
|
594
651
|
const next = headingEntries[0].id;
|
|
@@ -596,7 +653,7 @@ function ContentNavigation({
|
|
|
596
653
|
setActiveId(next);
|
|
597
654
|
}
|
|
598
655
|
}, [headingEntries]);
|
|
599
|
-
const computeOffsetPx =
|
|
656
|
+
const computeOffsetPx = React11.useCallback(() => {
|
|
600
657
|
if (!isBrowser) return 0;
|
|
601
658
|
try {
|
|
602
659
|
const root = document.documentElement;
|
|
@@ -606,8 +663,8 @@ function ContentNavigation({
|
|
|
606
663
|
return 0;
|
|
607
664
|
}
|
|
608
665
|
}, [isBrowser]);
|
|
609
|
-
const headingElementsRef =
|
|
610
|
-
const updateActiveFromElements =
|
|
666
|
+
const headingElementsRef = React11.useRef([]);
|
|
667
|
+
const updateActiveFromElements = React11.useCallback(
|
|
611
668
|
(elements) => {
|
|
612
669
|
if (!elements || !elements.length) return;
|
|
613
670
|
const offset = computeOffsetPx();
|
|
@@ -627,7 +684,7 @@ function ContentNavigation({
|
|
|
627
684
|
},
|
|
628
685
|
[computeOffsetPx]
|
|
629
686
|
);
|
|
630
|
-
|
|
687
|
+
React11.useEffect(() => {
|
|
631
688
|
if (!isBrowser) return void 0;
|
|
632
689
|
const elements = headingEntries.map((entry) => {
|
|
633
690
|
const element = document.getElementById(entry.id);
|
|
@@ -653,7 +710,7 @@ function ContentNavigation({
|
|
|
653
710
|
window.removeEventListener("resize", handle);
|
|
654
711
|
};
|
|
655
712
|
}, [headingEntries, isBrowser, updateActiveFromElements]);
|
|
656
|
-
const handleAnchorClick =
|
|
713
|
+
const handleAnchorClick = React11.useCallback(
|
|
657
714
|
(event, targetId, options = {}) => {
|
|
658
715
|
var _a;
|
|
659
716
|
try {
|
|
@@ -684,7 +741,7 @@ function ContentNavigation({
|
|
|
684
741
|
},
|
|
685
742
|
[computeOffsetPx, headingEntries, headingId, isBrowser]
|
|
686
743
|
);
|
|
687
|
-
const renderNodes2 =
|
|
744
|
+
const renderNodes2 = React11.useCallback(
|
|
688
745
|
(nodes) => {
|
|
689
746
|
if (!nodes || !nodes.length) return null;
|
|
690
747
|
return nodes.map((node) => {
|
|
@@ -693,7 +750,7 @@ function ContentNavigation({
|
|
|
693
750
|
const depth = node.depth || node.level || getSavedDepth(id, 2);
|
|
694
751
|
const idx = depthIndex(depth);
|
|
695
752
|
const isActive = id && activeId === id;
|
|
696
|
-
return /* @__PURE__ */
|
|
753
|
+
return /* @__PURE__ */ React11.createElement("li", { key: id || node.title, className: "canopy-sub-navigation__item", "data-depth": idx }, /* @__PURE__ */ React11.createElement(
|
|
697
754
|
"a",
|
|
698
755
|
{
|
|
699
756
|
className: `canopy-sub-navigation__link depth-${idx}${isActive ? " is-active" : ""}`,
|
|
@@ -702,7 +759,7 @@ function ContentNavigation({
|
|
|
702
759
|
"aria-current": isActive ? "location" : void 0
|
|
703
760
|
},
|
|
704
761
|
node.title
|
|
705
|
-
), node.children && node.children.length ? /* @__PURE__ */
|
|
762
|
+
), node.children && node.children.length ? /* @__PURE__ */ React11.createElement(
|
|
706
763
|
"ul",
|
|
707
764
|
{
|
|
708
765
|
className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested",
|
|
@@ -715,7 +772,7 @@ function ContentNavigation({
|
|
|
715
772
|
[handleAnchorClick, activeId, getSavedDepth]
|
|
716
773
|
);
|
|
717
774
|
const nestedItems = renderNodes2(items);
|
|
718
|
-
const topLink = headingId ? /* @__PURE__ */
|
|
775
|
+
const topLink = headingId ? /* @__PURE__ */ React11.createElement("li", { className: "canopy-sub-navigation__item", "data-depth": 0 }, /* @__PURE__ */ React11.createElement(
|
|
719
776
|
"a",
|
|
720
777
|
{
|
|
721
778
|
className: `canopy-sub-navigation__link depth-0${activeId === headingId ? " is-active" : ""}`,
|
|
@@ -724,7 +781,7 @@ function ContentNavigation({
|
|
|
724
781
|
"aria-current": activeId === headingId ? "location" : void 0
|
|
725
782
|
},
|
|
726
783
|
effectiveHeading || pageTitle || headingId
|
|
727
|
-
), nestedItems ? /* @__PURE__ */
|
|
784
|
+
), nestedItems ? /* @__PURE__ */ React11.createElement(
|
|
728
785
|
"ul",
|
|
729
786
|
{
|
|
730
787
|
className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested",
|
|
@@ -732,7 +789,7 @@ function ContentNavigation({
|
|
|
732
789
|
},
|
|
733
790
|
nestedItems
|
|
734
791
|
) : null) : null;
|
|
735
|
-
return /* @__PURE__ */
|
|
792
|
+
return /* @__PURE__ */ React11.createElement("nav", { className: combinedClassName, style, "aria-label": navLabel }, /* @__PURE__ */ React11.createElement("ul", { className: "canopy-sub-navigation__list", role: "list" }, topLink || nestedItems));
|
|
736
793
|
}
|
|
737
794
|
|
|
738
795
|
// ui/src/layout/Layout.jsx
|
|
@@ -764,10 +821,10 @@ function buildHeadingTree(headings) {
|
|
|
764
821
|
}
|
|
765
822
|
function buildNavigationAside(sidebar, className) {
|
|
766
823
|
if (!sidebar) {
|
|
767
|
-
return /* @__PURE__ */
|
|
824
|
+
return /* @__PURE__ */ React12.createElement(SubNavigation, { className });
|
|
768
825
|
}
|
|
769
826
|
if (typeof sidebar === "function") {
|
|
770
|
-
return
|
|
827
|
+
return React12.createElement(sidebar);
|
|
771
828
|
}
|
|
772
829
|
return sidebar;
|
|
773
830
|
}
|
|
@@ -784,26 +841,26 @@ function Layout({
|
|
|
784
841
|
...rest
|
|
785
842
|
}) {
|
|
786
843
|
const PageContext = navigationHelpers2 && typeof navigationHelpers2.getPageContext === "function" ? navigationHelpers2.getPageContext() : null;
|
|
787
|
-
const context = PageContext ?
|
|
788
|
-
const pageHeadings =
|
|
844
|
+
const context = PageContext ? React12.useContext(PageContext) : null;
|
|
845
|
+
const pageHeadings = React12.useMemo(() => {
|
|
789
846
|
const headings = context && context.page ? context.page.headings : null;
|
|
790
847
|
return Array.isArray(headings) ? headings : [];
|
|
791
848
|
}, [context]);
|
|
792
|
-
const contentHeading =
|
|
849
|
+
const contentHeading = React12.useMemo(() => {
|
|
793
850
|
const first = pageHeadings.find((heading) => {
|
|
794
851
|
const depth = heading && (heading.depth || heading.level);
|
|
795
852
|
return depth === 1;
|
|
796
853
|
});
|
|
797
854
|
return first && first.title ? first.title : null;
|
|
798
855
|
}, [pageHeadings]);
|
|
799
|
-
const headingAnchorId =
|
|
856
|
+
const headingAnchorId = React12.useMemo(() => {
|
|
800
857
|
const first = pageHeadings.find((heading) => {
|
|
801
858
|
const depth = heading && (heading.depth || heading.level);
|
|
802
859
|
return depth === 1;
|
|
803
860
|
});
|
|
804
861
|
return first && first.id ? first.id : null;
|
|
805
862
|
}, [pageHeadings]);
|
|
806
|
-
const headingTree =
|
|
863
|
+
const headingTree = React12.useMemo(
|
|
807
864
|
() => buildHeadingTree(pageHeadings),
|
|
808
865
|
[pageHeadings]
|
|
809
866
|
);
|
|
@@ -828,21 +885,17 @@ function Layout({
|
|
|
828
885
|
className
|
|
829
886
|
].filter(Boolean).join(" ");
|
|
830
887
|
const leftAsideClassName = [
|
|
831
|
-
"mt-8 md:mt-0 md:order-1 md:sticky md:top-24 md:max-h-[calc(100vh-6rem)] md:overflow-y-auto text-
|
|
888
|
+
"mt-8 md:mt-0 md:order-1 md:sticky md:top-24 md:max-h-[calc(100vh-6rem)] md:overflow-y-auto text-slate-600",
|
|
832
889
|
sidebarClassName
|
|
833
890
|
].filter(Boolean).join(" ");
|
|
834
891
|
const contentOrderClass = showLeftColumn ? "md:order-2" : hasContentNavigation ? "md:order-1" : "";
|
|
835
|
-
const contentClassNames = [
|
|
836
|
-
"space-y-6",
|
|
837
|
-
contentOrderClass,
|
|
838
|
-
contentClassName
|
|
839
|
-
].filter(Boolean).join(" ");
|
|
892
|
+
const contentClassNames = ["space-y-6", contentOrderClass, contentClassName].filter(Boolean).join(" ");
|
|
840
893
|
const contentNavigationAsideClassName = [
|
|
841
|
-
"hidden md:block md:order-3 mt-8 md:mt-0 md:sticky md:top-24 md:max-h-[calc(100vh-6rem)] md:overflow-y-auto text-
|
|
894
|
+
"hidden md:block md:order-3 mt-8 md:mt-0 md:sticky md:top-24 md:max-h-[calc(100vh-6rem)] md:overflow-y-auto text-slate-600",
|
|
842
895
|
contentNavigationClassName
|
|
843
896
|
].filter(Boolean).join(" ");
|
|
844
897
|
const sidebarNode = showLeftColumn ? buildNavigationAside(sidebar, sidebarClassName) : null;
|
|
845
|
-
return /* @__PURE__ */
|
|
898
|
+
return /* @__PURE__ */ React12.createElement("div", { className: containerClassName, ...rest }, showLeftColumn ? /* @__PURE__ */ React12.createElement("aside", { className: leftAsideClassName }, sidebarNode) : null, /* @__PURE__ */ React12.createElement("div", { className: contentClassNames }, children), hasContentNavigation ? /* @__PURE__ */ React12.createElement("aside", { className: contentNavigationAsideClassName }, /* @__PURE__ */ React12.createElement(
|
|
846
899
|
ContentNavigation,
|
|
847
900
|
{
|
|
848
901
|
items: headingTree,
|
|
@@ -854,17 +907,17 @@ function Layout({
|
|
|
854
907
|
}
|
|
855
908
|
|
|
856
909
|
// ui/src/layout/CanopyHeader.jsx
|
|
857
|
-
import
|
|
910
|
+
import React19 from "react";
|
|
858
911
|
|
|
859
912
|
// ui/src/search/SearchPanel.jsx
|
|
860
|
-
import
|
|
913
|
+
import React16 from "react";
|
|
861
914
|
|
|
862
915
|
// ui/src/Icons.jsx
|
|
863
|
-
import
|
|
864
|
-
var MagnifyingGlassIcon = (props) => /* @__PURE__ */
|
|
916
|
+
import React13 from "react";
|
|
917
|
+
var MagnifyingGlassIcon = (props) => /* @__PURE__ */ React13.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", ...props }, /* @__PURE__ */ React13.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" }));
|
|
865
918
|
|
|
866
919
|
// ui/src/search/SearchPanelForm.jsx
|
|
867
|
-
import
|
|
920
|
+
import React14 from "react";
|
|
868
921
|
function readBasePath() {
|
|
869
922
|
const normalize = (val) => {
|
|
870
923
|
const raw = typeof val === "string" ? val.trim() : "";
|
|
@@ -927,18 +980,18 @@ function SearchPanelForm(props = {}) {
|
|
|
927
980
|
clearLabel = "Clear search"
|
|
928
981
|
} = props || {};
|
|
929
982
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
930
|
-
const action =
|
|
983
|
+
const action = React14.useMemo(
|
|
931
984
|
() => resolveSearchPath(searchPath),
|
|
932
985
|
[searchPath]
|
|
933
986
|
);
|
|
934
|
-
const autoId = typeof
|
|
935
|
-
const [fallbackId] =
|
|
987
|
+
const autoId = typeof React14.useId === "function" ? React14.useId() : void 0;
|
|
988
|
+
const [fallbackId] = React14.useState(
|
|
936
989
|
() => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`
|
|
937
990
|
);
|
|
938
991
|
const inputId = inputIdProp || autoId || fallbackId;
|
|
939
|
-
const inputRef =
|
|
940
|
-
const [hasValue, setHasValue] =
|
|
941
|
-
const focusInput =
|
|
992
|
+
const inputRef = React14.useRef(null);
|
|
993
|
+
const [hasValue, setHasValue] = React14.useState(false);
|
|
994
|
+
const focusInput = React14.useCallback(() => {
|
|
942
995
|
const el = inputRef.current;
|
|
943
996
|
if (!el) return;
|
|
944
997
|
if (document.activeElement === el) return;
|
|
@@ -951,7 +1004,7 @@ function SearchPanelForm(props = {}) {
|
|
|
951
1004
|
}
|
|
952
1005
|
}
|
|
953
1006
|
}, []);
|
|
954
|
-
const handlePointerDown =
|
|
1007
|
+
const handlePointerDown = React14.useCallback(
|
|
955
1008
|
(event) => {
|
|
956
1009
|
const target = event.target;
|
|
957
1010
|
if (target && typeof target.closest === "function") {
|
|
@@ -963,23 +1016,23 @@ function SearchPanelForm(props = {}) {
|
|
|
963
1016
|
},
|
|
964
1017
|
[focusInput]
|
|
965
1018
|
);
|
|
966
|
-
|
|
1019
|
+
React14.useEffect(() => {
|
|
967
1020
|
const el = inputRef.current;
|
|
968
1021
|
if (!el) return;
|
|
969
1022
|
if (el.value && el.value.trim()) {
|
|
970
1023
|
setHasValue(true);
|
|
971
1024
|
}
|
|
972
1025
|
}, []);
|
|
973
|
-
const handleInputChange =
|
|
1026
|
+
const handleInputChange = React14.useCallback((event) => {
|
|
974
1027
|
var _a;
|
|
975
1028
|
const nextHasValue = Boolean(
|
|
976
1029
|
((_a = event == null ? void 0 : event.target) == null ? void 0 : _a.value) && event.target.value.trim()
|
|
977
1030
|
);
|
|
978
1031
|
setHasValue(nextHasValue);
|
|
979
1032
|
}, []);
|
|
980
|
-
const handleClear =
|
|
1033
|
+
const handleClear = React14.useCallback((event) => {
|
|
981
1034
|
}, []);
|
|
982
|
-
const handleClearKey =
|
|
1035
|
+
const handleClearKey = React14.useCallback(
|
|
983
1036
|
(event) => {
|
|
984
1037
|
if (event.key === "Enter" || event.key === " ") {
|
|
985
1038
|
event.preventDefault();
|
|
@@ -988,7 +1041,7 @@ function SearchPanelForm(props = {}) {
|
|
|
988
1041
|
},
|
|
989
1042
|
[handleClear]
|
|
990
1043
|
);
|
|
991
|
-
return /* @__PURE__ */
|
|
1044
|
+
return /* @__PURE__ */ React14.createElement(
|
|
992
1045
|
"form",
|
|
993
1046
|
{
|
|
994
1047
|
action,
|
|
@@ -1000,7 +1053,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1000
1053
|
onPointerDown: handlePointerDown,
|
|
1001
1054
|
"data-has-value": hasValue ? "1" : "0"
|
|
1002
1055
|
},
|
|
1003
|
-
/* @__PURE__ */
|
|
1056
|
+
/* @__PURE__ */ React14.createElement("label", { htmlFor: inputId, className: "canopy-search-form__label" }, /* @__PURE__ */ React14.createElement(MagnifyingGlassIcon, { className: "canopy-search-form__icon" }), /* @__PURE__ */ React14.createElement(
|
|
1004
1057
|
"input",
|
|
1005
1058
|
{
|
|
1006
1059
|
id: inputId,
|
|
@@ -1016,7 +1069,7 @@ function SearchPanelForm(props = {}) {
|
|
|
1016
1069
|
onInput: handleInputChange
|
|
1017
1070
|
}
|
|
1018
1071
|
)),
|
|
1019
|
-
hasValue ? /* @__PURE__ */
|
|
1072
|
+
hasValue ? /* @__PURE__ */ React14.createElement(
|
|
1020
1073
|
"button",
|
|
1021
1074
|
{
|
|
1022
1075
|
type: "button",
|
|
@@ -1029,32 +1082,31 @@ function SearchPanelForm(props = {}) {
|
|
|
1029
1082
|
},
|
|
1030
1083
|
"\xD7"
|
|
1031
1084
|
) : null,
|
|
1032
|
-
/* @__PURE__ */
|
|
1085
|
+
/* @__PURE__ */ React14.createElement(
|
|
1033
1086
|
"button",
|
|
1034
1087
|
{
|
|
1035
1088
|
type: "submit",
|
|
1036
1089
|
"data-canopy-search-form-trigger": "submit",
|
|
1037
1090
|
className: "canopy-search-form__submit"
|
|
1038
1091
|
},
|
|
1039
|
-
|
|
1040
|
-
/* @__PURE__ */ React13.createElement("span", { "aria-hidden": true, className: "canopy-search-form__shortcut" }, /* @__PURE__ */ React13.createElement("span", null, "\u2318"), /* @__PURE__ */ React13.createElement("span", null, "K"))
|
|
1092
|
+
text
|
|
1041
1093
|
)
|
|
1042
1094
|
);
|
|
1043
1095
|
}
|
|
1044
1096
|
|
|
1045
1097
|
// ui/src/search/SearchPanelTeaserResults.jsx
|
|
1046
|
-
import
|
|
1098
|
+
import React15 from "react";
|
|
1047
1099
|
function SearchPanelTeaserResults(props = {}) {
|
|
1048
1100
|
const { style, className } = props || {};
|
|
1049
1101
|
const classes = ["canopy-search-teaser", className].filter(Boolean).join(" ");
|
|
1050
|
-
return /* @__PURE__ */
|
|
1102
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1051
1103
|
"div",
|
|
1052
1104
|
{
|
|
1053
1105
|
"data-canopy-search-form-panel": true,
|
|
1054
1106
|
className: classes || void 0,
|
|
1055
1107
|
style
|
|
1056
1108
|
},
|
|
1057
|
-
/* @__PURE__ */
|
|
1109
|
+
/* @__PURE__ */ React15.createElement("div", { id: "cplist" })
|
|
1058
1110
|
);
|
|
1059
1111
|
}
|
|
1060
1112
|
|
|
@@ -1075,11 +1127,11 @@ function SearchPanel(props = {}) {
|
|
|
1075
1127
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
1076
1128
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
1077
1129
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
1078
|
-
return /* @__PURE__ */
|
|
1130
|
+
return /* @__PURE__ */ React16.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React16.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React16.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React16.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React16.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
|
|
1079
1131
|
}
|
|
1080
1132
|
|
|
1081
1133
|
// ui/src/layout/CanopyBrand.jsx
|
|
1082
|
-
import
|
|
1134
|
+
import React17 from "react";
|
|
1083
1135
|
function CanopyBrand(props = {}) {
|
|
1084
1136
|
const {
|
|
1085
1137
|
labelId,
|
|
@@ -1090,11 +1142,11 @@ function CanopyBrand(props = {}) {
|
|
|
1090
1142
|
} = props || {};
|
|
1091
1143
|
const spanProps = labelId ? { id: labelId } : {};
|
|
1092
1144
|
const classes = ["canopy-logo", className].filter(Boolean).join(" ");
|
|
1093
|
-
return /* @__PURE__ */
|
|
1145
|
+
return /* @__PURE__ */ React17.createElement("a", { href, className: classes }, typeof Logo === "function" ? /* @__PURE__ */ React17.createElement(Logo, null) : null, /* @__PURE__ */ React17.createElement("span", { ...spanProps }, label));
|
|
1094
1146
|
}
|
|
1095
1147
|
|
|
1096
1148
|
// ui/src/layout/CanopyModal.jsx
|
|
1097
|
-
import
|
|
1149
|
+
import React18 from "react";
|
|
1098
1150
|
function CanopyModal(props = {}) {
|
|
1099
1151
|
const {
|
|
1100
1152
|
id,
|
|
@@ -1145,7 +1197,7 @@ function CanopyModal(props = {}) {
|
|
|
1145
1197
|
if (padded) bodyClasses.push("canopy-modal__body--padded");
|
|
1146
1198
|
if (bodyClassName) bodyClasses.push(bodyClassName);
|
|
1147
1199
|
const bodyClassNameValue = bodyClasses.join(" ");
|
|
1148
|
-
return /* @__PURE__ */
|
|
1200
|
+
return /* @__PURE__ */ React18.createElement("div", { ...modalProps }, /* @__PURE__ */ React18.createElement("div", { className: "canopy-modal__panel" }, /* @__PURE__ */ React18.createElement("button", { ...closeButtonProps }, /* @__PURE__ */ React18.createElement(
|
|
1149
1201
|
"svg",
|
|
1150
1202
|
{
|
|
1151
1203
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -1155,8 +1207,8 @@ function CanopyModal(props = {}) {
|
|
|
1155
1207
|
strokeWidth: "1.5",
|
|
1156
1208
|
className: "canopy-modal__close-icon"
|
|
1157
1209
|
},
|
|
1158
|
-
/* @__PURE__ */
|
|
1159
|
-
), /* @__PURE__ */
|
|
1210
|
+
/* @__PURE__ */ React18.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 6l12 12M6 18L18 6" })
|
|
1211
|
+
), /* @__PURE__ */ React18.createElement("span", { className: "sr-only" }, closeLabel)), /* @__PURE__ */ React18.createElement("div", { className: bodyClassNameValue }, label ? /* @__PURE__ */ React18.createElement("div", { className: "canopy-modal__brand" }, /* @__PURE__ */ React18.createElement(
|
|
1160
1212
|
CanopyBrand,
|
|
1161
1213
|
{
|
|
1162
1214
|
labelId: resolvedLabelId,
|
|
@@ -1360,7 +1412,7 @@ function HeaderScript() {
|
|
|
1360
1412
|
});
|
|
1361
1413
|
})();
|
|
1362
1414
|
`;
|
|
1363
|
-
return /* @__PURE__ */
|
|
1415
|
+
return /* @__PURE__ */ React19.createElement(
|
|
1364
1416
|
"script",
|
|
1365
1417
|
{
|
|
1366
1418
|
dangerouslySetInnerHTML: {
|
|
@@ -1371,7 +1423,9 @@ function HeaderScript() {
|
|
|
1371
1423
|
}
|
|
1372
1424
|
function ensureArray(navLinks) {
|
|
1373
1425
|
if (!Array.isArray(navLinks)) return [];
|
|
1374
|
-
return navLinks.filter(
|
|
1426
|
+
return navLinks.filter(
|
|
1427
|
+
(link) => link && typeof link === "object" && typeof link.href === "string"
|
|
1428
|
+
);
|
|
1375
1429
|
}
|
|
1376
1430
|
function CanopyHeader(props = {}) {
|
|
1377
1431
|
const {
|
|
@@ -1384,59 +1438,98 @@ function CanopyHeader(props = {}) {
|
|
|
1384
1438
|
logo: SiteLogo
|
|
1385
1439
|
} = props;
|
|
1386
1440
|
const navLinks = ensureArray(navLinksProp);
|
|
1387
|
-
return /* @__PURE__ */
|
|
1388
|
-
|
|
1389
|
-
{
|
|
1390
|
-
label: title,
|
|
1391
|
-
href: brandHref,
|
|
1392
|
-
className: "canopy-header__brand-link",
|
|
1393
|
-
Logo: SiteLogo
|
|
1394
|
-
}
|
|
1395
|
-
)), /* @__PURE__ */ React18.createElement("div", { className: "canopy-header__desktop-search" }, /* @__PURE__ */ React18.createElement(SearchPanel, { label: searchLabel, hotkey: searchHotkey, placeholder: searchPlaceholder })), /* @__PURE__ */ React18.createElement("nav", { className: "canopy-nav-links canopy-header__desktop-nav", "aria-label": "Primary navigation" }, navLinks.map((link) => /* @__PURE__ */ React18.createElement("a", { key: link.href, href: link.href }, link.label || link.href))), /* @__PURE__ */ React18.createElement("div", { className: "canopy-header__actions" }, /* @__PURE__ */ React18.createElement(
|
|
1396
|
-
"button",
|
|
1441
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(
|
|
1442
|
+
"header",
|
|
1397
1443
|
{
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
"
|
|
1401
|
-
"aria-controls": "canopy-modal-search",
|
|
1402
|
-
"aria-expanded": "false",
|
|
1403
|
-
"data-canopy-header-toggle": "search"
|
|
1444
|
+
className: "canopy-header",
|
|
1445
|
+
"data-mobile-nav": "closed",
|
|
1446
|
+
"data-mobile-search": "closed"
|
|
1404
1447
|
},
|
|
1405
|
-
/* @__PURE__ */
|
|
1406
|
-
|
|
1448
|
+
/* @__PURE__ */ React19.createElement("div", { className: "canopy-header__brand" }, /* @__PURE__ */ React19.createElement(
|
|
1449
|
+
CanopyBrand,
|
|
1407
1450
|
{
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1451
|
+
label: title,
|
|
1452
|
+
href: brandHref,
|
|
1453
|
+
className: "canopy-header__brand-link",
|
|
1454
|
+
Logo: SiteLogo
|
|
1455
|
+
}
|
|
1456
|
+
)),
|
|
1457
|
+
/* @__PURE__ */ React19.createElement("div", { className: "canopy-header__desktop-search" }, /* @__PURE__ */ React19.createElement(
|
|
1458
|
+
SearchPanel,
|
|
1459
|
+
{
|
|
1460
|
+
label: searchLabel,
|
|
1461
|
+
hotkey: searchHotkey,
|
|
1462
|
+
placeholder: searchPlaceholder
|
|
1463
|
+
}
|
|
1464
|
+
)),
|
|
1465
|
+
/* @__PURE__ */ React19.createElement(
|
|
1466
|
+
"nav",
|
|
1467
|
+
{
|
|
1468
|
+
className: "canopy-nav-links canopy-header__desktop-nav",
|
|
1469
|
+
"aria-label": "Primary navigation"
|
|
1414
1470
|
},
|
|
1415
|
-
/* @__PURE__ */
|
|
1416
|
-
)
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
{
|
|
1420
|
-
type: "button",
|
|
1421
|
-
className: "canopy-header__icon-button canopy-header__menu",
|
|
1422
|
-
"aria-label": "Open navigation",
|
|
1423
|
-
"aria-controls": "canopy-modal-nav",
|
|
1424
|
-
"aria-expanded": "false",
|
|
1425
|
-
"data-canopy-header-toggle": "nav"
|
|
1426
|
-
},
|
|
1427
|
-
/* @__PURE__ */ React18.createElement(
|
|
1428
|
-
"svg",
|
|
1471
|
+
navLinks.map((link) => /* @__PURE__ */ React19.createElement("a", { key: link.href, href: link.href }, link.label || link.href))
|
|
1472
|
+
),
|
|
1473
|
+
/* @__PURE__ */ React19.createElement("div", { className: "canopy-header__actions" }, /* @__PURE__ */ React19.createElement(
|
|
1474
|
+
"button",
|
|
1429
1475
|
{
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1476
|
+
type: "button",
|
|
1477
|
+
className: "canopy-header__icon-button canopy-header__search-trigger",
|
|
1478
|
+
"aria-label": "Open search",
|
|
1479
|
+
"aria-controls": "canopy-modal-search",
|
|
1480
|
+
"aria-expanded": "false",
|
|
1481
|
+
"data-canopy-header-toggle": "search"
|
|
1436
1482
|
},
|
|
1437
|
-
/* @__PURE__ */
|
|
1438
|
-
|
|
1439
|
-
|
|
1483
|
+
/* @__PURE__ */ React19.createElement(
|
|
1484
|
+
"svg",
|
|
1485
|
+
{
|
|
1486
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1487
|
+
viewBox: "0 0 24 24",
|
|
1488
|
+
fill: "none",
|
|
1489
|
+
stroke: "currentColor",
|
|
1490
|
+
strokeWidth: "1.5",
|
|
1491
|
+
className: "canopy-header__search-icon"
|
|
1492
|
+
},
|
|
1493
|
+
/* @__PURE__ */ React19.createElement(
|
|
1494
|
+
"path",
|
|
1495
|
+
{
|
|
1496
|
+
strokeLinecap: "round",
|
|
1497
|
+
strokeLinejoin: "round",
|
|
1498
|
+
d: "m21 21-3.8-3.8M10.5 18a7.5 7.5 0 1 1 0-15 7.5 7.5 0 0 1 0 15Z"
|
|
1499
|
+
}
|
|
1500
|
+
)
|
|
1501
|
+
)
|
|
1502
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1503
|
+
"button",
|
|
1504
|
+
{
|
|
1505
|
+
type: "button",
|
|
1506
|
+
className: "canopy-header__icon-button canopy-header__menu",
|
|
1507
|
+
"aria-label": "Open navigation",
|
|
1508
|
+
"aria-controls": "canopy-modal-nav",
|
|
1509
|
+
"aria-expanded": "false",
|
|
1510
|
+
"data-canopy-header-toggle": "nav"
|
|
1511
|
+
},
|
|
1512
|
+
/* @__PURE__ */ React19.createElement(
|
|
1513
|
+
"svg",
|
|
1514
|
+
{
|
|
1515
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1516
|
+
fill: "none",
|
|
1517
|
+
viewBox: "0 0 24 24",
|
|
1518
|
+
strokeWidth: "1.5",
|
|
1519
|
+
stroke: "currentColor",
|
|
1520
|
+
className: "canopy-header__menu-icon"
|
|
1521
|
+
},
|
|
1522
|
+
/* @__PURE__ */ React19.createElement(
|
|
1523
|
+
"path",
|
|
1524
|
+
{
|
|
1525
|
+
strokeLinecap: "round",
|
|
1526
|
+
strokeLinejoin: "round",
|
|
1527
|
+
d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
|
|
1528
|
+
}
|
|
1529
|
+
)
|
|
1530
|
+
)
|
|
1531
|
+
))
|
|
1532
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1440
1533
|
CanopyModal,
|
|
1441
1534
|
{
|
|
1442
1535
|
id: "canopy-modal-nav",
|
|
@@ -1448,8 +1541,15 @@ function CanopyHeader(props = {}) {
|
|
|
1448
1541
|
closeLabel: "Close navigation",
|
|
1449
1542
|
closeDataAttr: "nav"
|
|
1450
1543
|
},
|
|
1451
|
-
/* @__PURE__ */
|
|
1452
|
-
|
|
1544
|
+
/* @__PURE__ */ React19.createElement(
|
|
1545
|
+
"nav",
|
|
1546
|
+
{
|
|
1547
|
+
className: "canopy-nav-links canopy-modal__nav",
|
|
1548
|
+
"aria-label": "Primary navigation"
|
|
1549
|
+
},
|
|
1550
|
+
navLinks.map((link) => /* @__PURE__ */ React19.createElement("a", { key: link.href, href: link.href }, link.label || link.href))
|
|
1551
|
+
)
|
|
1552
|
+
), /* @__PURE__ */ React19.createElement(
|
|
1453
1553
|
CanopyModal,
|
|
1454
1554
|
{
|
|
1455
1555
|
id: "canopy-modal-search",
|
|
@@ -1462,26 +1562,33 @@ function CanopyHeader(props = {}) {
|
|
|
1462
1562
|
closeDataAttr: "search",
|
|
1463
1563
|
bodyClassName: "canopy-modal__body--search"
|
|
1464
1564
|
},
|
|
1465
|
-
/* @__PURE__ */
|
|
1466
|
-
|
|
1565
|
+
/* @__PURE__ */ React19.createElement(
|
|
1566
|
+
SearchPanel,
|
|
1567
|
+
{
|
|
1568
|
+
label: searchLabel,
|
|
1569
|
+
hotkey: searchHotkey,
|
|
1570
|
+
placeholder: searchPlaceholder
|
|
1571
|
+
}
|
|
1572
|
+
)
|
|
1573
|
+
), /* @__PURE__ */ React19.createElement(HeaderScript, null));
|
|
1467
1574
|
}
|
|
1468
1575
|
|
|
1469
1576
|
// ui/src/layout/CanopyFooter.jsx
|
|
1470
|
-
import
|
|
1577
|
+
import React20 from "react";
|
|
1471
1578
|
function CanopyFooter({ className = "", children }) {
|
|
1472
1579
|
const footerClassName = ["canopy-footer", className].filter(Boolean).join(" ");
|
|
1473
|
-
return /* @__PURE__ */
|
|
1580
|
+
return /* @__PURE__ */ React20.createElement("footer", { className: footerClassName }, /* @__PURE__ */ React20.createElement("div", { className: "canopy-footer__inner" }, children));
|
|
1474
1581
|
}
|
|
1475
1582
|
|
|
1476
1583
|
// ui/src/layout/Container.jsx
|
|
1477
|
-
import
|
|
1584
|
+
import React21 from "react";
|
|
1478
1585
|
function Container({ className = "", children, ...rest }) {
|
|
1479
1586
|
const classes = ["mx-auto", "max-w-content", "w-full", "px-6", className].filter(Boolean).join(" ");
|
|
1480
|
-
return /* @__PURE__ */
|
|
1587
|
+
return /* @__PURE__ */ React21.createElement("div", { className: classes, ...rest }, children);
|
|
1481
1588
|
}
|
|
1482
1589
|
|
|
1483
1590
|
// ui/src/search/MdxSearchResults.jsx
|
|
1484
|
-
import
|
|
1591
|
+
import React22 from "react";
|
|
1485
1592
|
function MdxSearchResults(props) {
|
|
1486
1593
|
let json = "{}";
|
|
1487
1594
|
try {
|
|
@@ -1489,11 +1596,11 @@ function MdxSearchResults(props) {
|
|
|
1489
1596
|
} catch (_) {
|
|
1490
1597
|
json = "{}";
|
|
1491
1598
|
}
|
|
1492
|
-
return /* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ React22.createElement("div", { "data-canopy-search-results": "1" }, /* @__PURE__ */ React22.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
1493
1600
|
}
|
|
1494
1601
|
|
|
1495
1602
|
// ui/src/search/SearchSummary.jsx
|
|
1496
|
-
import
|
|
1603
|
+
import React23 from "react";
|
|
1497
1604
|
function SearchSummary(props) {
|
|
1498
1605
|
let json = "{}";
|
|
1499
1606
|
try {
|
|
@@ -1501,11 +1608,11 @@ function SearchSummary(props) {
|
|
|
1501
1608
|
} catch (_) {
|
|
1502
1609
|
json = "{}";
|
|
1503
1610
|
}
|
|
1504
|
-
return /* @__PURE__ */
|
|
1611
|
+
return /* @__PURE__ */ React23.createElement("div", { "data-canopy-search-summary": "1" }, /* @__PURE__ */ React23.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
1505
1612
|
}
|
|
1506
1613
|
|
|
1507
1614
|
// ui/src/search/MdxSearchTabs.jsx
|
|
1508
|
-
import
|
|
1615
|
+
import React24 from "react";
|
|
1509
1616
|
function MdxSearchTabs(props) {
|
|
1510
1617
|
let json = "{}";
|
|
1511
1618
|
try {
|
|
@@ -1513,11 +1620,11 @@ function MdxSearchTabs(props) {
|
|
|
1513
1620
|
} catch (_) {
|
|
1514
1621
|
json = "{}";
|
|
1515
1622
|
}
|
|
1516
|
-
return /* @__PURE__ */
|
|
1623
|
+
return /* @__PURE__ */ React24.createElement("div", { "data-canopy-search-tabs": "1" }, /* @__PURE__ */ React24.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
1517
1624
|
}
|
|
1518
1625
|
|
|
1519
1626
|
// ui/src/search-form/MdxSearchFormModal.jsx
|
|
1520
|
-
import
|
|
1627
|
+
import React25 from "react";
|
|
1521
1628
|
function MdxSearchFormModal(props = {}) {
|
|
1522
1629
|
const {
|
|
1523
1630
|
placeholder = "Search\u2026",
|
|
@@ -1533,11 +1640,11 @@ function MdxSearchFormModal(props = {}) {
|
|
|
1533
1640
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
1534
1641
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
1535
1642
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
1536
|
-
return /* @__PURE__ */
|
|
1643
|
+
return /* @__PURE__ */ React25.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React25.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React25.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React25.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React25.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
|
|
1537
1644
|
}
|
|
1538
1645
|
|
|
1539
1646
|
// ui/src/iiif/ManifestPrimitives.jsx
|
|
1540
|
-
import
|
|
1647
|
+
import React26 from "react";
|
|
1541
1648
|
import {
|
|
1542
1649
|
Label as CloverLabel,
|
|
1543
1650
|
Metadata as CloverMetadata,
|
|
@@ -1562,28 +1669,28 @@ function ensureMetadata(items) {
|
|
|
1562
1669
|
function Label({ manifest, label, ...rest }) {
|
|
1563
1670
|
const intl = label || manifest && manifest.label;
|
|
1564
1671
|
if (!hasInternationalValue(intl)) return null;
|
|
1565
|
-
return /* @__PURE__ */
|
|
1672
|
+
return /* @__PURE__ */ React26.createElement(CloverLabel, { label: intl, ...rest });
|
|
1566
1673
|
}
|
|
1567
1674
|
function Summary({ manifest, summary, ...rest }) {
|
|
1568
1675
|
const intl = summary || manifest && manifest.summary;
|
|
1569
1676
|
if (!hasInternationalValue(intl)) return null;
|
|
1570
|
-
return /* @__PURE__ */
|
|
1677
|
+
return /* @__PURE__ */ React26.createElement(CloverSummary, { summary: intl, ...rest });
|
|
1571
1678
|
}
|
|
1572
1679
|
function Metadata({ manifest, metadata, ...rest }) {
|
|
1573
1680
|
const items = ensureMetadata(metadata || manifest && manifest.metadata);
|
|
1574
1681
|
if (!items.length) return null;
|
|
1575
|
-
return /* @__PURE__ */
|
|
1682
|
+
return /* @__PURE__ */ React26.createElement(CloverMetadata, { metadata: items, ...rest });
|
|
1576
1683
|
}
|
|
1577
1684
|
function RequiredStatement({ manifest, requiredStatement, ...rest }) {
|
|
1578
1685
|
const stmt = requiredStatement || manifest && manifest.requiredStatement;
|
|
1579
1686
|
if (!stmt || !hasInternationalValue(stmt.label) || !hasInternationalValue(stmt.value)) {
|
|
1580
1687
|
return null;
|
|
1581
1688
|
}
|
|
1582
|
-
return /* @__PURE__ */
|
|
1689
|
+
return /* @__PURE__ */ React26.createElement(CloverRequiredStatement, { requiredStatement: stmt, ...rest });
|
|
1583
1690
|
}
|
|
1584
1691
|
|
|
1585
1692
|
// ui/src/docs/CodeBlock.jsx
|
|
1586
|
-
import
|
|
1693
|
+
import React27 from "react";
|
|
1587
1694
|
function parseHighlightAttr(attr) {
|
|
1588
1695
|
if (!attr) return /* @__PURE__ */ new Set();
|
|
1589
1696
|
const cleaned = String(attr || "").trim();
|
|
@@ -1629,10 +1736,10 @@ var highlightBaseStyle = {
|
|
|
1629
1736
|
};
|
|
1630
1737
|
function DocsCodeBlock(props = {}) {
|
|
1631
1738
|
const { children, ...rest } = props;
|
|
1632
|
-
const childArray =
|
|
1633
|
-
const codeElement = childArray.find((el) =>
|
|
1739
|
+
const childArray = React27.Children.toArray(children);
|
|
1740
|
+
const codeElement = childArray.find((el) => React27.isValidElement(el));
|
|
1634
1741
|
if (!codeElement || !codeElement.props) {
|
|
1635
|
-
return
|
|
1742
|
+
return React27.createElement("pre", props);
|
|
1636
1743
|
}
|
|
1637
1744
|
const {
|
|
1638
1745
|
className = "",
|
|
@@ -1647,8 +1754,8 @@ function DocsCodeBlock(props = {}) {
|
|
|
1647
1754
|
const highlightSet = parseHighlightAttr(highlightAttr);
|
|
1648
1755
|
const copyAttr = codeProps["data-copy"];
|
|
1649
1756
|
const enableCopy = copyAttr !== void 0 ? copyAttr === true || copyAttr === "true" || copyAttr === "" : false;
|
|
1650
|
-
const [copied, setCopied] =
|
|
1651
|
-
const handleCopy =
|
|
1757
|
+
const [copied, setCopied] = React27.useState(false);
|
|
1758
|
+
const handleCopy = React27.useCallback(async () => {
|
|
1652
1759
|
const text = rawCode;
|
|
1653
1760
|
try {
|
|
1654
1761
|
if (typeof navigator !== "undefined" && navigator.clipboard && navigator.clipboard.writeText) {
|
|
@@ -1712,20 +1819,20 @@ function DocsCodeBlock(props = {}) {
|
|
|
1712
1819
|
const highlight = highlightSet.has(lineNumber);
|
|
1713
1820
|
const style = highlight ? { ...baseLineStyle, ...highlightBaseStyle } : baseLineStyle;
|
|
1714
1821
|
const displayLine = line === "" ? " " : line;
|
|
1715
|
-
return
|
|
1822
|
+
return React27.createElement(
|
|
1716
1823
|
"span",
|
|
1717
1824
|
{ key: lineNumber, style },
|
|
1718
|
-
|
|
1825
|
+
React27.createElement("span", { style: lineContentStyle }, displayLine)
|
|
1719
1826
|
);
|
|
1720
1827
|
});
|
|
1721
|
-
return
|
|
1828
|
+
return React27.createElement(
|
|
1722
1829
|
"div",
|
|
1723
1830
|
{ style: containerStyle },
|
|
1724
|
-
|
|
1831
|
+
React27.createElement(
|
|
1725
1832
|
"div",
|
|
1726
1833
|
{ style: headerStyle },
|
|
1727
|
-
|
|
1728
|
-
enableCopy ?
|
|
1834
|
+
React27.createElement("span", null, showFilename ? filename : null),
|
|
1835
|
+
enableCopy ? React27.createElement(
|
|
1729
1836
|
"button",
|
|
1730
1837
|
{
|
|
1731
1838
|
type: "button",
|
|
@@ -1744,19 +1851,19 @@ function DocsCodeBlock(props = {}) {
|
|
|
1744
1851
|
copied ? "Copied" : "Copy"
|
|
1745
1852
|
) : null
|
|
1746
1853
|
),
|
|
1747
|
-
|
|
1854
|
+
React27.createElement(
|
|
1748
1855
|
"pre",
|
|
1749
1856
|
{ ...preRest, className: preClassName, style: mergedPreStyle },
|
|
1750
|
-
|
|
1857
|
+
React27.createElement("code", { style: codeStyle }, lineElements)
|
|
1751
1858
|
)
|
|
1752
1859
|
);
|
|
1753
1860
|
}
|
|
1754
1861
|
|
|
1755
1862
|
// ui/src/docs/MarkdownTable.jsx
|
|
1756
|
-
import
|
|
1863
|
+
import React28 from "react";
|
|
1757
1864
|
function MarkdownTable({ className = "", ...rest }) {
|
|
1758
1865
|
const merged = ["markdown-table", className].filter(Boolean).join(" ");
|
|
1759
|
-
return /* @__PURE__ */
|
|
1866
|
+
return /* @__PURE__ */ React28.createElement("div", { className: "markdown-table__frame" }, /* @__PURE__ */ React28.createElement("table", { className: merged, ...rest }));
|
|
1760
1867
|
}
|
|
1761
1868
|
export {
|
|
1762
1869
|
Button,
|
|
@@ -1769,6 +1876,7 @@ export {
|
|
|
1769
1876
|
DocsCodeBlock,
|
|
1770
1877
|
MarkdownTable as DocsMarkdownTable,
|
|
1771
1878
|
HelloWorld,
|
|
1879
|
+
Image,
|
|
1772
1880
|
interstitials_exports as Interstitials,
|
|
1773
1881
|
Label,
|
|
1774
1882
|
Layout,
|