@penn-libraries/web 1.2.0-dev.0 → 1.2.0-dev.2
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-DJo51Q03.js → index-Ag6DtE87.js} +3 -14
- package/dist/cjs/index-Ag6DtE87.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/{web/pennlibs-autocomplete.pennlibs-fallback-img.pennlibs-footer.pennlibs-header.pennlibs-iiif-img.entry.esm.js.map → cjs/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.cjs.js.map} +1 -1
- package/dist/cjs/{pennlibs-autocomplete_5.cjs.entry.js → pennlibs-autocomplete_4.cjs.entry.js} +54 -258
- package/dist/cjs/pennlibs-banner.cjs.entry.js +1 -1
- package/dist/cjs/pennlibs-chat.cjs.entry.js +1 -1
- package/dist/cjs/pennlibs-fallback-img.cjs.entry.js +20 -0
- package/dist/cjs/pennlibs-fallback-img.entry.cjs.js.map +1 -0
- package/dist/cjs/pennlibs-hero.cjs.entry.js +2 -2
- package/dist/cjs/pennlibs-iiif-img.cjs.entry.js +249 -0
- package/dist/cjs/pennlibs-iiif-img.entry.cjs.js.map +1 -0
- package/dist/cjs/web.cjs.js +2 -2
- package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.css +24 -15
- package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.js +50 -17
- package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.js.map +1 -1
- package/dist/collection/components/pennlibs-footer/pennlibs-footer.css +23 -2
- package/dist/collection/components/pennlibs-footer/pennlibs-footer.js +33 -3
- package/dist/collection/components/pennlibs-footer/pennlibs-footer.js.map +1 -1
- package/dist/collection/components/pennlibs-header/pennlibs-header.js +1 -1
- package/dist/collection/components/pennlibs-hero/pennlibs-hero.js +1 -1
- package/dist/components/pennlibs-feedback.js +16 -17
- package/dist/components/pennlibs-feedback.js.map +1 -1
- package/dist/components/pennlibs-footer.js +9 -4
- package/dist/components/pennlibs-footer.js.map +1 -1
- package/dist/components/pennlibs-header.js +1 -1
- package/dist/components/pennlibs-hero.js +1 -1
- package/dist/docs.json +75 -6
- package/dist/{web/p-RqnbThKP.js → esm/index-CNQ9-Wwh.js} +4 -15
- package/dist/esm/index-CNQ9-Wwh.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 → pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.js.map} +1 -1
- package/dist/esm/{pennlibs-autocomplete_5.entry.js → pennlibs-autocomplete_4.entry.js} +54 -257
- package/dist/esm/pennlibs-banner.entry.js +1 -1
- package/dist/esm/pennlibs-chat.entry.js +1 -1
- package/dist/esm/pennlibs-fallback-img.entry.js +18 -0
- package/dist/esm/pennlibs-fallback-img.entry.js.map +1 -0
- package/dist/esm/pennlibs-hero.entry.js +2 -2
- package/dist/esm/pennlibs-iiif-img.entry.js +247 -0
- package/dist/esm/pennlibs-iiif-img.entry.js.map +1 -0
- package/dist/esm/web.js +3 -3
- package/dist/types/components/pennlibs-feedback/pennlibs-feedback.d.ts +19 -3
- package/dist/types/components/pennlibs-footer/pennlibs-footer.d.ts +4 -0
- package/dist/types/components.d.ts +51 -0
- package/dist/web/index.esm.js +1 -1
- package/dist/web/{p-f37f3865.entry.js → p-3da26275.entry.js} +54 -257
- package/dist/web/p-662e4125.entry.js +18 -0
- package/dist/{esm/index-RqnbThKP.js → web/p-CNQ9-Wwh.js} +4 -15
- package/dist/web/p-CNQ9-Wwh.js.map +1 -0
- package/dist/web/{p-8ac5ef70.entry.js → p-a34e1e3e.entry.js} +1 -1
- package/dist/web/{p-b7b01d67.entry.js → p-b6e686d1.entry.js} +2 -2
- package/dist/web/{p-ce09ae2e.entry.js → p-c96a3643.entry.js} +1 -1
- package/dist/web/p-eb633f4d.entry.js +247 -0
- package/dist/{cjs/pennlibs-autocomplete.pennlibs-fallback-img.pennlibs-footer.pennlibs-header.pennlibs-iiif-img.entry.cjs.js.map → web/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.esm.js.map} +1 -1
- package/dist/web/pennlibs-fallback-img.entry.esm.js.map +1 -0
- package/dist/web/pennlibs-iiif-img.entry.esm.js.map +1 -0
- package/dist/web/web.esm.js +3 -3
- package/hydrate/index.js +39 -35
- package/hydrate/index.mjs +39 -35
- package/package.json +1 -1
- package/dist/cjs/index-DJo51Q03.js.map +0 -1
- package/dist/cjs/pennlibs-feedback.cjs.entry.js +0 -58
- package/dist/cjs/pennlibs-feedback.entry.cjs.js.map +0 -1
- package/dist/esm/index-RqnbThKP.js.map +0 -1
- package/dist/esm/pennlibs-feedback.entry.js +0 -56
- package/dist/esm/pennlibs-feedback.entry.js.map +0 -1
- package/dist/web/p-780e656e.entry.js +0 -56
- package/dist/web/p-RqnbThKP.js.map +0 -1
- package/dist/web/pennlibs-feedback.entry.esm.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as registerInstance,
|
|
1
|
+
import { r as registerInstance, d as createEvent, h, c as getElement, a as getAssetPath } from './p-CNQ9-Wwh.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,25 +275,65 @@ const Autocomplete = class {
|
|
|
275
275
|
};
|
|
276
276
|
Autocomplete.style = pennlibsAutocompleteCss;
|
|
277
277
|
|
|
278
|
-
const
|
|
278
|
+
const pennlibsFeedbackCss = ":host{display:block;background:#eeeff4;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;padding:0.75em 0}@media print{:host{display:none}}*,*::before,*::after{box-sizing:border-box}.viewport-margins{max-width:var(--pl-viewport-margins-max-width);margin:0 auto;padding:0 var(--pl-viewport-margins-gutter, 1em)}.feedback__content{display:flex;justify-content:space-between;gap:var(--pl-space-s);flex-wrap:wrap}.feedback__inline-question{display:flex;flex-wrap:wrap;gap:0.5em;align-items:center}h2{display:inline-block;margin:0;font-family:var(--pl-font-sans-serif);font-size:1em;font-weight:400}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-hover-text-decoration-thickness)}button{all:unset;display:flex;align-items:center;gap:0.5em;padding:0.25em 1.25em;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}";
|
|
279
279
|
|
|
280
|
-
const
|
|
280
|
+
const FEEDBACK_STORAGE_KEY = 'pennlibs-feedback-answer';
|
|
281
|
+
const FEEDBACK_TIMESTAMP_KEY = 'pennlibs-feedback-timestamp';
|
|
282
|
+
const FEEDBACK_TTL = 5 * 60 * 1000; // 5 minutes
|
|
283
|
+
const FEEDBACK_QUESTION = 'Is this page useful?';
|
|
284
|
+
const FEEDBACK_ERROR_STORAGE_KEY = 'pennlibs-feedback-error';
|
|
285
|
+
const PennlibsFeedback = class {
|
|
281
286
|
constructor(hostRef) {
|
|
282
287
|
registerInstance(this, hostRef);
|
|
288
|
+
this.feedbackEvent = createEvent(this, "pennlibs-feedback");
|
|
289
|
+
/**
|
|
290
|
+
* When true, hides the yes/no question and only shows the "share your feedback" link.
|
|
291
|
+
*/
|
|
292
|
+
this.hideQuestion = false;
|
|
293
|
+
this.error = false;
|
|
294
|
+
this.answer = undefined;
|
|
295
|
+
}
|
|
296
|
+
componentWillLoad() {
|
|
297
|
+
const timestamp = sessionStorage.getItem(FEEDBACK_TIMESTAMP_KEY);
|
|
298
|
+
if (timestamp && Date.now() - Number(timestamp) > FEEDBACK_TTL) {
|
|
299
|
+
sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);
|
|
300
|
+
sessionStorage.removeItem(FEEDBACK_TIMESTAMP_KEY);
|
|
301
|
+
}
|
|
302
|
+
if (sessionStorage.getItem(FEEDBACK_STORAGE_KEY)) {
|
|
303
|
+
this.answer = sessionStorage.getItem(FEEDBACK_STORAGE_KEY);
|
|
304
|
+
}
|
|
305
|
+
if (sessionStorage.getItem(FEEDBACK_ERROR_STORAGE_KEY)) {
|
|
306
|
+
this.error = sessionStorage.getItem(FEEDBACK_ERROR_STORAGE_KEY) === 'true';
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
handleFeedback(answer) {
|
|
310
|
+
var _a;
|
|
311
|
+
this.answer = answer;
|
|
312
|
+
sessionStorage.setItem(FEEDBACK_STORAGE_KEY, answer);
|
|
313
|
+
sessionStorage.setItem(FEEDBACK_TIMESTAMP_KEY, String(Date.now()));
|
|
314
|
+
this.feedbackEvent.emit({
|
|
315
|
+
question: FEEDBACK_QUESTION,
|
|
316
|
+
answer: answer,
|
|
317
|
+
url: window.location.href,
|
|
318
|
+
pageHeading: ((_a = document.querySelector('h1')) === null || _a === void 0 ? void 0 : _a.textContent) || undefined,
|
|
319
|
+
pageTitle: document.title || undefined
|
|
320
|
+
});
|
|
283
321
|
}
|
|
284
322
|
render() {
|
|
285
|
-
|
|
286
|
-
return (h("img", { key: 'ba6cc227e90aac2e22b9997ad5c794fd4fd6d5ef', src: shieldImg, alt: "", class: "no-image__img" }));
|
|
323
|
+
return (h("div", { key: '04053c96e964ee9f240ca1a77d7944ae0f53248d', class: "feedback__container" }, h("div", { key: 'f5f524b449d3473c1ecc2d454787034c54a811a0', class: "viewport-margins" }, h("div", { key: 'd0c832edc9361dac49d9cbfc143332fea04434ea', class: "feedback__content" }, !this.hideQuestion && (this.answer === 'yes' ? (h("p", null, "Thank you for letting us know.")) : this.answer === 'no' ? (h("p", null, "Thank you for letting us know. ", h("a", { href: "https://www.library.upenn.edu/contact-us" }, "Contact us"), " if you need help.")) : (h("div", { class: "feedback__inline-question" }, h("h2", null, "Did you find what you need?"), h("button", { onClick: () => this.handleFeedback('yes') }, h("span", null, "Yes"), h("span", { class: "visually-hidden" }, ", I found what I needed.")), h("button", { onClick: () => this.handleFeedback('no') }, h("span", null, "No"), h("span", { class: "visually-hidden" }, ", I did not find what I needed."))))), h("div", { key: '9d4de668c9e3696d8983c48fcc20ea89b2163ea1', class: "feedback__share-feedback" }, h("p", { key: '1377153ebba81c48b0a70756b190503b9cd33c61' }, "To help us improve, ", h("a", { key: '26f3f05b0af848ff58d959190a380d5b64db254a', href: "http://library.upenn.edu/feedback" }, "share your feedback"), "."))))));
|
|
287
324
|
}
|
|
288
|
-
static get assetsDirs() { return ["assets"]; }
|
|
289
325
|
};
|
|
290
|
-
|
|
326
|
+
PennlibsFeedback.style = pennlibsFeedbackCss;
|
|
291
327
|
|
|
292
|
-
const pennlibsFooterCss = ":host {\n font-family: var(--pl-font-family);\n font-size: var(--pl-font-size);\n --padding-bottom:
|
|
328
|
+
const pennlibsFooterCss = ":host {\n font-family: var(--pl-font-family);\n font-size: var(--pl-font-size);\n --padding-bottom: 3em;\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.built-with,\n.built-with a {\n color: var(--pl-color-fg-subtle-on-emphasis);\n}\n\n.built-with a {\n font-weight: 500;\n text-underline-offset: var(--pl-link-text-underline-offset);\n\n &:hover {\n text-decoration-thickness: var(--pl-link-hover-text-decoration-thickness);\n }\n}\n\n.built-with {\n opacity: 0.875;\n margin: 0; \n padding: 1.5em 0;\n font-size: 0.875em;\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.75em;\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}";
|
|
293
329
|
|
|
294
330
|
const Footer = class {
|
|
295
331
|
constructor(hostRef) {
|
|
296
332
|
registerInstance(this, hostRef);
|
|
333
|
+
/**
|
|
334
|
+
* When true, shows a "Built with the Penn Libraries Design System" line below the footer.
|
|
335
|
+
*/
|
|
336
|
+
this.showBuiltWith = false;
|
|
297
337
|
}
|
|
298
338
|
componentWillLoad() {
|
|
299
339
|
this.setNavigationByChildren();
|
|
@@ -318,12 +358,12 @@ const Footer = class {
|
|
|
318
358
|
}
|
|
319
359
|
render() {
|
|
320
360
|
const footerBackgroundSrc = getAssetPath('./assets/footer-bg.webp');
|
|
321
|
-
return (h("
|
|
361
|
+
return (h("footer", { key: '39b1bc7336fe2aa28e8c6093d13b8dfb3dd70d3e', class: "website-footer-wrapper" }, h("div", { key: '7902cf7cde3a468dec8ea71c2a139addafa5af79', class: "website-footer", style: {
|
|
322
362
|
background: `var(--pl-color-penn-blue) url(${footerBackgroundSrc}) no-repeat 50% 50%`,
|
|
323
363
|
backgroundSize: 'cover',
|
|
324
|
-
} }, h("div", { key: '
|
|
364
|
+
} }, h("div", { key: '804f9cd3f101997ee2d15d4a4749945ef553a118', class: "viewport-margins" }, h("div", { key: '3a09637400e74e729641666eb8142c0cf77d66b3', class: "website-footer__content" }, h("div", { key: 'cdb9270db298aa7781859a80c799949cb4c35787', class: "website-footer__links-container" }, h("section", { key: '20d953d2b85178798d2298aa8aaa9fb8e47d7af4' }, h("h2", { key: '79b1fe7f4fc2dff03134c7d4e96e9fd657131fc8', class: "website-footer__heading" }, "Penn Libraries"), h("ul", { key: 'ba8002b17457f979f9817c45a89f332064f0b5bb', class: "website-footer__links" }, h("li", { key: 'cb65fc4ad6432ef447a4b98a8dfdc0323bf37ccc' }, h("a", { key: '0b61506da9a1c18919f77410fa39d3937f7485df', href: "https://maps.google.com/?q=Van Pelt Library 3420 Walnut Street, Philadelphia, PA 19104-6206" }, "3420 Walnut Street", h("br", { key: 'ebd3def13a3107d1b301c0932d421b054e2bb338' }), "Philadelphia, PA 19104-6206")), h("li", { key: '3f26ebab3b90a33ba2d17cd3cfd8a485f1c7e74f' }, h("a", { key: 'c2dcf7a3d936eb5376b2568e677bb8a7dc7ab445', href: "tel:(215) 898-7555" }, "(215) 898-7555")), h("li", { key: '8c9374110f2d386c7275fad9522ea2565daf6c06' }, h("a", { key: 'd40a2fd7490f1b233e4839e38faf29d9bb04f519', href: "https://www.library.upenn.edu/contact-us" }, "Contact us")), h("li", { key: 'ab3016b1cfcc8827af060ec383d8556e8346713a' }, h("a", { key: '76a8d246128fb76606c1cdf24640198c23c9d317', href: "https://www.library.upenn.edu/about/hours", target: "_blank" }, "Locations and hours")))), h("section", { key: 'fd0abacbc35ffaafbb2016064c7a6194616ee2dc' }, h("h2", { key: 'a812d7d26e21a1808ce6bd115ec620e1b033a8bf', class: "website-footer__heading" }, "Stay in touch"), h("ul", { key: 'fe158ff1336379e1236a88c4a3d0f5e1efd9cdb8', class: "website-footer__links" }, h("li", { key: '32396df360b39190ff587400fabe405ee319a507' }, h("a", { key: '07ac56362dde7a2807e86c2a22564689ed9de90c', href: "https://www.alumni.upenn.edu/libsignup" }, "Newsletter")), h("li", { key: '95abd2bf0f6a79c0597c1e57e878f986002adde2' }, h("a", { key: '374044fae62fd82c9369cfba8b7c6223ded48d5a', href: "https://www.instagram.com/upennlib/" }, "Instagram")), h("li", { key: '86cc74d4ec21dfb51a072cfad87ed395e961f26f' }, h("a", { key: 'fda9e8c73918252b91e40dc23d289613a3fe5802', href: "https://www.facebook.com/PennLibraries/" }, "Facebook")), h("li", { key: 'b1ce60d7aa5ac8a2aa8bd4f826c11cc753b1488c' }, h("a", { key: 'ccfef8131fc7f9edd44936f1c212d31c08c61682', href: "https://www.linkedin.com/company/penn-libraries" }, "LinkedIn")))), this.navigationByChildren && [
|
|
325
365
|
this.navigationByChildren.map(section => (h("section", null, h("h2", { class: "website-footer__heading" }, section.heading), h("ul", { class: "website-footer__links" }, section.links.map(link => (h("li", null, h("a", { href: link.href }, link.label))))))))
|
|
326
|
-
]))), h("div", { key: '
|
|
366
|
+
]))), h("div", { key: '4430d39b9b8943d9336020d5ed04cdb80a3b91af', class: "website-footer__footer" }, h("div", { key: '437f0b8894b63c3857f8871eaaaf3d28277738ad', class: "viewport-margins" }, h("ul", { key: '8c4ac37a89006d543a66c8c1ba6bc9d7acc0d6db', class: "website-footer__links website-footer__links--footer" }, h("li", { key: 'ac1db31f3c5331a26c0aee171974c10f22d5da08' }, h("a", { key: 'ad8a6251cca9b0c904ccecff96a8800b22ed5568', href: "https://www.upenn.edu/" }, "UPenn")), h("li", { key: '1189f7119ec768d34ea9435f9ff85df2764abe61' }, h("a", { key: 'eb53d4f15fe49d32899d435670a34369a4e7e190', href: "https://www.upenn.edu/about/privacy-policy" }, "Privacy Policy")), h("li", { key: 'd2a155f7f91a31cca41df9d0c9d37f151bded247' }, h("a", { key: '8e329a895a25bd139867063dd7eed9c0aa7c0060', href: "https://accessibility.web-resources.upenn.edu/get-help" }, "Report Accessibility Issues and Get Help")), h("li", { key: '0b65f3da18b54b91158515d7966e010e4e0d64ac' }, h("a", { key: 'f8615c438f94216372fdb8afa26ae7150bbef816', href: "https://www.upenn.edu/about/disclaimer" }, "Disclaimer")), h("li", { key: 'cbf5febfb926a1b569e73d4a57e7ca8315f6d876' }, h("a", { key: '1116c792623c0fa819ce0189e105ee54c69ba73e', href: "https://www.publicsafety.upenn.edu/contact/" }, "Emergency Services")), h("li", { key: '385a84f264b263a9738d38d66ac917e3a6055db4' }, h("a", { key: 'dcd8517fb32ae46b983cb4802adb86e33e29bd71', href: "https://www.upenn.edu/about/report-copyright-infringement" }, "Report Copyright Infringement")))))), this.showBuiltWith && (h("div", { key: 'd3bca43144b06b50091b54dee5c8734de4f80d60', class: "viewport-margins" }, h("p", { key: 'a3d974ea56f521406bffc2a8eaf6b6e6c57bb595', class: "built-with" }, "Built with the ", h("a", { key: '7aa9fc3901510e0ad7d2b0ca4abf4f8c6f92d735', href: "https://designsystem.library.upenn.edu/" }, "Penn Libraries Design System"), ".")))));
|
|
327
367
|
}
|
|
328
368
|
static get assetsDirs() { return ["assets"]; }
|
|
329
369
|
get hostElement() { return getElement(this); }
|
|
@@ -381,255 +421,12 @@ const Header = class {
|
|
|
381
421
|
return (h("svg", { xmlns: "http://www.w3.org/2000/svg", height: "24", viewBox: "0 -960 960 960", width: "24" }, h("path", { fill: "currentColor", d: "M480-345 240-585l56-56 184 184 184-184 56 56-240 240Z" })));
|
|
382
422
|
}
|
|
383
423
|
render() {
|
|
384
|
-
return (h("header", { key: '
|
|
424
|
+
return (h("header", { key: '6d14c72db0c06f38d66927f3f3102b7db82c1317', class: `viewport-margins website-header ${this.theme === 'dark' && 'website-header--dark'}` }, h("div", { key: 'f7411c48f1f5ba8d267eb53cba7adb3d41c74aec', class: "website-header__inner-container" }, h("div", { key: '78be403367c64beaf5b4cdceac458efc0007980e', class: "website-header__logo-name-container" }, h("a", { key: '8b3e0da246ea69744b83debb0b5e23e271a64520', href: "https://www.library.upenn.edu/", class: "website-header_logo-link", "aria-label": "Penn Libraries" }, this.theme === 'dark' ? h(LogoWhite, null) : h(LogoBlue, null)), this.serviceName && (h("a", { key: '1e1208fd657497dac0f3bb8a09d6b8e8507d2d04', href: "/", class: "website-header__service-link" }, h("span", { key: '33a0c53e36a064a999025eeeae5d3bab9bca11bc', class: "website-header__service-name" }, this.serviceName), this.serviceLede && h("span", { key: '809ca2fdb42dbc35a80474a0e06a39bbba5fb675', class: "website-header__service-lede" }, this.serviceLede))), h("slot", { key: '91cfd1e15bd1e7de19a418d0bc05095fd634870b', name: "name-end" })), this.navigation.length > 0 && (h("nav", { key: 'ce1c1d9fb21fa12b81fb17f9204885c27f86e380', class: "website-header__navigation" }, h("button", { key: 'bdefe1220e526611c7ff9ef9f46be67028077263', class: "website-header__navigation-button", "aria-expanded": `${this.isMenuOpen}`, onClick: () => this.handleToggleMenu() }, this.renderMenuIcon(), " Menu"), this.navigation && (h("ol", { key: '0af8e80d1ba55d267037e28d18caa03714600b22', class: `website-header__navigation-list ${this.isMenuOpen && 'website-header__navigation-list--visible'}` }, this.navigation.map(element => h("li", { innerHTML: element.outerHTML })))))), h("slot", { key: '605d0e5b7caba6cdebf98ace0d708453ab0c4b0f', name: "end" }))));
|
|
385
425
|
}
|
|
386
426
|
static get assetsDirs() { return ["assets"]; }
|
|
387
427
|
get hostElement() { return getElement(this); }
|
|
388
428
|
};
|
|
389
429
|
Header.style = pennlibsHeaderCss;
|
|
390
430
|
|
|
391
|
-
|
|
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.esm.js.map
|
|
431
|
+
export { Autocomplete as pennlibs_autocomplete, PennlibsFeedback as pennlibs_feedback, Footer as pennlibs_footer, Header as pennlibs_header };
|
|
432
|
+
//# sourceMappingURL=pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.esm.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { r as registerInstance, a as getAssetPath, h } from './p-CNQ9-Wwh.js';
|
|
2
|
+
|
|
3
|
+
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)}";
|
|
4
|
+
|
|
5
|
+
const NoImage = class {
|
|
6
|
+
constructor(hostRef) {
|
|
7
|
+
registerInstance(this, hostRef);
|
|
8
|
+
}
|
|
9
|
+
render() {
|
|
10
|
+
const shieldImg = getAssetPath('./assets/simplified-shield.webp');
|
|
11
|
+
return (h("img", { key: 'ba6cc227e90aac2e22b9997ad5c794fd4fd6d5ef', src: shieldImg, alt: "", class: "no-image__img" }));
|
|
12
|
+
}
|
|
13
|
+
static get assetsDirs() { return ["assets"]; }
|
|
14
|
+
};
|
|
15
|
+
NoImage.style = pennlibsFallbackImgCss;
|
|
16
|
+
|
|
17
|
+
export { NoImage as pennlibs_fallback_img };
|
|
18
|
+
//# sourceMappingURL=pennlibs-fallback-img.entry.esm.js.map
|
|
@@ -1186,11 +1186,7 @@ var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialRen
|
|
|
1186
1186
|
}
|
|
1187
1187
|
}
|
|
1188
1188
|
}
|
|
1189
|
-
} else if (memberName === "key") ; else if (memberName === "
|
|
1190
|
-
if (newValue) {
|
|
1191
|
-
newValue(elm);
|
|
1192
|
-
}
|
|
1193
|
-
} else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
|
|
1189
|
+
} else if (memberName === "key") ; else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
|
|
1194
1190
|
if (memberName[2] === "-") {
|
|
1195
1191
|
memberName = memberName.slice(3);
|
|
1196
1192
|
} else if (isMemberInElement(win, ln)) {
|
|
@@ -1365,7 +1361,6 @@ var removeVnodes = (vnodes, startIdx, endIdx) => {
|
|
|
1365
1361
|
const vnode = vnodes[index];
|
|
1366
1362
|
if (vnode) {
|
|
1367
1363
|
const elm = vnode.$elm$;
|
|
1368
|
-
nullifyVNodeRefs(vnode);
|
|
1369
1364
|
if (elm) {
|
|
1370
1365
|
elm.remove();
|
|
1371
1366
|
}
|
|
@@ -1503,12 +1498,6 @@ var patch = (oldVNode, newVNode2, isInitialRender = false) => {
|
|
|
1503
1498
|
elm.data = text;
|
|
1504
1499
|
}
|
|
1505
1500
|
};
|
|
1506
|
-
var nullifyVNodeRefs = (vNode) => {
|
|
1507
|
-
{
|
|
1508
|
-
vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
|
|
1509
|
-
vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
|
|
1510
|
-
}
|
|
1511
|
-
};
|
|
1512
1501
|
var insertBefore = (parent, newNode, reference) => {
|
|
1513
1502
|
{
|
|
1514
1503
|
return parent == null ? void 0 : parent.insertBefore(newNode, reference);
|
|
@@ -2268,7 +2257,7 @@ var hostListenerOpts = (flags) => supportsListenerOptions ? {
|
|
|
2268
2257
|
// src/runtime/nonce.ts
|
|
2269
2258
|
var setNonce = (nonce) => plt.$nonce$ = nonce;
|
|
2270
2259
|
|
|
2271
|
-
export { getAssetPath as a, bootstrapLazy as b,
|
|
2272
|
-
//# sourceMappingURL=
|
|
2260
|
+
export { getAssetPath as a, bootstrapLazy as b, getElement as c, createEvent as d, setAssetPath as e, globalScripts as g, h, promiseResolve as p, registerInstance as r, setNonce as s };
|
|
2261
|
+
//# sourceMappingURL=p-CNQ9-Wwh.js.map
|
|
2273
2262
|
|
|
2274
|
-
//# sourceMappingURL=
|
|
2263
|
+
//# sourceMappingURL=p-CNQ9-Wwh.js.map
|