@penn-libraries/web 1.1.1-dev.1 → 1.2.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index-C0qvW4Ra.js → index-DJo51Q03.js} +58 -4
- package/dist/cjs/index-DJo51Q03.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/pennlibs-autocomplete.pennlibs-fallback-img.pennlibs-footer.pennlibs-header.pennlibs-iiif-img.entry.cjs.js.map +1 -0
- package/dist/cjs/{pennlibs-autocomplete_3.cjs.entry.js → pennlibs-autocomplete_5.cjs.entry.js} +261 -2
- package/dist/cjs/pennlibs-banner.cjs.entry.js +1 -1
- package/dist/cjs/pennlibs-chat.cjs.entry.js +1 -1
- package/dist/cjs/pennlibs-feedback.cjs.entry.js +1 -1
- package/dist/cjs/pennlibs-hero.cjs.entry.js +2 -2
- package/dist/cjs/pennlibs-hero.entry.cjs.js.map +1 -1
- package/dist/cjs/web.cjs.js +2 -2
- package/dist/collection/assets/fonts/perpetua.woff +0 -0
- package/dist/collection/assets/fonts/perpetua.woff2 +0 -0
- package/dist/collection/components/pennlibs-hero/pennlibs-hero.css +1 -1
- package/dist/collection/components/pennlibs-iiif-img/pennlibs-iiif-img.css +9 -2
- package/dist/collection/components/pennlibs-iiif-img/pennlibs-iiif-img.js +147 -25
- package/dist/collection/components/pennlibs-iiif-img/pennlibs-iiif-img.js.map +1 -1
- package/dist/components/pennlibs-hero.js +1 -1
- package/dist/components/pennlibs-hero.js.map +1 -1
- package/dist/components/pennlibs-iiif-img.js +144 -23
- package/dist/components/pennlibs-iiif-img.js.map +1 -1
- package/dist/docs.json +4 -4
- package/dist/{web/p-D9dYrmUF.js → esm/index-RqnbThKP.js} +58 -4
- package/dist/esm/index-RqnbThKP.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/pennlibs-autocomplete.pennlibs-fallback-img.pennlibs-footer.pennlibs-header.pennlibs-iiif-img.entry.js.map +1 -0
- package/dist/esm/{pennlibs-autocomplete_3.entry.js → pennlibs-autocomplete_5.entry.js} +260 -3
- package/dist/esm/pennlibs-banner.entry.js +1 -1
- package/dist/esm/pennlibs-chat.entry.js +1 -1
- package/dist/esm/pennlibs-feedback.entry.js +1 -1
- package/dist/esm/pennlibs-hero.entry.js +2 -2
- package/dist/esm/pennlibs-hero.entry.js.map +1 -1
- package/dist/esm/web.js +3 -3
- package/dist/types/components/pennlibs-iiif-img/pennlibs-iiif-img.d.ts +45 -4
- package/dist/types/components.d.ts +10 -10
- package/dist/web/assets/fonts/perpetua.woff +0 -0
- package/dist/web/assets/fonts/perpetua.woff2 +0 -0
- package/dist/web/index.esm.js +1 -1
- package/dist/web/{p-b4b58af0.entry.js → p-780e656e.entry.js} +1 -1
- package/dist/web/{p-43d9c2d4.entry.js → p-8ac5ef70.entry.js} +1 -1
- package/dist/{esm/index-D9dYrmUF.js → web/p-RqnbThKP.js} +58 -4
- package/dist/web/p-RqnbThKP.js.map +1 -0
- package/dist/web/{p-cb2584da.entry.js → p-b7b01d67.entry.js} +2 -2
- package/dist/web/{p-ad92090a.entry.js → p-ce09ae2e.entry.js} +1 -1
- package/dist/web/{p-e6188c30.entry.js → p-f37f3865.entry.js} +260 -3
- package/dist/web/pennlibs-autocomplete.pennlibs-fallback-img.pennlibs-footer.pennlibs-header.pennlibs-iiif-img.entry.esm.js.map +1 -0
- package/dist/web/pennlibs-hero.entry.esm.js.map +1 -1
- package/dist/web/web.css +36 -15
- package/dist/web/web.esm.js +3 -3
- package/hydrate/index.js +190 -31
- package/hydrate/index.mjs +190 -31
- package/package.json +1 -1
- package/dist/cjs/index-C0qvW4Ra.js.map +0 -1
- package/dist/cjs/pennlibs-autocomplete.pennlibs-footer.pennlibs-header.entry.cjs.js.map +0 -1
- package/dist/cjs/pennlibs-fallback-img.cjs.entry.js +0 -20
- package/dist/cjs/pennlibs-fallback-img.entry.cjs.js.map +0 -1
- package/dist/cjs/pennlibs-iiif-img.cjs.entry.js +0 -132
- package/dist/cjs/pennlibs-iiif-img.entry.cjs.js.map +0 -1
- package/dist/esm/index-D9dYrmUF.js.map +0 -1
- package/dist/esm/pennlibs-autocomplete.pennlibs-footer.pennlibs-header.entry.js.map +0 -1
- package/dist/esm/pennlibs-fallback-img.entry.js +0 -18
- package/dist/esm/pennlibs-fallback-img.entry.js.map +0 -1
- package/dist/esm/pennlibs-iiif-img.entry.js +0 -130
- package/dist/esm/pennlibs-iiif-img.entry.js.map +0 -1
- package/dist/web/p-D9dYrmUF.js.map +0 -1
- package/dist/web/p-c4074cf1.entry.js +0 -130
- package/dist/web/p-ce97059c.entry.js +0 -18
- package/dist/web/pennlibs-autocomplete.pennlibs-footer.pennlibs-header.entry.esm.js.map +0 -1
- package/dist/web/pennlibs-fallback-img.entry.esm.js.map +0 -1
- package/dist/web/pennlibs-iiif-img.entry.esm.js.map +0 -1
package/dist/web/web.css
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
@import url("https://use.typekit.net/gbh8cmg.css");
|
|
2
2
|
|
|
3
|
+
@font-face {
|
|
4
|
+
font-family: 'Perpetua';
|
|
5
|
+
src: url('assets/fonts/perpetua.woff2') format('woff2'),
|
|
6
|
+
url('assets/fonts/perpetua.woff') format('woff');
|
|
7
|
+
font-weight: 400;
|
|
8
|
+
font-display: swap;
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
:root {
|
|
4
12
|
--pl-color-penn-red: #990000;
|
|
5
13
|
--pl-color-penn-blue: #011F5B;
|
|
@@ -20,7 +28,7 @@
|
|
|
20
28
|
--pl-color-bg-gradient-2: linear-gradient(45deg, #dbe9f5, #feefdf);
|
|
21
29
|
--pl-font-size: 16px;
|
|
22
30
|
--pl-font-sans-serif: proxima-nova, system-ui, sans-serif;
|
|
23
|
-
--pl-font-serif:
|
|
31
|
+
--pl-font-serif: 'Perpetua', serif;
|
|
24
32
|
--pl-link-text-underline-offset: 0.2em;
|
|
25
33
|
--pl-link-text-decoration-thickness: 1px;
|
|
26
34
|
--pl-link-hover-text-decoration-thickness: 2px;
|
|
@@ -52,9 +60,9 @@
|
|
|
52
60
|
--pl-link-hover-text-decoration-thickness: 2px;
|
|
53
61
|
|
|
54
62
|
/* Font size tokens */
|
|
55
|
-
--pl-font-size-5xl:
|
|
56
|
-
--pl-font-size-4xl: 2.
|
|
57
|
-
--pl-font-size-3xl:
|
|
63
|
+
--pl-font-size-5xl: 3.5rem;
|
|
64
|
+
--pl-font-size-4xl: 2.5rem;
|
|
65
|
+
--pl-font-size-3xl: 2rem;
|
|
58
66
|
--pl-font-size-2xl: 1.5rem;
|
|
59
67
|
--pl-font-size-xl: 1.25rem;
|
|
60
68
|
--pl-font-size-l: 1.125rem;
|
|
@@ -175,9 +183,10 @@
|
|
|
175
183
|
|
|
176
184
|
& :is(h1, .pl-h1, h2, .pl-h2) {
|
|
177
185
|
font-family: var(--pl-font-serif);
|
|
186
|
+
font-weight: 400;
|
|
178
187
|
}
|
|
179
188
|
|
|
180
|
-
& :is(
|
|
189
|
+
& :is(h3, .pl-h3, h4, .pl-h4, h5, .pl-h5, h6, .pl-h6) {
|
|
181
190
|
font-weight: 600;
|
|
182
191
|
}
|
|
183
192
|
|
|
@@ -186,8 +195,7 @@
|
|
|
186
195
|
}
|
|
187
196
|
|
|
188
197
|
& :is(h1, .pl-h1, h2, .pl-h2) {
|
|
189
|
-
|
|
190
|
-
line-height: 1.125;
|
|
198
|
+
line-height: 1;
|
|
191
199
|
font-family: var(--pl-font-serif);
|
|
192
200
|
color: var(--pl-color-penn-blue);
|
|
193
201
|
position: relative;
|
|
@@ -204,7 +212,7 @@
|
|
|
204
212
|
|
|
205
213
|
& :is(h1, .pl-h1) {
|
|
206
214
|
font-size: var(--pl-font-size-5xl);
|
|
207
|
-
margin-bottom:
|
|
215
|
+
margin-bottom: var(--pl-space-l);
|
|
208
216
|
margin-top: 0;
|
|
209
217
|
|
|
210
218
|
&::after {
|
|
@@ -214,8 +222,8 @@
|
|
|
214
222
|
}
|
|
215
223
|
|
|
216
224
|
& :is(h2, .pl-h2) {
|
|
217
|
-
font-size: var(--pl-font-size-
|
|
218
|
-
margin-bottom:
|
|
225
|
+
font-size: var(--pl-font-size-4xl);
|
|
226
|
+
margin-bottom: var(--pl-space-m);
|
|
219
227
|
|
|
220
228
|
&::after {
|
|
221
229
|
background: #d6d6dc;
|
|
@@ -533,24 +541,37 @@
|
|
|
533
541
|
|
|
534
542
|
.pl-dl--inline {
|
|
535
543
|
display: block;
|
|
536
|
-
|
|
544
|
+
|
|
537
545
|
& dt,
|
|
538
546
|
& dd {
|
|
539
547
|
display: inline;
|
|
540
548
|
padding-right: 0.5rem;
|
|
541
549
|
margin-bottom: 0;
|
|
542
550
|
}
|
|
543
|
-
|
|
551
|
+
|
|
544
552
|
& dt {
|
|
545
553
|
font-weight: 600;
|
|
546
554
|
}
|
|
547
|
-
|
|
555
|
+
|
|
548
556
|
& dt:not(:first-of-type)::before {
|
|
549
557
|
content: "";
|
|
550
558
|
display: block;
|
|
551
|
-
margin-bottom: 0.
|
|
559
|
+
margin-bottom: 0.25rem;
|
|
552
560
|
}
|
|
553
|
-
|
|
561
|
+
|
|
562
|
+
& dd::after {
|
|
563
|
+
content: " ·";
|
|
564
|
+
padding-left: var(--pl-space-xs);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
& dd:has(+ dt)::after {
|
|
568
|
+
all: unset;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
& > *:last-child::after {
|
|
572
|
+
all: unset;
|
|
573
|
+
}
|
|
574
|
+
|
|
554
575
|
& a {
|
|
555
576
|
color: var(--pl-color-fg-default);
|
|
556
577
|
text-decoration-style: dotted;
|
package/dist/web/web.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as promiseResolve, g as globalScripts, b as bootstrapLazy } from './p-
|
|
2
|
-
export { s as setNonce } from './p-
|
|
1
|
+
import { p as promiseResolve, g as globalScripts, b as bootstrapLazy } from './p-RqnbThKP.js';
|
|
2
|
+
export { s as setNonce } from './p-RqnbThKP.js';
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
Stencil Client Patch Browser v4.38.1 | MIT Licensed | https://stenciljs.com
|
|
@@ -16,6 +16,6 @@ var patchBrowser = () => {
|
|
|
16
16
|
|
|
17
17
|
patchBrowser().then(async (options) => {
|
|
18
18
|
await globalScripts();
|
|
19
|
-
return bootstrapLazy([["p-
|
|
19
|
+
return bootstrapLazy([["p-8ac5ef70",[[257,"pennlibs-banner"]]],["p-ce09ae2e",[[257,"pennlibs-chat",{"href":[32]}]]],["p-780e656e",[[257,"pennlibs-feedback",{"error":[32],"answer":[32]}]]],["p-b7b01d67",[[257,"pennlibs-hero",{"heroPictureElement":[32],"heroHeadingElement":[32],"heroParagraphElement":[32],"heroSrc":[32]}]]],["p-f37f3865",[[257,"pennlibs-iiif-img",{"uuid":[1],"alt":[1],"region":[513],"rotation":[1],"quality":[1],"loading":[1],"showFallback":[4,"show-fallback"],"isLoaded":[32],"hasError":[32],"imageDimensions":[32],"observedWidth":[32]},null,{"region":["handleRegionChange"]}],[257,"pennlibs-autocomplete",{"for":[1],"showSuggestions":[32],"currentIndex":[32],"originalValue":[32],"options":[32]},[[0,"slotchange","handleSlotChange"],[16,"input","handleInputEvent"],[16,"focus","handleFocusEvent"],[16,"blur","handleBlurEvent"],[0,"focusout","handleFocusOut"],[4,"keydown","handleKeyDown"]]],[257,"pennlibs-footer",{"navigationByChildren":[32]}],[257,"pennlibs-header",{"serviceName":[1,"service-name"],"serviceLede":[1,"service-lede"],"serviceHref":[1,"service-href"],"theme":[1],"isMenuOpen":[32],"navigation":[32]}],[257,"pennlibs-fallback-img"]]]], options);
|
|
20
20
|
});
|
|
21
21
|
//# sourceMappingURL=web.esm.js.map
|
package/hydrate/index.js
CHANGED
|
@@ -127,7 +127,7 @@ function hydrateFactory($stencilWindow, $stencilHydrateOpts, $stencilHydrateResu
|
|
|
127
127
|
|
|
128
128
|
|
|
129
129
|
const NAMESPACE = 'web';
|
|
130
|
-
const BUILD = /* web */ { hydratedSelectorName: "hydrated",
|
|
130
|
+
const BUILD = /* web */ { hydratedSelectorName: "hydrated", slotRelocation: true, updatable: true};
|
|
131
131
|
|
|
132
132
|
/*
|
|
133
133
|
Stencil Hydrate Platform v4.38.1 | MIT Licensed | https://stenciljs.com
|
|
@@ -2105,6 +2105,14 @@ var renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
|
|
|
2105
2105
|
const isHostElement = isHost(renderFnResults);
|
|
2106
2106
|
const rootVnode = isHostElement ? renderFnResults : h(null, null, renderFnResults);
|
|
2107
2107
|
hostTagName = hostElm.tagName;
|
|
2108
|
+
if (cmpMeta.$attrsToReflect$) {
|
|
2109
|
+
rootVnode.$attrs$ = rootVnode.$attrs$ || {};
|
|
2110
|
+
cmpMeta.$attrsToReflect$.forEach(([propName, attribute]) => {
|
|
2111
|
+
{
|
|
2112
|
+
rootVnode.$attrs$[attribute] = hostElm[propName];
|
|
2113
|
+
}
|
|
2114
|
+
});
|
|
2115
|
+
}
|
|
2108
2116
|
if (isInitialLoad && rootVnode.$attrs$) {
|
|
2109
2117
|
for (const key of Object.keys(rootVnode.$attrs$)) {
|
|
2110
2118
|
if (hostElm.hasAttribute(key) && !["key", "ref", "style", "class"].includes(key)) {
|
|
@@ -2406,6 +2414,7 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
2406
2414
|
`Couldn't find host element for "${cmpMeta.$tagName$}" as it is unknown to this Stencil runtime. This usually happens when integrating a 3rd party Stencil component with another Stencil component or application. Please reach out to the maintainers of the 3rd party Stencil component or report this on the Stencil Discord server (https://chat.stenciljs.com) or comment on this similar [GitHub issue](https://github.com/stenciljs/core/issues/5457).`
|
|
2407
2415
|
);
|
|
2408
2416
|
}
|
|
2417
|
+
const elm = hostRef.$hostElement$ ;
|
|
2409
2418
|
const oldVal = hostRef.$instanceValues$.get(propName);
|
|
2410
2419
|
const flags = hostRef.$flags$;
|
|
2411
2420
|
const instance = hostRef.$lazyInstance$ ;
|
|
@@ -2417,6 +2426,18 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
2417
2426
|
if ((!(flags & 8 /* isConstructingInstance */) || oldVal === void 0) && didValueChange) {
|
|
2418
2427
|
hostRef.$instanceValues$.set(propName, newVal);
|
|
2419
2428
|
if (instance) {
|
|
2429
|
+
if (cmpMeta.$watchers$ && flags & 128 /* isWatchReady */) {
|
|
2430
|
+
const watchMethods = cmpMeta.$watchers$[propName];
|
|
2431
|
+
if (watchMethods) {
|
|
2432
|
+
watchMethods.map((watchMethodName) => {
|
|
2433
|
+
try {
|
|
2434
|
+
instance[watchMethodName](newVal, oldVal, propName);
|
|
2435
|
+
} catch (e) {
|
|
2436
|
+
consoleError(e, elm);
|
|
2437
|
+
}
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2420
2441
|
if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
|
|
2421
2442
|
if (instance.componentShouldUpdate) {
|
|
2422
2443
|
if (instance.componentShouldUpdate(newVal, oldVal, propName) === false) {
|
|
@@ -2433,7 +2454,18 @@ var setValue = (ref, propName, newVal, cmpMeta) => {
|
|
|
2433
2454
|
var proxyComponent = (Cstr, cmpMeta, flags) => {
|
|
2434
2455
|
var _a;
|
|
2435
2456
|
const prototype = Cstr.prototype;
|
|
2436
|
-
|
|
2457
|
+
{
|
|
2458
|
+
{
|
|
2459
|
+
if (Cstr.watchers && !cmpMeta.$watchers$) {
|
|
2460
|
+
cmpMeta.$watchers$ = Cstr.watchers;
|
|
2461
|
+
}
|
|
2462
|
+
if (Cstr.deserializers && !cmpMeta.$deserializers$) {
|
|
2463
|
+
cmpMeta.$deserializers$ = Cstr.deserializers;
|
|
2464
|
+
}
|
|
2465
|
+
if (Cstr.serializers && !cmpMeta.$serializers$) {
|
|
2466
|
+
cmpMeta.$serializers$ = Cstr.serializers;
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2437
2469
|
const members = Object.entries((_a = cmpMeta.$members$) != null ? _a : {});
|
|
2438
2470
|
members.map(([memberName, [memberFlags]]) => {
|
|
2439
2471
|
if ((memberFlags & 31 /* Prop */ || memberFlags & 32 /* State */)) {
|
|
@@ -2510,6 +2542,11 @@ var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
|
|
|
2510
2542
|
throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
|
|
2511
2543
|
}
|
|
2512
2544
|
if (!Cstr.isProxied) {
|
|
2545
|
+
{
|
|
2546
|
+
cmpMeta.$watchers$ = Cstr.watchers;
|
|
2547
|
+
cmpMeta.$serializers$ = Cstr.serializers;
|
|
2548
|
+
cmpMeta.$deserializers$ = Cstr.deserializers;
|
|
2549
|
+
}
|
|
2513
2550
|
proxyComponent(Cstr, cmpMeta);
|
|
2514
2551
|
Cstr.isProxied = true;
|
|
2515
2552
|
}
|
|
@@ -2525,6 +2562,9 @@ var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
|
|
|
2525
2562
|
{
|
|
2526
2563
|
hostRef.$flags$ &= -9 /* isConstructingInstance */;
|
|
2527
2564
|
}
|
|
2565
|
+
{
|
|
2566
|
+
hostRef.$flags$ |= 128 /* isWatchReady */;
|
|
2567
|
+
}
|
|
2528
2568
|
endNewInstance();
|
|
2529
2569
|
fireConnectedCallback(hostRef.$lazyInstance$, elm);
|
|
2530
2570
|
} else {
|
|
@@ -3800,7 +3840,7 @@ class Header {
|
|
|
3800
3840
|
}; }
|
|
3801
3841
|
}
|
|
3802
3842
|
|
|
3803
|
-
const pennlibsHeroCss = ":host{--pl-hero-height:clamp(42vh, 32rem, 26rem);--pl-hero-heading-font:var(--pl-font-serif);--pl-hero-color:var(--pl-color-fg-on-emphasis)}*,*:before,*:after{box-sizing:inherit}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.viewport-margins{width:100%;max-width:var(--pl-viewport-margins-max-width);margin:0 auto;padding:0 var(--pl-viewport-margins-gutter, 1em)}.hero{position:relative;min-height:var(--pl-hero-height);height:100%;background-size:cover;background-repeat:no-repeat;background-position:50% 33%;display:flex}.hero::before{content:\"\";display:flex;width:100%;height:100%;top:0;position:absolute;background:linear-gradient(360deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.7) 20%, rgba(0, 0, 0, 0.4) 40%, rgba(0, 0, 0, 0.05) 100%);z-index:0}.hero::after{content:\"\";display:flex;width:100%;height:100%;top:0;position:absolute;background:linear-gradient(180deg, rgba(1, 31, 91, 1) 0%, rgba(1, 31, 91, 0.9) 10%, rgba(1, 31, 91, 0.8) 20%, rgba(1, 31, 91, 0.1) 50%, rgba(1, 31, 91, 0.0) 100%);z-index:0}.hero__content{position:relative;display:flex;flex-direction:column;width:100%;z-index:1}.hero__heading-container{margin-top:auto;padding-top:var(--pl-space-3xl);padding-bottom:var(--pl-space-3xl)}.hero__heading{text-shadow:1px 1px 2px var(--pl-color-fg-default);line-height:1.1;font-size:3em;font-weight:
|
|
3843
|
+
const pennlibsHeroCss = ":host{--pl-hero-height:clamp(42vh, 32rem, 26rem);--pl-hero-heading-font:var(--pl-font-serif);--pl-hero-color:var(--pl-color-fg-on-emphasis)}*,*:before,*:after{box-sizing:inherit}.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}.viewport-margins{width:100%;max-width:var(--pl-viewport-margins-max-width);margin:0 auto;padding:0 var(--pl-viewport-margins-gutter, 1em)}.hero{position:relative;min-height:var(--pl-hero-height);height:100%;background-size:cover;background-repeat:no-repeat;background-position:50% 33%;display:flex}.hero::before{content:\"\";display:flex;width:100%;height:100%;top:0;position:absolute;background:linear-gradient(360deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.7) 20%, rgba(0, 0, 0, 0.4) 40%, rgba(0, 0, 0, 0.05) 100%);z-index:0}.hero::after{content:\"\";display:flex;width:100%;height:100%;top:0;position:absolute;background:linear-gradient(180deg, rgba(1, 31, 91, 1) 0%, rgba(1, 31, 91, 0.9) 10%, rgba(1, 31, 91, 0.8) 20%, rgba(1, 31, 91, 0.1) 50%, rgba(1, 31, 91, 0.0) 100%);z-index:0}.hero__content{position:relative;display:flex;flex-direction:column;width:100%;z-index:1}.hero__heading-container{margin-top:auto;padding-top:var(--pl-space-3xl);padding-bottom:var(--pl-space-3xl)}.hero__heading{text-shadow:1px 1px 2px var(--pl-color-fg-default);line-height:1.1;font-size:3em;font-weight:400;font-family:var(--pl-hero-heading-font);text-wrap:pretty;max-width:30ch;margin:0;color:var(--pl-hero-color)}@media (max-width: 920px){.hero__heading{font-size:2.5em}}.hero__sub-heading{font-size:1.25em;font-family:var(--pl-font-family);font-weight:500;color:var(--pl-hero-color);max-width:52ch;text-wrap:pretty;margin-top:1em;margin-bottom:0}.hero__sub-heading a{text-decoration:underline;text-underline-offset:var(--pl-link-text-underline-offset);text-decoration-thickness:var(--pl-link-text-decoration-thickness);color:var(--pl-hero-color)}.hero__sub-heading a:hover{text-decoration-thickness:var(--pl-link-hover-text-decoration-thickness)}.hero__sub-heading strong{font-weight:bold}@media (max-width: 620px){.hero__heading{font-size:2.75em}.hero__sub-heading{font-size:1em}}";
|
|
3804
3844
|
|
|
3805
3845
|
const getCurrentImageSource = (pictureElement) => {
|
|
3806
3846
|
const imgElement = pictureElement.querySelector('img');
|
|
@@ -3875,14 +3915,13 @@ class Hero {
|
|
|
3875
3915
|
}; }
|
|
3876
3916
|
}
|
|
3877
3917
|
|
|
3878
|
-
const pennlibsIiifImgCss = ":host{display:block;width:100%;max-width:100
|
|
3918
|
+
const pennlibsIiifImgCss = ":host{display:block;width:100%;max-width:100%;align-self:flex-start;aspect-ratio:var(--aspect-ratio, auto)}picture{display:block;line-height:0}.iiif-img{display:block;width:100%;max-width:100%;height:auto;opacity:0;filter:blur(5px);transition:opacity 0.15s ease-in, filter 0.15s ease-in}.iiif-img.loaded{opacity:1;filter:blur(0)}.fallback-container{display:block;width:100%;height:100%}.fallback-container pennlibs-fallback-img{width:100%;height:100%}pennlibs-fallback-img{display:block;width:100%;height:100%}";
|
|
3879
3919
|
|
|
3880
|
-
const
|
|
3881
|
-
const DEFAULT_IMAGE_SIZES = [400, 600, 800, 1200, 1600, 2400];
|
|
3920
|
+
const PIXEL_DENSITIES = [1, 1.5, 2];
|
|
3882
3921
|
/**
|
|
3883
3922
|
* Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.
|
|
3884
|
-
*
|
|
3885
|
-
* with modern WebP format and JPG fallback support.
|
|
3923
|
+
* Measures its own rendered width and automatically generates optimal image sources at
|
|
3924
|
+
* multiple pixel densities (1x, 1.5x, 2x) with modern WebP format and JPG fallback support.
|
|
3886
3925
|
*
|
|
3887
3926
|
* @component
|
|
3888
3927
|
* @example
|
|
@@ -3902,6 +3941,10 @@ class IIIFImg {
|
|
|
3902
3941
|
*
|
|
3903
3942
|
* `square`: A square area where width and height equal the shorter dimension.
|
|
3904
3943
|
*
|
|
3944
|
+
* `width:height`: Any aspect ratio format (e.g., `16:9`, `4:3`, `3:2`, `21:9`) applies
|
|
3945
|
+
* a centered crop based on the source image dimensions and sets the CSS aspect-ratio
|
|
3946
|
+
* property for layout reservation.
|
|
3947
|
+
*
|
|
3905
3948
|
* `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions).
|
|
3906
3949
|
*
|
|
3907
3950
|
* `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
@@ -3956,26 +3999,137 @@ class IIIFImg {
|
|
|
3956
3999
|
this.hasError = true;
|
|
3957
4000
|
};
|
|
3958
4001
|
}
|
|
4002
|
+
/**
|
|
4003
|
+
* Fetch IIIF image info to get actual dimensions.
|
|
4004
|
+
*/
|
|
4005
|
+
async fetchImageInfo() {
|
|
4006
|
+
try {
|
|
4007
|
+
const currentUuid = this.uuid; // Capture current UUID
|
|
4008
|
+
const infoUrl = `${this.baseUrl}/${currentUuid}/info.json`;
|
|
4009
|
+
const response = await fetch(infoUrl);
|
|
4010
|
+
if (!response.ok) {
|
|
4011
|
+
console.error(`Failed to fetch IIIF info.json for ${currentUuid}`);
|
|
4012
|
+
return;
|
|
4013
|
+
}
|
|
4014
|
+
const info = await response.json();
|
|
4015
|
+
// Only update dimensions if UUID hasn't changed during fetch
|
|
4016
|
+
// (protects against race conditions if component updates)
|
|
4017
|
+
if (this.uuid === currentUuid) {
|
|
4018
|
+
this.imageDimensions = {
|
|
4019
|
+
width: info.width,
|
|
4020
|
+
height: info.height,
|
|
4021
|
+
};
|
|
4022
|
+
this.fetchedUuid = currentUuid;
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
catch (error) {
|
|
4026
|
+
console.error(`Error fetching IIIF image info for ${this.uuid}:`, error);
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
/**
|
|
4030
|
+
* Check if a region value matches aspect ratio format (e.g., "16:9", "4:3", "3:2").
|
|
4031
|
+
*/
|
|
4032
|
+
isAspectRatio(value) {
|
|
4033
|
+
return /^\d+:\d+$/.test(value);
|
|
4034
|
+
}
|
|
4035
|
+
/**
|
|
4036
|
+
* Set CSS custom property for aspect ratio on the host element.
|
|
4037
|
+
*/
|
|
4038
|
+
setAspectRatioCss(aspectRatio) {
|
|
4039
|
+
const [widthRatio, heightRatio] = aspectRatio.split(':');
|
|
4040
|
+
this.hostElement.style.setProperty('--aspect-ratio', `${widthRatio} / ${heightRatio}`);
|
|
4041
|
+
}
|
|
4042
|
+
/**
|
|
4043
|
+
* Clear CSS custom property for aspect ratio from the host element.
|
|
4044
|
+
*/
|
|
4045
|
+
clearAspectRatioCss() {
|
|
4046
|
+
this.hostElement.style.removeProperty('--aspect-ratio');
|
|
4047
|
+
}
|
|
4048
|
+
/**
|
|
4049
|
+
* Format a number for IIIF percentage values (remove trailing zeros).
|
|
4050
|
+
* IIIF spec requires no trailing zeros per section 4.7.
|
|
4051
|
+
*/
|
|
4052
|
+
formatPercent(value) {
|
|
4053
|
+
return value.toFixed(2).replace(/\.?0+$/, '');
|
|
4054
|
+
}
|
|
4055
|
+
/**
|
|
4056
|
+
* Calculate a centered crop region for a given aspect ratio.
|
|
4057
|
+
* Requires actual image dimensions to calculate correctly.
|
|
4058
|
+
* @param aspectRatio - The target aspect ratio (e.g., "3:2" or "2:3")
|
|
4059
|
+
* @returns A IIIF percentage-based region string (e.g., "pct:0,16.67,100,66.67")
|
|
4060
|
+
*/
|
|
4061
|
+
calculateCenteredCrop(aspectRatio) {
|
|
4062
|
+
if (!this.imageDimensions) {
|
|
4063
|
+
throw new Error('Image dimensions required for aspect ratio calculation');
|
|
4064
|
+
}
|
|
4065
|
+
const [widthRatio, heightRatio] = aspectRatio.split(':').map(Number);
|
|
4066
|
+
const targetRatio = widthRatio / heightRatio;
|
|
4067
|
+
const sourceRatio = this.imageDimensions.width / this.imageDimensions.height;
|
|
4068
|
+
// Determine if we need to crop width or height
|
|
4069
|
+
if (sourceRatio > targetRatio) {
|
|
4070
|
+
// Source is wider than target - crop left and right
|
|
4071
|
+
const widthPercent = (targetRatio / sourceRatio) * 100;
|
|
4072
|
+
const xOffset = (100 - widthPercent) / 2;
|
|
4073
|
+
return `pct:${this.formatPercent(xOffset)},0,${this.formatPercent(widthPercent)},100`;
|
|
4074
|
+
}
|
|
4075
|
+
else {
|
|
4076
|
+
// Source is taller than target - crop top and bottom
|
|
4077
|
+
const heightPercent = (sourceRatio / targetRatio) * 100;
|
|
4078
|
+
const yOffset = (100 - heightPercent) / 2;
|
|
4079
|
+
return `pct:0,${this.formatPercent(yOffset)},100,${this.formatPercent(heightPercent)}`;
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4082
|
+
/**
|
|
4083
|
+
* Get the region parameter for the IIIF URL.
|
|
4084
|
+
*/
|
|
4085
|
+
getRegionParam() {
|
|
4086
|
+
// Handle custom aspect ratios
|
|
4087
|
+
let regionParam = this.region || 'full';
|
|
4088
|
+
if (this.isAspectRatio(regionParam)) {
|
|
4089
|
+
// Only apply crop if we have dimensions for the current UUID
|
|
4090
|
+
if (this.imageDimensions && this.fetchedUuid === this.uuid) {
|
|
4091
|
+
regionParam = this.calculateCenteredCrop(regionParam);
|
|
4092
|
+
}
|
|
4093
|
+
else {
|
|
4094
|
+
// Use full image until dimensions are loaded
|
|
4095
|
+
regionParam = 'full';
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
return regionParam;
|
|
4099
|
+
}
|
|
3959
4100
|
buildIIIFUrl(width, format = 'jpg') {
|
|
3960
4101
|
const sizeParam = width ? `${width},` : 'max';
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
const
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
}
|
|
3971
|
-
|
|
3972
|
-
if
|
|
3973
|
-
|
|
3974
|
-
return
|
|
4102
|
+
const regionParam = this.getRegionParam();
|
|
4103
|
+
return `${this.baseUrl}/${this.uuid}/${regionParam}/${sizeParam}/${this.rotation}/${this.quality}.${format}`;
|
|
4104
|
+
}
|
|
4105
|
+
generateSrcset(baseWidth, format) {
|
|
4106
|
+
return PIXEL_DENSITIES.map(density => {
|
|
4107
|
+
const width = Math.round(baseWidth * density);
|
|
4108
|
+
const url = this.buildIIIFUrl(width, format);
|
|
4109
|
+
return `${url} ${density}x`;
|
|
4110
|
+
}).join(', ');
|
|
4111
|
+
}
|
|
4112
|
+
handleRegionChange(newValue, oldValue) {
|
|
4113
|
+
// Only process if region actually changed
|
|
4114
|
+
if (newValue === oldValue) {
|
|
4115
|
+
return;
|
|
4116
|
+
}
|
|
4117
|
+
// If new region is an aspect ratio, set CSS and fetch info
|
|
4118
|
+
if (newValue && this.isAspectRatio(newValue)) {
|
|
4119
|
+
this.setAspectRatioCss(newValue);
|
|
4120
|
+
this.fetchImageInfo();
|
|
4121
|
+
}
|
|
4122
|
+
else {
|
|
4123
|
+
// Clear aspect ratio CSS if no longer using aspect ratio format
|
|
4124
|
+
this.clearAspectRatioCss();
|
|
3975
4125
|
}
|
|
3976
|
-
return [...DEFAULT_IMAGE_SIZES];
|
|
3977
4126
|
}
|
|
3978
4127
|
componentDidLoad() {
|
|
4128
|
+
// Set CSS aspect ratio and fetch image info if using aspect ratio format
|
|
4129
|
+
if (this.region && this.isAspectRatio(this.region)) {
|
|
4130
|
+
this.setAspectRatioCss(this.region);
|
|
4131
|
+
this.fetchImageInfo();
|
|
4132
|
+
}
|
|
3979
4133
|
if ('ResizeObserver' in window) {
|
|
3980
4134
|
this.resizeObserver = new ResizeObserver(entries => {
|
|
3981
4135
|
for (const entry of entries) {
|
|
@@ -3984,8 +4138,6 @@ class IIIFImg {
|
|
|
3984
4138
|
this.resizeObserver.disconnect();
|
|
3985
4139
|
this.resizeObserver = undefined;
|
|
3986
4140
|
}
|
|
3987
|
-
// Trigger re-render with optimized sizes
|
|
3988
|
-
this.isLoaded = this.isLoaded;
|
|
3989
4141
|
}
|
|
3990
4142
|
});
|
|
3991
4143
|
this.resizeObserver.observe(this.hostElement);
|
|
@@ -3998,7 +4150,10 @@ class IIIFImg {
|
|
|
3998
4150
|
}
|
|
3999
4151
|
}
|
|
4000
4152
|
render() {
|
|
4001
|
-
|
|
4153
|
+
// Show placeholder until we've measured the component width
|
|
4154
|
+
if (!this.observedWidth) {
|
|
4155
|
+
return hAsync("pennlibs-fallback-img", null);
|
|
4156
|
+
}
|
|
4002
4157
|
if (this.hasError && this.showFallback) {
|
|
4003
4158
|
return (hAsync("div", { class: "fallback-container" }, hAsync("pennlibs-fallback-img", null)));
|
|
4004
4159
|
}
|
|
@@ -4006,10 +4161,12 @@ class IIIFImg {
|
|
|
4006
4161
|
'iiif-img': true,
|
|
4007
4162
|
'loaded': this.isLoaded
|
|
4008
4163
|
};
|
|
4009
|
-
|
|
4010
|
-
return (hAsync("picture", null, hAsync("source", { type: "image/webp", srcSet: this.generateSrcset(sizes, 'webp'), sizes: "100vw" }), hAsync("img", { class: imgClasses, src: this.buildIIIFUrl(defaultSize, 'jpg'), srcSet: this.generateSrcset(sizes, 'jpg'), sizes: "100vw", alt: this.alt, loading: this.loading, onLoad: this.handleLoad, onError: this.handleError })));
|
|
4164
|
+
return (hAsync("picture", null, hAsync("source", { type: "image/webp", srcSet: this.generateSrcset(this.observedWidth, 'webp') }), hAsync("img", { class: imgClasses, src: this.buildIIIFUrl(this.observedWidth, 'jpg'), srcSet: this.generateSrcset(this.observedWidth, 'jpg'), alt: this.alt, loading: this.loading, onLoad: this.handleLoad, onError: this.handleError })));
|
|
4011
4165
|
}
|
|
4012
4166
|
get hostElement() { return getElement(this); }
|
|
4167
|
+
static get watchers() { return {
|
|
4168
|
+
"region": ["handleRegionChange"]
|
|
4169
|
+
}; }
|
|
4013
4170
|
static get style() { return pennlibsIiifImgCss; }
|
|
4014
4171
|
static get cmpMeta() { return {
|
|
4015
4172
|
"$flags$": 265,
|
|
@@ -4017,17 +4174,19 @@ class IIIFImg {
|
|
|
4017
4174
|
"$members$": {
|
|
4018
4175
|
"uuid": [1],
|
|
4019
4176
|
"alt": [1],
|
|
4020
|
-
"region": [
|
|
4177
|
+
"region": [513],
|
|
4021
4178
|
"rotation": [1],
|
|
4022
4179
|
"quality": [1],
|
|
4023
4180
|
"loading": [1],
|
|
4024
4181
|
"showFallback": [4, "show-fallback"],
|
|
4025
4182
|
"isLoaded": [32],
|
|
4026
|
-
"hasError": [32]
|
|
4183
|
+
"hasError": [32],
|
|
4184
|
+
"imageDimensions": [32],
|
|
4185
|
+
"observedWidth": [32]
|
|
4027
4186
|
},
|
|
4028
4187
|
"$listeners$": undefined,
|
|
4029
4188
|
"$lazyBundleId$": "-",
|
|
4030
|
-
"$attrsToReflect$": []
|
|
4189
|
+
"$attrsToReflect$": [["region", "region"]]
|
|
4031
4190
|
}; }
|
|
4032
4191
|
}
|
|
4033
4192
|
|