@canopy-iiif/app 0.10.30 → 0.10.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/build/mdx.js +10 -61
- package/lib/components/slider-runtime-entry.js +86 -0
- package/package.json +1 -1
- package/ui/dist/index.mjs +126 -5
- package/ui/dist/index.mjs.map +4 -4
- package/ui/dist/server.mjs +190 -23
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/components/_interstitial-hero.scss +22 -48
- package/ui/styles/index.css +20 -31
package/ui/dist/server.mjs
CHANGED
|
@@ -80,7 +80,120 @@ var Viewer = (props) => {
|
|
|
80
80
|
|
|
81
81
|
// ui/src/iiif/Slider.jsx
|
|
82
82
|
import React3, { useEffect as useEffect2, useState as useState2 } from "react";
|
|
83
|
-
|
|
83
|
+
|
|
84
|
+
// ui/src/iiif/sliderOptions.js
|
|
85
|
+
var UNIT_TOKEN = "__canopySliderUnit";
|
|
86
|
+
var UNIT_REM = "rem";
|
|
87
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
88
|
+
var cachedRootFontSize = null;
|
|
89
|
+
var sliderOptions = {
|
|
90
|
+
breakpoints: {
|
|
91
|
+
400: {
|
|
92
|
+
slidesPerView: 2,
|
|
93
|
+
spaceBetween: rem(1)
|
|
94
|
+
},
|
|
95
|
+
640: {
|
|
96
|
+
slidesPerView: 3,
|
|
97
|
+
spaceBetween: rem(1.618)
|
|
98
|
+
},
|
|
99
|
+
1024: {
|
|
100
|
+
slidesPerView: 4,
|
|
101
|
+
spaceBetween: rem(1.618)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
function rem(value) {
|
|
106
|
+
const numeric = typeof value === "number" ? value : parseFloat(value);
|
|
107
|
+
return {
|
|
108
|
+
[UNIT_TOKEN]: UNIT_REM,
|
|
109
|
+
value: Number.isFinite(numeric) ? numeric : 0
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function cloneBreakpoints(source) {
|
|
113
|
+
if (!source || typeof source !== "object") return void 0;
|
|
114
|
+
const clone = {};
|
|
115
|
+
Object.entries(source).forEach(([key, entry]) => {
|
|
116
|
+
clone[key] = entry && typeof entry === "object" ? { ...entry } : {};
|
|
117
|
+
});
|
|
118
|
+
return clone;
|
|
119
|
+
}
|
|
120
|
+
function cloneOptions(options = {}) {
|
|
121
|
+
const clone = { ...options };
|
|
122
|
+
if (options.breakpoints && typeof options.breakpoints === "object") {
|
|
123
|
+
clone.breakpoints = cloneBreakpoints(options.breakpoints);
|
|
124
|
+
}
|
|
125
|
+
return clone;
|
|
126
|
+
}
|
|
127
|
+
function mergeSliderOptions(overrides) {
|
|
128
|
+
const base = cloneOptions(sliderOptions);
|
|
129
|
+
const incoming = cloneOptions(overrides || {});
|
|
130
|
+
const merged = {
|
|
131
|
+
...base,
|
|
132
|
+
...incoming
|
|
133
|
+
};
|
|
134
|
+
if (base.breakpoints || incoming.breakpoints) {
|
|
135
|
+
merged.breakpoints = {
|
|
136
|
+
...base.breakpoints || {},
|
|
137
|
+
...incoming.breakpoints || {}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return merged;
|
|
141
|
+
}
|
|
142
|
+
function hasBrowserEnv() {
|
|
143
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
144
|
+
}
|
|
145
|
+
function measureRootFontSize() {
|
|
146
|
+
if (!hasBrowserEnv()) return DEFAULT_FONT_SIZE;
|
|
147
|
+
if (cachedRootFontSize !== null) return cachedRootFontSize;
|
|
148
|
+
let size = DEFAULT_FONT_SIZE;
|
|
149
|
+
try {
|
|
150
|
+
const root = window.document && window.document.documentElement;
|
|
151
|
+
if (root && window.getComputedStyle) {
|
|
152
|
+
const computed = window.getComputedStyle(root).fontSize;
|
|
153
|
+
const parsed = parseFloat(computed);
|
|
154
|
+
if (Number.isFinite(parsed)) size = parsed;
|
|
155
|
+
}
|
|
156
|
+
} catch (_) {
|
|
157
|
+
size = DEFAULT_FONT_SIZE;
|
|
158
|
+
}
|
|
159
|
+
cachedRootFontSize = size;
|
|
160
|
+
return size;
|
|
161
|
+
}
|
|
162
|
+
function convertSpacing(value) {
|
|
163
|
+
if (!hasBrowserEnv()) return value;
|
|
164
|
+
if (value && typeof value === "object" && value[UNIT_TOKEN] === UNIT_REM) {
|
|
165
|
+
const remValue = typeof value.value === "number" ? value.value : parseFloat(value.value);
|
|
166
|
+
if (!Number.isFinite(remValue)) return value;
|
|
167
|
+
return remValue * measureRootFontSize();
|
|
168
|
+
}
|
|
169
|
+
return value;
|
|
170
|
+
}
|
|
171
|
+
function normalizeBreakpoints(breakpoints) {
|
|
172
|
+
if (!breakpoints || typeof breakpoints !== "object") return breakpoints;
|
|
173
|
+
const normalized = {};
|
|
174
|
+
Object.entries(breakpoints).forEach(([key, entry]) => {
|
|
175
|
+
const clone = entry && typeof entry === "object" ? { ...entry } : {};
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(clone, "spaceBetween")) {
|
|
177
|
+
clone.spaceBetween = convertSpacing(clone.spaceBetween);
|
|
178
|
+
}
|
|
179
|
+
normalized[key] = clone;
|
|
180
|
+
});
|
|
181
|
+
return normalized;
|
|
182
|
+
}
|
|
183
|
+
function normalizeSliderOptions(options) {
|
|
184
|
+
const clone = cloneOptions(options || {});
|
|
185
|
+
if (!hasBrowserEnv()) return clone;
|
|
186
|
+
if (Object.prototype.hasOwnProperty.call(clone, "spaceBetween")) {
|
|
187
|
+
clone.spaceBetween = convertSpacing(clone.spaceBetween);
|
|
188
|
+
}
|
|
189
|
+
if (clone.breakpoints) {
|
|
190
|
+
clone.breakpoints = normalizeBreakpoints(clone.breakpoints);
|
|
191
|
+
}
|
|
192
|
+
return clone;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ui/src/iiif/Slider.jsx
|
|
196
|
+
var Slider = (props = {}) => {
|
|
84
197
|
const [CloverSlider, setCloverSlider] = useState2(null);
|
|
85
198
|
useEffect2(() => {
|
|
86
199
|
let mounted = true;
|
|
@@ -88,7 +201,6 @@ var Slider = (props) => {
|
|
|
88
201
|
if (canUseDom) {
|
|
89
202
|
import("@samvera/clover-iiif/slider").then((mod) => {
|
|
90
203
|
if (!mounted) return;
|
|
91
|
-
console.log(mod);
|
|
92
204
|
const Comp = mod && (mod.default || mod.Slider || mod);
|
|
93
205
|
setCloverSlider(() => Comp);
|
|
94
206
|
}).catch(() => {
|
|
@@ -98,14 +210,23 @@ var Slider = (props) => {
|
|
|
98
210
|
mounted = false;
|
|
99
211
|
};
|
|
100
212
|
}, []);
|
|
213
|
+
const { className, ...rest } = props || {};
|
|
214
|
+
const sliderClassName = ["canopy-slider", className].filter(Boolean).join(" ");
|
|
215
|
+
const mergedOptions = mergeSliderOptions(rest.options);
|
|
216
|
+
const normalizedOptions = normalizeSliderOptions(mergedOptions);
|
|
217
|
+
const resolvedProps = {
|
|
218
|
+
...rest,
|
|
219
|
+
className: sliderClassName,
|
|
220
|
+
options: normalizedOptions
|
|
221
|
+
};
|
|
101
222
|
if (!CloverSlider) {
|
|
102
223
|
let json = "{}";
|
|
103
224
|
try {
|
|
104
|
-
json = JSON.stringify(
|
|
225
|
+
json = JSON.stringify(resolvedProps || {});
|
|
105
226
|
} catch (_) {
|
|
106
227
|
json = "{}";
|
|
107
228
|
}
|
|
108
|
-
return /* @__PURE__ */ React3.createElement("div", { className:
|
|
229
|
+
return /* @__PURE__ */ React3.createElement("div", { className: sliderClassName, "data-canopy-slider": "1" }, /* @__PURE__ */ React3.createElement(
|
|
109
230
|
"script",
|
|
110
231
|
{
|
|
111
232
|
type: "application/json",
|
|
@@ -113,7 +234,7 @@ var Slider = (props) => {
|
|
|
113
234
|
}
|
|
114
235
|
));
|
|
115
236
|
}
|
|
116
|
-
return /* @__PURE__ */ React3.createElement(CloverSlider, { ...
|
|
237
|
+
return /* @__PURE__ */ React3.createElement(CloverSlider, { ...resolvedProps });
|
|
117
238
|
};
|
|
118
239
|
|
|
119
240
|
// ui/src/iiif/Scroll.jsx
|
|
@@ -295,6 +416,40 @@ function ButtonWrapper({
|
|
|
295
416
|
}
|
|
296
417
|
|
|
297
418
|
// ui/src/interstitials/Hero.jsx
|
|
419
|
+
var NavIconBase = ({ children, ...rest }) => /* @__PURE__ */ React9.createElement(
|
|
420
|
+
"svg",
|
|
421
|
+
{
|
|
422
|
+
width: "16",
|
|
423
|
+
height: "16",
|
|
424
|
+
viewBox: "0 0 16 16",
|
|
425
|
+
fill: "none",
|
|
426
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
427
|
+
"aria-hidden": "true",
|
|
428
|
+
focusable: "false",
|
|
429
|
+
...rest
|
|
430
|
+
},
|
|
431
|
+
children
|
|
432
|
+
);
|
|
433
|
+
var PrevArrowIcon = (props) => /* @__PURE__ */ React9.createElement(NavIconBase, { ...props }, /* @__PURE__ */ React9.createElement(
|
|
434
|
+
"path",
|
|
435
|
+
{
|
|
436
|
+
d: "M10.5 3L5.5 8L10.5 13",
|
|
437
|
+
stroke: "currentColor",
|
|
438
|
+
strokeWidth: "1.618",
|
|
439
|
+
strokeLinecap: "round",
|
|
440
|
+
strokeLinejoin: "round"
|
|
441
|
+
}
|
|
442
|
+
));
|
|
443
|
+
var NextArrowIcon = (props) => /* @__PURE__ */ React9.createElement(NavIconBase, { ...props }, /* @__PURE__ */ React9.createElement(
|
|
444
|
+
"path",
|
|
445
|
+
{
|
|
446
|
+
d: "M5.5 3L10.5 8L5.5 13",
|
|
447
|
+
stroke: "currentColor",
|
|
448
|
+
strokeWidth: "1.618",
|
|
449
|
+
strokeLinecap: "round",
|
|
450
|
+
strokeLinejoin: "round"
|
|
451
|
+
}
|
|
452
|
+
));
|
|
298
453
|
var HERO_DEFAULT_SIZES_ATTR = "(min-width: 1024px) 1280px, 100vw";
|
|
299
454
|
var basePath = (() => {
|
|
300
455
|
try {
|
|
@@ -464,26 +619,36 @@ function Hero({
|
|
|
464
619
|
loading: idx === 0 ? "eager" : "lazy"
|
|
465
620
|
};
|
|
466
621
|
if (slide.srcset) props.srcSet = slide.srcset;
|
|
467
|
-
if (slide.srcset)
|
|
468
|
-
props.sizes = slide.sizes || HERO_DEFAULT_SIZES_ATTR;
|
|
622
|
+
if (slide.srcset) props.sizes = slide.sizes || HERO_DEFAULT_SIZES_ATTR;
|
|
469
623
|
return props;
|
|
470
624
|
};
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
625
|
+
const wrapWithLink = (node) => {
|
|
626
|
+
if (!safeHref) return node;
|
|
627
|
+
return /* @__PURE__ */ React9.createElement(
|
|
628
|
+
"a",
|
|
474
629
|
{
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
|
|
630
|
+
href: safeHref,
|
|
631
|
+
className: "canopy-interstitial__slide-link",
|
|
632
|
+
"aria-label": slide.title || void 0
|
|
633
|
+
},
|
|
634
|
+
node
|
|
635
|
+
);
|
|
636
|
+
};
|
|
637
|
+
if (isStaticCaption) {
|
|
638
|
+
return /* @__PURE__ */ React9.createElement("div", { className: "swiper-slide", key: safeHref || idx }, wrapWithLink(
|
|
639
|
+
/* @__PURE__ */ React9.createElement("article", { className: paneClassName }, slide.thumbnail ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__media-frame" }, /* @__PURE__ */ React9.createElement(
|
|
640
|
+
"img",
|
|
641
|
+
{
|
|
642
|
+
...buildImageProps(
|
|
643
|
+
"canopy-interstitial__media canopy-interstitial__media--static"
|
|
644
|
+
)
|
|
645
|
+
}
|
|
646
|
+
)) : null, slide.title ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__caption canopy-interstitial__caption--static" }, /* @__PURE__ */ React9.createElement("span", { className: "canopy-interstitial__caption-link" }, slide.title)) : null)
|
|
647
|
+
));
|
|
480
648
|
}
|
|
481
|
-
return /* @__PURE__ */ React9.createElement("div", { className: "swiper-slide", key: safeHref || idx },
|
|
482
|
-
"img",
|
|
483
|
-
|
|
484
|
-
...buildImageProps("canopy-interstitial__media")
|
|
485
|
-
}
|
|
486
|
-
) : null, showVeil ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__veil", "aria-hidden": "true" }) : null, slide.title ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__caption" }, /* @__PURE__ */ React9.createElement("a", { href: safeHref, className: "canopy-interstitial__caption-link" }, slide.title)) : null));
|
|
649
|
+
return /* @__PURE__ */ React9.createElement("div", { className: "swiper-slide", key: safeHref || idx }, wrapWithLink(
|
|
650
|
+
/* @__PURE__ */ React9.createElement("article", { className: paneClassName }, slide.thumbnail ? /* @__PURE__ */ React9.createElement("img", { ...buildImageProps("canopy-interstitial__media") }) : null, showVeil ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__veil", "aria-hidden": "true" }) : null, slide.title ? /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__caption" }, /* @__PURE__ */ React9.createElement("span", { className: "canopy-interstitial__caption-link" }, slide.title)) : null)
|
|
651
|
+
));
|
|
487
652
|
};
|
|
488
653
|
const renderSlider = (options = {}) => /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__slider swiper" }, /* @__PURE__ */ React9.createElement("div", { className: "swiper-wrapper" }, orderedSlides.map((slide, idx) => renderSlide(slide, idx, options))), /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__nav" }, /* @__PURE__ */ React9.createElement(
|
|
489
654
|
"button",
|
|
@@ -491,14 +656,16 @@ function Hero({
|
|
|
491
656
|
type: "button",
|
|
492
657
|
"aria-label": "Previous slide",
|
|
493
658
|
className: "canopy-interstitial__nav-btn canopy-interstitial__nav-btn--prev swiper-button-prev"
|
|
494
|
-
}
|
|
659
|
+
},
|
|
660
|
+
/* @__PURE__ */ React9.createElement(PrevArrowIcon, null)
|
|
495
661
|
), /* @__PURE__ */ React9.createElement(
|
|
496
662
|
"button",
|
|
497
663
|
{
|
|
498
664
|
type: "button",
|
|
499
665
|
"aria-label": "Next slide",
|
|
500
666
|
className: "canopy-interstitial__nav-btn canopy-interstitial__nav-btn--next swiper-button-next"
|
|
501
|
-
}
|
|
667
|
+
},
|
|
668
|
+
/* @__PURE__ */ React9.createElement(NextArrowIcon, null)
|
|
502
669
|
)), /* @__PURE__ */ React9.createElement("div", { className: "canopy-interstitial__pagination swiper-pagination" }));
|
|
503
670
|
const overlayContent = /* @__PURE__ */ React9.createElement(React9.Fragment, null, overlayTitle ? /* @__PURE__ */ React9.createElement("h1", { className: "canopy-interstitial__headline" }, overlayTitle) : null, derivedDescription ? /* @__PURE__ */ React9.createElement("p", { className: "canopy-interstitial__description" }, derivedDescription) : null, overlayLinks.length ? /* @__PURE__ */ React9.createElement(ButtonWrapper, { className: "canopy-interstitial__actions" }, overlayLinks.map((link) => /* @__PURE__ */ React9.createElement(
|
|
504
671
|
Button,
|