@canopy-iiif/app 0.9.0 → 0.9.2
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/mdx.js +142 -1
- package/lib/build/pages.js +6 -0
- package/lib/build/search-index.js +10 -5
- package/lib/build/search.js +9 -1
- package/lib/search/search.js +1 -2
- package/package.json +2 -1
- package/ui/dist/index.mjs +30 -17
- package/ui/dist/index.mjs.map +3 -3
- package/ui/dist/server.mjs +369 -38
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/components/_sub-navigation.scss +0 -1
- package/ui/styles/index.css +0 -1
package/ui/dist/server.mjs
CHANGED
|
@@ -479,8 +479,338 @@ function SubNavigation({
|
|
|
479
479
|
return /* @__PURE__ */ React7.createElement("nav", { className: combinedClassName, style: inlineStyle, "aria-label": navLabel }, finalHeading ? /* @__PURE__ */ React7.createElement("div", { className: "canopy-sub-navigation__heading" }, finalHeading) : null, /* @__PURE__ */ React7.createElement("ul", { className: "canopy-sub-navigation__list", role: "list" }, renderNodes([rootNode], rootNode.slug || "root")));
|
|
480
480
|
}
|
|
481
481
|
|
|
482
|
-
// ui/src/
|
|
482
|
+
// ui/src/layout/Layout.jsx
|
|
483
|
+
import React9 from "react";
|
|
484
|
+
import navigationHelpers2 from "@canopy-iiif/app/lib/components/navigation.js";
|
|
485
|
+
|
|
486
|
+
// ui/src/layout/ContentNavigation.jsx
|
|
483
487
|
import React8 from "react";
|
|
488
|
+
var SCROLL_OFFSET_REM = 1.618;
|
|
489
|
+
function depthIndex(depth) {
|
|
490
|
+
return Math.max(0, Math.min(5, (depth || 1) - 1));
|
|
491
|
+
}
|
|
492
|
+
function ContentNavigation({
|
|
493
|
+
items = [],
|
|
494
|
+
className = "",
|
|
495
|
+
style = {},
|
|
496
|
+
heading,
|
|
497
|
+
headingId,
|
|
498
|
+
pageTitle,
|
|
499
|
+
ariaLabel
|
|
500
|
+
}) {
|
|
501
|
+
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
502
|
+
const savedDepthsRef = React8.useRef(null);
|
|
503
|
+
if ((!items || !items.length) && !headingId) return null;
|
|
504
|
+
const combinedClassName = ["canopy-sub-navigation canopy-content-navigation", className].filter(Boolean).join(" ");
|
|
505
|
+
const effectiveHeading = heading || pageTitle || null;
|
|
506
|
+
const navLabel = ariaLabel || (effectiveHeading ? `${effectiveHeading} navigation` : "Section navigation");
|
|
507
|
+
const getSavedDepth = React8.useCallback(
|
|
508
|
+
(id, fallback) => {
|
|
509
|
+
if (!id) return fallback;
|
|
510
|
+
if (!savedDepthsRef.current) savedDepthsRef.current = /* @__PURE__ */ new Map();
|
|
511
|
+
const store = savedDepthsRef.current;
|
|
512
|
+
if (store.has(id)) return store.get(id);
|
|
513
|
+
store.set(id, fallback);
|
|
514
|
+
return fallback;
|
|
515
|
+
},
|
|
516
|
+
[]
|
|
517
|
+
);
|
|
518
|
+
const headingEntries = React8.useMemo(() => {
|
|
519
|
+
const entries = [];
|
|
520
|
+
const seen = /* @__PURE__ */ new Set();
|
|
521
|
+
if (headingId) {
|
|
522
|
+
const topId = String(headingId);
|
|
523
|
+
entries.push({ id: topId, depth: 1 });
|
|
524
|
+
seen.add(topId);
|
|
525
|
+
}
|
|
526
|
+
const pushNodes = (nodes) => {
|
|
527
|
+
if (!Array.isArray(nodes)) return;
|
|
528
|
+
nodes.forEach((node) => {
|
|
529
|
+
if (!node || !node.id) return;
|
|
530
|
+
const id = String(node.id);
|
|
531
|
+
if (seen.has(id)) return;
|
|
532
|
+
seen.add(id);
|
|
533
|
+
const depth = node.depth || node.level || getSavedDepth(id, 2);
|
|
534
|
+
entries.push({ id, depth });
|
|
535
|
+
if (node.children && node.children.length) pushNodes(node.children);
|
|
536
|
+
});
|
|
537
|
+
};
|
|
538
|
+
pushNodes(items);
|
|
539
|
+
return entries;
|
|
540
|
+
}, [headingId, items, getSavedDepth]);
|
|
541
|
+
const fallbackId = headingEntries.length ? headingEntries[0].id : headingId || null;
|
|
542
|
+
const [activeId, setActiveId] = React8.useState(fallbackId);
|
|
543
|
+
const activeIdRef = React8.useRef(activeId);
|
|
544
|
+
React8.useEffect(() => {
|
|
545
|
+
activeIdRef.current = activeId;
|
|
546
|
+
}, [activeId]);
|
|
547
|
+
React8.useEffect(() => {
|
|
548
|
+
if (!headingEntries.length) return;
|
|
549
|
+
if (!headingEntries.some((entry) => entry.id === activeIdRef.current)) {
|
|
550
|
+
const next = headingEntries[0].id;
|
|
551
|
+
activeIdRef.current = next;
|
|
552
|
+
setActiveId(next);
|
|
553
|
+
}
|
|
554
|
+
}, [headingEntries]);
|
|
555
|
+
const computeOffsetPx = React8.useCallback(() => {
|
|
556
|
+
if (!isBrowser) return 0;
|
|
557
|
+
try {
|
|
558
|
+
const root = document.documentElement;
|
|
559
|
+
const fontSize = root ? parseFloat(window.getComputedStyle(root).fontSize || "16") || 16 : 16;
|
|
560
|
+
return fontSize * SCROLL_OFFSET_REM;
|
|
561
|
+
} catch (_) {
|
|
562
|
+
return 0;
|
|
563
|
+
}
|
|
564
|
+
}, [isBrowser]);
|
|
565
|
+
const headingElementsRef = React8.useRef([]);
|
|
566
|
+
const updateActiveFromElements = React8.useCallback(
|
|
567
|
+
(elements) => {
|
|
568
|
+
if (!elements || !elements.length) return;
|
|
569
|
+
const offset = computeOffsetPx();
|
|
570
|
+
let nextId = elements[0].id;
|
|
571
|
+
for (const { id, element } of elements) {
|
|
572
|
+
const rect = element.getBoundingClientRect();
|
|
573
|
+
if (rect.top - offset <= 0) {
|
|
574
|
+
nextId = id;
|
|
575
|
+
} else {
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
if (nextId && nextId !== activeIdRef.current) {
|
|
580
|
+
activeIdRef.current = nextId;
|
|
581
|
+
setActiveId(nextId);
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
[computeOffsetPx]
|
|
585
|
+
);
|
|
586
|
+
React8.useEffect(() => {
|
|
587
|
+
if (!isBrowser) return void 0;
|
|
588
|
+
const elements = headingEntries.map((entry) => {
|
|
589
|
+
const element = document.getElementById(entry.id);
|
|
590
|
+
return element ? { id: entry.id, element } : null;
|
|
591
|
+
}).filter(Boolean);
|
|
592
|
+
headingElementsRef.current = elements;
|
|
593
|
+
updateActiveFromElements(elements);
|
|
594
|
+
if (!elements.length) return void 0;
|
|
595
|
+
let ticking = false;
|
|
596
|
+
const handle = () => {
|
|
597
|
+
if (!ticking) {
|
|
598
|
+
ticking = true;
|
|
599
|
+
window.requestAnimationFrame(() => {
|
|
600
|
+
updateActiveFromElements(elements);
|
|
601
|
+
ticking = false;
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
window.addEventListener("scroll", handle, { passive: true });
|
|
606
|
+
window.addEventListener("resize", handle);
|
|
607
|
+
return () => {
|
|
608
|
+
window.removeEventListener("scroll", handle);
|
|
609
|
+
window.removeEventListener("resize", handle);
|
|
610
|
+
};
|
|
611
|
+
}, [headingEntries, isBrowser, updateActiveFromElements]);
|
|
612
|
+
const handleAnchorClick = React8.useCallback(
|
|
613
|
+
(event, targetId, options = {}) => {
|
|
614
|
+
var _a;
|
|
615
|
+
try {
|
|
616
|
+
if (event && typeof event.preventDefault === "function") event.preventDefault();
|
|
617
|
+
} catch (_) {
|
|
618
|
+
}
|
|
619
|
+
if (!isBrowser) return;
|
|
620
|
+
const offset = computeOffsetPx();
|
|
621
|
+
let top = 0;
|
|
622
|
+
if (targetId && targetId !== "top" && !options.scrollToTop) {
|
|
623
|
+
const el = document.getElementById(targetId);
|
|
624
|
+
if (el) {
|
|
625
|
+
const rect = el.getBoundingClientRect();
|
|
626
|
+
top = window.scrollY + rect.top - offset;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (!Number.isFinite(top) || top < 0 || options.scrollToTop) top = 0;
|
|
630
|
+
const nextId = targetId && targetId !== "top" ? targetId : ((_a = headingEntries[0]) == null ? void 0 : _a.id) || headingId || null;
|
|
631
|
+
if (nextId) {
|
|
632
|
+
activeIdRef.current = nextId;
|
|
633
|
+
setActiveId(nextId);
|
|
634
|
+
}
|
|
635
|
+
try {
|
|
636
|
+
window.scrollTo({ top, behavior: "smooth" });
|
|
637
|
+
} catch (_) {
|
|
638
|
+
window.scrollTo(0, top);
|
|
639
|
+
}
|
|
640
|
+
},
|
|
641
|
+
[computeOffsetPx, headingEntries, headingId, isBrowser]
|
|
642
|
+
);
|
|
643
|
+
const renderNodes2 = React8.useCallback(
|
|
644
|
+
(nodes) => {
|
|
645
|
+
if (!nodes || !nodes.length) return null;
|
|
646
|
+
return nodes.map((node) => {
|
|
647
|
+
if (!node) return null;
|
|
648
|
+
const id = node.id ? String(node.id) : "";
|
|
649
|
+
const depth = node.depth || node.level || getSavedDepth(id, 2);
|
|
650
|
+
const idx = depthIndex(depth);
|
|
651
|
+
const isActive = id && activeId === id;
|
|
652
|
+
return /* @__PURE__ */ React8.createElement("li", { key: id || node.title, className: "canopy-sub-navigation__item", "data-depth": idx }, /* @__PURE__ */ React8.createElement(
|
|
653
|
+
"a",
|
|
654
|
+
{
|
|
655
|
+
className: `canopy-sub-navigation__link depth-${idx}${isActive ? " is-active" : ""}`,
|
|
656
|
+
href: id ? `#${id}` : "#",
|
|
657
|
+
onClick: (event) => handleAnchorClick(event, id || null),
|
|
658
|
+
"aria-current": isActive ? "location" : void 0
|
|
659
|
+
},
|
|
660
|
+
node.title
|
|
661
|
+
), node.children && node.children.length ? /* @__PURE__ */ React8.createElement(
|
|
662
|
+
"ul",
|
|
663
|
+
{
|
|
664
|
+
className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested",
|
|
665
|
+
role: "list"
|
|
666
|
+
},
|
|
667
|
+
renderNodes2(node.children)
|
|
668
|
+
) : null);
|
|
669
|
+
});
|
|
670
|
+
},
|
|
671
|
+
[handleAnchorClick, activeId, getSavedDepth]
|
|
672
|
+
);
|
|
673
|
+
const nestedItems = renderNodes2(items);
|
|
674
|
+
const topLink = headingId ? /* @__PURE__ */ React8.createElement("li", { className: "canopy-sub-navigation__item", "data-depth": 0 }, /* @__PURE__ */ React8.createElement(
|
|
675
|
+
"a",
|
|
676
|
+
{
|
|
677
|
+
className: `canopy-sub-navigation__link depth-0${activeId === headingId ? " is-active" : ""}`,
|
|
678
|
+
href: `#${headingId}`,
|
|
679
|
+
onClick: (event) => handleAnchorClick(event, headingId, { scrollToTop: true }),
|
|
680
|
+
"aria-current": activeId === headingId ? "location" : void 0
|
|
681
|
+
},
|
|
682
|
+
effectiveHeading || pageTitle || headingId
|
|
683
|
+
), nestedItems ? /* @__PURE__ */ React8.createElement(
|
|
684
|
+
"ul",
|
|
685
|
+
{
|
|
686
|
+
className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested",
|
|
687
|
+
role: "list"
|
|
688
|
+
},
|
|
689
|
+
nestedItems
|
|
690
|
+
) : null) : null;
|
|
691
|
+
return /* @__PURE__ */ React8.createElement("nav", { className: combinedClassName, style, "aria-label": navLabel }, /* @__PURE__ */ React8.createElement("ul", { className: "canopy-sub-navigation__list", role: "list" }, topLink || nestedItems));
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// ui/src/layout/Layout.jsx
|
|
695
|
+
function buildHeadingTree(headings) {
|
|
696
|
+
if (!Array.isArray(headings) || !headings.length) return [];
|
|
697
|
+
const root = [];
|
|
698
|
+
const stack = [];
|
|
699
|
+
headings.forEach((heading) => {
|
|
700
|
+
if (!heading || typeof heading !== "object") return;
|
|
701
|
+
const depth = typeof heading.depth === "number" ? heading.depth : heading.level;
|
|
702
|
+
if (typeof depth !== "number" || depth < 2) return;
|
|
703
|
+
const entry = {
|
|
704
|
+
id: heading.id || heading.slug || heading.title,
|
|
705
|
+
title: heading.title || heading.text || heading.id,
|
|
706
|
+
depth,
|
|
707
|
+
children: []
|
|
708
|
+
};
|
|
709
|
+
while (stack.length && stack[stack.length - 1].depth >= entry.depth) {
|
|
710
|
+
stack.pop();
|
|
711
|
+
}
|
|
712
|
+
if (!stack.length) {
|
|
713
|
+
root.push(entry);
|
|
714
|
+
} else {
|
|
715
|
+
stack[stack.length - 1].children.push(entry);
|
|
716
|
+
}
|
|
717
|
+
stack.push(entry);
|
|
718
|
+
});
|
|
719
|
+
return root;
|
|
720
|
+
}
|
|
721
|
+
function buildNavigationAside(sidebar, className) {
|
|
722
|
+
if (!sidebar) {
|
|
723
|
+
return /* @__PURE__ */ React9.createElement(SubNavigation, { className });
|
|
724
|
+
}
|
|
725
|
+
if (typeof sidebar === "function") {
|
|
726
|
+
return React9.createElement(sidebar);
|
|
727
|
+
}
|
|
728
|
+
return sidebar;
|
|
729
|
+
}
|
|
730
|
+
function Layout({
|
|
731
|
+
children,
|
|
732
|
+
sidebar,
|
|
733
|
+
navigation = true,
|
|
734
|
+
fluid = false,
|
|
735
|
+
contentNavigation = true,
|
|
736
|
+
className = "",
|
|
737
|
+
contentClassName = "",
|
|
738
|
+
sidebarClassName = "",
|
|
739
|
+
contentNavigationClassName = "",
|
|
740
|
+
...rest
|
|
741
|
+
}) {
|
|
742
|
+
const PageContext = navigationHelpers2 && typeof navigationHelpers2.getPageContext === "function" ? navigationHelpers2.getPageContext() : null;
|
|
743
|
+
const context = PageContext ? React9.useContext(PageContext) : null;
|
|
744
|
+
const pageHeadings = React9.useMemo(() => {
|
|
745
|
+
const headings = context && context.page ? context.page.headings : null;
|
|
746
|
+
return Array.isArray(headings) ? headings : [];
|
|
747
|
+
}, [context]);
|
|
748
|
+
const contentHeading = React9.useMemo(() => {
|
|
749
|
+
const first = pageHeadings.find((heading) => {
|
|
750
|
+
const depth = heading && (heading.depth || heading.level);
|
|
751
|
+
return depth === 1;
|
|
752
|
+
});
|
|
753
|
+
return first && first.title ? first.title : null;
|
|
754
|
+
}, [pageHeadings]);
|
|
755
|
+
const headingAnchorId = React9.useMemo(() => {
|
|
756
|
+
const first = pageHeadings.find((heading) => {
|
|
757
|
+
const depth = heading && (heading.depth || heading.level);
|
|
758
|
+
return depth === 1;
|
|
759
|
+
});
|
|
760
|
+
return first && first.id ? first.id : null;
|
|
761
|
+
}, [pageHeadings]);
|
|
762
|
+
const headingTree = React9.useMemo(
|
|
763
|
+
() => buildHeadingTree(pageHeadings),
|
|
764
|
+
[pageHeadings]
|
|
765
|
+
);
|
|
766
|
+
const showLeftColumn = navigation !== false;
|
|
767
|
+
const hasContentNavigation = navigation !== false && contentNavigation !== false && headingTree.length > 0;
|
|
768
|
+
const gridClass = (() => {
|
|
769
|
+
if (showLeftColumn && hasContentNavigation) {
|
|
770
|
+
return "md:grid md:grid-cols-[17rem_minmax(0,1fr)_14rem] md:items-start md:gap-10";
|
|
771
|
+
}
|
|
772
|
+
if (showLeftColumn) {
|
|
773
|
+
return "md:grid md:grid-cols-[17rem_minmax(0,1fr)] md:items-start md:gap-10";
|
|
774
|
+
}
|
|
775
|
+
if (hasContentNavigation) {
|
|
776
|
+
return "md:grid md:grid-cols-[minmax(0,1fr)_14rem] md:items-start md:gap-10";
|
|
777
|
+
}
|
|
778
|
+
return "";
|
|
779
|
+
})();
|
|
780
|
+
const containerClassName = [
|
|
781
|
+
"w-full py-6 getting-started-layout",
|
|
782
|
+
gridClass,
|
|
783
|
+
fluid ? "px-4 md:px-8 lg:px-12" : "mx-auto max-w-content px-4",
|
|
784
|
+
className
|
|
785
|
+
].filter(Boolean).join(" ");
|
|
786
|
+
const leftAsideClassName = [
|
|
787
|
+
"mt-8 md:mt-0 md:order-1 md:sticky md:top-24 md:max-h-[calc(100vh-6rem)] md:overflow-y-auto text-sm text-slate-600",
|
|
788
|
+
sidebarClassName
|
|
789
|
+
].filter(Boolean).join(" ");
|
|
790
|
+
const contentOrderClass = showLeftColumn ? "md:order-2" : hasContentNavigation ? "md:order-1" : "";
|
|
791
|
+
const contentClassNames = [
|
|
792
|
+
"space-y-6",
|
|
793
|
+
contentOrderClass,
|
|
794
|
+
contentClassName
|
|
795
|
+
].filter(Boolean).join(" ");
|
|
796
|
+
const contentNavigationAsideClassName = [
|
|
797
|
+
"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-sm text-slate-600",
|
|
798
|
+
contentNavigationClassName
|
|
799
|
+
].filter(Boolean).join(" ");
|
|
800
|
+
const sidebarNode = showLeftColumn ? buildNavigationAside(sidebar, sidebarClassName) : null;
|
|
801
|
+
return /* @__PURE__ */ React9.createElement("div", { className: containerClassName, ...rest }, showLeftColumn ? /* @__PURE__ */ React9.createElement("aside", { className: leftAsideClassName }, sidebarNode) : null, /* @__PURE__ */ React9.createElement("div", { className: contentClassNames }, children), hasContentNavigation ? /* @__PURE__ */ React9.createElement("aside", { className: contentNavigationAsideClassName }, /* @__PURE__ */ React9.createElement(
|
|
802
|
+
ContentNavigation,
|
|
803
|
+
{
|
|
804
|
+
items: headingTree,
|
|
805
|
+
heading: contentHeading || void 0,
|
|
806
|
+
headingId: headingAnchorId || void 0,
|
|
807
|
+
pageTitle: context && context.page ? context.page.title : void 0
|
|
808
|
+
}
|
|
809
|
+
)) : null);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
// ui/src/search/MdxSearchResults.jsx
|
|
813
|
+
import React10 from "react";
|
|
484
814
|
function MdxSearchResults(props) {
|
|
485
815
|
let json = "{}";
|
|
486
816
|
try {
|
|
@@ -488,11 +818,11 @@ function MdxSearchResults(props) {
|
|
|
488
818
|
} catch (_) {
|
|
489
819
|
json = "{}";
|
|
490
820
|
}
|
|
491
|
-
return /* @__PURE__ */
|
|
821
|
+
return /* @__PURE__ */ React10.createElement("div", { "data-canopy-search-results": "1" }, /* @__PURE__ */ React10.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
492
822
|
}
|
|
493
823
|
|
|
494
824
|
// ui/src/search/SearchSummary.jsx
|
|
495
|
-
import
|
|
825
|
+
import React11 from "react";
|
|
496
826
|
function SearchSummary(props) {
|
|
497
827
|
let json = "{}";
|
|
498
828
|
try {
|
|
@@ -500,11 +830,11 @@ function SearchSummary(props) {
|
|
|
500
830
|
} catch (_) {
|
|
501
831
|
json = "{}";
|
|
502
832
|
}
|
|
503
|
-
return /* @__PURE__ */
|
|
833
|
+
return /* @__PURE__ */ React11.createElement("div", { "data-canopy-search-summary": "1" }, /* @__PURE__ */ React11.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
504
834
|
}
|
|
505
835
|
|
|
506
836
|
// ui/src/search/MdxSearchTabs.jsx
|
|
507
|
-
import
|
|
837
|
+
import React12 from "react";
|
|
508
838
|
function MdxSearchTabs(props) {
|
|
509
839
|
let json = "{}";
|
|
510
840
|
try {
|
|
@@ -512,18 +842,18 @@ function MdxSearchTabs(props) {
|
|
|
512
842
|
} catch (_) {
|
|
513
843
|
json = "{}";
|
|
514
844
|
}
|
|
515
|
-
return /* @__PURE__ */
|
|
845
|
+
return /* @__PURE__ */ React12.createElement("div", { "data-canopy-search-tabs": "1" }, /* @__PURE__ */ React12.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
516
846
|
}
|
|
517
847
|
|
|
518
848
|
// ui/src/search-form/MdxSearchFormModal.jsx
|
|
519
|
-
import
|
|
849
|
+
import React16 from "react";
|
|
520
850
|
|
|
521
851
|
// ui/src/Icons.jsx
|
|
522
|
-
import
|
|
523
|
-
var MagnifyingGlassIcon = (props) => /* @__PURE__ */
|
|
852
|
+
import React13 from "react";
|
|
853
|
+
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" }));
|
|
524
854
|
|
|
525
855
|
// ui/src/search/SearchPanelForm.jsx
|
|
526
|
-
import
|
|
856
|
+
import React14 from "react";
|
|
527
857
|
function readBasePath() {
|
|
528
858
|
const normalize = (val) => {
|
|
529
859
|
const raw = typeof val === "string" ? val.trim() : "";
|
|
@@ -586,18 +916,18 @@ function SearchPanelForm(props = {}) {
|
|
|
586
916
|
clearLabel = "Clear search"
|
|
587
917
|
} = props || {};
|
|
588
918
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
589
|
-
const action =
|
|
919
|
+
const action = React14.useMemo(
|
|
590
920
|
() => resolveSearchPath(searchPath),
|
|
591
921
|
[searchPath]
|
|
592
922
|
);
|
|
593
|
-
const autoId = typeof
|
|
594
|
-
const [fallbackId] =
|
|
923
|
+
const autoId = typeof React14.useId === "function" ? React14.useId() : void 0;
|
|
924
|
+
const [fallbackId] = React14.useState(
|
|
595
925
|
() => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`
|
|
596
926
|
);
|
|
597
927
|
const inputId = inputIdProp || autoId || fallbackId;
|
|
598
|
-
const inputRef =
|
|
599
|
-
const [hasValue, setHasValue] =
|
|
600
|
-
const focusInput =
|
|
928
|
+
const inputRef = React14.useRef(null);
|
|
929
|
+
const [hasValue, setHasValue] = React14.useState(false);
|
|
930
|
+
const focusInput = React14.useCallback(() => {
|
|
601
931
|
const el = inputRef.current;
|
|
602
932
|
if (!el) return;
|
|
603
933
|
if (document.activeElement === el) return;
|
|
@@ -610,7 +940,7 @@ function SearchPanelForm(props = {}) {
|
|
|
610
940
|
}
|
|
611
941
|
}
|
|
612
942
|
}, []);
|
|
613
|
-
const handlePointerDown =
|
|
943
|
+
const handlePointerDown = React14.useCallback(
|
|
614
944
|
(event) => {
|
|
615
945
|
const target = event.target;
|
|
616
946
|
if (target && typeof target.closest === "function") {
|
|
@@ -622,23 +952,23 @@ function SearchPanelForm(props = {}) {
|
|
|
622
952
|
},
|
|
623
953
|
[focusInput]
|
|
624
954
|
);
|
|
625
|
-
|
|
955
|
+
React14.useEffect(() => {
|
|
626
956
|
const el = inputRef.current;
|
|
627
957
|
if (!el) return;
|
|
628
958
|
if (el.value && el.value.trim()) {
|
|
629
959
|
setHasValue(true);
|
|
630
960
|
}
|
|
631
961
|
}, []);
|
|
632
|
-
const handleInputChange =
|
|
962
|
+
const handleInputChange = React14.useCallback((event) => {
|
|
633
963
|
var _a;
|
|
634
964
|
const nextHasValue = Boolean(
|
|
635
965
|
((_a = event == null ? void 0 : event.target) == null ? void 0 : _a.value) && event.target.value.trim()
|
|
636
966
|
);
|
|
637
967
|
setHasValue(nextHasValue);
|
|
638
968
|
}, []);
|
|
639
|
-
const handleClear =
|
|
969
|
+
const handleClear = React14.useCallback((event) => {
|
|
640
970
|
}, []);
|
|
641
|
-
const handleClearKey =
|
|
971
|
+
const handleClearKey = React14.useCallback(
|
|
642
972
|
(event) => {
|
|
643
973
|
if (event.key === "Enter" || event.key === " ") {
|
|
644
974
|
event.preventDefault();
|
|
@@ -647,7 +977,7 @@ function SearchPanelForm(props = {}) {
|
|
|
647
977
|
},
|
|
648
978
|
[handleClear]
|
|
649
979
|
);
|
|
650
|
-
return /* @__PURE__ */
|
|
980
|
+
return /* @__PURE__ */ React14.createElement(
|
|
651
981
|
"form",
|
|
652
982
|
{
|
|
653
983
|
action,
|
|
@@ -659,7 +989,7 @@ function SearchPanelForm(props = {}) {
|
|
|
659
989
|
onPointerDown: handlePointerDown,
|
|
660
990
|
"data-has-value": hasValue ? "1" : "0"
|
|
661
991
|
},
|
|
662
|
-
/* @__PURE__ */
|
|
992
|
+
/* @__PURE__ */ React14.createElement("label", { htmlFor: inputId, className: "canopy-search-form__label" }, /* @__PURE__ */ React14.createElement(MagnifyingGlassIcon, { className: "canopy-search-form__icon" }), /* @__PURE__ */ React14.createElement(
|
|
663
993
|
"input",
|
|
664
994
|
{
|
|
665
995
|
id: inputId,
|
|
@@ -675,7 +1005,7 @@ function SearchPanelForm(props = {}) {
|
|
|
675
1005
|
onInput: handleInputChange
|
|
676
1006
|
}
|
|
677
1007
|
)),
|
|
678
|
-
hasValue ? /* @__PURE__ */
|
|
1008
|
+
hasValue ? /* @__PURE__ */ React14.createElement(
|
|
679
1009
|
"button",
|
|
680
1010
|
{
|
|
681
1011
|
type: "button",
|
|
@@ -688,32 +1018,32 @@ function SearchPanelForm(props = {}) {
|
|
|
688
1018
|
},
|
|
689
1019
|
"\xD7"
|
|
690
1020
|
) : null,
|
|
691
|
-
/* @__PURE__ */
|
|
1021
|
+
/* @__PURE__ */ React14.createElement(
|
|
692
1022
|
"button",
|
|
693
1023
|
{
|
|
694
1024
|
type: "submit",
|
|
695
1025
|
"data-canopy-search-form-trigger": "submit",
|
|
696
1026
|
className: "canopy-search-form__submit"
|
|
697
1027
|
},
|
|
698
|
-
/* @__PURE__ */
|
|
699
|
-
/* @__PURE__ */
|
|
1028
|
+
/* @__PURE__ */ React14.createElement("span", null, text),
|
|
1029
|
+
/* @__PURE__ */ React14.createElement("span", { "aria-hidden": true, className: "canopy-search-form__shortcut" }, /* @__PURE__ */ React14.createElement("span", null, "\u2318"), /* @__PURE__ */ React14.createElement("span", null, "K"))
|
|
700
1030
|
)
|
|
701
1031
|
);
|
|
702
1032
|
}
|
|
703
1033
|
|
|
704
1034
|
// ui/src/search/SearchPanelTeaserResults.jsx
|
|
705
|
-
import
|
|
1035
|
+
import React15 from "react";
|
|
706
1036
|
function SearchPanelTeaserResults(props = {}) {
|
|
707
1037
|
const { style, className } = props || {};
|
|
708
1038
|
const classes = ["canopy-search-teaser", className].filter(Boolean).join(" ");
|
|
709
|
-
return /* @__PURE__ */
|
|
1039
|
+
return /* @__PURE__ */ React15.createElement(
|
|
710
1040
|
"div",
|
|
711
1041
|
{
|
|
712
1042
|
"data-canopy-search-form-panel": true,
|
|
713
1043
|
className: classes || void 0,
|
|
714
1044
|
style
|
|
715
1045
|
},
|
|
716
|
-
/* @__PURE__ */
|
|
1046
|
+
/* @__PURE__ */ React15.createElement("div", { id: "cplist" })
|
|
717
1047
|
);
|
|
718
1048
|
}
|
|
719
1049
|
|
|
@@ -733,11 +1063,11 @@ function MdxSearchFormModal(props = {}) {
|
|
|
733
1063
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
734
1064
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
735
1065
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
736
|
-
return /* @__PURE__ */
|
|
1066
|
+
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) } }));
|
|
737
1067
|
}
|
|
738
1068
|
|
|
739
1069
|
// ui/src/search/SearchPanel.jsx
|
|
740
|
-
import
|
|
1070
|
+
import React17 from "react";
|
|
741
1071
|
function SearchPanel(props = {}) {
|
|
742
1072
|
const {
|
|
743
1073
|
placeholder = "Search\u2026",
|
|
@@ -754,11 +1084,11 @@ function SearchPanel(props = {}) {
|
|
|
754
1084
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
755
1085
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
756
1086
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
757
|
-
return /* @__PURE__ */
|
|
1087
|
+
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) } }));
|
|
758
1088
|
}
|
|
759
1089
|
|
|
760
1090
|
// ui/src/iiif/ManifestPrimitives.jsx
|
|
761
|
-
import
|
|
1091
|
+
import React18 from "react";
|
|
762
1092
|
import {
|
|
763
1093
|
Label as CloverLabel,
|
|
764
1094
|
Metadata as CloverMetadata,
|
|
@@ -783,29 +1113,30 @@ function ensureMetadata(items) {
|
|
|
783
1113
|
function Label({ manifest, label, ...rest }) {
|
|
784
1114
|
const intl = label || manifest && manifest.label;
|
|
785
1115
|
if (!hasInternationalValue(intl)) return null;
|
|
786
|
-
return /* @__PURE__ */
|
|
1116
|
+
return /* @__PURE__ */ React18.createElement(CloverLabel, { label: intl, ...rest });
|
|
787
1117
|
}
|
|
788
1118
|
function Summary({ manifest, summary, ...rest }) {
|
|
789
1119
|
const intl = summary || manifest && manifest.summary;
|
|
790
1120
|
if (!hasInternationalValue(intl)) return null;
|
|
791
|
-
return /* @__PURE__ */
|
|
1121
|
+
return /* @__PURE__ */ React18.createElement(CloverSummary, { summary: intl, ...rest });
|
|
792
1122
|
}
|
|
793
1123
|
function Metadata({ manifest, metadata, ...rest }) {
|
|
794
1124
|
const items = ensureMetadata(metadata || manifest && manifest.metadata);
|
|
795
1125
|
if (!items.length) return null;
|
|
796
|
-
return /* @__PURE__ */
|
|
1126
|
+
return /* @__PURE__ */ React18.createElement(CloverMetadata, { metadata: items, ...rest });
|
|
797
1127
|
}
|
|
798
1128
|
function RequiredStatement({ manifest, requiredStatement, ...rest }) {
|
|
799
1129
|
const stmt = requiredStatement || manifest && manifest.requiredStatement;
|
|
800
1130
|
if (!stmt || !hasInternationalValue(stmt.label) || !hasInternationalValue(stmt.value)) {
|
|
801
1131
|
return null;
|
|
802
1132
|
}
|
|
803
|
-
return /* @__PURE__ */
|
|
1133
|
+
return /* @__PURE__ */ React18.createElement(CloverRequiredStatement, { requiredStatement: stmt, ...rest });
|
|
804
1134
|
}
|
|
805
1135
|
export {
|
|
806
1136
|
HelloWorld,
|
|
807
1137
|
interstitials_exports as Interstitials,
|
|
808
1138
|
Label,
|
|
1139
|
+
Layout,
|
|
809
1140
|
Metadata,
|
|
810
1141
|
MdxRelatedItems as RelatedItems,
|
|
811
1142
|
RequiredStatement,
|