@penn-libraries/web 1.2.0-dev.2 → 1.2.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.
Files changed (46) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/pennlibs-autocomplete.cjs.entry.js +281 -0
  3. package/dist/cjs/pennlibs-autocomplete.entry.cjs.js.map +1 -0
  4. package/dist/cjs/pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.cjs.js.map +1 -0
  5. package/dist/cjs/{pennlibs-autocomplete_4.cjs.entry.js → pennlibs-feedback_3.cjs.entry.js} +25 -297
  6. package/dist/cjs/web.cjs.js +1 -1
  7. package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.css +21 -0
  8. package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.js +25 -21
  9. package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.js.map +1 -1
  10. package/dist/components/pennlibs-feedback.js +26 -22
  11. package/dist/components/pennlibs-feedback.js.map +1 -1
  12. package/dist/docs.json +1 -1
  13. package/dist/esm/{index-CNQ9-Wwh.js → index-mkVX9lU0.js} +3 -3
  14. package/dist/esm/{index-CNQ9-Wwh.js.map → index-mkVX9lU0.js.map} +1 -1
  15. package/dist/esm/index.js +1 -1
  16. package/dist/esm/loader.js +3 -3
  17. package/dist/esm/pennlibs-autocomplete.entry.js +279 -0
  18. package/dist/esm/pennlibs-autocomplete.entry.js.map +1 -0
  19. package/dist/esm/pennlibs-banner.entry.js +1 -1
  20. package/dist/esm/pennlibs-chat.entry.js +1 -1
  21. package/dist/esm/pennlibs-fallback-img.entry.js +1 -1
  22. package/dist/esm/pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.js.map +1 -0
  23. package/dist/esm/{pennlibs-autocomplete_4.entry.js → pennlibs-feedback_3.entry.js} +27 -298
  24. package/dist/esm/pennlibs-hero.entry.js +1 -1
  25. package/dist/esm/pennlibs-iiif-img.entry.js +1 -1
  26. package/dist/esm/web.js +3 -3
  27. package/dist/types/components/pennlibs-feedback/pennlibs-feedback.d.ts +1 -1
  28. package/dist/web/index.esm.js +1 -1
  29. package/dist/web/{p-a34e1e3e.entry.js → p-0c1113f4.entry.js} +1 -1
  30. package/dist/web/{p-3da26275.entry.js → p-10931f0a.entry.js} +27 -298
  31. package/dist/web/{p-b6e686d1.entry.js → p-154851d1.entry.js} +1 -1
  32. package/dist/web/{p-c96a3643.entry.js → p-190f0293.entry.js} +1 -1
  33. package/dist/web/{p-eb633f4d.entry.js → p-4fb3e5a4.entry.js} +1 -1
  34. package/dist/web/p-7c6382d0.entry.js +279 -0
  35. package/dist/web/{p-662e4125.entry.js → p-e426fb61.entry.js} +1 -1
  36. package/dist/web/{p-CNQ9-Wwh.js → p-mkVX9lU0.js} +3 -3
  37. package/dist/web/{p-CNQ9-Wwh.js.map → p-mkVX9lU0.js.map} +1 -1
  38. package/dist/web/pennlibs-autocomplete.entry.esm.js.map +1 -0
  39. package/dist/web/pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.esm.js.map +1 -0
  40. package/dist/web/web.esm.js +3 -3
  41. package/hydrate/index.js +26 -22
  42. package/hydrate/index.mjs +26 -22
  43. package/package.json +1 -1
  44. package/dist/cjs/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.cjs.js.map +0 -1
  45. package/dist/esm/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.js.map +0 -1
  46. package/dist/web/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.esm.js.map +0 -1
@@ -1,12 +1,10 @@
1
1
  import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
2
2
 
3
- 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}";
3
+ 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}button.selected{background:var(--pl-color-bg-accent-emphasis);color:var(--pl-color-fg-on-emphasis);border-color:var(--pl-color-bg-accent-emphasis)}.feedback__inline-question+.feedback__share-feedback,p{animation:none}.feedback__content>p{animation:fadeIn 300ms ease-in}@keyframes fadeIn{from{opacity:0}to{opacity:1}}*: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
 
5
- const FEEDBACK_STORAGE_KEY = 'pennlibs-feedback-answer';
6
- const FEEDBACK_TIMESTAMP_KEY = 'pennlibs-feedback-timestamp';
5
+ const FEEDBACK_STORAGE_KEY = `pennlibs-feedback-${window.location.pathname}`;
7
6
  const FEEDBACK_TTL = 5 * 60 * 1000; // 5 minutes
8
- const FEEDBACK_QUESTION = 'Is this page useful?';
9
- const FEEDBACK_ERROR_STORAGE_KEY = 'pennlibs-feedback-error';
7
+ const FEEDBACK_QUESTION = 'Did you find what you need?';
10
8
  const PennlibsFeedback$1 = /*@__PURE__*/ proxyCustomElement(class PennlibsFeedback extends HTMLElement {
11
9
  constructor(registerHost) {
12
10
  super();
@@ -19,27 +17,30 @@ const PennlibsFeedback$1 = /*@__PURE__*/ proxyCustomElement(class PennlibsFeedba
19
17
  * When true, hides the yes/no question and only shows the "share your feedback" link.
20
18
  */
21
19
  this.hideQuestion = false;
22
- this.error = false;
23
20
  this.answer = undefined;
21
+ this.selected = undefined;
24
22
  }
25
23
  componentWillLoad() {
26
- const timestamp = sessionStorage.getItem(FEEDBACK_TIMESTAMP_KEY);
27
- if (timestamp && Date.now() - Number(timestamp) > FEEDBACK_TTL) {
28
- sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);
29
- sessionStorage.removeItem(FEEDBACK_TIMESTAMP_KEY);
30
- }
31
- if (sessionStorage.getItem(FEEDBACK_STORAGE_KEY)) {
32
- this.answer = sessionStorage.getItem(FEEDBACK_STORAGE_KEY);
33
- }
34
- if (sessionStorage.getItem(FEEDBACK_ERROR_STORAGE_KEY)) {
35
- this.error = sessionStorage.getItem(FEEDBACK_ERROR_STORAGE_KEY) === 'true';
24
+ const stored = sessionStorage.getItem(FEEDBACK_STORAGE_KEY);
25
+ if (stored) {
26
+ try {
27
+ const { answer, timestamp } = JSON.parse(stored);
28
+ if (Date.now() - timestamp > FEEDBACK_TTL) {
29
+ sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);
30
+ }
31
+ else {
32
+ this.answer = answer;
33
+ }
34
+ }
35
+ catch (_a) {
36
+ sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);
37
+ }
36
38
  }
37
39
  }
38
40
  handleFeedback(answer) {
39
41
  var _a;
40
- this.answer = answer;
41
- sessionStorage.setItem(FEEDBACK_STORAGE_KEY, answer);
42
- sessionStorage.setItem(FEEDBACK_TIMESTAMP_KEY, String(Date.now()));
42
+ this.selected = answer;
43
+ sessionStorage.setItem(FEEDBACK_STORAGE_KEY, JSON.stringify({ answer, timestamp: Date.now() }));
43
44
  this.feedbackEvent.emit({
44
45
  question: FEEDBACK_QUESTION,
45
46
  answer: answer,
@@ -47,15 +48,18 @@ const PennlibsFeedback$1 = /*@__PURE__*/ proxyCustomElement(class PennlibsFeedba
47
48
  pageHeading: ((_a = document.querySelector('h1')) === null || _a === void 0 ? void 0 : _a.textContent) || undefined,
48
49
  pageTitle: document.title || undefined
49
50
  });
51
+ setTimeout(() => {
52
+ this.answer = answer;
53
+ }, 600);
50
54
  }
51
55
  render() {
52
- 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"), "."))))));
56
+ return (h("div", { key: 'e470cb9ce96fecddda37c8a557c6670b581d8414', class: "feedback__container" }, h("div", { key: '0f3729d63102379f7219fd9a65c370f05c3f271c', class: "viewport-margins" }, h("div", { key: '3eaa8419d9b5fed5d7cf33de60ab93dd911afa34', class: "feedback__content" }, !this.hideQuestion && (this.answer === 'yes' ? (h("p", null, "Thank you for letting us know.")) : this.answer === 'no' ? (h("p", null, "We'd like to help. ", h("a", { href: "https://www.library.upenn.edu/contact-us" }, "Contact us"), " and let us know what you're looking for.")) : (h("div", { class: "feedback__inline-question" }, h("h2", null, "Did you find what you need?"), h("button", { class: { 'selected': this.selected === 'yes' }, disabled: !!this.selected, onClick: () => this.handleFeedback('yes') }, h("span", null, "Yes"), h("span", { class: "visually-hidden" }, ", I found what I needed.")), h("button", { class: { 'selected': this.selected === 'no' }, disabled: !!this.selected, onClick: () => this.handleFeedback('no') }, h("span", null, "No"), h("span", { class: "visually-hidden" }, ", I did not find what I needed."))))), h("div", { key: '50da9c1f23d14feeb6a2c408b0461a439331fcd9', class: "feedback__share-feedback" }, h("p", { key: '3580e25ecd7b463bb46103a6aee54a710e88c0ff' }, "To help us improve, ", h("a", { key: '276e226f4487ce94b9de30ae40f964e63f0d045b', href: `https://upenn.co1.qualtrics.com/jfe/form/SV_3xVrP7EKWS92zfE?reporting_from_url=${encodeURIComponent(window.location.href)}` }, "share your feedback"), "."))))));
53
57
  }
54
58
  static get style() { return pennlibsFeedbackCss; }
55
59
  }, [257, "pennlibs-feedback", {
56
60
  "hideQuestion": [4, "hide-question"],
57
- "error": [32],
58
- "answer": [32]
61
+ "answer": [32],
62
+ "selected": [32]
59
63
  }]);
60
64
  function defineCustomElement$1() {
61
65
  if (typeof customElements === "undefined") {
@@ -1 +1 @@
1
- {"file":"pennlibs-feedback.js","mappings":"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","names":["PennlibsFeedback","__stencil_proxyCustomElement"],"sources":["src/components/pennlibs-feedback/pennlibs-feedback.css?tag=pennlibs-feedback&encapsulation=shadow","src/components/pennlibs-feedback/pennlibs-feedback.tsx"],"sourcesContent":["/* Component Root Styles\n---------------------------------------- */\n:host {\n display: block;\n background: #eeeff4;\n font-family: var(--pl-font-family);\n font-size: var(--pl-font-size);\n color: var(--pl-color-fg-default);\n line-height: 1.4;\n box-sizing: border-box;\n padding: 0.75em 0;\n}\n\n@media print {\n :host {\n display: none;\n }\n}\n\n*, *::before, *::after {\n box-sizing: border-box;\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.feedback__content {\n display: flex;\n justify-content: space-between;\n gap: var(--pl-space-s);\n flex-wrap: wrap;\n}\n\n/* Container Layout\n---------------------------------------- */\n.feedback__inline-question {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5em;\n align-items: center;\n}\n\n/* Typography\n---------------------------------------- */\nh2 {\n display: inline-block;\n margin: 0;\n font-family: var(--pl-font-sans-serif);\n font-size: 1em;\n font-weight: 400;\n}\n\np {\n margin: 0;\n padding: calc(0.5em + 1px) 0;\n}\n\nstrong {\n font-weight: 600;\n}\n\n/* Links\n---------------------------------------- */\na {\n color: var(--pl-color-fg-accent);\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\n/* Buttons\n---------------------------------------- */\nbutton {\n all: unset;\n display: flex;\n align-items: center;\n gap: 0.5em;\n padding: 0.25em 1.25em;\n font-family: var(--pl-font-family);\n font-weight: 500;\n line-height: 1.4;\n color: var(--pl-color-fg-default);\n background: var(--pl-color-bg-default);\n border: solid 1px var(--pl-color-fg-subtle);\n border-radius: 1em;\n box-sizing: border-box;\n}\n\nbutton:hover {\n cursor: pointer;\n}\n\nbutton:hover span {\n text-decoration: underline;\n}\n\n/* Focus States\n---------------------------------------- */\n*:focus {\n outline: 0;\n box-shadow: \n 0 0 0 2px var(--pl-color-bg-attention),\n 0 0 0 3px var(--pl-color-bg-emphasis);\n}\n\np:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--pl-color-bg-attention), 0 0 0 3px var(--pl-color-bg-emphasis);\n}\n\n/* Responsive Adjustments\n---------------------------------------- */\n@media (max-width: 26em) {\n h2 {\n display: block;\n width: 100%;\n text-align: center;\n }\n}\n\n.help-us {\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n}\n\n/* Accessibility Helpers\n---------------------------------------- */\n.visually-hidden {\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n height: 1px;\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n\n/* This ensures the element remains hidden even when focused */\n.visually-hidden:focus,\n.visually-hidden:active {\n clip: auto;\n clip-path: none;\n height: auto;\n overflow: visible;\n position: static;\n white-space: normal;\n width: auto;\n}","import { Component, h, Prop, State, Event, EventEmitter } from '@stencil/core';\n\nconst FEEDBACK_STORAGE_KEY = 'pennlibs-feedback-answer';\nconst FEEDBACK_TIMESTAMP_KEY = 'pennlibs-feedback-timestamp';\nconst FEEDBACK_TTL = 5 * 60 * 1000; // 5 minutes\nconst FEEDBACK_QUESTION = 'Is this page useful?';\nconst FEEDBACK_ERROR_STORAGE_KEY = 'pennlibs-feedback-error';\n\n/**\n * A feedback component that asks visitors \"Did you find what you need?\" and\n * links to a feedback form. The answer is stored in sessionStorage for 5 minutes\n * to avoid re-prompting during a browsing session.\n *\n * @example\n * <pennlibs-feedback></pennlibs-feedback>\n *\n * @example\n * <pennlibs-feedback hide-question></pennlibs-feedback>\n */\n@Component({\n tag: 'pennlibs-feedback',\n styleUrl: 'pennlibs-feedback.css',\n shadow: true,\n})\nexport class PennlibsFeedback {\n /**\n * When true, hides the yes/no question and only shows the \"share your feedback\" link.\n */\n @Prop() hideQuestion: boolean = false;\n\n @State() error: boolean = false;\n @State() answer: string | undefined = undefined;\n\n /**\n * Emitted when a visitor answers the feedback question. Includes the question,\n * answer, current URL, and page heading/title for context.\n */\n @Event({\n eventName: 'pennlibs-feedback',\n composed: true,\n cancelable: true,\n bubbles: true,\n }) feedbackEvent!: EventEmitter<{\n question: string;\n answer: string;\n url: string;\n pageHeading?: string;\n pageTitle?: string;\n }>;\n\n componentWillLoad() {\n const timestamp = sessionStorage.getItem(FEEDBACK_TIMESTAMP_KEY);\n if (timestamp && Date.now() - Number(timestamp) > FEEDBACK_TTL) {\n sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);\n sessionStorage.removeItem(FEEDBACK_TIMESTAMP_KEY);\n }\n\n if (sessionStorage.getItem(FEEDBACK_STORAGE_KEY)) {\n this.answer = sessionStorage.getItem(FEEDBACK_STORAGE_KEY) as string;\n }\n\n if (sessionStorage.getItem(FEEDBACK_ERROR_STORAGE_KEY)) {\n this.error = sessionStorage.getItem(FEEDBACK_ERROR_STORAGE_KEY) === 'true';\n }\n }\n\n handleFeedback(answer: string) {\n this.answer = answer;\n sessionStorage.setItem(FEEDBACK_STORAGE_KEY, answer);\n sessionStorage.setItem(FEEDBACK_TIMESTAMP_KEY, String(Date.now()));\n \n this.feedbackEvent.emit({\n question: FEEDBACK_QUESTION,\n answer: answer,\n url: window.location.href,\n pageHeading: document.querySelector('h1')?.textContent || undefined,\n pageTitle: document.title || undefined\n });\n }\n \n render() {\n return (\n <div class=\"feedback__container\">\n <div class=\"viewport-margins\">\n <div class=\"feedback__content\">\n {!this.hideQuestion && (this.answer === 'yes' ? (\n <p>Thank you for letting us know.</p>\n ) : this.answer === 'no' ? (\n <p>Thank you for letting us know. <a href=\"https://www.library.upenn.edu/contact-us\">Contact us</a> if you need help.</p>\n ) : (\n <div class=\"feedback__inline-question\">\n <h2>Did you find what you need?</h2>\n <button onClick={() => this.handleFeedback('yes')}>\n <span>Yes</span><span class=\"visually-hidden\">, I found what I needed.</span>\n </button>\n <button onClick={() => this.handleFeedback('no')}>\n <span>No</span><span class=\"visually-hidden\">, I did not find what I needed.</span>\n </button>\n </div>\n ))}\n <div class=\"feedback__share-feedback\">\n <p>To help us improve, <a href=\"http://library.upenn.edu/feedback\">share your feedback</a>.</p>\n </div>\n </div>\n </div>\n </div>\n )\n }\n}\n\n"],"version":3}
1
+ {"file":"pennlibs-feedback.js","mappings":"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","names":["PennlibsFeedback","__stencil_proxyCustomElement"],"sources":["src/components/pennlibs-feedback/pennlibs-feedback.css?tag=pennlibs-feedback&encapsulation=shadow","src/components/pennlibs-feedback/pennlibs-feedback.tsx"],"sourcesContent":["/* Component Root Styles\n---------------------------------------- */\n:host {\n display: block;\n background: #eeeff4;\n font-family: var(--pl-font-family);\n font-size: var(--pl-font-size);\n color: var(--pl-color-fg-default);\n line-height: 1.4;\n box-sizing: border-box;\n padding: 0.75em 0;\n}\n\n@media print {\n :host {\n display: none;\n }\n}\n\n*, *::before, *::after {\n box-sizing: border-box;\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.feedback__content {\n display: flex;\n justify-content: space-between;\n gap: var(--pl-space-s);\n flex-wrap: wrap;\n}\n\n/* Container Layout\n---------------------------------------- */\n.feedback__inline-question {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5em;\n align-items: center;\n}\n\n/* Typography\n---------------------------------------- */\nh2 {\n display: inline-block;\n margin: 0;\n font-family: var(--pl-font-sans-serif);\n font-size: 1em;\n font-weight: 400;\n}\n\np {\n margin: 0;\n padding: calc(0.5em + 1px) 0;\n}\n\nstrong {\n font-weight: 600;\n}\n\n/* Links\n---------------------------------------- */\na {\n color: var(--pl-color-fg-accent);\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\n/* Buttons\n---------------------------------------- */\nbutton {\n all: unset;\n display: flex;\n align-items: center;\n gap: 0.5em;\n padding: 0.25em 1.25em;\n font-family: var(--pl-font-family);\n font-weight: 500;\n line-height: 1.4;\n color: var(--pl-color-fg-default);\n background: var(--pl-color-bg-default);\n border: solid 1px var(--pl-color-fg-subtle);\n border-radius: 1em;\n box-sizing: border-box;\n}\n\nbutton:hover {\n cursor: pointer;\n}\n\nbutton:hover span {\n text-decoration: underline;\n}\n\nbutton.selected {\n background: var(--pl-color-bg-accent-emphasis);\n color: var(--pl-color-fg-on-emphasis);\n border-color: var(--pl-color-bg-accent-emphasis);\n}\n\n/* Thank you message fade-in */\n.feedback__inline-question + .feedback__share-feedback,\np {\n animation: none;\n}\n\n.feedback__content > p {\n animation: fadeIn 300ms ease-in;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Focus States\n---------------------------------------- */\n*:focus {\n outline: 0;\n box-shadow: \n 0 0 0 2px var(--pl-color-bg-attention),\n 0 0 0 3px var(--pl-color-bg-emphasis);\n}\n\np:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--pl-color-bg-attention), 0 0 0 3px var(--pl-color-bg-emphasis);\n}\n\n/* Responsive Adjustments\n---------------------------------------- */\n@media (max-width: 26em) {\n h2 {\n display: block;\n width: 100%;\n text-align: center;\n }\n}\n\n.help-us {\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n}\n\n/* Accessibility Helpers\n---------------------------------------- */\n.visually-hidden {\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n height: 1px;\n overflow: hidden;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n\n/* This ensures the element remains hidden even when focused */\n.visually-hidden:focus,\n.visually-hidden:active {\n clip: auto;\n clip-path: none;\n height: auto;\n overflow: visible;\n position: static;\n white-space: normal;\n width: auto;\n}","import { Component, h, Prop, State, Event, EventEmitter } from '@stencil/core';\n\nconst FEEDBACK_STORAGE_KEY = `pennlibs-feedback-${window.location.pathname}`;\nconst FEEDBACK_TTL = 5 * 60 * 1000; // 5 minutes\nconst FEEDBACK_QUESTION = 'Did you find what you need?';\n\n\n/**\n * A feedback component that asks visitors \"Did you find what you need?\" and\n * links to a feedback form. The answer is stored in sessionStorage for 5 minutes\n * to avoid re-prompting during a browsing session.\n *\n * @example\n * <pennlibs-feedback></pennlibs-feedback>\n *\n * @example\n * <pennlibs-feedback hide-question></pennlibs-feedback>\n */\n@Component({\n tag: 'pennlibs-feedback',\n styleUrl: 'pennlibs-feedback.css',\n shadow: true,\n})\nexport class PennlibsFeedback {\n /**\n * When true, hides the yes/no question and only shows the \"share your feedback\" link.\n */\n @Prop() hideQuestion: boolean = false;\n\n @State() answer: string | undefined = undefined;\n @State() selected: string | undefined = undefined;\n\n /**\n * Emitted when a visitor answers the feedback question. Includes the question,\n * answer, current URL, and page heading/title for context.\n */\n @Event({\n eventName: 'pennlibs-feedback',\n composed: true,\n cancelable: true,\n bubbles: true,\n }) feedbackEvent!: EventEmitter<{\n question: string;\n answer: string;\n url: string;\n pageHeading?: string;\n pageTitle?: string;\n }>;\n\n componentWillLoad() {\n const stored = sessionStorage.getItem(FEEDBACK_STORAGE_KEY);\n if (stored) {\n try {\n const { answer, timestamp } = JSON.parse(stored);\n if (Date.now() - timestamp > FEEDBACK_TTL) {\n sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);\n } else {\n this.answer = answer;\n }\n } catch {\n sessionStorage.removeItem(FEEDBACK_STORAGE_KEY);\n }\n }\n }\n\n handleFeedback(answer: string) {\n this.selected = answer;\n sessionStorage.setItem(FEEDBACK_STORAGE_KEY, JSON.stringify({ answer, timestamp: Date.now() }));\n\n this.feedbackEvent.emit({\n question: FEEDBACK_QUESTION,\n answer: answer,\n url: window.location.href,\n pageHeading: document.querySelector('h1')?.textContent || undefined,\n pageTitle: document.title || undefined\n });\n\n setTimeout(() => {\n this.answer = answer;\n }, 600);\n }\n \n render() {\n return (\n <div class=\"feedback__container\">\n <div class=\"viewport-margins\">\n <div class=\"feedback__content\">\n {!this.hideQuestion && (this.answer === 'yes' ? (\n <p>Thank you for letting us know.</p>\n ) : this.answer === 'no' ? (\n <p>We'd like to help. <a href=\"https://www.library.upenn.edu/contact-us\">Contact us</a> and let us know what you're looking for.</p>\n ) : (\n <div class=\"feedback__inline-question\">\n <h2>Did you find what you need?</h2>\n <button class={{ 'selected': this.selected === 'yes' }} disabled={!!this.selected} onClick={() => this.handleFeedback('yes')}>\n <span>Yes</span><span class=\"visually-hidden\">, I found what I needed.</span>\n </button>\n <button class={{ 'selected': this.selected === 'no' }} disabled={!!this.selected} onClick={() => this.handleFeedback('no')}>\n <span>No</span><span class=\"visually-hidden\">, I did not find what I needed.</span>\n </button>\n </div>\n ))}\n <div class=\"feedback__share-feedback\">\n <p>To help us improve, <a href={`https://upenn.co1.qualtrics.com/jfe/form/SV_3xVrP7EKWS92zfE?reporting_from_url=${encodeURIComponent(window.location.href)}`}>share your feedback</a>.</p>\n </div>\n </div>\n </div>\n </div>\n )\n }\n}\n\n"],"version":3}
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-03-13T19:16:58",
2
+ "timestamp": "2026-03-16T15:51:31",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.38.1",
@@ -2257,7 +2257,7 @@ var hostListenerOpts = (flags) => supportsListenerOptions ? {
2257
2257
  // src/runtime/nonce.ts
2258
2258
  var setNonce = (nonce) => plt.$nonce$ = nonce;
2259
2259
 
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=index-CNQ9-Wwh.js.map
2260
+ export { getElement as a, bootstrapLazy as b, createEvent as c, getAssetPath as d, setAssetPath as e, globalScripts as g, h, promiseResolve as p, registerInstance as r, setNonce as s };
2261
+ //# sourceMappingURL=index-mkVX9lU0.js.map
2262
2262
 
2263
- //# sourceMappingURL=index-CNQ9-Wwh.js.map
2263
+ //# sourceMappingURL=index-mkVX9lU0.js.map