impress/app/assets/javascripts/pose-picker.js

54 lines
1.4 KiB
JavaScript
Raw Normal View History

2025-11-11 17:41:57 -08:00
/**
* PosePicker web component
*
* Progressive enhancement for pose picker forms:
* - Auto-submits the form when a pose is selected (if JS is enabled)
* - Shows a submit button as fallback (if JS is disabled or slow to load)
* - Uses Custom Element internals API to communicate state to CSS
*/
2025-11-11 18:07:06 -08:00
class PosePickerPopover extends HTMLElement {
2025-11-11 17:41:57 -08:00
#internals;
#styleListObserver;
2025-11-11 17:41:57 -08:00
constructor() {
super();
this.#internals = this.attachInternals();
}
connectedCallback() {
// Listen for changes to auto-submit the form, then tell CSS about it!
this.addEventListener("change", this.#handleChange);
this.#internals.states.add("auto-loading");
// When the style picker list becomes visible (e.g. tab switch or
// popover open), scroll the selected style into view.
const styleList = this.querySelector(".style-picker-list");
if (styleList) {
this.#styleListObserver = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
const checked = styleList.querySelector("input:checked");
checked
?.closest("label")
?.scrollIntoView({ block: "nearest" });
}
});
this.#styleListObserver.observe(styleList);
}
}
disconnectedCallback() {
this.#styleListObserver?.disconnect();
2025-11-11 17:41:57 -08:00
}
#handleChange(e) {
// Only auto-submit if a radio button was changed
if (e.target.type === "radio") {
2026-02-05 18:04:49 -08:00
e.target.closest("form").requestSubmit();
2025-11-11 17:41:57 -08:00
}
}
2025-11-11 17:41:57 -08:00
}
2025-11-11 18:07:06 -08:00
customElements.define("pose-picker-popover", PosePickerPopover);