@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h, d as getElement, a as getAssetPath } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, h, d as getElement, a as getAssetPath } from './index-RqnbThKP.js';
|
|
2
2
|
|
|
3
3
|
const pennlibsAutocompleteCss = ":host {\n display: block;\n width: 100%;\n border-radius: 1.25rem;\n padding: 0;\n border-top: 0;\n position: relative;\n}\n\n[role=listbox] {\n position: absolute;\n margin-top: var(--pl-space-xs);\n background: var(--pl-color-bg-default);\n border-radius: 1.25rem;\n box-shadow: rgba(140, 149, 159, 0.3) 0px 8px 24px 0px;\n width: 100%;\n overflow: hidden;\n z-index: 1;\n\n display: flex;\n flex-direction: column;\n}\n\np {\n margin: 0;\n font-size: var(--pl-font-size-s);\n color: var(--pl-color-fg-subtle);\n padding: var(--pl-space-xs) calc(var(--pl-space-m) + var(--pl-space-2xs));\n font-size: var(--pl-font-size-s);\n order: 2;\n font-weight: 500;\n background: var(--pl-color-bg-subtle);\n border-radius: 0 0 1.25rem 1.25rem;\n\n display: flex;\n gap: var(--pl-space-s) var(--pl-space-l);\n flex-wrap: wrap;\n}\n\nol {\n list-style: none;\n margin: 0;\n padding: var(--pl-space-xs) 0;\n order: 1;\n}\n\n[role=option] {\n color: var(--pl-color-fg-default);\n padding: var(--pl-space-s) calc(var(--pl-space-m) + var(--pl-space-2xs));\n text-decoration: none;\n font-weight: 700; \n\n &:hover {\n cursor: pointer;\n }\n\n &:hover,\n &:focus {\n text-decoration-thickness: 2px;\n text-underline-offset: 2px;\n text-decoration: underline;\n }\n}\n\n[aria-selected=true] {\n text-decoration-thickness: 2px;\n text-underline-offset: 2px;\n text-decoration: underline;\n}\n\nmark,\nb {\n background: none;\n font-weight: 400;\n}\n\n.suggestion--border {\n border-bottom: solid 1px rgb(from var(--pl-color-fg-default) r g b / 0.2);\n padding-bottom: calc(var(--pl-space-2xs) + var(--pl-space-s));\n margin-bottom: var(--pl-space-2xs);\n}";
|
|
4
4
|
|
|
@@ -275,6 +275,20 @@ const Autocomplete = class {
|
|
|
275
275
|
};
|
|
276
276
|
Autocomplete.style = pennlibsAutocompleteCss;
|
|
277
277
|
|
|
278
|
+
const pennlibsFallbackImgCss = ":host{font-family:var(--pl-font-family);font-size:var(--pl-font-size);display:flex;align-items:center;justify-content:center;padding:1rem;background:var(--pl-color-bg-subtle);aspect-ratio:3/2}.no-image__img{width:100%;max-width:150px;filter:grayscale(1) opacity(0.3)}";
|
|
279
|
+
|
|
280
|
+
const NoImage = class {
|
|
281
|
+
constructor(hostRef) {
|
|
282
|
+
registerInstance(this, hostRef);
|
|
283
|
+
}
|
|
284
|
+
render() {
|
|
285
|
+
const shieldImg = getAssetPath('./assets/simplified-shield.webp');
|
|
286
|
+
return (h("img", { key: 'ba6cc227e90aac2e22b9997ad5c794fd4fd6d5ef', src: shieldImg, alt: "", class: "no-image__img" }));
|
|
287
|
+
}
|
|
288
|
+
static get assetsDirs() { return ["assets"]; }
|
|
289
|
+
};
|
|
290
|
+
NoImage.style = pennlibsFallbackImgCss;
|
|
291
|
+
|
|
278
292
|
const pennlibsFooterCss = ":host {\n font-family: var(--pl-font-family);\n font-size: var(--pl-font-size);\n --padding-bottom: 5.75rem;\n}\n\n@media print {\n :host {\n display: none;\n }\n}\n\n*, *::before, *::after {\n box-sizing: border-box;\n}\n\n.website-footer-wrapper {\n background: var(--pl-color-penn-blue);\n padding-bottom: var(--padding-bottom);\n}\n\n.viewport-margins {\n max-width: var(--pl-viewport-margins-max-width);\n margin: 0 auto;\n padding: 0 var(--pl-viewport-margins-gutter, 1em);\n}\n\n.website-footer {\n background-size: cover;\n color: var(--pl-color-fg-subtle-on-emphasis);\n}\n\n.website-footer a {\n color: var(--pl-color-fg-subtle-on-emphasis);\n}\n\n.website-footer__content {\n padding: 4em 0;\n}\n\n.website-footer__links-container {\n gap: 4em 2em;\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(12em, 1fr));\n}\n\n.website-footer__heading {\n font-size: 0.8em;\n text-transform: uppercase;\n letter-spacing: 0.075em;\n margin-bottom: 1em;\n opacity: 0.75;\n}\n\n.website-footer__links {\n margin: 0;\n padding: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 0.75em;\n}\n\n.website-footer__links a {\n text-decoration: none;\n}\n\n.website-footer__links a:hover {\n text-decoration: underline;\n text-underline-offset: var(--pl-link-text-underline-offset);\n}\n\n.website-footer__footer {\n padding: 1em 0;\n background: rgba(1, 31, 91, 0.65);\n}\n\n.website-footer__links--footer {\n display: flex;\n flex-wrap: wrap;\n gap: 0;\n flex-direction: row;\n margin-left: -0.5em;\n\n @media (max-width: 1080px) {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(16em, 1fr));\n }\n}\n\n.website-footer__links--footer a {\n display: inline-block;\n padding: 0.5em 0.75em;\n font-size: 0.875em;\n opacity: 0.875;\n font-weight: 500;\n}\n\n.website-footer__links--footer a:hover {\n text-decoration: underline;\n text-underline-offset: var(--pl-link-text-underline-offset);\n}";
|
|
279
293
|
|
|
280
294
|
const Footer = class {
|
|
@@ -374,5 +388,248 @@ const Header = class {
|
|
|
374
388
|
};
|
|
375
389
|
Header.style = pennlibsHeaderCss;
|
|
376
390
|
|
|
377
|
-
|
|
378
|
-
|
|
391
|
+
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%}";
|
|
392
|
+
|
|
393
|
+
const PIXEL_DENSITIES = [1, 1.5, 2];
|
|
394
|
+
const IIIFImg = class {
|
|
395
|
+
constructor(hostRef) {
|
|
396
|
+
registerInstance(this, hostRef);
|
|
397
|
+
/**
|
|
398
|
+
* The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display.
|
|
399
|
+
* Defines the rectangular portion of the underlying image to return.
|
|
400
|
+
*
|
|
401
|
+
* `full`: The full image is returned, without any cropping.
|
|
402
|
+
*
|
|
403
|
+
* `square`: A square area where width and height equal the shorter dimension.
|
|
404
|
+
*
|
|
405
|
+
* `width:height`: Any aspect ratio format (e.g., `16:9`, `4:3`, `3:2`, `21:9`) applies
|
|
406
|
+
* a centered crop based on the source image dimensions and sets the CSS aspect-ratio
|
|
407
|
+
* property for layout reservation.
|
|
408
|
+
*
|
|
409
|
+
* `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions).
|
|
410
|
+
*
|
|
411
|
+
* `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
412
|
+
*
|
|
413
|
+
* @default 'full'
|
|
414
|
+
*/
|
|
415
|
+
this.region = 'full';
|
|
416
|
+
/**
|
|
417
|
+
* The IIIF [rotation](https://iiif.io/api/image/3.0/#44-rotation) to apply to the image.
|
|
418
|
+
* Specifies mirroring and clockwise rotation in degrees (0-360).
|
|
419
|
+
*
|
|
420
|
+
* `n`: Rotation in degrees only.
|
|
421
|
+
*
|
|
422
|
+
* `!n`: Mirror the image vertically, then rotate by n degrees.
|
|
423
|
+
*
|
|
424
|
+
* @default '0'
|
|
425
|
+
*/
|
|
426
|
+
this.rotation = '0';
|
|
427
|
+
/**
|
|
428
|
+
* The IIIF [quality](https://iiif.io/api/image/3.0/#quality) of the image.
|
|
429
|
+
* Controls the color delivery mode.
|
|
430
|
+
*
|
|
431
|
+
* `default`: The server's default quality.
|
|
432
|
+
*
|
|
433
|
+
* `color`: Full color information.
|
|
434
|
+
*
|
|
435
|
+
* `gray`: Grayscale rendering.
|
|
436
|
+
*
|
|
437
|
+
* `bitonal`: Black and white only.
|
|
438
|
+
*
|
|
439
|
+
* @default 'default'
|
|
440
|
+
*/
|
|
441
|
+
this.quality = 'default';
|
|
442
|
+
/**
|
|
443
|
+
* Native browser lazy loading behavior. Use "lazy" to defer loading until the image is near the viewport,
|
|
444
|
+
* or "eager" to load immediately.
|
|
445
|
+
* @default 'lazy'
|
|
446
|
+
*/
|
|
447
|
+
this.loading = 'lazy';
|
|
448
|
+
/**
|
|
449
|
+
* Whether to display a fallback placeholder image when the IIIF image fails to load.
|
|
450
|
+
* @default true
|
|
451
|
+
*/
|
|
452
|
+
this.showFallback = true;
|
|
453
|
+
this.isLoaded = false;
|
|
454
|
+
this.hasError = false;
|
|
455
|
+
this.baseUrl = 'https://iiif-images.library.upenn.edu/iiif/3';
|
|
456
|
+
this.handleLoad = () => {
|
|
457
|
+
this.isLoaded = true;
|
|
458
|
+
};
|
|
459
|
+
this.handleError = () => {
|
|
460
|
+
this.hasError = true;
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Fetch IIIF image info to get actual dimensions.
|
|
465
|
+
*/
|
|
466
|
+
async fetchImageInfo() {
|
|
467
|
+
try {
|
|
468
|
+
const currentUuid = this.uuid; // Capture current UUID
|
|
469
|
+
const infoUrl = `${this.baseUrl}/${currentUuid}/info.json`;
|
|
470
|
+
const response = await fetch(infoUrl);
|
|
471
|
+
if (!response.ok) {
|
|
472
|
+
console.error(`Failed to fetch IIIF info.json for ${currentUuid}`);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const info = await response.json();
|
|
476
|
+
// Only update dimensions if UUID hasn't changed during fetch
|
|
477
|
+
// (protects against race conditions if component updates)
|
|
478
|
+
if (this.uuid === currentUuid) {
|
|
479
|
+
this.imageDimensions = {
|
|
480
|
+
width: info.width,
|
|
481
|
+
height: info.height,
|
|
482
|
+
};
|
|
483
|
+
this.fetchedUuid = currentUuid;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
console.error(`Error fetching IIIF image info for ${this.uuid}:`, error);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Check if a region value matches aspect ratio format (e.g., "16:9", "4:3", "3:2").
|
|
492
|
+
*/
|
|
493
|
+
isAspectRatio(value) {
|
|
494
|
+
return /^\d+:\d+$/.test(value);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Set CSS custom property for aspect ratio on the host element.
|
|
498
|
+
*/
|
|
499
|
+
setAspectRatioCss(aspectRatio) {
|
|
500
|
+
const [widthRatio, heightRatio] = aspectRatio.split(':');
|
|
501
|
+
this.hostElement.style.setProperty('--aspect-ratio', `${widthRatio} / ${heightRatio}`);
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Clear CSS custom property for aspect ratio from the host element.
|
|
505
|
+
*/
|
|
506
|
+
clearAspectRatioCss() {
|
|
507
|
+
this.hostElement.style.removeProperty('--aspect-ratio');
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Format a number for IIIF percentage values (remove trailing zeros).
|
|
511
|
+
* IIIF spec requires no trailing zeros per section 4.7.
|
|
512
|
+
*/
|
|
513
|
+
formatPercent(value) {
|
|
514
|
+
return value.toFixed(2).replace(/\.?0+$/, '');
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Calculate a centered crop region for a given aspect ratio.
|
|
518
|
+
* Requires actual image dimensions to calculate correctly.
|
|
519
|
+
* @param aspectRatio - The target aspect ratio (e.g., "3:2" or "2:3")
|
|
520
|
+
* @returns A IIIF percentage-based region string (e.g., "pct:0,16.67,100,66.67")
|
|
521
|
+
*/
|
|
522
|
+
calculateCenteredCrop(aspectRatio) {
|
|
523
|
+
if (!this.imageDimensions) {
|
|
524
|
+
throw new Error('Image dimensions required for aspect ratio calculation');
|
|
525
|
+
}
|
|
526
|
+
const [widthRatio, heightRatio] = aspectRatio.split(':').map(Number);
|
|
527
|
+
const targetRatio = widthRatio / heightRatio;
|
|
528
|
+
const sourceRatio = this.imageDimensions.width / this.imageDimensions.height;
|
|
529
|
+
// Determine if we need to crop width or height
|
|
530
|
+
if (sourceRatio > targetRatio) {
|
|
531
|
+
// Source is wider than target - crop left and right
|
|
532
|
+
const widthPercent = (targetRatio / sourceRatio) * 100;
|
|
533
|
+
const xOffset = (100 - widthPercent) / 2;
|
|
534
|
+
return `pct:${this.formatPercent(xOffset)},0,${this.formatPercent(widthPercent)},100`;
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
// Source is taller than target - crop top and bottom
|
|
538
|
+
const heightPercent = (sourceRatio / targetRatio) * 100;
|
|
539
|
+
const yOffset = (100 - heightPercent) / 2;
|
|
540
|
+
return `pct:0,${this.formatPercent(yOffset)},100,${this.formatPercent(heightPercent)}`;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Get the region parameter for the IIIF URL.
|
|
545
|
+
*/
|
|
546
|
+
getRegionParam() {
|
|
547
|
+
// Handle custom aspect ratios
|
|
548
|
+
let regionParam = this.region || 'full';
|
|
549
|
+
if (this.isAspectRatio(regionParam)) {
|
|
550
|
+
// Only apply crop if we have dimensions for the current UUID
|
|
551
|
+
if (this.imageDimensions && this.fetchedUuid === this.uuid) {
|
|
552
|
+
regionParam = this.calculateCenteredCrop(regionParam);
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
// Use full image until dimensions are loaded
|
|
556
|
+
regionParam = 'full';
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return regionParam;
|
|
560
|
+
}
|
|
561
|
+
buildIIIFUrl(width, format = 'jpg') {
|
|
562
|
+
const sizeParam = width ? `${width},` : 'max';
|
|
563
|
+
const regionParam = this.getRegionParam();
|
|
564
|
+
return `${this.baseUrl}/${this.uuid}/${regionParam}/${sizeParam}/${this.rotation}/${this.quality}.${format}`;
|
|
565
|
+
}
|
|
566
|
+
generateSrcset(baseWidth, format) {
|
|
567
|
+
return PIXEL_DENSITIES.map(density => {
|
|
568
|
+
const width = Math.round(baseWidth * density);
|
|
569
|
+
const url = this.buildIIIFUrl(width, format);
|
|
570
|
+
return `${url} ${density}x`;
|
|
571
|
+
}).join(', ');
|
|
572
|
+
}
|
|
573
|
+
handleRegionChange(newValue, oldValue) {
|
|
574
|
+
// Only process if region actually changed
|
|
575
|
+
if (newValue === oldValue) {
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
// If new region is an aspect ratio, set CSS and fetch info
|
|
579
|
+
if (newValue && this.isAspectRatio(newValue)) {
|
|
580
|
+
this.setAspectRatioCss(newValue);
|
|
581
|
+
this.fetchImageInfo();
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
// Clear aspect ratio CSS if no longer using aspect ratio format
|
|
585
|
+
this.clearAspectRatioCss();
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
componentDidLoad() {
|
|
589
|
+
// Set CSS aspect ratio and fetch image info if using aspect ratio format
|
|
590
|
+
if (this.region && this.isAspectRatio(this.region)) {
|
|
591
|
+
this.setAspectRatioCss(this.region);
|
|
592
|
+
this.fetchImageInfo();
|
|
593
|
+
}
|
|
594
|
+
if ('ResizeObserver' in window) {
|
|
595
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
596
|
+
for (const entry of entries) {
|
|
597
|
+
this.observedWidth = Math.round(entry.contentRect.width);
|
|
598
|
+
if (this.resizeObserver) {
|
|
599
|
+
this.resizeObserver.disconnect();
|
|
600
|
+
this.resizeObserver = undefined;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
this.resizeObserver.observe(this.hostElement);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
disconnectedCallback() {
|
|
608
|
+
if (this.resizeObserver) {
|
|
609
|
+
this.resizeObserver.disconnect();
|
|
610
|
+
this.resizeObserver = undefined;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
render() {
|
|
614
|
+
// Show placeholder until we've measured the component width
|
|
615
|
+
if (!this.observedWidth) {
|
|
616
|
+
return h("pennlibs-fallback-img", null);
|
|
617
|
+
}
|
|
618
|
+
if (this.hasError && this.showFallback) {
|
|
619
|
+
return (h("div", { class: "fallback-container" }, h("pennlibs-fallback-img", null)));
|
|
620
|
+
}
|
|
621
|
+
const imgClasses = {
|
|
622
|
+
'iiif-img': true,
|
|
623
|
+
'loaded': this.isLoaded
|
|
624
|
+
};
|
|
625
|
+
return (h("picture", null, h("source", { type: "image/webp", srcSet: this.generateSrcset(this.observedWidth, 'webp') }), h("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 })));
|
|
626
|
+
}
|
|
627
|
+
get hostElement() { return getElement(this); }
|
|
628
|
+
static get watchers() { return {
|
|
629
|
+
"region": ["handleRegionChange"]
|
|
630
|
+
}; }
|
|
631
|
+
};
|
|
632
|
+
IIIFImg.style = pennlibsIiifImgCss;
|
|
633
|
+
|
|
634
|
+
export { Autocomplete as pennlibs_autocomplete, NoImage as pennlibs_fallback_img, Footer as pennlibs_footer, Header as pennlibs_header, IIIFImg as pennlibs_iiif_img };
|
|
635
|
+
//# sourceMappingURL=pennlibs-autocomplete.pennlibs-fallback-img.pennlibs-footer.pennlibs-header.pennlibs-iiif-img.entry.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, a as getAssetPath, h } from './index-
|
|
1
|
+
import { r as registerInstance, a as getAssetPath, h } from './index-RqnbThKP.js';
|
|
2
2
|
|
|
3
3
|
const pennlibsBannerCss = ":host{font-family:var(--pl-font-family);font-size:var(--pl-font-size);--max-width:1080px}.viewport-margins{max-width:calc(var(--max-width) + 0.5em);margin:0 auto;padding:0 var(--pl-viewport-margins-gutter, 1em)}.skip-to-content-link{position:absolute;transform:translateY(-300%);background:var(--pl-color-bg-default);left:0.5em;padding:0.5em 1em;margin-top:0.5em;position:absolute}.skip-to-content-link:focus{transform:translateY(0%);color:var(--pl-color-fg-default)}.universal-nav{background:var(--pl-color-penn-blue)}.universal-nav ul{display:flex;align-items:baseline;flex-wrap:wrap;scrollbar-color:var(--pl-color-penn-red);list-style:none;padding:0;margin:0}.universal-nav li{display:inline-block}.universal-nav a{display:inline-block;text-transform:uppercase;font-size:0.75em;letter-spacing:0.075em;font-weight:600;color:var(--pl-color-fg-subtle-on-emphasis);padding:0.5em;text-decoration:none}.universal-nav a:hover{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.15em}.universal-nav__shield-image{vertical-align:sub;height:1em;padding-right:0.5em;height:auto}";
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, h } from './index-
|
|
1
|
+
import { r as registerInstance, h } from './index-RqnbThKP.js';
|
|
2
2
|
|
|
3
3
|
const pennlibsChatCss = ":host {\n font-family: var(--pl-font-family);\n font-size: var(--pl-font-size);\n line-height: normal;\n}\n\n@media print {\n :host {\n display: none;\n }\n}\n\na {\n display: flex;\n align-items: center;\n background: linear-gradient(45deg, #faa755, #fcca99);\n border-radius: 1em;\n position: fixed;\n bottom: 0.75em;\n right: 0.75em;\n box-shadow: rgba(0,0,0,0.3) 0px 2px 16px 0px;\n color: var(--pl-color-penn-blue);\n text-decoration: none;\n font-weight: 500;\n padding: 0.15em;\n font-size: 1em;\n\n @media (min-width: 820px) {\n bottom: 1.5em;\n right: 1.5em;\n width: auto;\n padding: 0.15em 0.75em;\n padding-left: 0.5em;\n }\n}\n\na:hover {\n text-decoration: underline;\n text-underline-offset: var(--pl-link-text-underline-offset);\n text-decoration-thickness: var(--pl-link-hover-text-decoration-thickness);\n}\n\na:hover,\na:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--pl-color-bg-attention),0 0 0 4px var(--pl-color-penn-blue), rgba(0,0,0,0.3) 0px 2px 16px 0px;;\n}\n\nsvg {\n width: 2.5em;\n height: 2.5em;\n}\n\nspan {\n display: none;\n font-size: 1.1em;\n\n @media (min-width: 820px) {\n display: inline;\n }\n}";
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h } from './index-
|
|
1
|
+
import { r as registerInstance, c as createEvent, h } from './index-RqnbThKP.js';
|
|
2
2
|
|
|
3
3
|
const pennlibsFeedbackCss = ":host{display:block;background:#eeeff4;padding:1.5em 1em;font-family:var(--pl-font-family);font-size:var(--pl-font-size);color:var(--pl-color-fg-default);line-height:1.4;box-sizing:border-box}@media print{:host{display:none}}.feedback-container{display:flex;align-items:center;flex-wrap:wrap;gap:0.5em;width:100%;justify-content:center}@media (max-width: 26em){.feedback-container{justify-content:center}}h2{display:inline-block;margin:0 0.5em 0 0;font-family:var(--pl-font-sans-serif);font-size:1em;font-weight:600}p{margin:0;padding:calc(0.5em + 1px) 0}strong{font-weight:600}a{color:var(--pl-color-fg-accent);text-decoration:underline;text-underline-offset:var(--pl-link-text-underline-offset);text-decoration-thickness:var(--pl-link-text-decoration-thickness)}button{all:unset;display:flex;align-items:center;gap:0.5em;padding:0.5em 1.5em;font-family:var(--pl-font-family);font-weight:500;line-height:1.4;color:var(--pl-color-fg-default);background:var(--pl-color-bg-default);border:solid 1px var(--pl-color-fg-subtle);border-radius:1em;box-sizing:border-box}button:hover{cursor:pointer}button:hover span{text-decoration:underline}*:focus{outline:0;box-shadow:0 0 0 2px var(--pl-color-bg-attention),\n 0 0 0 3px var(--pl-color-bg-emphasis)}p:focus{outline:none;box-shadow:0 0 0 2px var(--pl-color-bg-attention), 0 0 0 3px var(--pl-color-bg-emphasis)}@media (max-width: 26em){h2{display:block;width:100%;text-align:center}}.help-us{display:flex;flex-direction:column;gap:0.5em}.visually-hidden{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}.visually-hidden:focus,.visually-hidden:active{clip:auto;clip-path:none;height:auto;overflow:visible;position:static;white-space:normal;width:auto}";
|
|
4
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as registerInstance, h, d as getElement } from './index-
|
|
1
|
+
import { r as registerInstance, h, d as getElement } from './index-RqnbThKP.js';
|
|
2
2
|
|
|
3
|
-
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:
|
|
3
|
+
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}}";
|
|
4
4
|
|
|
5
5
|
const getCurrentImageSource = (pictureElement) => {
|
|
6
6
|
const imgElement = pictureElement.querySelector('img');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pennlibs-hero.entry.js","sources":["src/components/pennlibs-hero/pennlibs-hero.css?tag=pennlibs-hero&encapsulation=shadow","src/components/pennlibs-hero/pennlibs-hero.tsx"],"sourcesContent":[":host {\n --pl-hero-height: clamp(42vh, 32rem, 26rem);\n --pl-hero-heading-font: var(--pl-font-serif);\n --pl-hero-color: var(--pl-color-fg-on-emphasis);\n}\n\n*, *:before, *:after {\n box-sizing: inherit;\n}\n\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.viewport-margins {\n width: 100%;\n max-width: var(--pl-viewport-margins-max-width);\n margin: 0 auto;\n padding: 0 var(--pl-viewport-margins-gutter, 1em);\n}\n\n/* Start of Selection */\n/* Hero section */\n.hero {\n position: relative;\n min-height: var(--pl-hero-height);\n height: 100%;\n background-size: cover;\n background-repeat: no-repeat;\n background-position: 50% 33%;\n display: flex;\n}\n/* End of Selection */\n\n.hero::before {\n content: \"\";\n display: flex;\n width: 100%;\n height: 100%;\n top: 0;\n position: absolute;\n 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%);\n z-index: 0;\n}\n\n \n.hero::after {\n content: \"\";\n display: flex;\n width: 100%;\n height: 100%;\n top: 0;\n position: absolute;\n 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%);\n z-index: 0;\n}\n\n.hero__content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n z-index: 1;\n}\n\n.hero__heading-container {\n margin-top: auto;\n padding-top: var(--pl-space-3xl);\n padding-bottom: var(--pl-space-3xl);\n}\n\n.hero__heading {\n text-shadow: 1px 1px 2px var(--pl-color-fg-default);\n line-height: 1.1;\n font-size: 3em;\n font-weight:
|
|
1
|
+
{"version":3,"file":"pennlibs-hero.entry.js","sources":["src/components/pennlibs-hero/pennlibs-hero.css?tag=pennlibs-hero&encapsulation=shadow","src/components/pennlibs-hero/pennlibs-hero.tsx"],"sourcesContent":[":host {\n --pl-hero-height: clamp(42vh, 32rem, 26rem);\n --pl-hero-heading-font: var(--pl-font-serif);\n --pl-hero-color: var(--pl-color-fg-on-emphasis);\n}\n\n*, *:before, *:after {\n box-sizing: inherit;\n}\n\n.visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.viewport-margins {\n width: 100%;\n max-width: var(--pl-viewport-margins-max-width);\n margin: 0 auto;\n padding: 0 var(--pl-viewport-margins-gutter, 1em);\n}\n\n/* Start of Selection */\n/* Hero section */\n.hero {\n position: relative;\n min-height: var(--pl-hero-height);\n height: 100%;\n background-size: cover;\n background-repeat: no-repeat;\n background-position: 50% 33%;\n display: flex;\n}\n/* End of Selection */\n\n.hero::before {\n content: \"\";\n display: flex;\n width: 100%;\n height: 100%;\n top: 0;\n position: absolute;\n 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%);\n z-index: 0;\n}\n\n \n.hero::after {\n content: \"\";\n display: flex;\n width: 100%;\n height: 100%;\n top: 0;\n position: absolute;\n 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%);\n z-index: 0;\n}\n\n.hero__content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n z-index: 1;\n}\n\n.hero__heading-container {\n margin-top: auto;\n padding-top: var(--pl-space-3xl);\n padding-bottom: var(--pl-space-3xl);\n}\n\n.hero__heading {\n text-shadow: 1px 1px 2px var(--pl-color-fg-default);\n line-height: 1.1;\n font-size: 3em;\n font-weight: 400;\n font-family: var(--pl-hero-heading-font);\n text-wrap: pretty;\n max-width: 30ch;\n margin: 0;\n color: var(--pl-hero-color);\n}\n\n@media (max-width: 920px) {\n .hero__heading {\n font-size: 2.5em;\n }\n}\n\n.hero__sub-heading {\n font-size: 1.25em;\n font-family: var(--pl-font-family);\n font-weight: 500;\n color: var(--pl-hero-color);\n max-width: 52ch;\n text-wrap: pretty;\n margin-top: 1em;\n margin-bottom: 0;\n}\n\n.hero__sub-heading a {\n text-decoration: underline;\n text-underline-offset: var(--pl-link-text-underline-offset);\n text-decoration-thickness: var(--pl-link-text-decoration-thickness);\n color: var(--pl-hero-color);\n}\n\n.hero__sub-heading a:hover {\n text-decoration-thickness: var(--pl-link-hover-text-decoration-thickness);\n}\n\n.hero__sub-heading strong {\n font-weight: bold;\n}\n\n@media (max-width: 620px) {\n .hero__heading {\n font-size: 2.75em;\n }\n\n .hero__sub-heading {\n font-size: 1em;\n }\n}","import { h, Component, State, Element } from \"@stencil/core\";\n\nconst getCurrentImageSource = (pictureElement: HTMLPictureElement): string => {\n const imgElement = pictureElement.querySelector('img');\n return imgElement?.currentSrc || '';\n};\n\n/**\n * Place your most important content in a prominent space, often at the top of your website.\n *\n * @slot start - Content to display at the start (top) of the hero.\n * \n * @prop --pl-viewport-margins-max-width: The maximum width of the hero inner content.\n * @prop --pl-viewport-margins-gutter: The gutter width of the hero inner content.\n */\n@Component({\n tag: 'pennlibs-hero',\n styleUrl: 'pennlibs-hero.css',\n shadow: true,\n assetsDirs: ['assets']\n})\nexport class Hero {\n @Element() hostElement: HTMLElement;\n @State() heroPictureElement: null | HTMLPictureElement = null;\n @State() heroHeadingElement: null | HTMLHeadingElement = null;\n @State() heroParagraphElement: null | HTMLParagraphElement = null;\n @State() heroSrc: string = \"\";\n private lastSrc: string = \"\";\n private animationFrameId: number;\n\n componentWillLoad() {\n const heroPictureElement = this.hostElement.querySelector('picture[hero=art-direction]') as HTMLPictureElement;\n if (heroPictureElement) {\n this.heroPictureElement = heroPictureElement;\n this.startWatchingCurrentSrc(heroPictureElement);\n }\n\n const heroHeadingElement = this.hostElement.querySelector('h1[hero=heading]') as HTMLHeadingElement;\n if (heroHeadingElement) {\n this.heroHeadingElement = heroHeadingElement;\n }\n\n const heroParagraphElement = this.hostElement.querySelector('p[hero=sub-heading]') as HTMLParagraphElement;\n if (heroParagraphElement) {\n this.heroParagraphElement = heroParagraphElement;\n }\n }\n\n private startWatchingCurrentSrc(pictureElement: HTMLPictureElement) {\n const checkCurrentSrc = () => {\n const currentSrc = getCurrentImageSource(pictureElement);\n if (currentSrc !== this.lastSrc) {\n this.lastSrc = currentSrc;\n this.heroSrc = currentSrc;\n }\n this.animationFrameId = requestAnimationFrame(checkCurrentSrc);\n };\n \n this.animationFrameId = requestAnimationFrame(checkCurrentSrc);\n }\n\n disconnectedCallback() {\n if (this.animationFrameId) {\n cancelAnimationFrame(this.animationFrameId);\n }\n }\n\n render() {\n return (\n <div class=\"hero\" style={{ backgroundImage: `url(${this.heroSrc})` }}>\n <div class=\"hero__content\">\n <slot name=\"start\" />\n <div class=\"hero__heading-container\">\n {this.heroHeadingElement && (\n <div class=\"viewport-margins\">\n <h1 class=\"hero__heading\" innerHTML={this.heroHeadingElement.innerText} />\n {this.heroParagraphElement && <p class=\"hero__sub-heading\" innerHTML={this.heroParagraphElement.innerHTML} />}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n }\n}"],"names":[],"mappings":"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"}
|
package/dist/esm/web.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as promiseResolve, g as globalScripts, b as bootstrapLazy } from './index-
|
|
2
|
-
export { s as setNonce } from './index-
|
|
1
|
+
import { p as promiseResolve, g as globalScripts, b as bootstrapLazy } from './index-RqnbThKP.js';
|
|
2
|
+
export { s as setNonce } from './index-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([["pennlibs-
|
|
19
|
+
return bootstrapLazy([["pennlibs-banner",[[257,"pennlibs-banner"]]],["pennlibs-chat",[[257,"pennlibs-chat",{"href":[32]}]]],["pennlibs-feedback",[[257,"pennlibs-feedback",{"error":[32],"answer":[32]}]]],["pennlibs-hero",[[257,"pennlibs-hero",{"heroPictureElement":[32],"heroHeadingElement":[32],"heroParagraphElement":[32],"heroSrc":[32]}]]],["pennlibs-autocomplete_5",[[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.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.
|
|
3
|
-
*
|
|
4
|
-
* with modern WebP format and JPG fallback support.
|
|
3
|
+
* Measures its own rendered width and automatically generates optimal image sources at
|
|
4
|
+
* multiple pixel densities (1x, 1.5x, 2x) with modern WebP format and JPG fallback support.
|
|
5
5
|
*
|
|
6
6
|
* @component
|
|
7
7
|
* @example
|
|
@@ -30,6 +30,10 @@ export declare class IIIFImg {
|
|
|
30
30
|
*
|
|
31
31
|
* `square`: A square area where width and height equal the shorter dimension.
|
|
32
32
|
*
|
|
33
|
+
* `width:height`: Any aspect ratio format (e.g., `16:9`, `4:3`, `3:2`, `21:9`) applies
|
|
34
|
+
* a centered crop based on the source image dimensions and sets the CSS aspect-ratio
|
|
35
|
+
* property for layout reservation.
|
|
36
|
+
*
|
|
33
37
|
* `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions).
|
|
34
38
|
*
|
|
35
39
|
* `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
@@ -76,13 +80,50 @@ export declare class IIIFImg {
|
|
|
76
80
|
showFallback?: boolean;
|
|
77
81
|
isLoaded: boolean;
|
|
78
82
|
hasError: boolean;
|
|
79
|
-
|
|
83
|
+
imageDimensions?: {
|
|
84
|
+
width: number;
|
|
85
|
+
height: number;
|
|
86
|
+
};
|
|
87
|
+
observedWidth?: number;
|
|
88
|
+
private fetchedUuid?;
|
|
80
89
|
private readonly baseUrl;
|
|
90
|
+
/**
|
|
91
|
+
* Fetch IIIF image info to get actual dimensions.
|
|
92
|
+
*/
|
|
93
|
+
private fetchImageInfo;
|
|
94
|
+
/**
|
|
95
|
+
* Check if a region value matches aspect ratio format (e.g., "16:9", "4:3", "3:2").
|
|
96
|
+
*/
|
|
97
|
+
private isAspectRatio;
|
|
98
|
+
/**
|
|
99
|
+
* Set CSS custom property for aspect ratio on the host element.
|
|
100
|
+
*/
|
|
101
|
+
private setAspectRatioCss;
|
|
102
|
+
/**
|
|
103
|
+
* Clear CSS custom property for aspect ratio from the host element.
|
|
104
|
+
*/
|
|
105
|
+
private clearAspectRatioCss;
|
|
106
|
+
/**
|
|
107
|
+
* Format a number for IIIF percentage values (remove trailing zeros).
|
|
108
|
+
* IIIF spec requires no trailing zeros per section 4.7.
|
|
109
|
+
*/
|
|
110
|
+
private formatPercent;
|
|
111
|
+
/**
|
|
112
|
+
* Calculate a centered crop region for a given aspect ratio.
|
|
113
|
+
* Requires actual image dimensions to calculate correctly.
|
|
114
|
+
* @param aspectRatio - The target aspect ratio (e.g., "3:2" or "2:3")
|
|
115
|
+
* @returns A IIIF percentage-based region string (e.g., "pct:0,16.67,100,66.67")
|
|
116
|
+
*/
|
|
117
|
+
private calculateCenteredCrop;
|
|
118
|
+
/**
|
|
119
|
+
* Get the region parameter for the IIIF URL.
|
|
120
|
+
*/
|
|
121
|
+
private getRegionParam;
|
|
81
122
|
private buildIIIFUrl;
|
|
82
123
|
private generateSrcset;
|
|
83
|
-
private getOptimalSizes;
|
|
84
124
|
private handleLoad;
|
|
85
125
|
private handleError;
|
|
126
|
+
handleRegionChange(newValue: string, oldValue: string): void;
|
|
86
127
|
componentDidLoad(): void;
|
|
87
128
|
disconnectedCallback(): void;
|
|
88
129
|
render(): any;
|
|
@@ -91,8 +91,8 @@ export namespace Components {
|
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
93
|
* Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.
|
|
94
|
-
*
|
|
95
|
-
* with modern WebP format and JPG fallback support.
|
|
94
|
+
* Measures its own rendered width and automatically generates optimal image sources at
|
|
95
|
+
* multiple pixel densities (1x, 1.5x, 2x) with modern WebP format and JPG fallback support.
|
|
96
96
|
* @component
|
|
97
97
|
* @example <pennlibs-iiif-img
|
|
98
98
|
* uuid="063ff35c-bbdd-4b63-bbdd-6206590e20d5"
|
|
@@ -115,7 +115,7 @@ export namespace Components {
|
|
|
115
115
|
*/
|
|
116
116
|
"quality"?: string;
|
|
117
117
|
/**
|
|
118
|
-
* The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display. Defines the rectangular portion of the underlying image to return. `full`: The full image is returned, without any cropping. `square`: A square area where width and height equal the shorter dimension. `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions). `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
118
|
+
* The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display. Defines the rectangular portion of the underlying image to return. `full`: The full image is returned, without any cropping. `square`: A square area where width and height equal the shorter dimension. `width:height`: Any aspect ratio format (e.g., `16:9`, `4:3`, `3:2`, `21:9`) applies a centered crop based on the source image dimensions and sets the CSS aspect-ratio property for layout reservation. `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions). `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
119
119
|
* @default 'full'
|
|
120
120
|
*/
|
|
121
121
|
"region"?: string;
|
|
@@ -264,8 +264,8 @@ declare global {
|
|
|
264
264
|
};
|
|
265
265
|
/**
|
|
266
266
|
* Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.
|
|
267
|
-
*
|
|
268
|
-
* with modern WebP format and JPG fallback support.
|
|
267
|
+
* Measures its own rendered width and automatically generates optimal image sources at
|
|
268
|
+
* multiple pixel densities (1x, 1.5x, 2x) with modern WebP format and JPG fallback support.
|
|
269
269
|
* @component
|
|
270
270
|
* @example <pennlibs-iiif-img
|
|
271
271
|
* uuid="063ff35c-bbdd-4b63-bbdd-6206590e20d5"
|
|
@@ -386,8 +386,8 @@ declare namespace LocalJSX {
|
|
|
386
386
|
}
|
|
387
387
|
/**
|
|
388
388
|
* Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.
|
|
389
|
-
*
|
|
390
|
-
* with modern WebP format and JPG fallback support.
|
|
389
|
+
* Measures its own rendered width and automatically generates optimal image sources at
|
|
390
|
+
* multiple pixel densities (1x, 1.5x, 2x) with modern WebP format and JPG fallback support.
|
|
391
391
|
* @component
|
|
392
392
|
* @example <pennlibs-iiif-img
|
|
393
393
|
* uuid="063ff35c-bbdd-4b63-bbdd-6206590e20d5"
|
|
@@ -410,7 +410,7 @@ declare namespace LocalJSX {
|
|
|
410
410
|
*/
|
|
411
411
|
"quality"?: string;
|
|
412
412
|
/**
|
|
413
|
-
* The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display. Defines the rectangular portion of the underlying image to return. `full`: The full image is returned, without any cropping. `square`: A square area where width and height equal the shorter dimension. `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions). `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
413
|
+
* The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display. Defines the rectangular portion of the underlying image to return. `full`: The full image is returned, without any cropping. `square`: A square area where width and height equal the shorter dimension. `width:height`: Any aspect ratio format (e.g., `16:9`, `4:3`, `3:2`, `21:9`) applies a centered crop based on the source image dimensions and sets the CSS aspect-ratio property for layout reservation. `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions). `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
|
|
414
414
|
* @default 'full'
|
|
415
415
|
*/
|
|
416
416
|
"region"?: string;
|
|
@@ -497,8 +497,8 @@ declare module "@stencil/core" {
|
|
|
497
497
|
"pennlibs-hero": LocalJSX.PennlibsHero & JSXBase.HTMLAttributes<HTMLPennlibsHeroElement>;
|
|
498
498
|
/**
|
|
499
499
|
* Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.
|
|
500
|
-
*
|
|
501
|
-
* with modern WebP format and JPG fallback support.
|
|
500
|
+
* Measures its own rendered width and automatically generates optimal image sources at
|
|
501
|
+
* multiple pixel densities (1x, 1.5x, 2x) with modern WebP format and JPG fallback support.
|
|
502
502
|
* @component
|
|
503
503
|
* @example <pennlibs-iiif-img
|
|
504
504
|
* uuid="063ff35c-bbdd-4b63-bbdd-6206590e20d5"
|
|
Binary file
|
|
Binary file
|
package/dist/web/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { e as setAssetPath } from './p-
|
|
1
|
+
export { e as setAssetPath } from './p-RqnbThKP.js';
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, c as createEvent, h } from './p-
|
|
1
|
+
import { r as registerInstance, c as createEvent, h } from './p-RqnbThKP.js';
|
|
2
2
|
|
|
3
3
|
const pennlibsFeedbackCss = ":host{display:block;background:#eeeff4;padding:1.5em 1em;font-family:var(--pl-font-family);font-size:var(--pl-font-size);color:var(--pl-color-fg-default);line-height:1.4;box-sizing:border-box}@media print{:host{display:none}}.feedback-container{display:flex;align-items:center;flex-wrap:wrap;gap:0.5em;width:100%;justify-content:center}@media (max-width: 26em){.feedback-container{justify-content:center}}h2{display:inline-block;margin:0 0.5em 0 0;font-family:var(--pl-font-sans-serif);font-size:1em;font-weight:600}p{margin:0;padding:calc(0.5em + 1px) 0}strong{font-weight:600}a{color:var(--pl-color-fg-accent);text-decoration:underline;text-underline-offset:var(--pl-link-text-underline-offset);text-decoration-thickness:var(--pl-link-text-decoration-thickness)}button{all:unset;display:flex;align-items:center;gap:0.5em;padding:0.5em 1.5em;font-family:var(--pl-font-family);font-weight:500;line-height:1.4;color:var(--pl-color-fg-default);background:var(--pl-color-bg-default);border:solid 1px var(--pl-color-fg-subtle);border-radius:1em;box-sizing:border-box}button:hover{cursor:pointer}button:hover span{text-decoration:underline}*:focus{outline:0;box-shadow:0 0 0 2px var(--pl-color-bg-attention),\n 0 0 0 3px var(--pl-color-bg-emphasis)}p:focus{outline:none;box-shadow:0 0 0 2px var(--pl-color-bg-attention), 0 0 0 3px var(--pl-color-bg-emphasis)}@media (max-width: 26em){h2{display:block;width:100%;text-align:center}}.help-us{display:flex;flex-direction:column;gap:0.5em}.visually-hidden{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}.visually-hidden:focus,.visually-hidden:active{clip:auto;clip-path:none;height:auto;overflow:visible;position:static;white-space:normal;width:auto}";
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance, a as getAssetPath, h } from './p-
|
|
1
|
+
import { r as registerInstance, a as getAssetPath, h } from './p-RqnbThKP.js';
|
|
2
2
|
|
|
3
3
|
const pennlibsBannerCss = ":host{font-family:var(--pl-font-family);font-size:var(--pl-font-size);--max-width:1080px}.viewport-margins{max-width:calc(var(--max-width) + 0.5em);margin:0 auto;padding:0 var(--pl-viewport-margins-gutter, 1em)}.skip-to-content-link{position:absolute;transform:translateY(-300%);background:var(--pl-color-bg-default);left:0.5em;padding:0.5em 1em;margin-top:0.5em;position:absolute}.skip-to-content-link:focus{transform:translateY(0%);color:var(--pl-color-fg-default)}.universal-nav{background:var(--pl-color-penn-blue)}.universal-nav ul{display:flex;align-items:baseline;flex-wrap:wrap;scrollbar-color:var(--pl-color-penn-red);list-style:none;padding:0;margin:0}.universal-nav li{display:inline-block}.universal-nav a{display:inline-block;text-transform:uppercase;font-size:0.75em;letter-spacing:0.075em;font-weight:600;color:var(--pl-color-fg-subtle-on-emphasis);padding:0.5em;text-decoration:none}.universal-nav a:hover{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:.15em}.universal-nav__shield-image{vertical-align:sub;height:1em;padding-right:0.5em;height:auto}";
|
|
4
4
|
|