@penn-libraries/web 1.1.0-dev.7 → 1.1.1-dev.1

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.
Files changed (112) hide show
  1. package/dist/cjs/{index-C0A2bnrZ.js → index-C0qvW4Ra.js} +289 -191
  2. package/dist/cjs/index-C0qvW4Ra.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +1 -3
  4. package/dist/cjs/loader.cjs.js +3 -6
  5. package/dist/cjs/loader.cjs.js.map +1 -1
  6. package/dist/cjs/pennlibs-autocomplete.pennlibs-footer.pennlibs-header.entry.cjs.js.map +1 -1
  7. package/dist/cjs/pennlibs-autocomplete_3.cjs.entry.js +25 -36
  8. package/dist/cjs/pennlibs-banner.cjs.entry.js +1 -3
  9. package/dist/cjs/pennlibs-chat.cjs.entry.js +1 -3
  10. package/dist/cjs/pennlibs-fallback-img.cjs.entry.js +1 -3
  11. package/dist/cjs/pennlibs-feedback.cjs.entry.js +1 -3
  12. package/dist/cjs/pennlibs-hero.cjs.entry.js +1 -3
  13. package/dist/cjs/pennlibs-iiif-img.cjs.entry.js +132 -0
  14. package/dist/cjs/pennlibs-iiif-img.entry.cjs.js.map +1 -0
  15. package/dist/cjs/web.cjs.js +4 -7
  16. package/dist/cjs/web.cjs.js.map +1 -1
  17. package/dist/collection/collection-manifest.json +4 -3
  18. package/dist/collection/components/pennlibs-autocomplete/pennlibs-autocomplete.js +40 -23
  19. package/dist/collection/components/pennlibs-autocomplete/pennlibs-autocomplete.js.map +1 -1
  20. package/dist/collection/components/pennlibs-header/pennlibs-header.js +6 -6
  21. package/dist/collection/components/pennlibs-iiif-img/pennlibs-iiif-img.css +37 -0
  22. package/dist/collection/components/pennlibs-iiif-img/pennlibs-iiif-img.js +310 -0
  23. package/dist/collection/components/pennlibs-iiif-img/pennlibs-iiif-img.js.map +1 -0
  24. package/dist/components/index.d.ts +2 -0
  25. package/dist/components/index.js +2 -1
  26. package/dist/components/index.js.map +1 -1
  27. package/dist/components/pennlibs-autocomplete.js +28 -20
  28. package/dist/components/pennlibs-autocomplete.js.map +1 -1
  29. package/dist/components/pennlibs-banner.js +5 -3
  30. package/dist/components/pennlibs-banner.js.map +1 -1
  31. package/dist/components/pennlibs-chat.js +5 -3
  32. package/dist/components/pennlibs-chat.js.map +1 -1
  33. package/dist/components/pennlibs-fallback-img.js +1 -30
  34. package/dist/components/pennlibs-fallback-img.js.map +1 -1
  35. package/dist/components/pennlibs-fallback-img2.js +37 -0
  36. package/dist/components/pennlibs-fallback-img2.js.map +1 -0
  37. package/dist/components/pennlibs-feedback.js +5 -3
  38. package/dist/components/pennlibs-feedback.js.map +1 -1
  39. package/dist/components/pennlibs-footer.js +5 -3
  40. package/dist/components/pennlibs-footer.js.map +1 -1
  41. package/dist/components/pennlibs-header.js +6 -19
  42. package/dist/components/pennlibs-header.js.map +1 -1
  43. package/dist/components/pennlibs-hero.js +5 -3
  44. package/dist/components/pennlibs-hero.js.map +1 -1
  45. package/dist/components/pennlibs-iiif-img.d.ts +11 -0
  46. package/dist/components/pennlibs-iiif-img.js +168 -0
  47. package/dist/components/pennlibs-iiif-img.js.map +1 -0
  48. package/dist/docs.json +268 -12
  49. package/dist/esm/{index-CE_ILdTo.js → index-D9dYrmUF.js} +289 -192
  50. package/dist/esm/index-D9dYrmUF.js.map +1 -0
  51. package/dist/esm/index.js +1 -3
  52. package/dist/esm/loader.js +3 -6
  53. package/dist/esm/loader.js.map +1 -1
  54. package/dist/esm/pennlibs-autocomplete.pennlibs-footer.pennlibs-header.entry.js.map +1 -1
  55. package/dist/esm/pennlibs-autocomplete_3.entry.js +25 -36
  56. package/dist/esm/pennlibs-banner.entry.js +1 -3
  57. package/dist/esm/pennlibs-chat.entry.js +1 -3
  58. package/dist/esm/pennlibs-fallback-img.entry.js +1 -3
  59. package/dist/esm/pennlibs-feedback.entry.js +1 -3
  60. package/dist/esm/pennlibs-hero.entry.js +1 -3
  61. package/dist/esm/pennlibs-iiif-img.entry.js +130 -0
  62. package/dist/esm/pennlibs-iiif-img.entry.js.map +1 -0
  63. package/dist/esm/web.js +4 -7
  64. package/dist/esm/web.js.map +1 -1
  65. package/dist/types/components/pennlibs-autocomplete/pennlibs-autocomplete.d.ts +17 -1
  66. package/dist/types/components/pennlibs-iiif-img/pennlibs-iiif-img.d.ts +89 -0
  67. package/dist/types/components.d.ts +143 -0
  68. package/dist/types/stencil-public-runtime.d.ts +73 -9
  69. package/dist/web/index.esm.js +1 -3
  70. package/dist/web/loader.esm.js.map +1 -1
  71. package/dist/web/{p-20c0bd7a.entry.js → p-43d9c2d4.entry.js} +1 -3
  72. package/dist/web/{p-CE_ILdTo.js → p-D9dYrmUF.js} +289 -192
  73. package/dist/web/p-D9dYrmUF.js.map +1 -0
  74. package/dist/web/{p-cbae5952.entry.js → p-ad92090a.entry.js} +1 -3
  75. package/dist/web/{p-370e32b1.entry.js → p-b4b58af0.entry.js} +1 -3
  76. package/dist/web/p-c4074cf1.entry.js +130 -0
  77. package/dist/web/{p-07ad051f.entry.js → p-cb2584da.entry.js} +1 -3
  78. package/dist/web/{p-5e385536.entry.js → p-ce97059c.entry.js} +1 -3
  79. package/dist/web/{p-e1215158.entry.js → p-e6188c30.entry.js} +25 -36
  80. package/dist/web/pennlibs-autocomplete.pennlibs-footer.pennlibs-header.entry.esm.js.map +1 -1
  81. package/dist/web/pennlibs-iiif-img.entry.esm.js.map +1 -0
  82. package/dist/web/web.esm.js +4 -7
  83. package/dist/web/web.esm.js.map +1 -1
  84. package/hydrate/index.d.ts +28 -24
  85. package/hydrate/index.js +609 -241
  86. package/hydrate/index.mjs +609 -241
  87. package/package.json +3 -9
  88. package/dist/cjs/app-globals-V2Kpy_OQ.js +0 -8
  89. package/dist/cjs/app-globals-V2Kpy_OQ.js.map +0 -1
  90. package/dist/cjs/index-C0A2bnrZ.js.map +0 -1
  91. package/dist/cjs/pennlibs-autocomplete_3.cjs.entry.js.map +0 -1
  92. package/dist/cjs/pennlibs-banner.cjs.entry.js.map +0 -1
  93. package/dist/cjs/pennlibs-chat.cjs.entry.js.map +0 -1
  94. package/dist/cjs/pennlibs-fallback-img.cjs.entry.js.map +0 -1
  95. package/dist/cjs/pennlibs-feedback.cjs.entry.js.map +0 -1
  96. package/dist/cjs/pennlibs-hero.cjs.entry.js.map +0 -1
  97. package/dist/collection/utils/utils.js +0 -4
  98. package/dist/collection/utils/utils.js.map +0 -1
  99. package/dist/esm/app-globals-DQuL1Twl.js +0 -6
  100. package/dist/esm/app-globals-DQuL1Twl.js.map +0 -1
  101. package/dist/esm/index-CE_ILdTo.js.map +0 -1
  102. package/dist/esm/pennlibs-autocomplete_3.entry.js.map +0 -1
  103. package/dist/types/utils/utils.d.ts +0 -1
  104. package/dist/web/p-07ad051f.entry.js.map +0 -1
  105. package/dist/web/p-20c0bd7a.entry.js.map +0 -1
  106. package/dist/web/p-370e32b1.entry.js.map +0 -1
  107. package/dist/web/p-5e385536.entry.js.map +0 -1
  108. package/dist/web/p-CE_ILdTo.js.map +0 -1
  109. package/dist/web/p-DQuL1Twl.js +0 -6
  110. package/dist/web/p-DQuL1Twl.js.map +0 -1
  111. package/dist/web/p-cbae5952.entry.js.map +0 -1
  112. package/dist/web/p-e1215158.entry.js.map +0 -1
@@ -7,9 +7,11 @@ const getCurrentImageSource = (pictureElement) => {
7
7
  return (imgElement === null || imgElement === void 0 ? void 0 : imgElement.currentSrc) || '';
8
8
  };
9
9
  const Hero = /*@__PURE__*/ proxyCustomElement(class Hero extends HTMLElement {
10
- constructor() {
10
+ constructor(registerHost) {
11
11
  super();
12
- this.__registerHost();
12
+ if (registerHost !== false) {
13
+ this.__registerHost();
14
+ }
13
15
  this.__attachShadow();
14
16
  this.heroPictureElement = null;
15
17
  this.heroHeadingElement = null;
@@ -54,7 +56,7 @@ const Hero = /*@__PURE__*/ proxyCustomElement(class Hero extends HTMLElement {
54
56
  static get assetsDirs() { return ["assets"]; }
55
57
  get hostElement() { return this; }
56
58
  static get style() { return pennlibsHeroCss; }
57
- }, [1, "pennlibs-hero", {
59
+ }, [257, "pennlibs-hero", {
58
60
  "heroPictureElement": [32],
59
61
  "heroHeadingElement": [32],
60
62
  "heroParagraphElement": [32],
@@ -1 +1 @@
1
- {"file":"pennlibs-hero.js","mappings":"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","names":["__stencil_proxyCustomElement"],"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: bold;\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}"],"version":3}
1
+ {"file":"pennlibs-hero.js","mappings":"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","names":["__stencil_proxyCustomElement"],"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: bold;\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}"],"version":3}
@@ -0,0 +1,11 @@
1
+ import type { Components, JSX } from "../types/components";
2
+
3
+ interface PennlibsIiifImg extends Components.PennlibsIiifImg, HTMLElement {}
4
+ export const PennlibsIiifImg: {
5
+ prototype: PennlibsIiifImg;
6
+ new (): PennlibsIiifImg;
7
+ };
8
+ /**
9
+ * Used to define this component and all nested components recursively.
10
+ */
11
+ export const defineCustomElement: () => void;
@@ -0,0 +1,168 @@
1
+ import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client';
2
+ import { d as defineCustomElement$2 } from './pennlibs-fallback-img2.js';
3
+
4
+ const pennlibsIiifImgCss = ":host{display:block;width:100%;max-width:100%}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:auto;min-height:200px}.fallback-container pennlibs-fallback-img{width:100%;height:100%}";
5
+
6
+ const PIXEL_DENSITY_MULTIPLIERS = [0.5, 0.75, 1, 1.5, 2];
7
+ const DEFAULT_IMAGE_SIZES = [400, 600, 800, 1200, 1600, 2400];
8
+ const IIIFImg = /*@__PURE__*/ proxyCustomElement(class IIIFImg extends HTMLElement {
9
+ constructor(registerHost) {
10
+ super();
11
+ if (registerHost !== false) {
12
+ this.__registerHost();
13
+ }
14
+ this.__attachShadow();
15
+ /**
16
+ * The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display.
17
+ * Defines the rectangular portion of the underlying image to return.
18
+ *
19
+ * `full`: The full image is returned, without any cropping.
20
+ *
21
+ * `square`: A square area where width and height equal the shorter dimension.
22
+ *
23
+ * `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions).
24
+ *
25
+ * `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.
26
+ *
27
+ * @default 'full'
28
+ */
29
+ this.region = 'full';
30
+ /**
31
+ * The IIIF [rotation](https://iiif.io/api/image/3.0/#44-rotation) to apply to the image.
32
+ * Specifies mirroring and clockwise rotation in degrees (0-360).
33
+ *
34
+ * `n`: Rotation in degrees only.
35
+ *
36
+ * `!n`: Mirror the image vertically, then rotate by n degrees.
37
+ *
38
+ * @default '0'
39
+ */
40
+ this.rotation = '0';
41
+ /**
42
+ * The IIIF [quality](https://iiif.io/api/image/3.0/#quality) of the image.
43
+ * Controls the color delivery mode.
44
+ *
45
+ * `default`: The server's default quality.
46
+ *
47
+ * `color`: Full color information.
48
+ *
49
+ * `gray`: Grayscale rendering.
50
+ *
51
+ * `bitonal`: Black and white only.
52
+ *
53
+ * @default 'default'
54
+ */
55
+ this.quality = 'default';
56
+ /**
57
+ * Native browser lazy loading behavior. Use "lazy" to defer loading until the image is near the viewport,
58
+ * or "eager" to load immediately.
59
+ * @default 'lazy'
60
+ */
61
+ this.loading = 'lazy';
62
+ /**
63
+ * Whether to display a fallback placeholder image when the IIIF image fails to load.
64
+ * @default true
65
+ */
66
+ this.showFallback = true;
67
+ this.isLoaded = false;
68
+ this.hasError = false;
69
+ this.baseUrl = 'https://iiif-images.library.upenn.edu/iiif/3';
70
+ this.handleLoad = () => {
71
+ this.isLoaded = true;
72
+ };
73
+ this.handleError = () => {
74
+ this.hasError = true;
75
+ };
76
+ }
77
+ buildIIIFUrl(width, format = 'jpg') {
78
+ const sizeParam = width ? `${width},` : 'max';
79
+ return `${this.baseUrl}/${this.uuid}/${this.region}/${sizeParam}/${this.rotation}/${this.quality}.${format}`;
80
+ }
81
+ generateSrcset(sizes, format) {
82
+ const uniqueSizes = [...new Set(sizes)].sort((a, b) => a - b);
83
+ const srcsetEntries = uniqueSizes.map(size => {
84
+ const url = this.buildIIIFUrl(size, format);
85
+ return `${url} ${size}w`;
86
+ });
87
+ return srcsetEntries.join(', ');
88
+ }
89
+ getOptimalSizes() {
90
+ if (this.observedWidth) {
91
+ const baseSizes = PIXEL_DENSITY_MULTIPLIERS.map(multiplier => Math.round(this.observedWidth * multiplier));
92
+ return baseSizes;
93
+ }
94
+ return [...DEFAULT_IMAGE_SIZES];
95
+ }
96
+ componentDidLoad() {
97
+ if ('ResizeObserver' in window) {
98
+ this.resizeObserver = new ResizeObserver(entries => {
99
+ for (const entry of entries) {
100
+ this.observedWidth = Math.round(entry.contentRect.width);
101
+ if (this.resizeObserver) {
102
+ this.resizeObserver.disconnect();
103
+ this.resizeObserver = undefined;
104
+ }
105
+ // Trigger re-render with optimized sizes
106
+ this.isLoaded = this.isLoaded;
107
+ }
108
+ });
109
+ this.resizeObserver.observe(this.hostElement);
110
+ }
111
+ }
112
+ disconnectedCallback() {
113
+ if (this.resizeObserver) {
114
+ this.resizeObserver.disconnect();
115
+ this.resizeObserver = undefined;
116
+ }
117
+ }
118
+ render() {
119
+ const sizes = this.getOptimalSizes();
120
+ if (this.hasError && this.showFallback) {
121
+ return (h("div", { class: "fallback-container" }, h("pennlibs-fallback-img", null)));
122
+ }
123
+ const imgClasses = {
124
+ 'iiif-img': true,
125
+ 'loaded': this.isLoaded
126
+ };
127
+ const defaultSize = sizes[0];
128
+ return (h("picture", null, h("source", { type: "image/webp", srcSet: this.generateSrcset(sizes, 'webp'), sizes: "100vw" }), h("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 })));
129
+ }
130
+ get hostElement() { return this; }
131
+ static get style() { return pennlibsIiifImgCss; }
132
+ }, [257, "pennlibs-iiif-img", {
133
+ "uuid": [1],
134
+ "alt": [1],
135
+ "region": [1],
136
+ "rotation": [1],
137
+ "quality": [1],
138
+ "loading": [1],
139
+ "showFallback": [4, "show-fallback"],
140
+ "isLoaded": [32],
141
+ "hasError": [32]
142
+ }]);
143
+ function defineCustomElement$1() {
144
+ if (typeof customElements === "undefined") {
145
+ return;
146
+ }
147
+ const components = ["pennlibs-iiif-img", "pennlibs-fallback-img"];
148
+ components.forEach(tagName => { switch (tagName) {
149
+ case "pennlibs-iiif-img":
150
+ if (!customElements.get(tagName)) {
151
+ customElements.define(tagName, IIIFImg);
152
+ }
153
+ break;
154
+ case "pennlibs-fallback-img":
155
+ if (!customElements.get(tagName)) {
156
+ defineCustomElement$2();
157
+ }
158
+ break;
159
+ } });
160
+ }
161
+
162
+ const PennlibsIiifImg = IIIFImg;
163
+ const defineCustomElement = defineCustomElement$1;
164
+
165
+ export { PennlibsIiifImg, defineCustomElement };
166
+ //# sourceMappingURL=pennlibs-iiif-img.js.map
167
+
168
+ //# sourceMappingURL=pennlibs-iiif-img.js.map
@@ -0,0 +1 @@
1
+ {"file":"pennlibs-iiif-img.js","mappings":"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","names":["__stencil_proxyCustomElement"],"sources":["src/components/pennlibs-iiif-img/pennlibs-iiif-img.css?tag=pennlibs-iiif-img&encapsulation=shadow","src/components/pennlibs-iiif-img/pennlibs-iiif-img.tsx"],"sourcesContent":[":host {\n display: block;\n width: 100%;\n max-width: 100%;\n}\n\npicture {\n display: block;\n line-height: 0;\n}\n\n.iiif-img {\n display: block;\n width: 100%;\n max-width: 100%;\n height: auto;\n opacity: 0;\n filter: blur(5px);\n transition: opacity 0.15s ease-in, filter 0.15s ease-in;\n}\n\n.iiif-img.loaded {\n opacity: 1;\n filter: blur(0);\n}\n\n.fallback-container {\n display: block;\n width: 100%;\n height: auto;\n min-height: 200px;\n}\n\n.fallback-container pennlibs-fallback-img {\n width: 100%;\n height: 100%;\n}\n","import { Component, h, Prop, State, Element } from '@stencil/core';\n\ntype ImageFormat = 'jpg' | 'webp';\n\nconst PIXEL_DENSITY_MULTIPLIERS = [0.5, 0.75, 1, 1.5, 2] as const;\nconst DEFAULT_IMAGE_SIZES = [400, 600, 800, 1200, 1600, 2400] as const;\n\n/**\n * Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.\n * Automatically generates optimal image sources for different viewport sizes and pixel densities,\n * with modern WebP format and JPG fallback support.\n *\n * @component\n * @example\n * <pennlibs-iiif-img\n * uuid=\"063ff35c-bbdd-4b63-bbdd-6206590e20d5\"\n * alt=\"\">\n * </pennlibs-iiif-img>\n */\n@Component({\n tag: 'pennlibs-iiif-img',\n styleUrl: 'pennlibs-iiif-img.css',\n shadow: true,\n})\nexport class IIIFImg {\n private resizeObserver?: ResizeObserver;\n\n @Element() hostElement!: HTMLElement;\n\n /**\n * The IIIF [UUID identifier](https://iiif.io/api/image/3.0/#3-identifier) of the image resource on the Penn Libraries IIIF server.\n */\n @Prop() uuid!: string;\n\n /**\n * Alternative text that describes the image content for screen readers and when images fail to load.\n * Use an empty string for purely decorative images.\n */\n @Prop() alt!: string;\n\n /**\n * The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display.\n * Defines the rectangular portion of the underlying image to return.\n * \n * `full`: The full image is returned, without any cropping.\n * \n * `square`: A square area where width and height equal the shorter dimension.\n * \n * `x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions).\n * \n * `pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.\n * \n * @default 'full'\n */\n @Prop() region?: string = 'full';\n\n /**\n * The IIIF [rotation](https://iiif.io/api/image/3.0/#44-rotation) to apply to the image.\n * Specifies mirroring and clockwise rotation in degrees (0-360).\n * \n * `n`: Rotation in degrees only.\n * \n * `!n`: Mirror the image vertically, then rotate by n degrees.\n * \n * @default '0'\n */\n @Prop() rotation?: string = '0';\n\n /**\n * The IIIF [quality](https://iiif.io/api/image/3.0/#quality) of the image.\n * Controls the color delivery mode.\n * \n * `default`: The server's default quality.\n * \n * `color`: Full color information.\n * \n * `gray`: Grayscale rendering.\n * \n * `bitonal`: Black and white only.\n * \n * @default 'default'\n */\n @Prop() quality?: string = 'default';\n\n /**\n * Native browser lazy loading behavior. Use \"lazy\" to defer loading until the image is near the viewport,\n * or \"eager\" to load immediately.\n * @default 'lazy'\n */\n @Prop() loading?: 'lazy' | 'eager' = 'lazy';\n\n /**\n * Whether to display a fallback placeholder image when the IIIF image fails to load.\n * @default true\n */\n @Prop() showFallback?: boolean = true;\n\n @State() isLoaded: boolean = false;\n @State() hasError: boolean = false;\n\n private observedWidth?: number;\n\n private readonly baseUrl = 'https://iiif-images.library.upenn.edu/iiif/3';\n\n private buildIIIFUrl(width?: number, format: ImageFormat = 'jpg'): string {\n const sizeParam = width ? `${width},` : 'max';\n return `${this.baseUrl}/${this.uuid}/${this.region}/${sizeParam}/${this.rotation}/${this.quality}.${format}`;\n }\n\n private generateSrcset(sizes: number[], format: ImageFormat): string {\n const uniqueSizes = [...new Set(sizes)].sort((a, b) => a - b);\n\n const srcsetEntries = uniqueSizes.map(size => {\n const url = this.buildIIIFUrl(size, format);\n return `${url} ${size}w`;\n });\n\n return srcsetEntries.join(', ');\n }\n\n private getOptimalSizes(): number[] {\n if (this.observedWidth) {\n const baseSizes = PIXEL_DENSITY_MULTIPLIERS.map(multiplier =>\n Math.round(this.observedWidth! * multiplier)\n );\n\n return baseSizes;\n }\n\n return [...DEFAULT_IMAGE_SIZES];\n }\n\n private handleLoad = () => {\n this.isLoaded = true;\n };\n\n private handleError = () => {\n this.hasError = true;\n };\n\n componentDidLoad() {\n if ('ResizeObserver' in window) {\n this.resizeObserver = new ResizeObserver(entries => {\n for (const entry of entries) {\n this.observedWidth = Math.round(entry.contentRect.width);\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = undefined;\n }\n\n // Trigger re-render with optimized sizes\n this.isLoaded = this.isLoaded;\n }\n });\n\n this.resizeObserver.observe(this.hostElement);\n }\n }\n\n disconnectedCallback() {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = undefined;\n }\n }\n\n render() {\n const sizes = this.getOptimalSizes();\n\n if (this.hasError && this.showFallback) {\n return (\n <div class=\"fallback-container\">\n <pennlibs-fallback-img />\n </div>\n );\n }\n\n const imgClasses = {\n 'iiif-img': true,\n 'loaded': this.isLoaded\n };\n\n const defaultSize = sizes[0];\n\n return (\n <picture>\n <source\n type=\"image/webp\"\n srcSet={this.generateSrcset(sizes, 'webp')}\n sizes=\"100vw\"\n />\n\n <img\n class={imgClasses}\n src={this.buildIIIFUrl(defaultSize, 'jpg')}\n srcSet={this.generateSrcset(sizes, 'jpg')}\n sizes=\"100vw\"\n alt={this.alt}\n loading={this.loading}\n onLoad={this.handleLoad}\n onError={this.handleError}\n />\n </picture>\n );\n }\n}\n"],"version":3}
package/dist/docs.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
- "timestamp": "2025-11-11T21:11:26",
2
+ "timestamp": "2025-11-20T21:55:55",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
- "version": "4.29.3",
6
- "typescriptVersion": "5.5.4"
5
+ "version": "4.38.1",
6
+ "typescriptVersion": "5.9.3"
7
7
  },
8
8
  "components": [
9
9
  {
@@ -11,8 +11,13 @@
11
11
  "encapsulation": "shadow",
12
12
  "tag": "pennlibs-autocomplete",
13
13
  "readme": "# pennlibs-autocomplete\n\n\n",
14
- "docs": "",
15
- "docsTags": [],
14
+ "docs": "Offer predictive suggestions while typing your search query.",
15
+ "docsTags": [
16
+ {
17
+ "name": "slot",
18
+ "text": "start - Content to display at the start (top)."
19
+ }
20
+ ],
16
21
  "usage": {},
17
22
  "props": [
18
23
  {
@@ -26,8 +31,13 @@
26
31
  "mutable": false,
27
32
  "attr": "for",
28
33
  "reflectToAttr": false,
29
- "docs": "",
30
- "docsTags": [],
34
+ "docs": "The `id` of the input that this autocomplete is attached to.",
35
+ "docsTags": [
36
+ {
37
+ "name": "prop",
38
+ "text": "for"
39
+ }
40
+ ],
31
41
  "values": [
32
42
  {
33
43
  "type": "string"
@@ -58,8 +68,13 @@
58
68
  },
59
69
  "cancelable": true,
60
70
  "composed": true,
61
- "docs": "",
62
- "docsTags": []
71
+ "docs": "Emitted when a user activates (selects) an autocomplete suggestion.",
72
+ "docsTags": [
73
+ {
74
+ "name": "event",
75
+ "text": "pl:activated"
76
+ }
77
+ ]
63
78
  }
64
79
  ],
65
80
  "listeners": [
@@ -99,7 +114,12 @@
99
114
  }
100
115
  ],
101
116
  "styles": [],
102
- "slots": [],
117
+ "slots": [
118
+ {
119
+ "name": "start",
120
+ "docs": "Content to display at the start (top)."
121
+ }
122
+ ],
103
123
  "parts": [],
104
124
  "dependents": [],
105
125
  "dependencies": [],
@@ -157,9 +177,15 @@
157
177
  "styles": [],
158
178
  "slots": [],
159
179
  "parts": [],
160
- "dependents": [],
180
+ "dependents": [
181
+ "pennlibs-iiif-img"
182
+ ],
161
183
  "dependencies": [],
162
- "dependencyGraph": {}
184
+ "dependencyGraph": {
185
+ "pennlibs-iiif-img": [
186
+ "pennlibs-fallback-img"
187
+ ]
188
+ }
163
189
  },
164
190
  {
165
191
  "filePath": "src/components/pennlibs-feedback/pennlibs-feedback.tsx",
@@ -437,6 +463,236 @@
437
463
  "dependents": [],
438
464
  "dependencies": [],
439
465
  "dependencyGraph": {}
466
+ },
467
+ {
468
+ "filePath": "src/components/pennlibs-iiif-img/pennlibs-iiif-img.tsx",
469
+ "encapsulation": "shadow",
470
+ "tag": "pennlibs-iiif-img",
471
+ "readme": "# pennlibs-iiif-img\n\n\n",
472
+ "docs": "Display responsive, high-quality images from Penn Libraries' IIIF Image API 3.0 server.\nAutomatically generates optimal image sources for different viewport sizes and pixel densities,\nwith modern WebP format and JPG fallback support.",
473
+ "docsTags": [
474
+ {
475
+ "name": "component"
476
+ },
477
+ {
478
+ "name": "example",
479
+ "text": "<pennlibs-iiif-img\n uuid=\"063ff35c-bbdd-4b63-bbdd-6206590e20d5\"\n alt=\"\">\n</pennlibs-iiif-img>"
480
+ }
481
+ ],
482
+ "usage": {},
483
+ "props": [
484
+ {
485
+ "name": "alt",
486
+ "type": "string",
487
+ "complexType": {
488
+ "original": "string",
489
+ "resolved": "string",
490
+ "references": {}
491
+ },
492
+ "mutable": false,
493
+ "attr": "alt",
494
+ "reflectToAttr": false,
495
+ "docs": "Alternative text that describes the image content for screen readers and when images fail to load.\nUse an empty string for purely decorative images.",
496
+ "docsTags": [],
497
+ "values": [
498
+ {
499
+ "type": "string"
500
+ }
501
+ ],
502
+ "optional": false,
503
+ "required": true,
504
+ "getter": false,
505
+ "setter": false
506
+ },
507
+ {
508
+ "name": "loading",
509
+ "type": "\"eager\" | \"lazy\"",
510
+ "complexType": {
511
+ "original": "'lazy' | 'eager'",
512
+ "resolved": "\"eager\" | \"lazy\"",
513
+ "references": {}
514
+ },
515
+ "mutable": false,
516
+ "attr": "loading",
517
+ "reflectToAttr": false,
518
+ "docs": "Native browser lazy loading behavior. Use \"lazy\" to defer loading until the image is near the viewport,\nor \"eager\" to load immediately.",
519
+ "docsTags": [
520
+ {
521
+ "name": "default",
522
+ "text": "'lazy'"
523
+ }
524
+ ],
525
+ "default": "'lazy'",
526
+ "values": [
527
+ {
528
+ "value": "eager",
529
+ "type": "string"
530
+ },
531
+ {
532
+ "value": "lazy",
533
+ "type": "string"
534
+ }
535
+ ],
536
+ "optional": true,
537
+ "required": false,
538
+ "getter": false,
539
+ "setter": false
540
+ },
541
+ {
542
+ "name": "quality",
543
+ "type": "string",
544
+ "complexType": {
545
+ "original": "string",
546
+ "resolved": "string",
547
+ "references": {}
548
+ },
549
+ "mutable": false,
550
+ "attr": "quality",
551
+ "reflectToAttr": false,
552
+ "docs": "The IIIF [quality](https://iiif.io/api/image/3.0/#quality) of the image.\nControls the color delivery mode.\n\n`default`: The server's default quality.\n\n`color`: Full color information.\n\n`gray`: Grayscale rendering.\n\n`bitonal`: Black and white only.",
553
+ "docsTags": [
554
+ {
555
+ "name": "default",
556
+ "text": "'default'"
557
+ }
558
+ ],
559
+ "default": "'default'",
560
+ "values": [
561
+ {
562
+ "type": "string"
563
+ }
564
+ ],
565
+ "optional": true,
566
+ "required": false,
567
+ "getter": false,
568
+ "setter": false
569
+ },
570
+ {
571
+ "name": "region",
572
+ "type": "string",
573
+ "complexType": {
574
+ "original": "string",
575
+ "resolved": "string",
576
+ "references": {}
577
+ },
578
+ "mutable": false,
579
+ "attr": "region",
580
+ "reflectToAttr": false,
581
+ "docs": "The IIIF [region](https://iiif.io/api/image/3.0/#41-region) of the image to display.\nDefines the rectangular portion of the underlying image to return.\n\n`full`: The full image is returned, without any cropping.\n\n`square`: A square area where width and height equal the shorter dimension.\n\n`x,y,w,h`: Absolute pixel coordinates (x, y position; w, h dimensions).\n\n`pct:x,y,w,h`: Percentage-based coordinates of full image dimensions.",
582
+ "docsTags": [
583
+ {
584
+ "name": "default",
585
+ "text": "'full'"
586
+ }
587
+ ],
588
+ "default": "'full'",
589
+ "values": [
590
+ {
591
+ "type": "string"
592
+ }
593
+ ],
594
+ "optional": true,
595
+ "required": false,
596
+ "getter": false,
597
+ "setter": false
598
+ },
599
+ {
600
+ "name": "rotation",
601
+ "type": "string",
602
+ "complexType": {
603
+ "original": "string",
604
+ "resolved": "string",
605
+ "references": {}
606
+ },
607
+ "mutable": false,
608
+ "attr": "rotation",
609
+ "reflectToAttr": false,
610
+ "docs": "The IIIF [rotation](https://iiif.io/api/image/3.0/#44-rotation) to apply to the image.\nSpecifies mirroring and clockwise rotation in degrees (0-360).\n\n`n`: Rotation in degrees only.\n\n`!n`: Mirror the image vertically, then rotate by n degrees.",
611
+ "docsTags": [
612
+ {
613
+ "name": "default",
614
+ "text": "'0'"
615
+ }
616
+ ],
617
+ "default": "'0'",
618
+ "values": [
619
+ {
620
+ "type": "string"
621
+ }
622
+ ],
623
+ "optional": true,
624
+ "required": false,
625
+ "getter": false,
626
+ "setter": false
627
+ },
628
+ {
629
+ "name": "showFallback",
630
+ "type": "boolean",
631
+ "complexType": {
632
+ "original": "boolean",
633
+ "resolved": "boolean",
634
+ "references": {}
635
+ },
636
+ "mutable": false,
637
+ "attr": "show-fallback",
638
+ "reflectToAttr": false,
639
+ "docs": "Whether to display a fallback placeholder image when the IIIF image fails to load.",
640
+ "docsTags": [
641
+ {
642
+ "name": "default",
643
+ "text": "true"
644
+ }
645
+ ],
646
+ "default": "true",
647
+ "values": [
648
+ {
649
+ "type": "boolean"
650
+ }
651
+ ],
652
+ "optional": true,
653
+ "required": false,
654
+ "getter": false,
655
+ "setter": false
656
+ },
657
+ {
658
+ "name": "uuid",
659
+ "type": "string",
660
+ "complexType": {
661
+ "original": "string",
662
+ "resolved": "string",
663
+ "references": {}
664
+ },
665
+ "mutable": false,
666
+ "attr": "uuid",
667
+ "reflectToAttr": false,
668
+ "docs": "The IIIF [UUID identifier](https://iiif.io/api/image/3.0/#3-identifier) of the image resource on the Penn Libraries IIIF server.",
669
+ "docsTags": [],
670
+ "values": [
671
+ {
672
+ "type": "string"
673
+ }
674
+ ],
675
+ "optional": false,
676
+ "required": true,
677
+ "getter": false,
678
+ "setter": false
679
+ }
680
+ ],
681
+ "methods": [],
682
+ "events": [],
683
+ "listeners": [],
684
+ "styles": [],
685
+ "slots": [],
686
+ "parts": [],
687
+ "dependents": [],
688
+ "dependencies": [
689
+ "pennlibs-fallback-img"
690
+ ],
691
+ "dependencyGraph": {
692
+ "pennlibs-iiif-img": [
693
+ "pennlibs-fallback-img"
694
+ ]
695
+ }
440
696
  }
441
697
  ],
442
698
  "typeLibrary": {