@canopy-iiif/app 0.8.2 → 0.8.4
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 -1
- package/lib/build/build.js +10 -0
- package/lib/build/dev.js +87 -40
- package/lib/build/iiif.js +124 -43
- package/lib/build/mdx.js +14 -4
- package/lib/build/pages.js +23 -9
- package/lib/build/runtimes.js +6 -6
- package/lib/build/search.js +7 -10
- package/lib/build/verify.js +9 -9
- package/lib/components/featured.js +17 -3
- package/lib/components/navigation.js +308 -0
- package/lib/page-context.js +14 -0
- package/lib/search/search-app.jsx +2 -2
- package/lib/search/{command-runtime.js → search-form-runtime.js} +9 -9
- package/lib/search/search.js +2 -2
- package/package.json +1 -1
- package/ui/dist/index.mjs +76 -63
- package/ui/dist/index.mjs.map +3 -3
- package/ui/dist/server.mjs +170 -67
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/base/_common.scss +19 -6
- package/ui/styles/base/_heading.scss +17 -0
- package/ui/styles/base/index.scss +2 -1
- package/ui/styles/components/_sub-navigation.scss +76 -0
- package/ui/styles/components/header/_header.scss +13 -0
- package/ui/styles/components/header/_logo.scss +20 -0
- package/ui/styles/components/header/_navbar.scss +15 -0
- package/ui/styles/components/header/index.scss +3 -0
- package/ui/styles/components/index.scss +5 -4
- package/ui/styles/components/search/_filters.scss +265 -0
- package/ui/styles/components/search/_form.scss +171 -0
- package/ui/styles/components/search/_results.scss +158 -0
- package/ui/styles/components/search/index.scss +3 -0
- package/ui/styles/index.css +584 -71
- package/ui/styles/variables.scss +15 -5
- package/ui/styles/components/_command.scss +0 -164
- package/ui/styles/components/_header.scss +0 -0
package/ui/dist/index.mjs
CHANGED
|
@@ -120,7 +120,7 @@ function GridItem({ children, className = "", style = {}, ...rest }) {
|
|
|
120
120
|
}
|
|
121
121
|
function Grid({
|
|
122
122
|
breakpointCols,
|
|
123
|
-
gap = "
|
|
123
|
+
gap = "1.618rem",
|
|
124
124
|
paddingY = "0",
|
|
125
125
|
className = "",
|
|
126
126
|
style = {},
|
|
@@ -391,12 +391,12 @@ function SearchTabs({
|
|
|
391
391
|
const toLabel = (t) => t && t.length ? t.charAt(0).toUpperCase() + t.slice(1) : "";
|
|
392
392
|
const hasFilters = typeof onOpenFilters === "function";
|
|
393
393
|
const filterBadge = activeFilterCount > 0 ? ` (${activeFilterCount})` : "";
|
|
394
|
-
return /* @__PURE__ */ React11.createElement("div", { className: "
|
|
394
|
+
return /* @__PURE__ */ React11.createElement("div", { className: "canopy-search-tabs-wrapper" }, /* @__PURE__ */ React11.createElement(
|
|
395
395
|
"div",
|
|
396
396
|
{
|
|
397
397
|
role: "tablist",
|
|
398
398
|
"aria-label": "Search types",
|
|
399
|
-
className: "
|
|
399
|
+
className: "canopy-search-tabs"
|
|
400
400
|
},
|
|
401
401
|
orderedTypes.map((t) => {
|
|
402
402
|
const active = String(type).toLowerCase() === String(t).toLowerCase();
|
|
@@ -409,8 +409,7 @@ function SearchTabs({
|
|
|
409
409
|
role: "tab",
|
|
410
410
|
"aria-selected": active,
|
|
411
411
|
type: "button",
|
|
412
|
-
onClick: () => onTypeChange && onTypeChange(t)
|
|
413
|
-
className: "px-3 py-2 text-sm rounded-t-md border-b-2 -mb-px transition-colors " + (active ? "border-brand-600 text-brand-700" : "border-transparent text-slate-600 hover:text-slate-900 hover:border-slate-300")
|
|
412
|
+
onClick: () => onTypeChange && onTypeChange(t)
|
|
414
413
|
},
|
|
415
414
|
toLabel(t),
|
|
416
415
|
" (",
|
|
@@ -479,18 +478,18 @@ function FacetSection({ facet, selected, onToggle }) {
|
|
|
479
478
|
return /* @__PURE__ */ React12.createElement(
|
|
480
479
|
"details",
|
|
481
480
|
{
|
|
482
|
-
className: "
|
|
481
|
+
className: "canopy-search-filters__facet",
|
|
483
482
|
open: hasSelection
|
|
484
483
|
},
|
|
485
|
-
/* @__PURE__ */ React12.createElement("summary", { className: "
|
|
486
|
-
/* @__PURE__ */ React12.createElement("div", { className: "
|
|
484
|
+
/* @__PURE__ */ React12.createElement("summary", { className: "canopy-search-filters__facet-summary" }, /* @__PURE__ */ React12.createElement("span", null, label), /* @__PURE__ */ React12.createElement("span", { className: "canopy-search-filters__facet-count" }, values.length)),
|
|
485
|
+
/* @__PURE__ */ React12.createElement("div", { className: "canopy-search-filters__facet-content" }, /* @__PURE__ */ React12.createElement("div", { className: "canopy-search-filters__quick" }, /* @__PURE__ */ React12.createElement(
|
|
487
486
|
"input",
|
|
488
487
|
{
|
|
489
488
|
type: "search",
|
|
490
489
|
value: quickQuery,
|
|
491
490
|
onChange: (event) => setQuickQuery(event.target.value),
|
|
492
491
|
placeholder: "Search values",
|
|
493
|
-
className: "
|
|
492
|
+
className: "canopy-search-filters__quick-input",
|
|
494
493
|
"aria-label": `Filter ${label} values`
|
|
495
494
|
}
|
|
496
495
|
), quickQuery ? /* @__PURE__ */ React12.createElement(
|
|
@@ -498,19 +497,19 @@ function FacetSection({ facet, selected, onToggle }) {
|
|
|
498
497
|
{
|
|
499
498
|
type: "button",
|
|
500
499
|
onClick: () => setQuickQuery(""),
|
|
501
|
-
className: "
|
|
500
|
+
className: "canopy-search-filters__quick-clear"
|
|
502
501
|
},
|
|
503
502
|
"Clear"
|
|
504
|
-
) : null), hasQuery && !filteredValues.length ? /* @__PURE__ */ React12.createElement("p", { className: "
|
|
503
|
+
) : null), hasQuery && !filteredValues.length ? /* @__PURE__ */ React12.createElement("p", { className: "canopy-search-filters__facet-notice" }, "No matches found.") : null, /* @__PURE__ */ React12.createElement("ul", { className: "canopy-search-filters__facet-list" }, filteredValues.map((entry) => {
|
|
505
504
|
const valueSlug = String(entry.slug || entry.value || "");
|
|
506
505
|
const isChecked = selectedValues.has(valueSlug);
|
|
507
506
|
const inputId = checkboxId(valueSlug);
|
|
508
|
-
return /* @__PURE__ */ React12.createElement("li", { key: valueSlug, className: "
|
|
507
|
+
return /* @__PURE__ */ React12.createElement("li", { key: valueSlug, className: "canopy-search-filters__facet-item" }, /* @__PURE__ */ React12.createElement(
|
|
509
508
|
"input",
|
|
510
509
|
{
|
|
511
510
|
id: inputId,
|
|
512
511
|
type: "checkbox",
|
|
513
|
-
className: "
|
|
512
|
+
className: "canopy-search-filters__facet-checkbox",
|
|
514
513
|
checked: isChecked,
|
|
515
514
|
onChange: (event) => {
|
|
516
515
|
const nextChecked = !!event.target.checked;
|
|
@@ -521,11 +520,11 @@ function FacetSection({ facet, selected, onToggle }) {
|
|
|
521
520
|
"label",
|
|
522
521
|
{
|
|
523
522
|
htmlFor: inputId,
|
|
524
|
-
className: "
|
|
523
|
+
className: "canopy-search-filters__facet-label"
|
|
525
524
|
},
|
|
526
|
-
/* @__PURE__ */ React12.createElement("span", null, entry.value, " ", Number.isFinite(entry.doc_count) ? /* @__PURE__ */ React12.createElement("span", { className: "
|
|
525
|
+
/* @__PURE__ */ React12.createElement("span", null, entry.value, " ", Number.isFinite(entry.doc_count) ? /* @__PURE__ */ React12.createElement("span", { className: "canopy-search-filters__facet-count" }, "(", entry.doc_count, ")") : null)
|
|
527
526
|
));
|
|
528
|
-
}), !filteredValues.length && !hasQuery ? /* @__PURE__ */ React12.createElement("li", { className: "
|
|
527
|
+
}), !filteredValues.length && !hasQuery ? /* @__PURE__ */ React12.createElement("li", { className: "canopy-search-filters__facet-empty" }, "No values available.") : null))
|
|
529
528
|
);
|
|
530
529
|
}
|
|
531
530
|
function SearchFiltersDialog(props = {}) {
|
|
@@ -550,21 +549,21 @@ function SearchFiltersDialog(props = {}) {
|
|
|
550
549
|
{
|
|
551
550
|
role: "dialog",
|
|
552
551
|
"aria-modal": "true",
|
|
553
|
-
className: "
|
|
552
|
+
className: "canopy-search-filters-overlay",
|
|
554
553
|
onClick: (event) => {
|
|
555
554
|
if (event.target === event.currentTarget && onOpenChange)
|
|
556
555
|
onOpenChange(false);
|
|
557
556
|
}
|
|
558
557
|
},
|
|
559
|
-
/* @__PURE__ */ React12.createElement("div", { className: "
|
|
558
|
+
/* @__PURE__ */ React12.createElement("div", { className: "canopy-search-filters" }, /* @__PURE__ */ React12.createElement("header", { className: "canopy-search-filters__header" }, /* @__PURE__ */ React12.createElement("div", null, /* @__PURE__ */ React12.createElement("h2", { className: "canopy-search-filters__title" }, title), /* @__PURE__ */ React12.createElement("p", { className: "canopy-search-filters__subtitle" }, subtitle)), /* @__PURE__ */ React12.createElement(
|
|
560
559
|
"button",
|
|
561
560
|
{
|
|
562
561
|
type: "button",
|
|
563
562
|
onClick: () => onOpenChange && onOpenChange(false),
|
|
564
|
-
className: "
|
|
563
|
+
className: "canopy-search-filters__close"
|
|
565
564
|
},
|
|
566
565
|
"Close"
|
|
567
|
-
)), /* @__PURE__ */ React12.createElement("div", { className: "
|
|
566
|
+
)), /* @__PURE__ */ React12.createElement("div", { className: "canopy-search-filters__body" }, Array.isArray(facets) && facets.length ? /* @__PURE__ */ React12.createElement("div", { className: "canopy-search-filters__facets" }, facets.map((facet) => /* @__PURE__ */ React12.createElement(
|
|
568
567
|
FacetSection,
|
|
569
568
|
{
|
|
570
569
|
key: facet.slug || facet.label,
|
|
@@ -572,7 +571,7 @@ function SearchFiltersDialog(props = {}) {
|
|
|
572
571
|
selected: selectedMap,
|
|
573
572
|
onToggle
|
|
574
573
|
}
|
|
575
|
-
))) : /* @__PURE__ */ React12.createElement("p", { className: "
|
|
574
|
+
))) : /* @__PURE__ */ React12.createElement("p", { className: "canopy-search-filters__empty" }, "No filters are available for this collection.")), /* @__PURE__ */ React12.createElement("footer", { className: "canopy-search-filters__footer" }, /* @__PURE__ */ React12.createElement("div", null, activeCount ? `${activeCount} filter${activeCount === 1 ? "" : "s"} applied` : "No filters applied"), /* @__PURE__ */ React12.createElement("div", { className: "canopy-search-filters__footer-actions" }, /* @__PURE__ */ React12.createElement(
|
|
576
575
|
"button",
|
|
577
576
|
{
|
|
578
577
|
type: "button",
|
|
@@ -580,7 +579,7 @@ function SearchFiltersDialog(props = {}) {
|
|
|
580
579
|
if (onClear) onClear();
|
|
581
580
|
},
|
|
582
581
|
disabled: !activeCount,
|
|
583
|
-
className: "
|
|
582
|
+
className: "canopy-search-filters__button canopy-search-filters__button--secondary"
|
|
584
583
|
},
|
|
585
584
|
"Clear all"
|
|
586
585
|
), /* @__PURE__ */ React12.createElement(
|
|
@@ -588,14 +587,14 @@ function SearchFiltersDialog(props = {}) {
|
|
|
588
587
|
{
|
|
589
588
|
type: "button",
|
|
590
589
|
onClick: () => onOpenChange && onOpenChange(false),
|
|
591
|
-
className: "
|
|
590
|
+
className: "canopy-search-filters__button canopy-search-filters__button--primary"
|
|
592
591
|
},
|
|
593
592
|
"Done"
|
|
594
593
|
))))
|
|
595
594
|
);
|
|
596
595
|
}
|
|
597
596
|
|
|
598
|
-
// ui/src/
|
|
597
|
+
// ui/src/search-form/MdxSearchFormModal.jsx
|
|
599
598
|
import React16 from "react";
|
|
600
599
|
|
|
601
600
|
// ui/src/Icons.jsx
|
|
@@ -671,10 +670,11 @@ function SearchPanelForm(props = {}) {
|
|
|
671
670
|
);
|
|
672
671
|
const autoId = typeof React14.useId === "function" ? React14.useId() : void 0;
|
|
673
672
|
const [fallbackId] = React14.useState(
|
|
674
|
-
() => `canopy-
|
|
673
|
+
() => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`
|
|
675
674
|
);
|
|
676
675
|
const inputId = inputIdProp || autoId || fallbackId;
|
|
677
676
|
const inputRef = React14.useRef(null);
|
|
677
|
+
const [hasValue, setHasValue] = React14.useState(false);
|
|
678
678
|
const focusInput = React14.useCallback(() => {
|
|
679
679
|
const el = inputRef.current;
|
|
680
680
|
if (!el) return;
|
|
@@ -688,14 +688,29 @@ function SearchPanelForm(props = {}) {
|
|
|
688
688
|
}
|
|
689
689
|
}
|
|
690
690
|
}, []);
|
|
691
|
-
const handlePointerDown = React14.useCallback(
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
if (target.closest
|
|
691
|
+
const handlePointerDown = React14.useCallback(
|
|
692
|
+
(event) => {
|
|
693
|
+
const target = event.target;
|
|
694
|
+
if (target && typeof target.closest === "function") {
|
|
695
|
+
if (target.closest("[data-canopy-search-form-trigger]")) return;
|
|
696
|
+
}
|
|
697
|
+
event.preventDefault();
|
|
698
|
+
focusInput();
|
|
699
|
+
},
|
|
700
|
+
[focusInput]
|
|
701
|
+
);
|
|
702
|
+
React14.useEffect(() => {
|
|
703
|
+
const el = inputRef.current;
|
|
704
|
+
if (!el) return;
|
|
705
|
+
if (el.value && el.value.trim()) {
|
|
706
|
+
setHasValue(true);
|
|
695
707
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
708
|
+
}, []);
|
|
709
|
+
const handleInputChange = React14.useCallback((event) => {
|
|
710
|
+
var _a;
|
|
711
|
+
const nextHasValue = Boolean(((_a = event == null ? void 0 : event.target) == null ? void 0 : _a.value) && event.target.value.trim());
|
|
712
|
+
setHasValue(nextHasValue);
|
|
713
|
+
}, []);
|
|
699
714
|
return /* @__PURE__ */ React14.createElement(
|
|
700
715
|
"form",
|
|
701
716
|
{
|
|
@@ -704,17 +719,18 @@ function SearchPanelForm(props = {}) {
|
|
|
704
719
|
role: "search",
|
|
705
720
|
autoComplete: "off",
|
|
706
721
|
spellCheck: "false",
|
|
707
|
-
className: "
|
|
722
|
+
className: "canopy-search-form canopy-search-form-shell",
|
|
708
723
|
onPointerDown: handlePointerDown,
|
|
709
|
-
"data-placeholder": placeholder || ""
|
|
724
|
+
"data-placeholder": placeholder || "",
|
|
725
|
+
"data-has-value": hasValue ? "1" : "0"
|
|
710
726
|
},
|
|
711
727
|
/* @__PURE__ */ React14.createElement(
|
|
712
728
|
"label",
|
|
713
729
|
{
|
|
714
730
|
htmlFor: inputId,
|
|
715
|
-
className: "
|
|
731
|
+
className: "canopy-search-form__label"
|
|
716
732
|
},
|
|
717
|
-
/* @__PURE__ */ React14.createElement(MagnifyingGlassIcon, { className: "
|
|
733
|
+
/* @__PURE__ */ React14.createElement(MagnifyingGlassIcon, { className: "canopy-search-form__icon" }),
|
|
718
734
|
/* @__PURE__ */ React14.createElement(
|
|
719
735
|
"input",
|
|
720
736
|
{
|
|
@@ -722,11 +738,13 @@ function SearchPanelForm(props = {}) {
|
|
|
722
738
|
type: "search",
|
|
723
739
|
name: "q",
|
|
724
740
|
inputMode: "search",
|
|
725
|
-
"data-canopy-
|
|
741
|
+
"data-canopy-search-form-input": true,
|
|
726
742
|
placeholder,
|
|
727
|
-
className: "
|
|
743
|
+
className: "canopy-search-form__input",
|
|
728
744
|
"aria-label": "Search",
|
|
729
|
-
ref: inputRef
|
|
745
|
+
ref: inputRef,
|
|
746
|
+
onChange: handleInputChange,
|
|
747
|
+
onInput: handleInputChange
|
|
730
748
|
}
|
|
731
749
|
)
|
|
732
750
|
),
|
|
@@ -734,11 +752,11 @@ function SearchPanelForm(props = {}) {
|
|
|
734
752
|
"button",
|
|
735
753
|
{
|
|
736
754
|
type: "submit",
|
|
737
|
-
"data-canopy-
|
|
738
|
-
className: "
|
|
755
|
+
"data-canopy-search-form-trigger": "submit",
|
|
756
|
+
className: "canopy-search-form__submit"
|
|
739
757
|
},
|
|
740
758
|
/* @__PURE__ */ React14.createElement("span", null, text),
|
|
741
|
-
/* @__PURE__ */ React14.createElement("span", { "aria-hidden": true, className: "
|
|
759
|
+
/* @__PURE__ */ React14.createElement("span", { "aria-hidden": true, className: "canopy-search-form__shortcut" }, /* @__PURE__ */ React14.createElement("span", null, "\u2318"), /* @__PURE__ */ React14.createElement("span", null, "K"))
|
|
742
760
|
)
|
|
743
761
|
);
|
|
744
762
|
}
|
|
@@ -746,26 +764,21 @@ function SearchPanelForm(props = {}) {
|
|
|
746
764
|
// ui/src/search/SearchPanelTeaserResults.jsx
|
|
747
765
|
import React15 from "react";
|
|
748
766
|
function SearchPanelTeaserResults(props = {}) {
|
|
749
|
-
const { style } = props || {};
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
zIndex: 1e3,
|
|
761
|
-
overflow: "auto",
|
|
762
|
-
maxHeight: "60vh"
|
|
763
|
-
};
|
|
764
|
-
return /* @__PURE__ */ React15.createElement("div", { "data-canopy-command-panel": true, style: { ...baseStyle, ...style || {} } }, /* @__PURE__ */ React15.createElement("div", { id: "cplist" }));
|
|
767
|
+
const { style, className } = props || {};
|
|
768
|
+
const classes = ["canopy-search-teaser", className].filter(Boolean).join(" ");
|
|
769
|
+
return /* @__PURE__ */ React15.createElement(
|
|
770
|
+
"div",
|
|
771
|
+
{
|
|
772
|
+
"data-canopy-search-form-panel": true,
|
|
773
|
+
className: classes || void 0,
|
|
774
|
+
style
|
|
775
|
+
},
|
|
776
|
+
/* @__PURE__ */ React15.createElement("div", { id: "cplist" })
|
|
777
|
+
);
|
|
765
778
|
}
|
|
766
779
|
|
|
767
|
-
// ui/src/
|
|
768
|
-
function
|
|
780
|
+
// ui/src/search-form/MdxSearchFormModal.jsx
|
|
781
|
+
function MdxSearchFormModal(props = {}) {
|
|
769
782
|
const {
|
|
770
783
|
placeholder = "Search\u2026",
|
|
771
784
|
hotkey = "mod+k",
|
|
@@ -780,7 +793,7 @@ function MdxCommandPalette(props = {}) {
|
|
|
780
793
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
781
794
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
782
795
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
783
|
-
return /* @__PURE__ */ React16.createElement("div", { "data-canopy-
|
|
796
|
+
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) } }));
|
|
784
797
|
}
|
|
785
798
|
|
|
786
799
|
// ui/src/search/SearchPanel.jsx
|
|
@@ -801,16 +814,16 @@ function SearchPanel(props = {}) {
|
|
|
801
814
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
802
815
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
803
816
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
804
|
-
return /* @__PURE__ */ React17.createElement("div", { "data-canopy-
|
|
817
|
+
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) } }));
|
|
805
818
|
}
|
|
806
819
|
export {
|
|
807
820
|
Card,
|
|
808
|
-
MdxCommandPalette as CommandPalette,
|
|
809
821
|
Grid,
|
|
810
822
|
GridItem,
|
|
811
823
|
HelloWorld,
|
|
812
824
|
MdxRelatedItems as RelatedItems,
|
|
813
825
|
SearchFiltersDialog,
|
|
826
|
+
MdxSearchFormModal as SearchFormModal,
|
|
814
827
|
SearchPanel,
|
|
815
828
|
SearchPanelForm,
|
|
816
829
|
SearchPanelTeaserResults,
|
package/ui/dist/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/HelloWorld.jsx", "../src/layout/Card.jsx", "../src/layout/Grid.jsx", "../src/iiif/Viewer.jsx", "../src/iiif/Slider.jsx", "../src/iiif/MdxRelatedItems.jsx", "../src/search/MdxSearchResults.jsx", "../src/search/SearchSummary.jsx", "../src/search/MdxSearchTabs.jsx", "../src/search/SearchResults.jsx", "../src/search/SearchTabs.jsx", "../src/search/SearchFiltersDialog.jsx", "../src/
|
|
4
|
-
"sourcesContent": ["import React from \"react\";\n\nexport const HelloWorld = () => {\n return <div>Hello, World!</div>;\n};\n", "import React, { useEffect, useRef, useState } from \"react\";\n\n/**\n * Card\n *\n * Renders an anchor wrapping a figure with an image and caption.\n * Minimal styling; consumers can override via className/style.\n *\n * Props:\n * - href: string (required) \u2014 link target\n * - src: string (optional) \u2014 image source\n * - alt: string (optional) \u2014 image alt text (falls back to title)\n * - title: string (optional) \u2014 primary caption text\n * - subtitle: string (optional) \u2014 secondary caption text\n * - className: string (optional)\n * - style: object (optional)\n * - children: ReactNode (optional) \u2014 appended inside figcaption\n */\nexport default function Card({\n href,\n src,\n alt,\n title,\n subtitle,\n // Optional intrinsic dimensions or aspect ratio to compute a responsive height\n imgWidth,\n imgHeight,\n aspectRatio,\n className,\n style,\n children,\n ...rest\n}) {\n const containerRef = useRef(null);\n const [inView, setInView] = useState(false);\n const [imageLoaded, setImageLoaded] = useState(false);\n\n /**\n * Use IntersectionObserver to detect when the card enters the viewport.\n * When in view, setInView(true) to trigger image loading.\n * If IntersectionObserver is not supported, default to inView=true.\n */\n useEffect(() => {\n if (!containerRef.current) return;\n if (typeof IntersectionObserver !== \"function\") {\n setInView(true);\n return;\n }\n const el = containerRef.current;\n const obs = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n setInView(true);\n try {\n obs.unobserve(el);\n } catch (_) {}\n break;\n }\n }\n },\n { root: null, rootMargin: \"100px\", threshold: 0.1 }\n );\n try {\n obs.observe(el);\n } catch (_) {}\n return () => {\n try {\n obs.disconnect();\n } catch (_) {}\n };\n }, []);\n\n /**\n * Calculate aspect ratio and padding percent for responsive image container.\n */\n const w = Number(imgWidth);\n const h = Number(imgHeight);\n const ratio =\n Number.isFinite(Number(aspectRatio)) && Number(aspectRatio) > 0\n ? Number(aspectRatio)\n : Number.isFinite(w) && w > 0 && Number.isFinite(h) && h > 0\n ? w / h\n : undefined;\n const paddingPercent = ratio ? 100 / ratio : 100;\n\n /**\n * Caption element (figcaption), rendered if title, subtitle, or children are provided.\n */\n const caption = (\n <figcaption>\n {title && <span>{title}</span>}\n {subtitle && <span>{subtitle}</span>}\n {children}\n </figcaption>\n );\n\n return (\n <a\n href={href}\n className={[\"canopy-card\", className].filter(Boolean).join(\" \")}\n style={style}\n ref={containerRef}\n data-aspect-ratio={ratio}\n data-in-view={inView ? \"true\" : \"false\"}\n data-image-loaded={imageLoaded ? \"true\" : \"false\"}\n {...rest}\n >\n <figure>\n {src ? (\n ratio ? (\n <div\n className=\"canopy-card-media\"\n style={{ \"--canopy-card-padding\": `${paddingPercent}%` }}\n >\n {inView ? (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n />\n ) : null}\n </div>\n ) : (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n className=\"canopy-card-image\"\n />\n )\n ) : null}\n {caption}\n </figure>\n </a>\n );\n}\n", "import Masonry from \"react-masonry-css\";\nimport React from \"react\";\n\n// Simple item wrapper to provide consistent spacing between items.\nexport function GridItem({ children, className = \"\", style = {}, ...rest }) {\n return (\n <div\n className={`canopy-grid-item ${className}`.trim()}\n style={style}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Grid (Masonry)\n *\n * Lightweight wrapper around `react-masonry-css` with sensible defaults\n * and inline styles so it works without a global CSS pipeline.\n *\n * Props:\n * - breakpointCols: number | object \u2014 columns per breakpoint (react-masonry-css prop)\n * - gap: CSS length string \u2014 spacing between items/columns (default '1rem')\n * - paddingY: CSS length string \u2014 vertical padding for the grid (default '0')\n * - className, style \u2014 forwarded to container\n * - columnClassName \u2014 forwarded to Masonry (defaults to 'canopy-grid-column')\n * - children \u2014 usually a list of <GridItem> elements\n */\nexport default function Grid({\n breakpointCols,\n gap = \"2rem\",\n paddingY = \"0\",\n className = \"\",\n style = {},\n columnClassName = \"canopy-grid-column\",\n children,\n ...rest\n}) {\n const cols = breakpointCols || {\n default: 6,\n 1280: 5,\n 1024: 4,\n 768: 3,\n 640: 2,\n };\n const vars = { \"--grid-gap\": gap, \"--grid-padding-y\": paddingY };\n\n return (\n <div className=\"canopy-grid-wrap\">\n {/* Scoped styles so the component works standalone */}\n <style\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: `\n .canopy-grid { display: flex; width: auto; position: relative; padding: var(--grid-padding-y, 0) 0; z-index: 1; }\n .canopy-grid .${columnClassName} { margin-left: var(--grid-gap, 1rem); }\n .canopy-grid .${columnClassName}:first-child { margin-left: 0; }\n .canopy-grid-item { margin-bottom: var(--grid-gap, 1rem); }\n `,\n }}\n />\n <Masonry\n breakpointCols={cols}\n className={`canopy-grid ${className}`.trim()}\n columnClassName={columnClassName}\n style={{ ...vars, ...style }}\n {...rest}\n >\n {children}\n </Masonry>\n </div>\n );\n}\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's viewer. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\n\n// Default Clover viewer options; can be overridden per-usage via props.options\nconst DEFAULT_VIEWER_OPTIONS = {\n showDownload: false,\n showIIIFBadge: false,\n showTitle: false,\n informationPanel: {\n open: false,\n renderAbout: false,\n renderToggle: false,\n },\n};\n\nfunction isPlainObject(val) {\n return val && typeof val === \"object\" && !Array.isArray(val);\n}\n\nfunction deepMerge(base, override) {\n if (!isPlainObject(base)) return override;\n const out = { ...base };\n if (!isPlainObject(override)) return out;\n for (const key of Object.keys(override)) {\n const a = base[key];\n const b = override[key];\n if (isPlainObject(a) && isPlainObject(b)) out[key] = deepMerge(a, b);\n else out[key] = b;\n }\n return out;\n}\n\nexport const Viewer = (props) => {\n const [CloverViewer, setCloverViewer] = useState(null);\n const mergedOptions = deepMerge(\n DEFAULT_VIEWER_OPTIONS,\n props && props.options\n );\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/viewer\")\n .then((mod) => {\n if (!mounted) return;\n // Loaded Clover viewer dynamically in the browser\n const Comp = mod && (mod.default || mod.Viewer || mod);\n setCloverViewer(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverViewer) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n const p = { ...(props || {}) };\n if (mergedOptions) p.options = mergedOptions;\n json = JSON.stringify(p);\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-viewer=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverViewer {...props} options={mergedOptions} />;\n};\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's slider. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\nexport const Slider = (props) => {\n const [CloverSlider, setCloverSlider] = useState(null);\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/slider\")\n .then((mod) => {\n if (!mounted) return;\n console.log(mod);\n const Comp = mod && (mod.default || mod.Slider || mod);\n setCloverSlider(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverSlider) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-slider=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverSlider {...props} />;\n};\n", "import React from 'react';\n\n// SSR-safe placeholder for RelatedItems. Hydrated by canopy-related-items.js + canopy-slider.js\nexport default function MdxRelatedItems(props) {\n let json = '{}';\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = '{}';\n }\n return (\n <div data-canopy-related-items=\"1\" className=\"not-prose\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n", "import React from 'react';\n\nexport default function MdxSearchResults(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-results=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function SearchSummary(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-summary=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function MdxSearchTabs(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-tabs=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import Grid, { GridItem } from \"../layout/Grid.jsx\";\n\nimport Card from \"../layout/Card.jsx\";\nimport React from \"react\";\n\nexport default function SearchResults({\n results = [],\n type = \"all\",\n layout = \"grid\",\n}) {\n if (!results.length) {\n return (\n <div className=\"text-slate-600\">\n <em>No results</em>\n </div>\n );\n }\n\n if (layout === \"list\") {\n return (\n <ul id=\"search-results\" className=\"space-y-3\">\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <li\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </li>\n );\n })}\n </ul>\n );\n }\n\n // Default: grid (masonry)\n return (\n <div id=\"search-results\">\n <Grid>\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <GridItem\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </GridItem>\n );\n })}\n </Grid>\n </div>\n );\n}\n", "import React from \"react\";\n\nexport default function SearchTabs({\n type = \"all\",\n onTypeChange,\n types = [],\n counts = {},\n onOpenFilters,\n activeFilterCount = 0,\n filtersLabel = \"Filters\",\n filtersOpen = false,\n}) {\n const orderedTypes = Array.isArray(types) ? types : [];\n const toLabel = (t) =>\n t && t.length ? t.charAt(0).toUpperCase() + t.slice(1) : \"\";\n const hasFilters = typeof onOpenFilters === \"function\";\n const filterBadge = activeFilterCount > 0 ? ` (${activeFilterCount})` : \"\";\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 pb-1\">\n <div\n role=\"tablist\"\n aria-label=\"Search types\"\n className=\"flex items-center gap-2\"\n >\n {orderedTypes.map((t) => {\n const active = String(type).toLowerCase() === String(t).toLowerCase();\n const cRaw =\n counts && Object.prototype.hasOwnProperty.call(counts, t)\n ? counts[t]\n : undefined;\n const c = Number.isFinite(Number(cRaw)) ? Number(cRaw) : 0;\n return (\n <button\n key={t}\n role=\"tab\"\n aria-selected={active}\n type=\"button\"\n onClick={() => onTypeChange && onTypeChange(t)}\n className={\n \"px-3 py-2 text-sm rounded-t-md border-b-2 -mb-px transition-colors \" +\n (active\n ? \"border-brand-600 text-brand-700\"\n : \"border-transparent text-slate-600 hover:text-slate-900 hover:border-slate-300\")\n }\n >\n {toLabel(t)} ({c})\n </button>\n );\n })}\n </div>\n {hasFilters ? (\n <button\n type=\"button\"\n onClick={() => onOpenFilters && onOpenFilters()}\n aria-expanded={filtersOpen ? \"true\" : \"false\"}\n className=\"inline-flex items-center gap-2 rounded-md border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 shadow-sm transition hover:border-brand-200 hover:bg-brand-50 hover:text-brand-700\"\n >\n <span>\n {filtersLabel}\n {filterBadge}\n </span>\n </button>\n ) : null}\n </div>\n );\n}\n", "import React from \"react\";\n\nfunction toArray(input) {\n if (!input) return [];\n if (Array.isArray(input)) return input;\n return [input];\n}\n\nfunction normalizeSelected(selected = {}) {\n const map = new Map();\n if (selected && typeof selected === \"object\") {\n Object.keys(selected).forEach((key) => {\n const vals = new Set(toArray(selected[key]).map((v) => String(v)));\n if (vals.size) map.set(String(key), vals);\n });\n }\n return map;\n}\n\nfunction facetMatches(values = [], query) {\n const q = String(query || \"\")\n .trim()\n .toLowerCase();\n if (!q) return values;\n const starts = [];\n const contains = [];\n values.forEach((entry) => {\n if (!entry || !entry.value) return;\n const value = String(entry.value);\n const slug = String(entry.slug || entry.value || \"\");\n const match = value.toLowerCase();\n if (match.startsWith(q))\n starts.push({value, slug, doc_count: entry.doc_count});\n else if (match.includes(q))\n contains.push({value, slug, doc_count: entry.doc_count});\n });\n return [...starts, ...contains].slice(0, 10);\n}\n\nfunction FacetSection({facet, selected, onToggle}) {\n if (!facet || !facet.label || !Array.isArray(facet.values)) return null;\n const {label, slug, values} = facet;\n const selectedValues = selected.get(String(slug)) || new Set();\n const checkboxId = (valueSlug) => `filter-${slug}-${valueSlug}`;\n const hasSelection = selectedValues.size > 0;\n const [quickQuery, setQuickQuery] = React.useState(\"\");\n const hasQuery = quickQuery.trim().length > 0;\n const filteredValues = React.useMemo(\n () => facetMatches(values, quickQuery),\n [values, quickQuery]\n );\n\n return (\n <details\n className=\"rounded-lg border border-slate-200 bg-slate-50\"\n open={hasSelection}\n >\n <summary className=\"flex cursor-pointer items-center justify-between gap-3 px-4 py-3 text-sm font-medium text-slate-900\">\n <span>{label}</span>\n <span className=\"text-xs font-normal text-slate-500\">\n {values.length}\n </span>\n </summary>\n <div className=\"max-h-60 overflow-y-auto border-t border-slate-200 bg-white px-4 py-3 text-sm text-slate-700\">\n <div className=\"mb-3 flex items-center gap-2\">\n <input\n type=\"search\"\n value={quickQuery}\n onChange={(event) => setQuickQuery(event.target.value)}\n placeholder=\"Search values\"\n className=\"flex-1 rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 focus:border-brand focus:outline-none focus:ring-1 focus:ring-brand\"\n aria-label={`Filter ${label} values`}\n />\n {quickQuery ? (\n <button\n type=\"button\"\n onClick={() => setQuickQuery(\"\")}\n className=\"rounded-md border border-slate-200 px-2 py-1 text-xs text-slate-600 transition hover:bg-slate-100\"\n >\n Clear\n </button>\n ) : null}\n </div>\n {hasQuery && !filteredValues.length ? (\n <p className=\"mb-3 text-xs text-slate-400\">No matches found.</p>\n ) : null}\n <ul className=\"space-y-2\" style={{padding: 0}}>\n {filteredValues.map((entry) => {\n const valueSlug = String(entry.slug || entry.value || \"\");\n const isChecked = selectedValues.has(valueSlug);\n const inputId = checkboxId(valueSlug);\n return (\n <li key={valueSlug} className=\"flex items-start gap-2\">\n <input\n id={inputId}\n type=\"checkbox\"\n className=\"mt-1 h-4 w-4 rounded border-slate-300 text-brand focus:ring-brand\"\n checked={isChecked}\n onChange={(event) => {\n const nextChecked = !!event.target.checked;\n if (onToggle) onToggle(slug, valueSlug, nextChecked);\n }}\n />\n <label\n htmlFor={inputId}\n className=\"flex flex-1 flex-col gap-0.5\"\n >\n <span>\n {entry.value}{\" \"}\n {Number.isFinite(entry.doc_count) ? (\n <span className=\"text-xs text-slate-500\">\n ({entry.doc_count})\n </span>\n ) : null}\n </span>\n </label>\n </li>\n );\n })}\n {!filteredValues.length && !hasQuery ? (\n <li className=\"text-xs text-slate-400\">No values available.</li>\n ) : null}\n </ul>\n </div>\n </details>\n );\n}\n\nexport default function SearchFiltersDialog(props = {}) {\n const {\n open = false,\n onOpenChange,\n facets = [],\n selected = {},\n onToggle,\n onClear,\n title = \"Filters\",\n subtitle = \"Refine results by metadata\",\n } = props;\n\n const selectedMap = normalizeSelected(selected);\n const activeCount = Array.from(selectedMap.values()).reduce(\n (total, set) => total + set.size,\n 0\n );\n\n if (!open) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex items-start justify-center bg-slate-900/50 px-4 py-8\"\n onClick={(event) => {\n if (event.target === event.currentTarget && onOpenChange)\n onOpenChange(false);\n }}\n >\n <div className=\"w-full max-w-3xl overflow-hidden rounded-xl bg-white shadow-2xl\">\n <header className=\"flex items-start justify-between gap-4 border-b border-slate-200 px-6 py-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-slate-900\">{title}</h2>\n <p className=\"text-sm text-slate-500\">{subtitle}</p>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"rounded-md border border-transparent px-2 py-1 text-sm text-slate-600 transition hover:bg-slate-100 hover:text-slate-900\"\n >\n Close\n </button>\n </header>\n <div className=\"grid gap-4 px-6 py-6\">\n {Array.isArray(facets) && facets.length ? (\n <div className=\"space-y-3\">\n {facets.map((facet) => (\n <FacetSection\n key={facet.slug || facet.label}\n facet={facet}\n selected={selectedMap}\n onToggle={onToggle}\n />\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-slate-500\">\n No filters are available for this collection.\n </p>\n )}\n </div>\n <footer className=\"flex items-center justify-between gap-4 border-t border-slate-200 px-6 py-4\">\n <div className=\"text-sm text-slate-500\">\n {activeCount\n ? `${activeCount} filter${activeCount === 1 ? \"\" : \"s\"} applied`\n : \"No filters applied\"}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n if (onClear) onClear();\n }}\n disabled={!activeCount}\n className=\"rounded-md border border-slate-200 px-3 py-1.5 text-sm text-slate-600 transition disabled:cursor-not-allowed disabled:text-slate-400 hover:bg-slate-100\"\n >\n Clear all\n </button>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"rounded-md bg-brand px-4 py-1.5 text-sm font-semibold text-white shadow-sm transition hover:bg-brand-700\"\n >\n Done\n </button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from '../search/SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from '../search/SearchPanelTeaserResults.jsx';\n\n// SSR-safe placeholder for the command palette, composed from SearchPanel parts.\n// This ensures a single JSX source of truth for form/panel markup.\nexport default function MdxCommandPalette(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'page'],\n button = true, // kept for backward compat; ignored by teaser form\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n return (\n <div data-canopy-command className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <style>{`.relative[data-canopy-panel-auto='1']:focus-within [data-canopy-command-panel]{display:block}`}</style>\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n", "import React from \"react\";\n\nexport const MagnifyingGlassIcon = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" {...props}>\n <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\" />\n </svg>\n);\n", "import { MagnifyingGlassIcon } from \"../Icons\";\nimport React from \"react\";\n\nfunction readBasePath() {\n const normalize = (val) => {\n const raw = typeof val === \"string\" ? val.trim() : \"\";\n if (!raw) return \"\";\n return raw.replace(/\\/+$/, \"\");\n };\n try {\n if (typeof window !== \"undefined\" && window.CANOPY_BASE_PATH != null) {\n const fromWindow = normalize(window.CANOPY_BASE_PATH);\n if (fromWindow) return fromWindow;\n }\n } catch (_) {}\n try {\n if (typeof globalThis !== \"undefined\" && globalThis.CANOPY_BASE_PATH != null) {\n const fromGlobal = normalize(globalThis.CANOPY_BASE_PATH);\n if (fromGlobal) return fromGlobal;\n }\n } catch (_) {}\n try {\n if (typeof process !== \"undefined\" && process.env && process.env.CANOPY_BASE_PATH) {\n const fromEnv = normalize(process.env.CANOPY_BASE_PATH);\n if (fromEnv) return fromEnv;\n }\n } catch (_) {}\n return \"\";\n}\n\nfunction isAbsoluteUrl(href) {\n try {\n return /^https?:/i.test(String(href || \"\"));\n } catch (_) {\n return false;\n }\n}\n\nexport function resolveSearchPath(pathValue) {\n let raw = typeof pathValue === \"string\" ? pathValue.trim() : \"\";\n if (!raw) raw = \"/search\";\n if (isAbsoluteUrl(raw)) return raw;\n const normalizedPath = raw.startsWith(\"/\") ? raw : `/${raw}`;\n const base = readBasePath();\n if (!base) return normalizedPath;\n const baseWithLead = base.startsWith(\"/\") ? base : `/${base}`;\n const baseTrimmed = baseWithLead.replace(/\\/+$/, \"\");\n if (!baseTrimmed) return normalizedPath;\n if (\n normalizedPath === baseTrimmed ||\n normalizedPath.startsWith(`${baseTrimmed}/`)\n ) {\n return normalizedPath;\n }\n const pathTrimmed = normalizedPath.replace(/^\\/+/, \"\");\n return `${baseTrimmed}/${pathTrimmed}`;\n}\n\nexport default function SearchPanelForm(props = {}) {\n const {\n placeholder = \"Search\u2026\",\n buttonLabel = \"Search\",\n label,\n searchPath = \"/search\",\n inputId: inputIdProp,\n } = props || {};\n\n const text =\n typeof label === \"string\" && label.trim() ? label.trim() : buttonLabel;\n const action = React.useMemo(\n () => resolveSearchPath(searchPath),\n [searchPath]\n );\n const autoId = typeof React.useId === 'function' ? React.useId() : undefined;\n const [fallbackId] = React.useState(\n () => `canopy-cmdk-${Math.random().toString(36).slice(2, 10)}`\n );\n const inputId = inputIdProp || autoId || fallbackId;\n const inputRef = React.useRef(null);\n\n const focusInput = React.useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (document.activeElement === el) return;\n try { el.focus({ preventScroll: true }); }\n catch (_) {\n try { el.focus(); } catch (_) {}\n }\n }, []);\n\n const handlePointerDown = React.useCallback((event) => {\n const target = event.target;\n if (target && typeof target.closest === 'function') {\n if (target.closest('[data-canopy-command-trigger]')) return;\n }\n event.preventDefault();\n focusInput();\n }, [focusInput]);\n\n return (\n <form\n action={action}\n method=\"get\"\n role=\"search\"\n autoComplete=\"off\"\n spellCheck=\"false\"\n className=\"group flex items-center gap-2 rounded-lg border border-slate-300 text-slate-700 shadow-sm transition focus-within:ring-2 focus-within:ring-brand-500 canopy-cmdk-form\"\n onPointerDown={handlePointerDown}\n data-placeholder={placeholder || ''}\n >\n <label\n htmlFor={inputId}\n className=\"flex items-center gap-2 flex-1 min-w-0 cursor-text canopy-cmdk-label\"\n >\n <MagnifyingGlassIcon className=\"w-5 h-5 text-slate-400 group-focus-within:text-brand-500 pointer-events-none\" />\n <input\n id={inputId}\n type=\"search\"\n name=\"q\"\n inputMode=\"search\"\n data-canopy-command-input\n placeholder={placeholder}\n className=\"flex-1 bg-transparent outline-none placeholder:text-slate-400 py-1 min-w-0\"\n aria-label=\"Search\"\n ref={inputRef}\n />\n </label>\n <button\n type=\"submit\"\n data-canopy-command-trigger=\"submit\"\n className=\"inline-flex items-center gap-2 rounded-md border border-transparent bg-brand px-2 py-1 text-sm font-medium text-white shadow-sm transition hover:bg-brand-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2\"\n >\n <span>{text}</span>\n <span aria-hidden className=\"hidden sm:inline-flex items-center gap-1 text-xs font-semibold canopy-cmdk-shortcut\">\n <span>\u2318</span>\n <span>K</span>\n </span>\n </button>\n </form>\n );\n}\n", "import React from \"react\";\n\n// SSR placeholder for teaser results panel; the runtime controls visibility and content.\nexport default function SearchPanelTeaserResults(props = {}) {\n const { style } = props || {};\n const baseStyle = {\n display: \"none\",\n position: \"absolute\",\n left: 0,\n right: 0,\n top: \"calc(100% + 4px)\",\n background: \"#fff\",\n border: \"1px solid #e5e7eb\",\n borderRadius: 8,\n boxShadow: \"0 10px 25px rgba(0,0,0,0.12)\",\n zIndex: 1000,\n overflow: \"auto\",\n maxHeight: \"60vh\",\n };\n return (\n <div data-canopy-command-panel style={{ ...baseStyle, ...(style || {}) }}>\n <div id=\"cplist\" />\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from './SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from './SearchPanelTeaserResults.jsx';\n\n// High-level SearchPanel composed of a teaser form and teaser results panel.\n// Encodes configuration as JSON for the client runtime.\nexport default function SearchPanel(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'docs', 'page'],\n // Kept for backward compat; form always renders submit\n button = true, // eslint-disable-line no-unused-vars\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n\n return (\n <div data-canopy-command className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <style>{`.relative[data-canopy-panel-auto='1']:focus-within [data-canopy-command-panel]{display:block}`}</style>\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/HelloWorld.jsx", "../src/layout/Card.jsx", "../src/layout/Grid.jsx", "../src/iiif/Viewer.jsx", "../src/iiif/Slider.jsx", "../src/iiif/MdxRelatedItems.jsx", "../src/search/MdxSearchResults.jsx", "../src/search/SearchSummary.jsx", "../src/search/MdxSearchTabs.jsx", "../src/search/SearchResults.jsx", "../src/search/SearchTabs.jsx", "../src/search/SearchFiltersDialog.jsx", "../src/search-form/MdxSearchFormModal.jsx", "../src/Icons.jsx", "../src/search/SearchPanelForm.jsx", "../src/search/SearchPanelTeaserResults.jsx", "../src/search/SearchPanel.jsx"],
|
|
4
|
+
"sourcesContent": ["import React from \"react\";\n\nexport const HelloWorld = () => {\n return <div>Hello, World!</div>;\n};\n", "import React, { useEffect, useRef, useState } from \"react\";\n\n/**\n * Card\n *\n * Renders an anchor wrapping a figure with an image and caption.\n * Minimal styling; consumers can override via className/style.\n *\n * Props:\n * - href: string (required) \u2014 link target\n * - src: string (optional) \u2014 image source\n * - alt: string (optional) \u2014 image alt text (falls back to title)\n * - title: string (optional) \u2014 primary caption text\n * - subtitle: string (optional) \u2014 secondary caption text\n * - className: string (optional)\n * - style: object (optional)\n * - children: ReactNode (optional) \u2014 appended inside figcaption\n */\nexport default function Card({\n href,\n src,\n alt,\n title,\n subtitle,\n // Optional intrinsic dimensions or aspect ratio to compute a responsive height\n imgWidth,\n imgHeight,\n aspectRatio,\n className,\n style,\n children,\n ...rest\n}) {\n const containerRef = useRef(null);\n const [inView, setInView] = useState(false);\n const [imageLoaded, setImageLoaded] = useState(false);\n\n /**\n * Use IntersectionObserver to detect when the card enters the viewport.\n * When in view, setInView(true) to trigger image loading.\n * If IntersectionObserver is not supported, default to inView=true.\n */\n useEffect(() => {\n if (!containerRef.current) return;\n if (typeof IntersectionObserver !== \"function\") {\n setInView(true);\n return;\n }\n const el = containerRef.current;\n const obs = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n setInView(true);\n try {\n obs.unobserve(el);\n } catch (_) {}\n break;\n }\n }\n },\n { root: null, rootMargin: \"100px\", threshold: 0.1 }\n );\n try {\n obs.observe(el);\n } catch (_) {}\n return () => {\n try {\n obs.disconnect();\n } catch (_) {}\n };\n }, []);\n\n /**\n * Calculate aspect ratio and padding percent for responsive image container.\n */\n const w = Number(imgWidth);\n const h = Number(imgHeight);\n const ratio =\n Number.isFinite(Number(aspectRatio)) && Number(aspectRatio) > 0\n ? Number(aspectRatio)\n : Number.isFinite(w) && w > 0 && Number.isFinite(h) && h > 0\n ? w / h\n : undefined;\n const paddingPercent = ratio ? 100 / ratio : 100;\n\n /**\n * Caption element (figcaption), rendered if title, subtitle, or children are provided.\n */\n const caption = (\n <figcaption>\n {title && <span>{title}</span>}\n {subtitle && <span>{subtitle}</span>}\n {children}\n </figcaption>\n );\n\n return (\n <a\n href={href}\n className={[\"canopy-card\", className].filter(Boolean).join(\" \")}\n style={style}\n ref={containerRef}\n data-aspect-ratio={ratio}\n data-in-view={inView ? \"true\" : \"false\"}\n data-image-loaded={imageLoaded ? \"true\" : \"false\"}\n {...rest}\n >\n <figure>\n {src ? (\n ratio ? (\n <div\n className=\"canopy-card-media\"\n style={{ \"--canopy-card-padding\": `${paddingPercent}%` }}\n >\n {inView ? (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n />\n ) : null}\n </div>\n ) : (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n className=\"canopy-card-image\"\n />\n )\n ) : null}\n {caption}\n </figure>\n </a>\n );\n}\n", "import Masonry from \"react-masonry-css\";\nimport React from \"react\";\n\n// Simple item wrapper to provide consistent spacing between items.\nexport function GridItem({children, className = \"\", style = {}, ...rest}) {\n return (\n <div\n className={`canopy-grid-item ${className}`.trim()}\n style={style}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Grid (Masonry)\n *\n * Lightweight wrapper around `react-masonry-css` with sensible defaults\n * and inline styles so it works without a global CSS pipeline.\n *\n * Props:\n * - breakpointCols: number | object \u2014 columns per breakpoint (react-masonry-css prop)\n * - gap: CSS length string \u2014 spacing between items/columns (default '1rem')\n * - paddingY: CSS length string \u2014 vertical padding for the grid (default '0')\n * - className, style \u2014 forwarded to container\n * - columnClassName \u2014 forwarded to Masonry (defaults to 'canopy-grid-column')\n * - children \u2014 usually a list of <GridItem> elements\n */\nexport default function Grid({\n breakpointCols,\n gap = \"1.618rem\",\n paddingY = \"0\",\n className = \"\",\n style = {},\n columnClassName = \"canopy-grid-column\",\n children,\n ...rest\n}) {\n const cols = breakpointCols || {\n default: 6,\n 1280: 5,\n 1024: 4,\n 768: 3,\n 640: 2,\n };\n const vars = {\"--grid-gap\": gap, \"--grid-padding-y\": paddingY};\n\n return (\n <div className=\"canopy-grid-wrap\">\n {/* Scoped styles so the component works standalone */}\n <style\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: `\n .canopy-grid { display: flex; width: auto; position: relative; padding: var(--grid-padding-y, 0) 0; z-index: 1; }\n .canopy-grid .${columnClassName} { margin-left: var(--grid-gap, 1rem); }\n .canopy-grid .${columnClassName}:first-child { margin-left: 0; }\n .canopy-grid-item { margin-bottom: var(--grid-gap, 1rem); }\n `,\n }}\n />\n <Masonry\n breakpointCols={cols}\n className={`canopy-grid ${className}`.trim()}\n columnClassName={columnClassName}\n style={{...vars, ...style}}\n {...rest}\n >\n {children}\n </Masonry>\n </div>\n );\n}\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's viewer. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\n\n// Default Clover viewer options; can be overridden per-usage via props.options\nconst DEFAULT_VIEWER_OPTIONS = {\n showDownload: false,\n showIIIFBadge: false,\n showTitle: false,\n informationPanel: {\n open: false,\n renderAbout: false,\n renderToggle: false,\n },\n};\n\nfunction isPlainObject(val) {\n return val && typeof val === \"object\" && !Array.isArray(val);\n}\n\nfunction deepMerge(base, override) {\n if (!isPlainObject(base)) return override;\n const out = { ...base };\n if (!isPlainObject(override)) return out;\n for (const key of Object.keys(override)) {\n const a = base[key];\n const b = override[key];\n if (isPlainObject(a) && isPlainObject(b)) out[key] = deepMerge(a, b);\n else out[key] = b;\n }\n return out;\n}\n\nexport const Viewer = (props) => {\n const [CloverViewer, setCloverViewer] = useState(null);\n const mergedOptions = deepMerge(\n DEFAULT_VIEWER_OPTIONS,\n props && props.options\n );\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/viewer\")\n .then((mod) => {\n if (!mounted) return;\n // Loaded Clover viewer dynamically in the browser\n const Comp = mod && (mod.default || mod.Viewer || mod);\n setCloverViewer(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverViewer) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n const p = { ...(props || {}) };\n if (mergedOptions) p.options = mergedOptions;\n json = JSON.stringify(p);\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-viewer=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverViewer {...props} options={mergedOptions} />;\n};\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's slider. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\nexport const Slider = (props) => {\n const [CloverSlider, setCloverSlider] = useState(null);\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/slider\")\n .then((mod) => {\n if (!mounted) return;\n console.log(mod);\n const Comp = mod && (mod.default || mod.Slider || mod);\n setCloverSlider(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverSlider) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-slider=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverSlider {...props} />;\n};\n", "import React from 'react';\n\n// SSR-safe placeholder for RelatedItems. Hydrated by canopy-related-items.js + canopy-slider.js\nexport default function MdxRelatedItems(props) {\n let json = '{}';\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = '{}';\n }\n return (\n <div data-canopy-related-items=\"1\" className=\"not-prose\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n", "import React from 'react';\n\nexport default function MdxSearchResults(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-results=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function SearchSummary(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-summary=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function MdxSearchTabs(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-tabs=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import Grid, { GridItem } from \"../layout/Grid.jsx\";\n\nimport Card from \"../layout/Card.jsx\";\nimport React from \"react\";\n\nexport default function SearchResults({\n results = [],\n type = \"all\",\n layout = \"grid\",\n}) {\n if (!results.length) {\n return (\n <div className=\"text-slate-600\">\n <em>No results</em>\n </div>\n );\n }\n\n if (layout === \"list\") {\n return (\n <ul id=\"search-results\" className=\"space-y-3\">\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <li\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </li>\n );\n })}\n </ul>\n );\n }\n\n // Default: grid (masonry)\n return (\n <div id=\"search-results\">\n <Grid>\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <GridItem\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </GridItem>\n );\n })}\n </Grid>\n </div>\n );\n}\n", "import React from \"react\";\n\nexport default function SearchTabs({\n type = \"all\",\n onTypeChange,\n types = [],\n counts = {},\n onOpenFilters,\n activeFilterCount = 0,\n filtersLabel = \"Filters\",\n filtersOpen = false,\n}) {\n const orderedTypes = Array.isArray(types) ? types : [];\n const toLabel = (t) =>\n t && t.length ? t.charAt(0).toUpperCase() + t.slice(1) : \"\";\n const hasFilters = typeof onOpenFilters === \"function\";\n const filterBadge = activeFilterCount > 0 ? ` (${activeFilterCount})` : \"\";\n return (\n <div className=\"canopy-search-tabs-wrapper\">\n <div\n role=\"tablist\"\n aria-label=\"Search types\"\n className=\"canopy-search-tabs\"\n >\n {orderedTypes.map((t) => {\n const active = String(type).toLowerCase() === String(t).toLowerCase();\n const cRaw =\n counts && Object.prototype.hasOwnProperty.call(counts, t)\n ? counts[t]\n : undefined;\n const c = Number.isFinite(Number(cRaw)) ? Number(cRaw) : 0;\n return (\n <button\n key={t}\n role=\"tab\"\n aria-selected={active}\n type=\"button\"\n onClick={() => onTypeChange && onTypeChange(t)}\n >\n {toLabel(t)} ({c})\n </button>\n );\n })}\n </div>\n {hasFilters ? (\n <button\n type=\"button\"\n onClick={() => onOpenFilters && onOpenFilters()}\n aria-expanded={filtersOpen ? \"true\" : \"false\"}\n className=\"inline-flex items-center gap-2 rounded-md border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 shadow-sm transition hover:border-brand-200 hover:bg-brand-50 hover:text-brand-700\"\n >\n <span>\n {filtersLabel}\n {filterBadge}\n </span>\n </button>\n ) : null}\n </div>\n );\n}\n", "import React from \"react\";\n\nfunction toArray(input) {\n if (!input) return [];\n if (Array.isArray(input)) return input;\n return [input];\n}\n\nfunction normalizeSelected(selected = {}) {\n const map = new Map();\n if (selected && typeof selected === \"object\") {\n Object.keys(selected).forEach((key) => {\n const vals = new Set(toArray(selected[key]).map((v) => String(v)));\n if (vals.size) map.set(String(key), vals);\n });\n }\n return map;\n}\n\nfunction facetMatches(values = [], query) {\n const q = String(query || \"\")\n .trim()\n .toLowerCase();\n if (!q) return values;\n const starts = [];\n const contains = [];\n values.forEach((entry) => {\n if (!entry || !entry.value) return;\n const value = String(entry.value);\n const slug = String(entry.slug || entry.value || \"\");\n const match = value.toLowerCase();\n if (match.startsWith(q))\n starts.push({value, slug, doc_count: entry.doc_count});\n else if (match.includes(q))\n contains.push({value, slug, doc_count: entry.doc_count});\n });\n return [...starts, ...contains].slice(0, 10);\n}\n\nfunction FacetSection({facet, selected, onToggle}) {\n if (!facet || !facet.label || !Array.isArray(facet.values)) return null;\n const {label, slug, values} = facet;\n const selectedValues = selected.get(String(slug)) || new Set();\n const checkboxId = (valueSlug) => `filter-${slug}-${valueSlug}`;\n const hasSelection = selectedValues.size > 0;\n const [quickQuery, setQuickQuery] = React.useState(\"\");\n const hasQuery = quickQuery.trim().length > 0;\n const filteredValues = React.useMemo(\n () => facetMatches(values, quickQuery),\n [values, quickQuery]\n );\n\n return (\n <details\n className=\"canopy-search-filters__facet\"\n open={hasSelection}\n >\n <summary className=\"canopy-search-filters__facet-summary\">\n <span>{label}</span>\n <span className=\"canopy-search-filters__facet-count\">\n {values.length}\n </span>\n </summary>\n <div className=\"canopy-search-filters__facet-content\">\n <div className=\"canopy-search-filters__quick\">\n <input\n type=\"search\"\n value={quickQuery}\n onChange={(event) => setQuickQuery(event.target.value)}\n placeholder=\"Search values\"\n className=\"canopy-search-filters__quick-input\"\n aria-label={`Filter ${label} values`}\n />\n {quickQuery ? (\n <button\n type=\"button\"\n onClick={() => setQuickQuery(\"\")}\n className=\"canopy-search-filters__quick-clear\"\n >\n Clear\n </button>\n ) : null}\n </div>\n {hasQuery && !filteredValues.length ? (\n <p className=\"canopy-search-filters__facet-notice\">No matches found.</p>\n ) : null}\n <ul className=\"canopy-search-filters__facet-list\">\n {filteredValues.map((entry) => {\n const valueSlug = String(entry.slug || entry.value || \"\");\n const isChecked = selectedValues.has(valueSlug);\n const inputId = checkboxId(valueSlug);\n return (\n <li key={valueSlug} className=\"canopy-search-filters__facet-item\">\n <input\n id={inputId}\n type=\"checkbox\"\n className=\"canopy-search-filters__facet-checkbox\"\n checked={isChecked}\n onChange={(event) => {\n const nextChecked = !!event.target.checked;\n if (onToggle) onToggle(slug, valueSlug, nextChecked);\n }}\n />\n <label\n htmlFor={inputId}\n className=\"canopy-search-filters__facet-label\"\n >\n <span>\n {entry.value}{\" \"}\n {Number.isFinite(entry.doc_count) ? (\n <span className=\"canopy-search-filters__facet-count\">\n ({entry.doc_count})\n </span>\n ) : null}\n </span>\n </label>\n </li>\n );\n })}\n {!filteredValues.length && !hasQuery ? (\n <li className=\"canopy-search-filters__facet-empty\">No values available.</li>\n ) : null}\n </ul>\n </div>\n </details>\n );\n}\n\nexport default function SearchFiltersDialog(props = {}) {\n const {\n open = false,\n onOpenChange,\n facets = [],\n selected = {},\n onToggle,\n onClear,\n title = \"Filters\",\n subtitle = \"Refine results by metadata\",\n } = props;\n\n const selectedMap = normalizeSelected(selected);\n const activeCount = Array.from(selectedMap.values()).reduce(\n (total, set) => total + set.size,\n 0\n );\n\n if (!open) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"canopy-search-filters-overlay\"\n onClick={(event) => {\n if (event.target === event.currentTarget && onOpenChange)\n onOpenChange(false);\n }}\n >\n <div className=\"canopy-search-filters\">\n <header className=\"canopy-search-filters__header\">\n <div>\n <h2 className=\"canopy-search-filters__title\">{title}</h2>\n <p className=\"canopy-search-filters__subtitle\">{subtitle}</p>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"canopy-search-filters__close\"\n >\n Close\n </button>\n </header>\n <div className=\"canopy-search-filters__body\">\n {Array.isArray(facets) && facets.length ? (\n <div className=\"canopy-search-filters__facets\">\n {facets.map((facet) => (\n <FacetSection\n key={facet.slug || facet.label}\n facet={facet}\n selected={selectedMap}\n onToggle={onToggle}\n />\n ))}\n </div>\n ) : (\n <p className=\"canopy-search-filters__empty\">\n No filters are available for this collection.\n </p>\n )}\n </div>\n <footer className=\"canopy-search-filters__footer\">\n <div>\n {activeCount\n ? `${activeCount} filter${activeCount === 1 ? \"\" : \"s\"} applied`\n : \"No filters applied\"}\n </div>\n <div className=\"canopy-search-filters__footer-actions\">\n <button\n type=\"button\"\n onClick={() => {\n if (onClear) onClear();\n }}\n disabled={!activeCount}\n className=\"canopy-search-filters__button canopy-search-filters__button--secondary\"\n >\n Clear all\n </button>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"canopy-search-filters__button canopy-search-filters__button--primary\"\n >\n Done\n </button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from '../search/SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from '../search/SearchPanelTeaserResults.jsx';\n\n// SSR-safe placeholder for the search form modal, composed from SearchPanel parts.\n// This ensures a single JSX source of truth for form/panel markup.\nexport default function MdxSearchFormModal(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'page'],\n button = true, // kept for backward compat; ignored by teaser form\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n return (\n <div data-canopy-search-form className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n", "import React from \"react\";\n\nexport const MagnifyingGlassIcon = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" {...props}>\n <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\" />\n </svg>\n);\n", "import {MagnifyingGlassIcon} from \"../Icons\";\nimport React from \"react\";\n\nfunction readBasePath() {\n const normalize = (val) => {\n const raw = typeof val === \"string\" ? val.trim() : \"\";\n if (!raw) return \"\";\n return raw.replace(/\\/+$/, \"\");\n };\n try {\n if (typeof window !== \"undefined\" && window.CANOPY_BASE_PATH != null) {\n const fromWindow = normalize(window.CANOPY_BASE_PATH);\n if (fromWindow) return fromWindow;\n }\n } catch (_) {}\n try {\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.CANOPY_BASE_PATH != null\n ) {\n const fromGlobal = normalize(globalThis.CANOPY_BASE_PATH);\n if (fromGlobal) return fromGlobal;\n }\n } catch (_) {}\n try {\n if (\n typeof process !== \"undefined\" &&\n process.env &&\n process.env.CANOPY_BASE_PATH\n ) {\n const fromEnv = normalize(process.env.CANOPY_BASE_PATH);\n if (fromEnv) return fromEnv;\n }\n } catch (_) {}\n return \"\";\n}\n\nfunction isAbsoluteUrl(href) {\n try {\n return /^https?:/i.test(String(href || \"\"));\n } catch (_) {\n return false;\n }\n}\n\nexport function resolveSearchPath(pathValue) {\n let raw = typeof pathValue === \"string\" ? pathValue.trim() : \"\";\n if (!raw) raw = \"/search\";\n if (isAbsoluteUrl(raw)) return raw;\n const normalizedPath = raw.startsWith(\"/\") ? raw : `/${raw}`;\n const base = readBasePath();\n if (!base) return normalizedPath;\n const baseWithLead = base.startsWith(\"/\") ? base : `/${base}`;\n const baseTrimmed = baseWithLead.replace(/\\/+$/, \"\");\n if (!baseTrimmed) return normalizedPath;\n if (\n normalizedPath === baseTrimmed ||\n normalizedPath.startsWith(`${baseTrimmed}/`)\n ) {\n return normalizedPath;\n }\n const pathTrimmed = normalizedPath.replace(/^\\/+/, \"\");\n return `${baseTrimmed}/${pathTrimmed}`;\n}\n\nexport default function SearchPanelForm(props = {}) {\n const {\n placeholder = \"Search\u2026\",\n buttonLabel = \"Search\",\n label,\n searchPath = \"/search\",\n inputId: inputIdProp,\n } = props || {};\n\n const text =\n typeof label === \"string\" && label.trim() ? label.trim() : buttonLabel;\n const action = React.useMemo(\n () => resolveSearchPath(searchPath),\n [searchPath]\n );\n const autoId = typeof React.useId === \"function\" ? React.useId() : undefined;\n const [fallbackId] = React.useState(\n () => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`\n );\n const inputId = inputIdProp || autoId || fallbackId;\n const inputRef = React.useRef(null);\n const [hasValue, setHasValue] = React.useState(false);\n\n const focusInput = React.useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (document.activeElement === el) return;\n try {\n el.focus({preventScroll: true});\n } catch (_) {\n try {\n el.focus();\n } catch (_) {}\n }\n }, []);\n\n const handlePointerDown = React.useCallback(\n (event) => {\n const target = event.target;\n if (target && typeof target.closest === \"function\") {\n if (target.closest(\"[data-canopy-search-form-trigger]\")) return;\n }\n event.preventDefault();\n focusInput();\n },\n [focusInput]\n );\n\n React.useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n if (el.value && el.value.trim()) {\n setHasValue(true);\n }\n }, []);\n\n const handleInputChange = React.useCallback((event) => {\n const nextHasValue = Boolean(event?.target?.value && event.target.value.trim());\n setHasValue(nextHasValue);\n }, []);\n\n return (\n <form\n action={action}\n method=\"get\"\n role=\"search\"\n autoComplete=\"off\"\n spellCheck=\"false\"\n className=\"canopy-search-form canopy-search-form-shell\"\n onPointerDown={handlePointerDown}\n data-placeholder={placeholder || \"\"}\n data-has-value={hasValue ? \"1\" : \"0\"}\n >\n <label\n htmlFor={inputId}\n className=\"canopy-search-form__label\"\n >\n <MagnifyingGlassIcon className=\"canopy-search-form__icon\" />\n <input\n id={inputId}\n type=\"search\"\n name=\"q\"\n inputMode=\"search\"\n data-canopy-search-form-input\n placeholder={placeholder}\n className=\"canopy-search-form__input\"\n aria-label=\"Search\"\n ref={inputRef}\n onChange={handleInputChange}\n onInput={handleInputChange}\n />\n </label>\n <button\n type=\"submit\"\n data-canopy-search-form-trigger=\"submit\"\n className=\"canopy-search-form__submit\"\n >\n <span>{text}</span>\n <span aria-hidden className=\"canopy-search-form__shortcut\">\n <span>\u2318</span>\n <span>K</span>\n </span>\n </button>\n </form>\n );\n}\n", "import React from \"react\";\n\n// SSR placeholder for teaser results panel; the runtime controls visibility and content.\nexport default function SearchPanelTeaserResults(props = {}) {\n const { style, className } = props || {};\n const classes = [\"canopy-search-teaser\", className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n data-canopy-search-form-panel\n className={classes || undefined}\n style={style}\n >\n <div id=\"cplist\" />\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from './SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from './SearchPanelTeaserResults.jsx';\n\n// High-level SearchPanel composed of a teaser form and teaser results panel.\n// Encodes configuration as JSON for the client runtime.\nexport default function SearchPanel(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'docs', 'page'],\n // Kept for backward compat; form always renders submit\n button = true, // eslint-disable-line no-unused-vars\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n\n return (\n <div data-canopy-search-form className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["React", "React", "React", "useEffect", "useState", "React", "useEffect", "useState", "React", "React", "React", "React", "React", "React", "React", "React", "React", "React", "_", "React", "React", "React", "React"]
|
|
7
7
|
}
|