@canopy-iiif/app 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3212,8 +3212,212 @@ function MdxTimeline({ children, ...rest }) {
3212
3212
  ));
3213
3213
  }
3214
3214
 
3215
- // ui/src/search/MdxSearchResults.jsx
3215
+ // ui/src/content/map/MdxMap.jsx
3216
3216
  import React29 from "react";
3217
+ import ReactDOMServer2 from "react-dom/server";
3218
+
3219
+ // ui/src/content/map/MapPoint.jsx
3220
+ function MapPoint() {
3221
+ return null;
3222
+ }
3223
+ MapPoint.displayName = "MapPoint";
3224
+
3225
+ // ui/src/content/map/MdxMap.jsx
3226
+ import navPlaceHelpers from "@canopy-iiif/app/lib/components/nav-place.js";
3227
+ function normalizeNumber(value) {
3228
+ if (value == null) return null;
3229
+ const num = Number(value);
3230
+ return Number.isFinite(num) ? num : null;
3231
+ }
3232
+ function normalizeCoordinates(props = {}) {
3233
+ var _a, _b, _c, _d, _e, _f;
3234
+ const lat = (_b = (_a = normalizeNumber(props.lat)) != null ? _a : normalizeNumber(props.latitude)) != null ? _b : normalizeNumber(props.y);
3235
+ const lng = (_f = (_e = (_d = (_c = normalizeNumber(props.lng)) != null ? _c : normalizeNumber(props.lon)) != null ? _d : normalizeNumber(props.long)) != null ? _e : normalizeNumber(props.longitude)) != null ? _f : normalizeNumber(props.x);
3236
+ if (lat == null || lng == null) return null;
3237
+ return { lat, lng };
3238
+ }
3239
+ function renderDetailsHtml(children) {
3240
+ if (!children) return "";
3241
+ try {
3242
+ return ReactDOMServer2.renderToStaticMarkup(
3243
+ React29.createElement(React29.Fragment, null, children)
3244
+ );
3245
+ } catch (_) {
3246
+ return "";
3247
+ }
3248
+ }
3249
+ function normalizeCustomPoint(child, index) {
3250
+ var _a;
3251
+ if (!React29.isValidElement(child)) return null;
3252
+ if (child.type !== MapPoint && ((_a = child.type) == null ? void 0 : _a.displayName) !== "MapPoint") return null;
3253
+ const coords = normalizeCoordinates(child.props || {});
3254
+ if (!coords) return null;
3255
+ const props = child.props || {};
3256
+ const id = props.id || `map-point-${index + 1}`;
3257
+ const title = props.title || props.label || `Point ${index + 1}`;
3258
+ const summary = props.summary || props.description || "";
3259
+ const href = props.href || props.link || "";
3260
+ const thumbnail = props.thumbnail || props.image || "";
3261
+ const thumbnailWidth = normalizeNumber(props.thumbnailWidth || props.width);
3262
+ const thumbnailHeight = normalizeNumber(props.thumbnailHeight || props.height);
3263
+ const detailsHtml = renderDetailsHtml(props.children);
3264
+ return {
3265
+ id,
3266
+ title,
3267
+ summary,
3268
+ href,
3269
+ thumbnail,
3270
+ thumbnailWidth: Number.isFinite(thumbnailWidth) ? thumbnailWidth : void 0,
3271
+ thumbnailHeight: Number.isFinite(thumbnailHeight) ? thumbnailHeight : void 0,
3272
+ lat: coords.lat,
3273
+ lng: coords.lng,
3274
+ detailsHtml,
3275
+ type: "custom"
3276
+ };
3277
+ }
3278
+ function normalizeCustomPoints(children) {
3279
+ return React29.Children.toArray(children).map((child, index) => normalizeCustomPoint(child, index)).filter(Boolean);
3280
+ }
3281
+ function normalizeHeight(value) {
3282
+ if (value == null) return "600px";
3283
+ if (typeof value === "number") {
3284
+ return `${value}px`;
3285
+ }
3286
+ if (typeof value === "string") {
3287
+ const trimmed = value.trim();
3288
+ if (!trimmed) return "600px";
3289
+ if (/^[0-9.]+$/.test(trimmed)) {
3290
+ return `${trimmed}px`;
3291
+ }
3292
+ return trimmed;
3293
+ }
3294
+ return "600px";
3295
+ }
3296
+ function normalizeTileLayer(entry, index) {
3297
+ if (!entry) return null;
3298
+ if (typeof entry === "string") {
3299
+ const url = entry.trim();
3300
+ if (!url) return null;
3301
+ return {
3302
+ name: `Layer ${index + 1}`,
3303
+ url,
3304
+ attribution: ""
3305
+ };
3306
+ }
3307
+ if (typeof entry === "object") {
3308
+ const url = entry.url || entry.href;
3309
+ if (!url) return null;
3310
+ const layer = {
3311
+ name: entry.name || entry.title || `Layer ${index + 1}`,
3312
+ url: String(url),
3313
+ attribution: entry.attribution || entry.credit || ""
3314
+ };
3315
+ const minZoom = normalizeNumber(entry.minZoom);
3316
+ const maxZoom = normalizeNumber(entry.maxZoom);
3317
+ if (Number.isFinite(minZoom)) layer.minZoom = minZoom;
3318
+ if (Number.isFinite(maxZoom)) layer.maxZoom = maxZoom;
3319
+ if (entry.subdomains) layer.subdomains = entry.subdomains;
3320
+ return layer;
3321
+ }
3322
+ return null;
3323
+ }
3324
+ function normalizeTileLayers(value) {
3325
+ const list = Array.isArray(value) ? value : value ? [value] : [];
3326
+ return list.map((entry, index) => normalizeTileLayer(entry, index)).filter(Boolean);
3327
+ }
3328
+ function parseBoolean(value, fallback) {
3329
+ if (value === void 0) return fallback;
3330
+ if (typeof value === "boolean") return value;
3331
+ const normalized = String(value).trim().toLowerCase();
3332
+ if (!normalized) return fallback;
3333
+ if (["false", "0", "no", "off"].includes(normalized)) return false;
3334
+ if (["true", "1", "yes", "on"].includes(normalized)) return true;
3335
+ return fallback;
3336
+ }
3337
+ function normalizeCenter(value) {
3338
+ if (!value) return null;
3339
+ if (typeof value === "string") {
3340
+ const parts = value.split(/[,\s]+/).filter(Boolean);
3341
+ if (parts.length >= 2) {
3342
+ const coords = normalizeCoordinates({ lat: parts[0], lng: parts[1] });
3343
+ if (coords) return coords;
3344
+ }
3345
+ return null;
3346
+ }
3347
+ if (typeof value === "object") {
3348
+ const coords = normalizeCoordinates(value);
3349
+ if (coords) return coords;
3350
+ }
3351
+ return null;
3352
+ }
3353
+ function serializeProps2(props, payload) {
3354
+ const clone = {};
3355
+ Object.keys(props || {}).forEach((key) => {
3356
+ if (key === "children") return;
3357
+ const value = props[key];
3358
+ if (typeof value === "function" || typeof value === "symbol") return;
3359
+ clone[key] = value;
3360
+ });
3361
+ return { ...clone, ...payload };
3362
+ }
3363
+ function serializeForScript2(data) {
3364
+ try {
3365
+ return JSON.stringify(data).replace(/</g, "\\u003c");
3366
+ } catch (_) {
3367
+ return "{}";
3368
+ }
3369
+ }
3370
+ function getDatasetInfo() {
3371
+ if (!navPlaceHelpers) {
3372
+ return { hasFeatures: false, version: null, href: "/api/navplace.json" };
3373
+ }
3374
+ try {
3375
+ return navPlaceHelpers.getNavPlaceDatasetInfo();
3376
+ } catch (_) {
3377
+ return {
3378
+ hasFeatures: false,
3379
+ version: null,
3380
+ href: navPlaceHelpers.NAVPLACE_PUBLIC_HREF || "/api/navplace.json"
3381
+ };
3382
+ }
3383
+ }
3384
+ function MdxMap({ children, ...rest }) {
3385
+ const customPoints = normalizeCustomPoints(children);
3386
+ const datasetInfo = getDatasetInfo();
3387
+ const navDataset = {
3388
+ hasFeatures: Boolean(datasetInfo && datasetInfo.hasFeatures),
3389
+ href: datasetInfo && datasetInfo.href || "/api/navplace.json",
3390
+ version: datasetInfo && datasetInfo.version ? datasetInfo.version : null
3391
+ };
3392
+ const height = normalizeHeight(rest.height);
3393
+ const tileLayers = normalizeTileLayers(rest.tileLayers || rest.tileLayer);
3394
+ const scrollWheelZoom = parseBoolean(rest.scrollWheelZoom, false);
3395
+ const cluster = parseBoolean(rest.cluster, true);
3396
+ const defaultCenter = normalizeCenter(rest.defaultCenter || rest.center);
3397
+ const defaultZoom = normalizeNumber(rest.defaultZoom || rest.zoom);
3398
+ const payload = serializeProps2(rest, {
3399
+ className: rest.className || "",
3400
+ id: rest.id || null,
3401
+ height,
3402
+ tileLayers,
3403
+ scrollWheelZoom,
3404
+ cluster,
3405
+ customPoints,
3406
+ navDataset,
3407
+ defaultCenter,
3408
+ defaultZoom: Number.isFinite(defaultZoom) ? defaultZoom : null
3409
+ });
3410
+ const json = serializeForScript2(payload);
3411
+ const placeholderClass = ["canopy-map", rest.className].filter(Boolean).join(" ");
3412
+ const placeholderProps = {};
3413
+ if (placeholderClass) placeholderProps.className = placeholderClass;
3414
+ if (rest.id) placeholderProps.id = rest.id;
3415
+ if (rest.style) placeholderProps.style = rest.style;
3416
+ return /* @__PURE__ */ React29.createElement("div", { "data-canopy-map": "1" }, /* @__PURE__ */ React29.createElement("div", { ...placeholderProps, "aria-live": "polite" }, /* @__PURE__ */ React29.createElement("div", { className: "canopy-map__status" }, "Loading map\u2026")), /* @__PURE__ */ React29.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3417
+ }
3418
+
3419
+ // ui/src/search/MdxSearchResults.jsx
3420
+ import React30 from "react";
3217
3421
  function MdxSearchResults(props) {
3218
3422
  let json = "{}";
3219
3423
  try {
@@ -3221,11 +3425,11 @@ function MdxSearchResults(props) {
3221
3425
  } catch (_) {
3222
3426
  json = "{}";
3223
3427
  }
3224
- return /* @__PURE__ */ React29.createElement("div", { "data-canopy-search-results": "1" }, /* @__PURE__ */ React29.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3428
+ return /* @__PURE__ */ React30.createElement("div", { "data-canopy-search-results": "1" }, /* @__PURE__ */ React30.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3225
3429
  }
3226
3430
 
3227
3431
  // ui/src/search/SearchSummary.jsx
3228
- import React30 from "react";
3432
+ import React31 from "react";
3229
3433
  function SearchSummary(props) {
3230
3434
  let json = "{}";
3231
3435
  try {
@@ -3233,11 +3437,11 @@ function SearchSummary(props) {
3233
3437
  } catch (_) {
3234
3438
  json = "{}";
3235
3439
  }
3236
- return /* @__PURE__ */ React30.createElement("div", { "data-canopy-search-summary": "1" }, /* @__PURE__ */ React30.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3440
+ return /* @__PURE__ */ React31.createElement("div", { "data-canopy-search-summary": "1" }, /* @__PURE__ */ React31.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3237
3441
  }
3238
3442
 
3239
3443
  // ui/src/search/MdxSearchTabs.jsx
3240
- import React31 from "react";
3444
+ import React32 from "react";
3241
3445
  function MdxSearchTabs(props) {
3242
3446
  let json = "{}";
3243
3447
  try {
@@ -3245,11 +3449,11 @@ function MdxSearchTabs(props) {
3245
3449
  } catch (_) {
3246
3450
  json = "{}";
3247
3451
  }
3248
- return /* @__PURE__ */ React31.createElement("div", { "data-canopy-search-tabs": "1" }, /* @__PURE__ */ React31.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3452
+ return /* @__PURE__ */ React32.createElement("div", { "data-canopy-search-tabs": "1" }, /* @__PURE__ */ React32.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
3249
3453
  }
3250
3454
 
3251
3455
  // ui/src/search/MdxSearch.jsx
3252
- import React32 from "react";
3456
+ import React33 from "react";
3253
3457
  function MdxSearch(props = {}) {
3254
3458
  const {
3255
3459
  layout,
@@ -3267,11 +3471,11 @@ function MdxSearch(props = {}) {
3267
3471
  resultsPayload.layout = layout;
3268
3472
  }
3269
3473
  const classes = ["canopy-search", className].filter(Boolean).join(" ");
3270
- return /* @__PURE__ */ React32.createElement("section", { className: classes, "data-canopy-search": "1" }, showTabs ? /* @__PURE__ */ React32.createElement(MdxSearchTabs, { ...tabsProps }) : null, showSummary ? /* @__PURE__ */ React32.createElement(SearchSummary, { ...summaryProps }) : null, showResults ? /* @__PURE__ */ React32.createElement(MdxSearchResults, { ...resultsPayload }) : null, children || null);
3474
+ return /* @__PURE__ */ React33.createElement("section", { className: classes, "data-canopy-search": "1" }, showTabs ? /* @__PURE__ */ React33.createElement(MdxSearchTabs, { ...tabsProps }) : null, showSummary ? /* @__PURE__ */ React33.createElement(SearchSummary, { ...summaryProps }) : null, showResults ? /* @__PURE__ */ React33.createElement(MdxSearchResults, { ...resultsPayload }) : null, children || null);
3271
3475
  }
3272
3476
 
3273
3477
  // ui/src/search-form/MdxSearchFormModal.jsx
3274
- import React33 from "react";
3478
+ import React34 from "react";
3275
3479
  function MdxSearchFormModal(props = {}) {
3276
3480
  const {
3277
3481
  placeholder = "Search\u2026",
@@ -3287,12 +3491,12 @@ function MdxSearchFormModal(props = {}) {
3287
3491
  const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
3288
3492
  const resolvedSearchPath = resolveSearchPath(searchPath);
3289
3493
  const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
3290
- return /* @__PURE__ */ React33.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React33.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React33.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React33.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React33.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
3494
+ return /* @__PURE__ */ React34.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React34.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React34.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React34.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React34.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
3291
3495
  }
3292
3496
 
3293
3497
  // ui/src/iiif/ManifestPrimitives.jsx
3294
3498
  var import_slugify = __toESM(require_slugify());
3295
- import React34 from "react";
3499
+ import React35 from "react";
3296
3500
  import {
3297
3501
  Label as CloverLabel,
3298
3502
  Metadata as CloverMetadata,
@@ -3433,7 +3637,7 @@ function MetadataFacetLink(props) {
3433
3637
  const valueSlug = facetSlug ? toValueSlug(text) : "";
3434
3638
  const href = facetSlug && valueSlug ? buildFacetSearchHref(facetSlug, valueSlug) : "";
3435
3639
  if (!href) return text;
3436
- return /* @__PURE__ */ React34.createElement(
3640
+ return /* @__PURE__ */ React35.createElement(
3437
3641
  "a",
3438
3642
  {
3439
3643
  href,
@@ -3459,7 +3663,7 @@ function buildFacetCustomValueContent(items, manifest) {
3459
3663
  seen.add(normalized);
3460
3664
  custom.push({
3461
3665
  matchingLabel: item.label,
3462
- Content: /* @__PURE__ */ React34.createElement(MetadataFacetLink, { facetSlug: facet.slug })
3666
+ Content: /* @__PURE__ */ React35.createElement(MetadataFacetLink, { facetSlug: facet.slug })
3463
3667
  });
3464
3668
  }
3465
3669
  return custom;
@@ -3491,12 +3695,12 @@ function mergeCustomValueContent(userContent, autoContent) {
3491
3695
  function Label({ manifest, label, ...rest }) {
3492
3696
  const intl = label || manifest && manifest.label;
3493
3697
  if (!hasInternationalValue(intl)) return null;
3494
- return /* @__PURE__ */ React34.createElement(CloverLabel, { label: intl, ...rest });
3698
+ return /* @__PURE__ */ React35.createElement(CloverLabel, { label: intl, ...rest });
3495
3699
  }
3496
3700
  function Summary({ manifest, summary, ...rest }) {
3497
3701
  const intl = summary || manifest && manifest.summary;
3498
3702
  if (!hasInternationalValue(intl)) return null;
3499
- return /* @__PURE__ */ React34.createElement(CloverSummary, { summary: intl, ...rest });
3703
+ return /* @__PURE__ */ React35.createElement(CloverSummary, { summary: intl, ...rest });
3500
3704
  }
3501
3705
  function Metadata({ manifest, metadata, customValueContent, ...rest }) {
3502
3706
  const items = ensureMetadata(metadata || manifest && manifest.metadata);
@@ -3506,7 +3710,7 @@ function Metadata({ manifest, metadata, customValueContent, ...rest }) {
3506
3710
  customValueContent,
3507
3711
  autoCustomContent
3508
3712
  );
3509
- return /* @__PURE__ */ React34.createElement(
3713
+ return /* @__PURE__ */ React35.createElement(
3510
3714
  CloverMetadata,
3511
3715
  {
3512
3716
  metadata: items,
@@ -3520,11 +3724,11 @@ function RequiredStatement({ manifest, requiredStatement, ...rest }) {
3520
3724
  if (!stmt || !hasInternationalValue(stmt.label) || !hasInternationalValue(stmt.value)) {
3521
3725
  return null;
3522
3726
  }
3523
- return /* @__PURE__ */ React34.createElement(CloverRequiredStatement, { requiredStatement: stmt, ...rest });
3727
+ return /* @__PURE__ */ React35.createElement(CloverRequiredStatement, { requiredStatement: stmt, ...rest });
3524
3728
  }
3525
3729
 
3526
3730
  // ui/src/docs/CodeBlock.jsx
3527
- import React35 from "react";
3731
+ import React36 from "react";
3528
3732
  function parseHighlightAttr(attr) {
3529
3733
  if (!attr) return /* @__PURE__ */ new Set();
3530
3734
  const cleaned = String(attr || "").trim();
@@ -3570,10 +3774,10 @@ var highlightBaseStyle = {
3570
3774
  };
3571
3775
  function DocsCodeBlock(props = {}) {
3572
3776
  const { children, ...rest } = props;
3573
- const childArray = React35.Children.toArray(children);
3574
- const codeElement = childArray.find((el) => React35.isValidElement(el));
3777
+ const childArray = React36.Children.toArray(children);
3778
+ const codeElement = childArray.find((el) => React36.isValidElement(el));
3575
3779
  if (!codeElement || !codeElement.props) {
3576
- return React35.createElement("pre", props);
3780
+ return React36.createElement("pre", props);
3577
3781
  }
3578
3782
  const {
3579
3783
  className = "",
@@ -3588,8 +3792,8 @@ function DocsCodeBlock(props = {}) {
3588
3792
  const highlightSet = parseHighlightAttr(highlightAttr);
3589
3793
  const copyAttr = codeProps["data-copy"];
3590
3794
  const enableCopy = copyAttr !== void 0 ? copyAttr === true || copyAttr === "true" || copyAttr === "" : false;
3591
- const [copied, setCopied] = React35.useState(false);
3592
- const handleCopy = React35.useCallback(async () => {
3795
+ const [copied, setCopied] = React36.useState(false);
3796
+ const handleCopy = React36.useCallback(async () => {
3593
3797
  const text = rawCode;
3594
3798
  try {
3595
3799
  if (typeof navigator !== "undefined" && navigator.clipboard && navigator.clipboard.writeText) {
@@ -3654,20 +3858,20 @@ function DocsCodeBlock(props = {}) {
3654
3858
  const highlight = highlightSet.has(lineNumber);
3655
3859
  const style = highlight ? { ...baseLineStyle, ...highlightBaseStyle } : baseLineStyle;
3656
3860
  const displayLine = line === "" ? " " : line;
3657
- return React35.createElement(
3861
+ return React36.createElement(
3658
3862
  "span",
3659
3863
  { key: lineNumber, style },
3660
- React35.createElement("span", { style: lineContentStyle }, displayLine)
3864
+ React36.createElement("span", { style: lineContentStyle }, displayLine)
3661
3865
  );
3662
3866
  });
3663
- return React35.createElement(
3867
+ return React36.createElement(
3664
3868
  "div",
3665
3869
  { style: containerStyle },
3666
- showHeader ? React35.createElement(
3870
+ showHeader ? React36.createElement(
3667
3871
  "div",
3668
3872
  { style: headerStyle },
3669
- React35.createElement("span", null, showFilename ? filename : null),
3670
- enableCopy ? React35.createElement(
3873
+ React36.createElement("span", null, showFilename ? filename : null),
3874
+ enableCopy ? React36.createElement(
3671
3875
  "button",
3672
3876
  {
3673
3877
  type: "button",
@@ -3686,29 +3890,29 @@ function DocsCodeBlock(props = {}) {
3686
3890
  copied ? "Copied" : "Copy"
3687
3891
  ) : null
3688
3892
  ) : null,
3689
- React35.createElement(
3893
+ React36.createElement(
3690
3894
  "pre",
3691
3895
  { ...preRest, className: preClassName, style: mergedPreStyle },
3692
- React35.createElement("code", { style: codeStyle }, lineElements)
3896
+ React36.createElement("code", { style: codeStyle }, lineElements)
3693
3897
  )
3694
3898
  );
3695
3899
  }
3696
3900
 
3697
3901
  // ui/src/docs/MarkdownTable.jsx
3698
- import React36 from "react";
3902
+ import React37 from "react";
3699
3903
  function MarkdownTable({ className = "", ...rest }) {
3700
3904
  const merged = ["markdown-table", className].filter(Boolean).join(" ");
3701
- return /* @__PURE__ */ React36.createElement("div", { className: "markdown-table__frame" }, /* @__PURE__ */ React36.createElement("table", { className: merged, ...rest }));
3905
+ return /* @__PURE__ */ React37.createElement("div", { className: "markdown-table__frame" }, /* @__PURE__ */ React37.createElement("table", { className: merged, ...rest }));
3702
3906
  }
3703
3907
 
3704
3908
  // ui/src/docs/Diagram.jsx
3705
- import React37 from "react";
3909
+ import React38 from "react";
3706
3910
  function CanopyDiagram() {
3707
- return /* @__PURE__ */ React37.createElement("div", { className: "canopy-diagram" }, /* @__PURE__ */ React37.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--collections" }, /* @__PURE__ */ React37.createElement("h3", null, "IIIF Collection(s)"), /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__section-summary" }, "Source collections contribute 105 total manifests that Canopy retrieves as-is via IIIF endpoints."), /* @__PURE__ */ React37.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Collection A"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "70 Manifests"), /* @__PURE__ */ React37.createElement("li", null, "IIIF Images + A/V"), /* @__PURE__ */ React37.createElement("li", null, "Textual Annotations"))), /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Collection B"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "35 Manifests"), /* @__PURE__ */ React37.createElement("li", null, "IIIF Images + A/V"), /* @__PURE__ */ React37.createElement("li", null, "Textual Annotations"))))), /* @__PURE__ */ React37.createElement("div", { className: "canopy-diagram__arrow", "aria-hidden": "true" }, /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__arrow-line" }), /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__arrow-head" })), /* @__PURE__ */ React37.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--build" }, /* @__PURE__ */ React37.createElement("h3", null, "Canopy Build Process"), /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__section-summary" }, "Canopy syncs manifests, page content, and annotations before bundling the site."), /* @__PURE__ */ React37.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Automated content"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "105 manifests \u2192 105 work pages"), /* @__PURE__ */ React37.createElement("li", null, "One page per manifest"), /* @__PURE__ */ React37.createElement("li", null, "Customize page layout"))), /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Contextual content"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "Markdown & MDX pages"), /* @__PURE__ */ React37.createElement("li", null, "Author narratives & tours"), /* @__PURE__ */ React37.createElement("li", null, "Reference manifests inline"))), /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Search index"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "Combines works + pages"), /* @__PURE__ */ React37.createElement("li", null, "Customize result layout"), /* @__PURE__ */ React37.createElement("li", null, "Optional annotations"))))), /* @__PURE__ */ React37.createElement("div", { className: "canopy-diagram__arrow", "aria-hidden": "true" }, /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__arrow-line" }), /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__arrow-head" })), /* @__PURE__ */ React37.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--output" }, /* @__PURE__ */ React37.createElement("h3", null, "Static Digital Project"), /* @__PURE__ */ React37.createElement("span", { className: "canopy-diagram__section-summary" }, "The output is a lightweight bundle of HTML, CSS, JS, and JSON assets that can deploy anywhere."), /* @__PURE__ */ React37.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Work pages"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "105 generated HTML pages"), /* @__PURE__ */ React37.createElement("li", null, "Each links back to source manifests"), /* @__PURE__ */ React37.createElement("li", null, "Styled with Canopy components"))), /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Custom pages"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "Markdown & MDX-authored content"), /* @__PURE__ */ React37.createElement("li", null, "Reusable layouts for narratives"), /* @__PURE__ */ React37.createElement("li", null, "Embed IIIF media & interstitials"))), /* @__PURE__ */ React37.createElement("article", null, /* @__PURE__ */ React37.createElement("h4", null, "Search bundle"), /* @__PURE__ */ React37.createElement("ul", null, /* @__PURE__ */ React37.createElement("li", null, "Static FlexSearch index"), /* @__PURE__ */ React37.createElement("li", null, "Works + pages share records"), /* @__PURE__ */ React37.createElement("li", null, "Optional annotation dataset"))))));
3911
+ return /* @__PURE__ */ React38.createElement("div", { className: "canopy-diagram" }, /* @__PURE__ */ React38.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--collections" }, /* @__PURE__ */ React38.createElement("h3", null, "IIIF Collection(s)"), /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__section-summary" }, "Source collections contribute 105 total manifests that Canopy retrieves as-is via IIIF endpoints."), /* @__PURE__ */ React38.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Collection A"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "70 Manifests"), /* @__PURE__ */ React38.createElement("li", null, "IIIF Images + A/V"), /* @__PURE__ */ React38.createElement("li", null, "Textual Annotations"))), /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Collection B"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "35 Manifests"), /* @__PURE__ */ React38.createElement("li", null, "IIIF Images + A/V"), /* @__PURE__ */ React38.createElement("li", null, "Textual Annotations"))))), /* @__PURE__ */ React38.createElement("div", { className: "canopy-diagram__arrow", "aria-hidden": "true" }, /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__arrow-line" }), /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__arrow-head" })), /* @__PURE__ */ React38.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--build" }, /* @__PURE__ */ React38.createElement("h3", null, "Canopy Build Process"), /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__section-summary" }, "Canopy syncs manifests, page content, and annotations before bundling the site."), /* @__PURE__ */ React38.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Automated content"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "105 manifests \u2192 105 work pages"), /* @__PURE__ */ React38.createElement("li", null, "One page per manifest"), /* @__PURE__ */ React38.createElement("li", null, "Customize page layout"))), /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Contextual content"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "Markdown & MDX pages"), /* @__PURE__ */ React38.createElement("li", null, "Author narratives & tours"), /* @__PURE__ */ React38.createElement("li", null, "Reference manifests inline"))), /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Search index"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "Combines works + pages"), /* @__PURE__ */ React38.createElement("li", null, "Customize result layout"), /* @__PURE__ */ React38.createElement("li", null, "Optional annotations"))))), /* @__PURE__ */ React38.createElement("div", { className: "canopy-diagram__arrow", "aria-hidden": "true" }, /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__arrow-line" }), /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__arrow-head" })), /* @__PURE__ */ React38.createElement("section", { className: "canopy-diagram__section canopy-diagram__section--output" }, /* @__PURE__ */ React38.createElement("h3", null, "Static Digital Project"), /* @__PURE__ */ React38.createElement("span", { className: "canopy-diagram__section-summary" }, "The output is a lightweight bundle of HTML, CSS, JS, and JSON assets that can deploy anywhere."), /* @__PURE__ */ React38.createElement("div", { className: "canopy-diagram__grid" }, /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Work pages"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "105 generated HTML pages"), /* @__PURE__ */ React38.createElement("li", null, "Each links back to source manifests"), /* @__PURE__ */ React38.createElement("li", null, "Styled with Canopy components"))), /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Custom pages"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "Markdown & MDX-authored content"), /* @__PURE__ */ React38.createElement("li", null, "Reusable layouts for narratives"), /* @__PURE__ */ React38.createElement("li", null, "Embed IIIF media & interstitials"))), /* @__PURE__ */ React38.createElement("article", null, /* @__PURE__ */ React38.createElement("h4", null, "Search bundle"), /* @__PURE__ */ React38.createElement("ul", null, /* @__PURE__ */ React38.createElement("li", null, "Static FlexSearch index"), /* @__PURE__ */ React38.createElement("li", null, "Works + pages share records"), /* @__PURE__ */ React38.createElement("li", null, "Optional annotation dataset"))))));
3708
3912
  }
3709
3913
 
3710
3914
  // ui/src/docs/ThemeShowcase.jsx
3711
- import React38 from "react";
3915
+ import React39 from "react";
3712
3916
 
3713
3917
  // ../../node_modules/@radix-ui/colors/index.mjs
3714
3918
  var colors_exports = {};
@@ -7541,21 +7745,21 @@ var ACCENT_COLOR_NAMES = [
7541
7745
  "sky"
7542
7746
  ];
7543
7747
  var GRAY_COLOR_NAMES = ["gray", "mauve", "slate", "sage", "olive", "sand"];
7544
- var Section = ({ title, description, children }) => /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase__section" }, /* @__PURE__ */ React38.createElement("h3", { className: "canopy-theme-showcase__section-title" }, title), description ? /* @__PURE__ */ React38.createElement("p", { className: "canopy-theme-showcase__section-description" }, description) : null, children);
7545
- var ColorScaleRow = ({ label, prefix }) => /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase__scale-row" }, /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase__scale-label" }, /* @__PURE__ */ React38.createElement("strong", null, label)), /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase__scale-track" }, COLOR_STOPS.map((stop) => /* @__PURE__ */ React38.createElement(
7748
+ var Section = ({ title, description, children }) => /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase__section" }, /* @__PURE__ */ React39.createElement("h3", { className: "canopy-theme-showcase__section-title" }, title), description ? /* @__PURE__ */ React39.createElement("p", { className: "canopy-theme-showcase__section-description" }, description) : null, children);
7749
+ var ColorScaleRow = ({ label, prefix }) => /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase__scale-row" }, /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase__scale-label" }, /* @__PURE__ */ React39.createElement("strong", null, label)), /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase__scale-track" }, COLOR_STOPS.map((stop) => /* @__PURE__ */ React39.createElement(
7546
7750
  "div",
7547
7751
  {
7548
7752
  key: `${label}-${stop}`,
7549
7753
  className: "canopy-theme-showcase__scale-stop"
7550
7754
  },
7551
- /* @__PURE__ */ React38.createElement(
7755
+ /* @__PURE__ */ React39.createElement(
7552
7756
  "span",
7553
7757
  {
7554
7758
  className: "canopy-theme-showcase__scale-chip",
7555
7759
  style: { backgroundColor: `var(${prefix}-${stop})` }
7556
7760
  }
7557
7761
  ),
7558
- /* @__PURE__ */ React38.createElement("span", { className: "canopy-theme-showcase__scale-token" }, stop)
7762
+ /* @__PURE__ */ React39.createElement("span", { className: "canopy-theme-showcase__scale-token" }, stop)
7559
7763
  ))));
7560
7764
  function ThemeShowcase() {
7561
7765
  const accentColors = ACCENT_COLOR_NAMES;
@@ -7566,15 +7770,15 @@ function ThemeShowcase() {
7566
7770
  if (!scale) return null;
7567
7771
  return scale[`${name}9`] || Object.values(scale)[8];
7568
7772
  };
7569
- const ColorsLabeled = ({ colors }) => /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase__swatch-grid" }, colors.map((name) => {
7773
+ const ColorsLabeled = ({ colors }) => /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase__swatch-grid" }, colors.map((name) => {
7570
7774
  const colorValue = getRadixSwatch(name);
7571
- return /* @__PURE__ */ React38.createElement("div", { key: name, className: "canopy-theme-showcase__swatch" }, /* @__PURE__ */ React38.createElement(
7775
+ return /* @__PURE__ */ React39.createElement("div", { key: name, className: "canopy-theme-showcase__swatch" }, /* @__PURE__ */ React39.createElement(
7572
7776
  "div",
7573
7777
  {
7574
7778
  className: "canopy-theme-showcase__swatch-chip",
7575
7779
  style: { background: colorValue || "var(--color-gray-200)" }
7576
7780
  }
7577
- ), /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase__swatch-label" }, name));
7781
+ ), /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase__swatch-label" }, name));
7578
7782
  }));
7579
7783
  const styles = `
7580
7784
  .canopy-theme-showcase__section {
@@ -7658,13 +7862,13 @@ function ThemeShowcase() {
7658
7862
  font-weight: 300;
7659
7863
  }
7660
7864
  `;
7661
- return /* @__PURE__ */ React38.createElement("div", { className: "canopy-theme-showcase" }, /* @__PURE__ */ React38.createElement("style", { dangerouslySetInnerHTML: { __html: styles } }), /* @__PURE__ */ React38.createElement(
7865
+ return /* @__PURE__ */ React39.createElement("div", { className: "canopy-theme-showcase" }, /* @__PURE__ */ React39.createElement("style", { dangerouslySetInnerHTML: { __html: styles } }), /* @__PURE__ */ React39.createElement(
7662
7866
  Section,
7663
7867
  {
7664
7868
  title: "Color scales",
7665
7869
  description: "Accent and gray ramps from the active theme."
7666
7870
  },
7667
- /* @__PURE__ */ React38.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem" } }, COLOR_SCALES.map((scale) => /* @__PURE__ */ React38.createElement(
7871
+ /* @__PURE__ */ React39.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem" } }, COLOR_SCALES.map((scale) => /* @__PURE__ */ React39.createElement(
7668
7872
  ColorScaleRow,
7669
7873
  {
7670
7874
  key: scale.label,
@@ -7672,20 +7876,20 @@ function ThemeShowcase() {
7672
7876
  prefix: scale.prefix
7673
7877
  }
7674
7878
  )))
7675
- ), /* @__PURE__ */ React38.createElement(
7879
+ ), /* @__PURE__ */ React39.createElement(
7676
7880
  Section,
7677
7881
  {
7678
7882
  title: "Accent color palette options",
7679
7883
  description: "Primary color steps used for buttons, links, and highlights."
7680
7884
  },
7681
- /* @__PURE__ */ React38.createElement(ColorsLabeled, { colors: accentColors })
7682
- ), /* @__PURE__ */ React38.createElement(
7885
+ /* @__PURE__ */ React39.createElement(ColorsLabeled, { colors: accentColors })
7886
+ ), /* @__PURE__ */ React39.createElement(
7683
7887
  Section,
7684
7888
  {
7685
7889
  title: "Gray color palette options",
7686
7890
  description: "Neutral color steps used for backgrounds, borders, and text."
7687
7891
  },
7688
- /* @__PURE__ */ React38.createElement(ColorsLabeled, { colors: grayColors })
7892
+ /* @__PURE__ */ React39.createElement(ColorsLabeled, { colors: grayColors })
7689
7893
  ));
7690
7894
  }
7691
7895
  export {
@@ -7706,6 +7910,8 @@ export {
7706
7910
  interstitials_exports as Interstitials,
7707
7911
  Label,
7708
7912
  Layout,
7913
+ MdxMap as Map,
7914
+ MapPoint,
7709
7915
  Metadata,
7710
7916
  ReferencedItems,
7711
7917
  References,