@penn-libraries/web 1.2.0-dev.1 → 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.
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/pennlibs-autocomplete.cjs.entry.js +281 -0
- package/dist/cjs/pennlibs-autocomplete.entry.cjs.js.map +1 -0
- package/dist/cjs/pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.cjs.js.map +1 -0
- package/dist/cjs/{pennlibs-autocomplete_4.cjs.entry.js → pennlibs-feedback_3.cjs.entry.js} +33 -301
- package/dist/cjs/web.cjs.js +1 -1
- package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.css +22 -1
- package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.js +25 -21
- package/dist/collection/components/pennlibs-feedback/pennlibs-feedback.js.map +1 -1
- package/dist/collection/components/pennlibs-footer/pennlibs-footer.css +12 -3
- 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/components/pennlibs-feedback.js +26 -22
- 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/docs.json +32 -2
- package/dist/esm/{index-CNQ9-Wwh.js → index-mkVX9lU0.js} +3 -3
- package/dist/esm/{index-CNQ9-Wwh.js.map → index-mkVX9lU0.js.map} +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/pennlibs-autocomplete.entry.js +279 -0
- package/dist/esm/pennlibs-autocomplete.entry.js.map +1 -0
- 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 +1 -1
- package/dist/esm/pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.js.map +1 -0
- package/dist/esm/{pennlibs-autocomplete_4.entry.js → pennlibs-feedback_3.entry.js} +35 -302
- package/dist/esm/pennlibs-hero.entry.js +1 -1
- package/dist/esm/pennlibs-iiif-img.entry.js +1 -1
- package/dist/esm/web.js +3 -3
- package/dist/types/components/pennlibs-feedback/pennlibs-feedback.d.ts +1 -1
- package/dist/types/components/pennlibs-footer/pennlibs-footer.d.ts +4 -0
- package/dist/types/components.d.ts +10 -0
- package/dist/web/index.esm.js +1 -1
- package/dist/web/{p-a34e1e3e.entry.js → p-0c1113f4.entry.js} +1 -1
- package/dist/web/{p-b9538aed.entry.js → p-10931f0a.entry.js} +35 -302
- package/dist/web/{p-b6e686d1.entry.js → p-154851d1.entry.js} +1 -1
- package/dist/web/{p-c96a3643.entry.js → p-190f0293.entry.js} +1 -1
- package/dist/web/{p-eb633f4d.entry.js → p-4fb3e5a4.entry.js} +1 -1
- package/dist/web/p-7c6382d0.entry.js +279 -0
- package/dist/web/{p-662e4125.entry.js → p-e426fb61.entry.js} +1 -1
- package/dist/web/{p-CNQ9-Wwh.js → p-mkVX9lU0.js} +3 -3
- package/dist/web/{p-CNQ9-Wwh.js.map → p-mkVX9lU0.js.map} +1 -1
- package/dist/web/pennlibs-autocomplete.entry.esm.js.map +1 -0
- package/dist/web/pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.esm.js.map +1 -0
- package/dist/web/web.esm.js +3 -3
- package/hydrate/index.js +35 -26
- package/hydrate/index.mjs +35 -26
- package/package.json +1 -1
- package/dist/cjs/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.cjs.js.map +0 -1
- package/dist/esm/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.js.map +0 -1
- package/dist/web/pennlibs-autocomplete.pennlibs-feedback.pennlibs-footer.pennlibs-header.entry.esm.js.map +0 -1
package/dist/cjs/loader.cjs.js
CHANGED
|
@@ -5,7 +5,7 @@ var index = require('./index-Ag6DtE87.js');
|
|
|
5
5
|
const defineCustomElements = async (win, options) => {
|
|
6
6
|
if (typeof window === 'undefined') return undefined;
|
|
7
7
|
await index.globalScripts();
|
|
8
|
-
return index.bootstrapLazy([["pennlibs-iiif-img.cjs",[[257,"pennlibs-iiif-img",{"uuid":[1],"alt":[1],"region":[513],"rotation":[1],"quality":[1],"loading":[1],"showFallback":[4,"show-fallback"],"isLoaded":[32],"hasError":[32],"imageDimensions":[32],"observedWidth":[32]},null,{"region":["handleRegionChange"]}]]],["pennlibs-
|
|
8
|
+
return index.bootstrapLazy([["pennlibs-iiif-img.cjs",[[257,"pennlibs-iiif-img",{"uuid":[1],"alt":[1],"region":[513],"rotation":[1],"quality":[1],"loading":[1],"showFallback":[4,"show-fallback"],"isLoaded":[32],"hasError":[32],"imageDimensions":[32],"observedWidth":[32]},null,{"region":["handleRegionChange"]}]]],["pennlibs-feedback_3.cjs",[[257,"pennlibs-feedback",{"hideQuestion":[4,"hide-question"],"answer":[32],"selected":[32]}],[257,"pennlibs-footer",{"showBuiltWith":[4,"show-built-with"],"navigationByChildren":[32]}],[257,"pennlibs-header",{"serviceName":[1,"service-name"],"serviceLede":[1,"service-lede"],"serviceHref":[1,"service-href"],"theme":[1],"isMenuOpen":[32],"navigation":[32]}]]],["pennlibs-autocomplete.cjs",[[257,"pennlibs-autocomplete",{"for":[1],"showSuggestions":[32],"currentIndex":[32],"originalValue":[32],"options":[32]},[[0,"slotchange","handleSlotChange"],[16,"input","handleInputEvent"],[16,"focus","handleFocusEvent"],[16,"blur","handleBlurEvent"],[0,"focusout","handleFocusOut"],[4,"keydown","handleKeyDown"]]]]],["pennlibs-banner.cjs",[[257,"pennlibs-banner"]]],["pennlibs-chat.cjs",[[257,"pennlibs-chat",{"href":[32]}]]],["pennlibs-hero.cjs",[[257,"pennlibs-hero",{"heroPictureElement":[32],"heroHeadingElement":[32],"heroParagraphElement":[32],"heroSrc":[32]}]]],["pennlibs-fallback-img.cjs",[[257,"pennlibs-fallback-img"]]]], options);
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
exports.setNonce = index.setNonce;
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var index = require('./index-Ag6DtE87.js');
|
|
4
|
+
|
|
5
|
+
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}";
|
|
6
|
+
|
|
7
|
+
const Autocomplete = class {
|
|
8
|
+
constructor(hostRef) {
|
|
9
|
+
index.registerInstance(this, hostRef);
|
|
10
|
+
this.activated = index.createEvent(this, "pl:activated");
|
|
11
|
+
this.showSuggestions = false;
|
|
12
|
+
this.currentIndex = -1;
|
|
13
|
+
this.originalValue = '';
|
|
14
|
+
this.options = [];
|
|
15
|
+
this.keyHandlerMap = {
|
|
16
|
+
'Escape': () => this.handleEscape(),
|
|
17
|
+
'ArrowDown': () => this.handleArrowDown(),
|
|
18
|
+
'ArrowUp': () => this.handleArrowUp(),
|
|
19
|
+
'Enter': () => this.handleEnter()
|
|
20
|
+
};
|
|
21
|
+
this.handleOptionClick = (index) => {
|
|
22
|
+
this.currentIndex = index;
|
|
23
|
+
this.selectCurrent();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
componentWillLoad() {
|
|
27
|
+
this.options = this.parseOptionsFromDOM();
|
|
28
|
+
}
|
|
29
|
+
componentDidLoad() {
|
|
30
|
+
this.setupInput();
|
|
31
|
+
this.setupMutationObserver();
|
|
32
|
+
}
|
|
33
|
+
disconnectedCallback() {
|
|
34
|
+
if (this.blurTimeout)
|
|
35
|
+
clearTimeout(this.blurTimeout);
|
|
36
|
+
if (this.mutationObserver)
|
|
37
|
+
this.mutationObserver.disconnect();
|
|
38
|
+
}
|
|
39
|
+
setupMutationObserver() {
|
|
40
|
+
this.mutationObserver = new MutationObserver(() => {
|
|
41
|
+
this.options = this.parseOptionsFromDOM();
|
|
42
|
+
});
|
|
43
|
+
this.mutationObserver.observe(this.el, {
|
|
44
|
+
childList: true,
|
|
45
|
+
subtree: true,
|
|
46
|
+
characterData: true
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
parseOptionsFromDOM() {
|
|
50
|
+
const listbox = this.findListbox();
|
|
51
|
+
if (!listbox)
|
|
52
|
+
return [];
|
|
53
|
+
const elements = Array.from(listbox.querySelectorAll('[role="option"]'));
|
|
54
|
+
return elements.map((el, i) => this.createOption(el, i));
|
|
55
|
+
}
|
|
56
|
+
findListbox() {
|
|
57
|
+
return Array.from(this.el.children).find(child => child.matches('ol[role="listbox"]'));
|
|
58
|
+
}
|
|
59
|
+
createOption(element, index) {
|
|
60
|
+
var _a;
|
|
61
|
+
return {
|
|
62
|
+
id: element.id || `option-${index}`,
|
|
63
|
+
html: element.innerHTML,
|
|
64
|
+
value: element.getAttribute('data-pl-value') || ((_a = element.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || ''
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
getInput() {
|
|
68
|
+
var _a;
|
|
69
|
+
if (!this.for)
|
|
70
|
+
return null;
|
|
71
|
+
const slot = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot[name="start"]');
|
|
72
|
+
if (!slot)
|
|
73
|
+
return null;
|
|
74
|
+
const assignedElements = slot.assignedElements();
|
|
75
|
+
if (assignedElements.length === 0)
|
|
76
|
+
return null;
|
|
77
|
+
const input = assignedElements[0].querySelector(`input#${this.for}`);
|
|
78
|
+
return input || null;
|
|
79
|
+
}
|
|
80
|
+
isInputFocused() {
|
|
81
|
+
return this.getInput() === document.activeElement;
|
|
82
|
+
}
|
|
83
|
+
isTrackedInput(input) {
|
|
84
|
+
return (input === null || input === void 0 ? void 0 : input.getAttribute('data-pl-autocomplete-connected')) === 'true' &&
|
|
85
|
+
this.el.contains(input);
|
|
86
|
+
}
|
|
87
|
+
setupInput() {
|
|
88
|
+
if (!this.for) {
|
|
89
|
+
console.warn('<pennlibs-autocomplete> Missing "for" attribute. Please add for="input-id" to specify which input to attach to.');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const input = this.getInput();
|
|
93
|
+
if (!input) {
|
|
94
|
+
console.warn(`<pennlibs-autocomplete> No input element found with id="${this.for}". Ensure an input with this id exists.`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.setComboboxAttributes(input);
|
|
98
|
+
input.setAttribute('data-pl-autocomplete-connected', 'true');
|
|
99
|
+
}
|
|
100
|
+
setComboboxAttributes(input) {
|
|
101
|
+
input.setAttribute('role', 'combobox');
|
|
102
|
+
input.setAttribute('aria-autocomplete', 'list');
|
|
103
|
+
input.setAttribute('aria-expanded', 'false');
|
|
104
|
+
input.setAttribute('aria-controls', 'listbox');
|
|
105
|
+
}
|
|
106
|
+
handleSlotChange() {
|
|
107
|
+
this.options = this.parseOptionsFromDOM();
|
|
108
|
+
this.setupInput();
|
|
109
|
+
}
|
|
110
|
+
handleInputEvent(event) {
|
|
111
|
+
const input = event.target;
|
|
112
|
+
if (this.isTrackedInput(input)) {
|
|
113
|
+
this.currentIndex = -1;
|
|
114
|
+
this.openSuggestions();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
handleFocusEvent(event) {
|
|
118
|
+
const input = event.target;
|
|
119
|
+
if (this.isTrackedInput(input))
|
|
120
|
+
this.showSuggestionsPanel();
|
|
121
|
+
}
|
|
122
|
+
handleBlurEvent(event) {
|
|
123
|
+
const input = event.target;
|
|
124
|
+
if (this.isTrackedInput(input))
|
|
125
|
+
this.deferCloseSuggestions();
|
|
126
|
+
}
|
|
127
|
+
handleFocusOut(event) {
|
|
128
|
+
if (this.isFocusLeavingComponent(event))
|
|
129
|
+
this.closeSuggestions();
|
|
130
|
+
}
|
|
131
|
+
handleKeyDown(event) {
|
|
132
|
+
if (!this.isInputFocused())
|
|
133
|
+
return;
|
|
134
|
+
if (event.metaKey || event.ctrlKey)
|
|
135
|
+
return; // Ignore keyboard shortcuts
|
|
136
|
+
const handler = this.keyHandlerMap[event.key];
|
|
137
|
+
if (handler) {
|
|
138
|
+
// Don't prevent default for Enter - allow form submission
|
|
139
|
+
if (event.key !== 'Enter') {
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
}
|
|
142
|
+
handler();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
handleEscape() {
|
|
146
|
+
this.reset();
|
|
147
|
+
this.syncAll();
|
|
148
|
+
}
|
|
149
|
+
handleArrowDown() {
|
|
150
|
+
if (!this.showSuggestions)
|
|
151
|
+
return;
|
|
152
|
+
this.moveNext();
|
|
153
|
+
this.syncAll();
|
|
154
|
+
}
|
|
155
|
+
handleArrowUp() {
|
|
156
|
+
if (!this.showSuggestions)
|
|
157
|
+
return;
|
|
158
|
+
this.movePrevious();
|
|
159
|
+
this.syncAll();
|
|
160
|
+
}
|
|
161
|
+
handleEnter() {
|
|
162
|
+
if (this.canSelect())
|
|
163
|
+
this.selectCurrent();
|
|
164
|
+
}
|
|
165
|
+
// Navigation
|
|
166
|
+
moveNext() {
|
|
167
|
+
const lastIndex = this.options.length - 1;
|
|
168
|
+
this.currentIndex = this.currentIndex < lastIndex ? this.currentIndex + 1 : -1;
|
|
169
|
+
}
|
|
170
|
+
movePrevious() {
|
|
171
|
+
const lastIndex = this.options.length - 1;
|
|
172
|
+
this.currentIndex = this.currentIndex > -1 ? this.currentIndex - 1 : lastIndex;
|
|
173
|
+
}
|
|
174
|
+
canSelect() {
|
|
175
|
+
return this.showSuggestions && this.currentIndex >= 0;
|
|
176
|
+
}
|
|
177
|
+
selectCurrent() {
|
|
178
|
+
if (this.currentIndex < 0)
|
|
179
|
+
return;
|
|
180
|
+
const selectedOption = this.options[this.currentIndex];
|
|
181
|
+
this.applySelection(selectedOption);
|
|
182
|
+
this.emitActivation(selectedOption);
|
|
183
|
+
this.closeSuggestions();
|
|
184
|
+
}
|
|
185
|
+
applySelection(option) {
|
|
186
|
+
const input = this.getInput();
|
|
187
|
+
if (!input)
|
|
188
|
+
return;
|
|
189
|
+
input.value = option.value;
|
|
190
|
+
this.originalValue = option.value;
|
|
191
|
+
}
|
|
192
|
+
emitActivation(option) {
|
|
193
|
+
this.activated.emit({
|
|
194
|
+
index: this.currentIndex,
|
|
195
|
+
value: option.value
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
openSuggestions() {
|
|
199
|
+
if (!this.isInputFocused())
|
|
200
|
+
return;
|
|
201
|
+
const input = this.getInput();
|
|
202
|
+
if (input)
|
|
203
|
+
this.originalValue = input.value;
|
|
204
|
+
this.showSuggestionsPanel();
|
|
205
|
+
}
|
|
206
|
+
showSuggestionsPanel() {
|
|
207
|
+
this.showSuggestions = true;
|
|
208
|
+
this.syncAriaAttributes();
|
|
209
|
+
}
|
|
210
|
+
closeSuggestions() {
|
|
211
|
+
this.reset();
|
|
212
|
+
this.syncAll();
|
|
213
|
+
}
|
|
214
|
+
deferCloseSuggestions() {
|
|
215
|
+
if (this.blurTimeout)
|
|
216
|
+
clearTimeout(this.blurTimeout);
|
|
217
|
+
this.blurTimeout = setTimeout(() => {
|
|
218
|
+
if (this.isFocusOutsideComponent())
|
|
219
|
+
this.closeSuggestions();
|
|
220
|
+
}, 150);
|
|
221
|
+
}
|
|
222
|
+
reset() {
|
|
223
|
+
this.showSuggestions = false;
|
|
224
|
+
this.currentIndex = -1;
|
|
225
|
+
}
|
|
226
|
+
isFocusLeavingComponent(event) {
|
|
227
|
+
var _a;
|
|
228
|
+
const target = event.relatedTarget;
|
|
229
|
+
return !target ||
|
|
230
|
+
(!this.el.contains(target) && !((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(target)));
|
|
231
|
+
}
|
|
232
|
+
isFocusOutsideComponent() {
|
|
233
|
+
var _a;
|
|
234
|
+
const active = document.activeElement;
|
|
235
|
+
return !((_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.contains(active)) && active !== this.getInput();
|
|
236
|
+
}
|
|
237
|
+
syncAriaAttributes() {
|
|
238
|
+
const input = this.getInput();
|
|
239
|
+
if (!input)
|
|
240
|
+
return;
|
|
241
|
+
this.updateAriaExpanded(input);
|
|
242
|
+
this.updateAriaActiveDescendant(input);
|
|
243
|
+
}
|
|
244
|
+
syncInputValueToSelection() {
|
|
245
|
+
const input = this.getInput();
|
|
246
|
+
if (!input)
|
|
247
|
+
return;
|
|
248
|
+
input.value = this.currentIndex >= 0 && this.currentIndex < this.options.length
|
|
249
|
+
? this.options[this.currentIndex].value
|
|
250
|
+
: this.originalValue;
|
|
251
|
+
}
|
|
252
|
+
syncAll() {
|
|
253
|
+
this.syncAriaAttributes();
|
|
254
|
+
this.syncInputValueToSelection();
|
|
255
|
+
}
|
|
256
|
+
updateAriaExpanded(input) {
|
|
257
|
+
input.setAttribute('aria-expanded', this.showSuggestions.toString());
|
|
258
|
+
}
|
|
259
|
+
updateAriaActiveDescendant(input) {
|
|
260
|
+
const hasSelection = this.showSuggestions &&
|
|
261
|
+
this.currentIndex >= 0 &&
|
|
262
|
+
this.currentIndex < this.options.length;
|
|
263
|
+
if (hasSelection) {
|
|
264
|
+
input.setAttribute('aria-activedescendant', this.options[this.currentIndex].id);
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
input.removeAttribute('aria-activedescendant');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
shouldShowListbox() {
|
|
271
|
+
return this.showSuggestions && this.options.length > 0 && this.isInputFocused();
|
|
272
|
+
}
|
|
273
|
+
render() {
|
|
274
|
+
return (index.h("div", { key: 'ee4ead1b5bec44a561901a29d3d5e119da0d09f8' }, index.h("slot", { key: '7d7128ab7968544ab25125d30a648136f8d8a566', name: "start" }), this.shouldShowListbox() && (index.h("ol", { key: '95d45d524847f83b646853a8d919bc88f471f150', role: "listbox", id: "listbox" }, this.options.map((option, index$1) => (index.h("li", { role: "option", id: option.id, "aria-selected": this.currentIndex === index$1 ? 'true' : 'false', tabindex: "-1", onClick: () => this.handleOptionClick(index$1), innerHTML: option.html })))))));
|
|
275
|
+
}
|
|
276
|
+
get el() { return index.getElement(this); }
|
|
277
|
+
};
|
|
278
|
+
Autocomplete.style = pennlibsAutocompleteCss;
|
|
279
|
+
|
|
280
|
+
exports.pennlibs_autocomplete = Autocomplete;
|
|
281
|
+
//# sourceMappingURL=pennlibs-autocomplete.entry.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pennlibs-autocomplete.entry.cjs.js","sources":["src/components/pennlibs-autocomplete/pennlibs-autocomplete.css?tag=pennlibs-autocomplete&encapsulation=shadow","src/components/pennlibs-autocomplete/pennlibs-autocomplete.tsx"],"sourcesContent":[":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}","import { Component, h, Element, State, Listen, Event, EventEmitter, Prop } from '@stencil/core';\n\ninterface ListboxOption {\n id: string;\n html: string;\n value: string;\n}\n\nexport interface ActivatedEvent {\n value: string;\n index: number;\n}\n\n/**\n * Offer predictive suggestions while typing your search query.\n *\n * @slot start - Content to display at the start (top).\n */\n@Component({\n tag: 'pennlibs-autocomplete',\n styleUrl: 'pennlibs-autocomplete.css',\n shadow: true\n})\nexport class Autocomplete {\n @Element() el!: HTMLElement;\n\n /**\n * The `id` of the input that this autocomplete is attached to.\n * @prop for\n */\n @Prop() for?: string;\n\n @State() showSuggestions: boolean = false;\n @State() currentIndex: number = -1;\n @State() originalValue: string = '';\n @State() options: ListboxOption[] = [];\n\n /**\n * Emitted when a user activates (selects) an autocomplete suggestion.\n * @event pl:activated\n */\n @Event({ eventName: 'pl:activated' }) activated: EventEmitter<ActivatedEvent>;\n\n private blurTimeout: number;\n private mutationObserver: MutationObserver;\n private readonly keyHandlerMap = {\n 'Escape': () => this.handleEscape(),\n 'ArrowDown': () => this.handleArrowDown(),\n 'ArrowUp': () => this.handleArrowUp(),\n 'Enter': () => this.handleEnter()\n };\n\n componentWillLoad() {\n this.options = this.parseOptionsFromDOM();\n }\n\n componentDidLoad() {\n this.setupInput();\n this.setupMutationObserver();\n }\n\n disconnectedCallback() {\n if (this.blurTimeout) clearTimeout(this.blurTimeout);\n if (this.mutationObserver) this.mutationObserver.disconnect();\n }\n\n private setupMutationObserver(): void {\n this.mutationObserver = new MutationObserver(() => {\n this.options = this.parseOptionsFromDOM();\n });\n\n this.mutationObserver.observe(this.el, {\n childList: true,\n subtree: true,\n characterData: true\n });\n }\n\n private parseOptionsFromDOM(): ListboxOption[] {\n const listbox = this.findListbox();\n if (!listbox) return [];\n\n const elements = Array.from(listbox.querySelectorAll('[role=\"option\"]')) as HTMLElement[];\n return elements.map((el, i) => this.createOption(el, i));\n }\n\n private findListbox(): HTMLOListElement | null {\n return Array.from(this.el.children).find(child =>\n child.matches('ol[role=\"listbox\"]')\n ) as HTMLOListElement;\n }\n\n private createOption(element: HTMLElement, index: number): ListboxOption {\n return {\n id: element.id || `option-${index}`,\n html: element.innerHTML,\n value: element.getAttribute('data-pl-value') || element.textContent?.trim() || ''\n };\n }\n\n private getInput(): HTMLInputElement | null {\n if (!this.for) return null;\n\n const slot = this.el.shadowRoot?.querySelector('slot[name=\"start\"]') as HTMLSlotElement;\n if (!slot) return null;\n\n const assignedElements = slot.assignedElements();\n if (assignedElements.length === 0) return null;\n\n const input = assignedElements[0].querySelector(`input#${this.for}`) as HTMLInputElement;\n return input || null;\n }\n\n private isInputFocused(): boolean {\n return this.getInput() === document.activeElement;\n }\n\n private isTrackedInput(input: HTMLInputElement): boolean {\n return input?.getAttribute('data-pl-autocomplete-connected') === 'true' &&\n this.el.contains(input);\n }\n\n private setupInput(): void {\n if (!this.for) {\n console.warn('<pennlibs-autocomplete> Missing \"for\" attribute. Please add for=\"input-id\" to specify which input to attach to.');\n return;\n }\n\n const input = this.getInput();\n if (!input) {\n console.warn(`<pennlibs-autocomplete> No input element found with id=\"${this.for}\". Ensure an input with this id exists.`);\n return;\n }\n\n this.setComboboxAttributes(input);\n input.setAttribute('data-pl-autocomplete-connected', 'true');\n }\n\n private setComboboxAttributes(input: HTMLInputElement): void {\n input.setAttribute('role', 'combobox');\n input.setAttribute('aria-autocomplete', 'list');\n input.setAttribute('aria-expanded', 'false');\n input.setAttribute('aria-controls', 'listbox');\n }\n\n @Listen('slotchange')\n handleSlotChange() {\n this.options = this.parseOptionsFromDOM();\n this.setupInput();\n }\n\n @Listen('input', { target: 'body' })\n handleInputEvent(event: Event) {\n const input = event.target as HTMLInputElement;\n if (this.isTrackedInput(input)) {\n this.currentIndex = -1;\n this.openSuggestions();\n }\n }\n\n @Listen('focus', { target: 'body' })\n handleFocusEvent(event: Event) {\n const input = event.target as HTMLInputElement;\n if (this.isTrackedInput(input)) this.showSuggestionsPanel();\n }\n\n @Listen('blur', { target: 'body' })\n handleBlurEvent(event: Event) {\n const input = event.target as HTMLInputElement;\n if (this.isTrackedInput(input)) this.deferCloseSuggestions();\n }\n\n @Listen('focusout')\n handleFocusOut(event: FocusEvent) {\n if (this.isFocusLeavingComponent(event)) this.closeSuggestions();\n }\n\n @Listen('keydown', { target: 'document' })\n handleKeyDown(event: KeyboardEvent) {\n if (!this.isInputFocused()) return;\n if (event.metaKey || event.ctrlKey) return; // Ignore keyboard shortcuts\n\n const handler = this.keyHandlerMap[event.key];\n if (handler) {\n // Don't prevent default for Enter - allow form submission\n if (event.key !== 'Enter') {\n event.preventDefault();\n }\n handler();\n }\n }\n\n private handleEscape() {\n this.reset();\n this.syncAll();\n }\n\n private handleArrowDown() {\n if (!this.showSuggestions) return;\n this.moveNext();\n this.syncAll();\n }\n\n private handleArrowUp() {\n if (!this.showSuggestions) return;\n this.movePrevious();\n this.syncAll();\n }\n\n private handleEnter() {\n if (this.canSelect()) this.selectCurrent();\n }\n\n // Navigation\n private moveNext(): void {\n const lastIndex = this.options.length - 1;\n this.currentIndex = this.currentIndex < lastIndex ? this.currentIndex + 1 : -1;\n }\n\n private movePrevious(): void {\n const lastIndex = this.options.length - 1;\n this.currentIndex = this.currentIndex > -1 ? this.currentIndex - 1 : lastIndex;\n }\n\n private canSelect(): boolean {\n return this.showSuggestions && this.currentIndex >= 0;\n }\n\n private selectCurrent(): void {\n if (this.currentIndex < 0) return;\n\n const selectedOption = this.options[this.currentIndex];\n this.applySelection(selectedOption);\n this.emitActivation(selectedOption);\n this.closeSuggestions();\n }\n\n private applySelection(option: ListboxOption): void {\n const input = this.getInput();\n if (!input) return;\n\n input.value = option.value;\n this.originalValue = option.value;\n }\n\n private emitActivation(option: ListboxOption): void {\n this.activated.emit({\n index: this.currentIndex,\n value: option.value\n });\n }\n\n private handleOptionClick = (index: number): void => {\n this.currentIndex = index;\n this.selectCurrent();\n }\n\n private openSuggestions(): void {\n if (!this.isInputFocused()) return;\n\n const input = this.getInput();\n if (input) this.originalValue = input.value;\n\n this.showSuggestionsPanel();\n }\n\n private showSuggestionsPanel(): void {\n this.showSuggestions = true;\n this.syncAriaAttributes();\n }\n\n private closeSuggestions(): void {\n this.reset();\n this.syncAll();\n }\n\n private deferCloseSuggestions(): void {\n if (this.blurTimeout) clearTimeout(this.blurTimeout);\n this.blurTimeout = setTimeout(() => {\n if (this.isFocusOutsideComponent()) this.closeSuggestions();\n }, 150) as unknown as number;\n }\n\n private reset(): void {\n this.showSuggestions = false;\n this.currentIndex = -1;\n }\n\n private isFocusLeavingComponent(event: FocusEvent): boolean {\n const target = event.relatedTarget as HTMLElement;\n return !target ||\n (!this.el.contains(target) && !this.el.shadowRoot?.contains(target));\n }\n\n private isFocusOutsideComponent(): boolean {\n const active = document.activeElement;\n return !this.el.shadowRoot?.contains(active) && active !== this.getInput();\n }\n\n private syncAriaAttributes(): void {\n const input = this.getInput();\n if (!input) return;\n\n this.updateAriaExpanded(input);\n this.updateAriaActiveDescendant(input);\n }\n\n private syncInputValueToSelection(): void {\n const input = this.getInput();\n if (!input) return;\n\n input.value = this.currentIndex >= 0 && this.currentIndex < this.options.length\n ? this.options[this.currentIndex].value\n : this.originalValue;\n }\n\n private syncAll(): void {\n this.syncAriaAttributes();\n this.syncInputValueToSelection();\n }\n\n private updateAriaExpanded(input: HTMLInputElement): void {\n input.setAttribute('aria-expanded', this.showSuggestions.toString());\n }\n\n private updateAriaActiveDescendant(input: HTMLInputElement): void {\n const hasSelection = this.showSuggestions &&\n this.currentIndex >= 0 &&\n this.currentIndex < this.options.length;\n if (hasSelection) {\n input.setAttribute('aria-activedescendant', this.options[this.currentIndex].id);\n } else {\n input.removeAttribute('aria-activedescendant');\n }\n }\n\n private shouldShowListbox(): boolean {\n return this.showSuggestions && this.options.length > 0 && this.isInputFocused();\n }\n\n render() {\n return (\n <div>\n <slot name=\"start\" />\n {this.shouldShowListbox() && (\n <ol role=\"listbox\" id=\"listbox\">\n {this.options.map((option, index) => (\n <li\n role=\"option\"\n id={option.id}\n aria-selected={this.currentIndex === index ? 'true' : 'false'}\n tabindex=\"-1\"\n onClick={() => this.handleOptionClick(index)}\n innerHTML={option.html}\n />\n ))}\n </ol>\n )}\n </div>\n )\n }\n}\n"],"names":["h","index"],"mappings":"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"}
|