@unabridged/midwest 0.24.0 → 0.24.4
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/app/assets/javascript/midwest/index.ts +10 -0
- package/app/assets/javascript/midwest/map_providers.ts +61 -0
- package/app/assets/javascript/midwest/viewport_observer.ts +49 -0
- package/app/assets/javascript/midwest.js +1056 -70
- package/app/assets/javascript/midwest.js.map +1 -1
- package/app/assets/stylesheets/midwest.css +1 -1
- package/app/assets/stylesheets/midwest.tailwind.css +7 -1
- package/dist/css/midwest.css +1 -1
- package/dist/javascript/collection/app/assets/javascript/midwest/index.js +10 -0
- package/dist/javascript/collection/app/assets/javascript/midwest/index.js.map +1 -1
- package/dist/javascript/collection/app/assets/javascript/midwest/map_providers.js +56 -0
- package/dist/javascript/collection/app/assets/javascript/midwest/map_providers.js.map +1 -0
- package/dist/javascript/collection/app/assets/javascript/midwest/viewport_observer.js +22 -0
- package/dist/javascript/collection/app/assets/javascript/midwest/viewport_observer.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/carousel_component/carousel_component_controller.js +4 -7
- package/dist/javascript/collection/app/components/midwest/carousel_component/carousel_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/dropdown_component/dropdown_component_controller.js +0 -6
- package/dist/javascript/collection/app/components/midwest/dropdown_component/dropdown_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/form/address_component/address_component_controller.js +441 -0
- package/dist/javascript/collection/app/components/midwest/form/address_component/address_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/form/live_summary_component/live_summary_component_controller.js +55 -1
- package/dist/javascript/collection/app/components/midwest/form/live_summary_component/live_summary_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/intersection_observer_component/intersection_observer_component_controller.js +20 -25
- package/dist/javascript/collection/app/components/midwest/intersection_observer_component/intersection_observer_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/map_component/map_component_controller.js +297 -0
- package/dist/javascript/collection/app/components/midwest/map_component/map_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/motion_component/motion_component_controller.js +32 -0
- package/dist/javascript/collection/app/components/midwest/motion_component/motion_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/notification_component/notification_component_controller.js +4 -12
- package/dist/javascript/collection/app/components/midwest/notification_component/notification_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/onboarding_component/onboarding_component_controller.js +34 -5
- package/dist/javascript/collection/app/components/midwest/onboarding_component/onboarding_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/page_transition_component/page_transition_component_controller.js +38 -0
- package/dist/javascript/collection/app/components/midwest/page_transition_component/page_transition_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/popover_component/popover_component_controller.js +67 -0
- package/dist/javascript/collection/app/components/midwest/popover_component/popover_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/table_component/load_more_controller.js +10 -14
- package/dist/javascript/collection/app/components/midwest/table_component/load_more_controller.js.map +1 -1
- package/dist/javascript/midwest.js +1056 -70
- package/dist/javascript/midwest.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,10 +6,7 @@ class Notification extends Controller {
|
|
|
6
6
|
connect() {
|
|
7
7
|
this.container = this.element.closest("[popover]");
|
|
8
8
|
this.container?.showPopover?.();
|
|
9
|
-
|
|
10
|
-
this.element.classList.add("visible");
|
|
11
|
-
});
|
|
12
|
-
const frame = this.element.parentElement;
|
|
9
|
+
const frame = this.element.closest("turbo-frame");
|
|
13
10
|
if (frame) {
|
|
14
11
|
this.observer = new MutationObserver(() => this.syncCountdown());
|
|
15
12
|
this.observer.observe(frame, { childList: true });
|
|
@@ -28,14 +25,8 @@ class Notification extends Controller {
|
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
close() {
|
|
31
|
-
if (!this.element.classList.contains("animated")) {
|
|
32
|
-
this.element.remove();
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
28
|
this.element.classList.add("closing");
|
|
36
|
-
setTimeout(() =>
|
|
37
|
-
this.element.remove();
|
|
38
|
-
}, 350);
|
|
29
|
+
setTimeout(() => (this.element.parentElement ?? this.element).remove(), 350);
|
|
39
30
|
}
|
|
40
31
|
syncCountdown() {
|
|
41
32
|
const timerEl = this.element.querySelector('[data-controller~="midwest-countdown-timer"]');
|
|
@@ -47,7 +38,8 @@ class Notification extends Controller {
|
|
|
47
38
|
);
|
|
48
39
|
if (!timer)
|
|
49
40
|
return;
|
|
50
|
-
const
|
|
41
|
+
const wrapper = this.element.parentElement ?? this.element;
|
|
42
|
+
const isTop = wrapper === wrapper.parentElement?.firstElementChild;
|
|
51
43
|
if (isTop) {
|
|
52
44
|
timer.resume();
|
|
53
45
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification_component_controller.js","sources":["../../../../../../../app/components/midwest/notification_component/notification_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\ntype PopoverElement = HTMLElement & { showPopover?(): void; hidePopover?(): void }\n\ninterface PausableTimer {\n pause(): void\n resume(): void\n}\n\nexport default class Notification extends Controller<HTMLElement> {\n private container: PopoverElement | null = null\n private observer: MutationObserver | null = null\n\n connect () {\n this.container = this.element.closest<PopoverElement>('[popover]')\n this.container?.showPopover?.()\n\n
|
|
1
|
+
{"version":3,"file":"notification_component_controller.js","sources":["../../../../../../../app/components/midwest/notification_component/notification_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\ntype PopoverElement = HTMLElement & { showPopover?(): void; hidePopover?(): void }\n\ninterface PausableTimer {\n pause(): void\n resume(): void\n}\n\nexport default class Notification extends Controller<HTMLElement> {\n private container: PopoverElement | null = null\n private observer: MutationObserver | null = null\n\n connect () {\n this.container = this.element.closest<PopoverElement>('[popover]')\n this.container?.showPopover?.()\n\n const frame = this.element.closest('turbo-frame')\n if (frame) {\n this.observer = new MutationObserver(() => this.syncCountdown())\n this.observer.observe(frame, { childList: true })\n // Defer until nested controllers (e.g. CountdownTimer) have connected\n setTimeout(() => this.syncCountdown())\n }\n }\n\n disconnect () {\n this.observer?.disconnect()\n this.observer = null\n\n if (this.container) {\n const frame = this.container.querySelector('turbo-frame')\n if (frame?.children.length === 0 && this.container.matches(':popover-open')) {\n this.container.hidePopover?.()\n }\n this.container = null\n }\n }\n\n close () {\n this.element.classList.add('closing')\n setTimeout(() => (this.element.parentElement ?? this.element).remove(), 350)\n }\n\n private syncCountdown (): void {\n const timerEl = this.element.querySelector<HTMLElement>('[data-controller~=\"midwest-countdown-timer\"]')\n if (!timerEl) return\n\n const timer = this.application.getControllerForElementAndIdentifier(\n timerEl, 'midwest-countdown-timer'\n ) as PausableTimer | null\n if (!timer) return\n\n // Position is measured on the motion wrapper (the direct turbo-frame child),\n // not on this.element which is always the sole child of its wrapper.\n const wrapper = this.element.parentElement ?? this.element\n const isTop = wrapper === wrapper.parentElement?.firstElementChild\n if (isTop) { timer.resume() } else { timer.pause() }\n }\n}\n"],"names":[],"mappings":";;AASA,MAAqB,qBAAqB,UAAwB,CAAA;AAAA,EACxD,SAAmC,GAAA,IAAA,CAAA;AAAA,EACnC,QAAoC,GAAA,IAAA,CAAA;AAAA,EAE5C,OAAW,GAAA;AACT,IAAA,IAAA,CAAK,SAAY,GAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,CAAwB,WAAW,CAAA,CAAA;AACjE,IAAA,IAAA,CAAK,WAAW,WAAc,IAAA,CAAA;AAE9B,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,CAAQ,aAAa,CAAA,CAAA;AAChD,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,IAAA,CAAK,WAAW,IAAI,gBAAA,CAAiB,MAAM,IAAA,CAAK,eAAe,CAAA,CAAA;AAC/D,MAAA,IAAA,CAAK,SAAS,OAAQ,CAAA,KAAA,EAAO,EAAE,SAAA,EAAW,MAAM,CAAA,CAAA;AAEhD,MAAW,UAAA,CAAA,MAAM,IAAK,CAAA,aAAA,EAAe,CAAA,CAAA;AAAA,KACvC;AAAA,GACF;AAAA,EAEA,UAAc,GAAA;AACZ,IAAA,IAAA,CAAK,UAAU,UAAW,EAAA,CAAA;AAC1B,IAAA,IAAA,CAAK,QAAW,GAAA,IAAA,CAAA;AAEhB,IAAA,IAAI,KAAK,SAAW,EAAA;AAClB,MAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,SAAU,CAAA,aAAA,CAAc,aAAa,CAAA,CAAA;AACxD,MAAI,IAAA,KAAA,EAAO,SAAS,MAAW,KAAA,CAAA,IAAK,KAAK,SAAU,CAAA,OAAA,CAAQ,eAAe,CAAG,EAAA;AAC3E,QAAA,IAAA,CAAK,UAAU,WAAc,IAAA,CAAA;AAAA,OAC/B;AACA,MAAA,IAAA,CAAK,SAAY,GAAA,IAAA,CAAA;AAAA,KACnB;AAAA,GACF;AAAA,EAEA,KAAS,GAAA;AACP,IAAK,IAAA,CAAA,OAAA,CAAQ,SAAU,CAAA,GAAA,CAAI,SAAS,CAAA,CAAA;AACpC,IAAW,UAAA,CAAA,MAAA,CAAO,KAAK,OAAQ,CAAA,aAAA,IAAiB,KAAK,OAAS,EAAA,MAAA,IAAU,GAAG,CAAA,CAAA;AAAA,GAC7E;AAAA,EAEQ,aAAuB,GAAA;AAC7B,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,OAAQ,CAAA,aAAA,CAA2B,8CAA8C,CAAA,CAAA;AACtG,IAAA,IAAI,CAAC,OAAA;AAAS,MAAA,OAAA;AAEd,IAAM,MAAA,KAAA,GAAQ,KAAK,WAAY,CAAA,oCAAA;AAAA,MAC7B,OAAA;AAAA,MAAS,yBAAA;AAAA,KACX,CAAA;AACA,IAAA,IAAI,CAAC,KAAA;AAAO,MAAA,OAAA;AAIZ,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,OAAQ,CAAA,aAAA,IAAiB,IAAK,CAAA,OAAA,CAAA;AACnD,IAAM,MAAA,KAAA,GAAQ,OAAY,KAAA,OAAA,CAAQ,aAAe,EAAA,iBAAA,CAAA;AACjD,IAAA,IAAI,KAAO,EAAA;AAAE,MAAA,KAAA,CAAM,MAAO,EAAA,CAAA;AAAA,KAAS,MAAA;AAAE,MAAA,KAAA,CAAM,KAAM,EAAA,CAAA;AAAA,KAAE;AAAA,GACrD;AACF;;;;"}
|
|
@@ -10,14 +10,14 @@ const FOCUSABLE = [
|
|
|
10
10
|
].join(", ");
|
|
11
11
|
const GAP = 12;
|
|
12
12
|
class Onboarding extends Controller {
|
|
13
|
-
static targets = ["step", "overlay", "card", "title", "body", "back", "next", "done", "arrow"];
|
|
13
|
+
static targets = ["step", "overlay", "card", "title", "body", "back", "next", "done", "arrow", "motion"];
|
|
14
14
|
static values = {
|
|
15
|
-
autoOpen: { type: Boolean, default: false }
|
|
16
|
-
confirm: { type: String, default: "" }
|
|
15
|
+
autoOpen: { type: Boolean, default: false }
|
|
17
16
|
};
|
|
18
17
|
steps = [];
|
|
19
18
|
index = 0;
|
|
20
19
|
active = false;
|
|
20
|
+
justOpened = false;
|
|
21
21
|
previousFocus = null;
|
|
22
22
|
highlighted = null;
|
|
23
23
|
connect() {
|
|
@@ -47,6 +47,7 @@ class Onboarding extends Controller {
|
|
|
47
47
|
this.previousFocus = document.activeElement;
|
|
48
48
|
this.overlayTarget.hidden = false;
|
|
49
49
|
this.cardTarget.hidden = false;
|
|
50
|
+
this.justOpened = true;
|
|
50
51
|
document.addEventListener("keydown", this.handleKeydown, true);
|
|
51
52
|
window.addEventListener("resize", this.reposition);
|
|
52
53
|
window.addEventListener("scroll", this.reposition, true);
|
|
@@ -81,14 +82,14 @@ class Onboarding extends Controller {
|
|
|
81
82
|
cancel() {
|
|
82
83
|
if (!this.active)
|
|
83
84
|
return;
|
|
84
|
-
if (this.confirmValue && !window.confirm(this.confirmValue))
|
|
85
|
-
return;
|
|
86
85
|
this.teardown();
|
|
87
86
|
this.dispatch("cancel", { bubbles: true });
|
|
88
87
|
}
|
|
89
88
|
render(index) {
|
|
90
89
|
this.index = index;
|
|
91
90
|
const step = this.steps[index];
|
|
91
|
+
const replay = !this.justOpened;
|
|
92
|
+
this.justOpened = false;
|
|
92
93
|
this.clearHighlight();
|
|
93
94
|
this.titleTarget.textContent = step.title;
|
|
94
95
|
this.renderBody(step);
|
|
@@ -100,6 +101,9 @@ class Onboarding extends Controller {
|
|
|
100
101
|
} else {
|
|
101
102
|
this.center();
|
|
102
103
|
}
|
|
104
|
+
if (replay && this.hasMotionTarget) {
|
|
105
|
+
this.replayMotion(this.cardTarget.dataset.placement ?? "center");
|
|
106
|
+
}
|
|
103
107
|
this.dispatch("show", { detail: { index, name: step.name }, bubbles: true });
|
|
104
108
|
this.focusCard();
|
|
105
109
|
}
|
|
@@ -201,9 +205,34 @@ class Onboarding extends Controller {
|
|
|
201
205
|
this.cardTarget.focus();
|
|
202
206
|
});
|
|
203
207
|
}
|
|
208
|
+
// Re-triggers the midwest_motion @starting-style entry on step transitions.
|
|
209
|
+
// The initial show is handled by @starting-style firing when the card's
|
|
210
|
+
// `hidden` is removed; subsequent steps need an explicit re-trigger since the
|
|
211
|
+
// card stays in the DOM. Toggling `hidden` on the motion element triggers
|
|
212
|
+
// @starting-style again; the rAF ensures both DOM writes land in the same
|
|
213
|
+
// paint so there is no blank-card flash.
|
|
214
|
+
replayMotion(placement) {
|
|
215
|
+
const el = this.motionTarget;
|
|
216
|
+
const dir = { bottom: "up", top: "down", right: "left", left: "right" };
|
|
217
|
+
el.classList.remove("from-up", "from-down", "from-left", "from-right");
|
|
218
|
+
const from = dir[placement];
|
|
219
|
+
if (from)
|
|
220
|
+
el.classList.add(`from-${from}`);
|
|
221
|
+
el.hidden = true;
|
|
222
|
+
requestAnimationFrame(() => {
|
|
223
|
+
if (this.active)
|
|
224
|
+
el.hidden = false;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
204
227
|
teardown() {
|
|
205
228
|
this.active = false;
|
|
206
229
|
this.clearHighlight();
|
|
230
|
+
this.element.querySelectorAll("[popover]").forEach((el) => {
|
|
231
|
+
try {
|
|
232
|
+
el.hidePopover();
|
|
233
|
+
} catch {
|
|
234
|
+
}
|
|
235
|
+
});
|
|
207
236
|
this.overlayTarget.hidden = true;
|
|
208
237
|
this.cardTarget.hidden = true;
|
|
209
238
|
document.removeEventListener("keydown", this.handleKeydown, true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding_component_controller.js","sources":["../../../../../../../app/components/midwest/onboarding_component/onboarding_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])'\n].join(', ')\n\nconst GAP = 12 // px between the target and the card\n\ninterface StepConfig {\n el: HTMLElement\n name: string\n selector: string\n position: string\n title: string\n nextText: string\n backText: string\n completeText: string\n canClickTarget: boolean\n}\n\n// Native, dependency-free guided-tour engine. Reads the nested step config\n// carriers, then walks the user through them with a dimmed overlay, a card\n// positioned against each step's target element, and Back/Next/Done buttons.\nexport default class Onboarding extends Controller<HTMLElement> {\n static targets = ['step', 'overlay', 'card', 'title', 'body', 'back', 'next', 'done', 'arrow']\n\n static values = {\n autoOpen: { type: Boolean, default: false },\n confirm: { type: String, default: '' }\n }\n\n declare readonly stepTargets: HTMLElement[]\n declare readonly overlayTarget: HTMLElement\n declare readonly cardTarget: HTMLElement\n declare readonly titleTarget: HTMLElement\n declare readonly bodyTarget: HTMLElement\n declare readonly backTarget: HTMLButtonElement\n declare readonly nextTarget: HTMLButtonElement\n declare readonly doneTarget: HTMLButtonElement\n declare readonly arrowTarget: HTMLElement\n declare autoOpenValue: boolean\n declare confirmValue: string\n\n private steps: StepConfig[] = []\n private index = 0\n private active = false\n private previousFocus: HTMLElement | null = null\n private highlighted: HTMLElement | null = null\n\n connect () {\n this.steps = this.stepTargets.map((el) => ({\n el,\n name: el.dataset.name ?? '',\n selector: el.dataset.selector ?? '',\n position: el.dataset.position ?? 'auto',\n title: el.dataset.title ?? '',\n nextText: el.dataset.nextText ?? 'Next',\n backText: el.dataset.backText ?? 'Back',\n completeText: el.dataset.completeText ?? 'Done',\n canClickTarget: el.dataset.canClickTarget === 'true'\n }))\n\n window.addEventListener('midwest-onboarding:open', this.handleOpen)\n\n if (this.autoOpenValue) this.start()\n }\n\n disconnect () {\n window.removeEventListener('midwest-onboarding:open', this.handleOpen)\n this.teardown()\n }\n\n start () {\n if (this.active || this.steps.length === 0) return\n this.active = true\n this.previousFocus = document.activeElement as HTMLElement | null\n this.overlayTarget.hidden = false\n this.cardTarget.hidden = false\n document.addEventListener('keydown', this.handleKeydown, true)\n window.addEventListener('resize', this.reposition)\n window.addEventListener('scroll', this.reposition, true)\n this.dispatch('start', { bubbles: true })\n this.render(0)\n }\n\n next () {\n if (this.index < this.steps.length - 1) this.render(this.index + 1)\n else this.complete()\n }\n\n back () {\n if (this.index > 0) this.render(this.index - 1)\n }\n\n // Jump to a step by its `name`.\n show (name: string) {\n const target = this.steps.findIndex((step) => step.name === name)\n if (target >= 0) {\n if (!this.active) this.start()\n this.render(target)\n }\n }\n\n complete () {\n if (!this.active) return\n this.teardown()\n this.dispatch('complete', { bubbles: true })\n }\n\n cancel () {\n if (!this.active) return\n if (this.confirmValue && !window.confirm(this.confirmValue)) return\n this.teardown()\n this.dispatch('cancel', { bubbles: true })\n }\n\n private render (index: number) {\n this.index = index\n const step = this.steps[index]\n\n this.clearHighlight()\n\n this.titleTarget.textContent = step.title\n this.renderBody(step)\n this.renderButtons(step, index)\n\n const target = step.selector\n ? document.querySelector<HTMLElement>(step.selector)\n : null\n\n if (target) {\n this.highlight(target, step.canClickTarget)\n this.position(target, step.position)\n } else {\n this.center()\n }\n\n this.dispatch('show', { detail: { index, name: step.name }, bubbles: true })\n this.focusCard()\n }\n\n private renderBody (step: StepConfig) {\n this.bodyTarget.replaceChildren()\n const template = step.el.querySelector('template')\n if (template) this.bodyTarget.appendChild(template.content.cloneNode(true))\n }\n\n private renderButtons (step: StepConfig, index: number) {\n const isFirst = index === 0\n const isLast = index === this.steps.length - 1\n\n // Back keeps its layout box (visibility) so the forward button never shifts;\n // Next and Done are mutually exclusive, so exactly one fills the right slot.\n this.backTarget.textContent = step.backText\n this.backTarget.style.visibility = isFirst ? 'hidden' : ''\n\n // Inline display beats the button's own `display: inline-flex` rule.\n this.nextTarget.textContent = step.nextText\n this.nextTarget.style.display = isLast ? 'none' : ''\n\n this.doneTarget.textContent = step.completeText\n this.doneTarget.style.display = isLast ? '' : 'none'\n }\n\n private highlight (target: HTMLElement, canClickTarget: boolean) {\n target.classList.add('midwest-onboarding-highlight')\n target.classList.toggle('is-locked', !canClickTarget)\n this.highlighted = target\n target.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n\n private clearHighlight () {\n this.highlighted?.classList.remove('midwest-onboarding-highlight', 'is-locked')\n this.highlighted = null\n }\n\n // Places the card against the target, choosing a side when `position` is auto.\n private position (target: HTMLElement, position: string) {\n const rect = target.getBoundingClientRect()\n const card = this.cardTarget.getBoundingClientRect()\n const vw = window.innerWidth\n const vh = window.innerHeight\n\n let placement = position\n if (placement === 'auto') {\n if (rect.bottom + card.height + GAP <= vh) placement = 'bottom'\n else if (rect.top - card.height - GAP >= 0) placement = 'top'\n else if (rect.right + card.width + GAP <= vw) placement = 'right'\n else placement = 'left'\n }\n\n let top: number\n let left: number\n\n switch (placement) {\n case 'top':\n top = rect.top - card.height - GAP\n left = rect.left + rect.width / 2 - card.width / 2\n break\n case 'left':\n top = rect.top + rect.height / 2 - card.height / 2\n left = rect.left - card.width - GAP\n break\n case 'right':\n top = rect.top + rect.height / 2 - card.height / 2\n left = rect.right + GAP\n break\n default: // bottom\n top = rect.bottom + GAP\n left = rect.left + rect.width / 2 - card.width / 2\n break\n }\n\n // Keep the card fully on screen.\n left = Math.max(8, Math.min(left, vw - card.width - 8))\n top = Math.max(8, Math.min(top, vh - card.height - 8))\n\n this.cardTarget.style.top = `${top}px`\n this.cardTarget.style.left = `${left}px`\n this.cardTarget.dataset.placement = placement\n\n this.positionArrow(placement, rect, top, left)\n }\n\n // Nudges the arrow so it points at the target's center, not the card's.\n private positionArrow (placement: string, rect: DOMRect, top: number, left: number) {\n const card = this.cardTarget.getBoundingClientRect()\n const arrow = this.arrowTarget.style\n\n if (placement === 'top' || placement === 'bottom') {\n const targetCenter = rect.left + rect.width / 2\n const offset = Math.max(12, Math.min(targetCenter - left, card.width - 12))\n arrow.left = `${offset}px`\n arrow.top = ''\n } else {\n const targetCenter = rect.top + rect.height / 2\n const offset = Math.max(12, Math.min(targetCenter - top, card.height - 12))\n arrow.top = `${offset}px`\n arrow.left = ''\n }\n }\n\n private center () {\n const card = this.cardTarget.getBoundingClientRect()\n this.cardTarget.style.top = `${Math.max(8, window.innerHeight / 2 - card.height / 2)}px`\n this.cardTarget.style.left = `${Math.max(8, window.innerWidth / 2 - card.width / 2)}px`\n this.cardTarget.dataset.placement = 'center'\n }\n\n private focusCard () {\n requestAnimationFrame(() => {\n if (this.active) this.cardTarget.focus()\n })\n }\n\n private teardown () {\n this.active = false\n this.clearHighlight()\n this.overlayTarget.hidden = true\n this.cardTarget.hidden = true\n document.removeEventListener('keydown', this.handleKeydown, true)\n window.removeEventListener('resize', this.reposition)\n window.removeEventListener('scroll', this.reposition, true)\n this.previousFocus?.focus()\n this.previousFocus = null\n }\n\n private handleOpen = (event: Event) => {\n const detail = (event as CustomEvent).detail ?? {}\n const id = String(detail.id ?? '').replace('#', '')\n if (id === this.element.id) this.start()\n }\n\n private reposition = () => {\n if (!this.active) return\n const step = this.steps[this.index]\n const target = step.selector ? document.querySelector<HTMLElement>(step.selector) : null\n if (target) this.position(target, step.position)\n else this.center()\n }\n\n private handleKeydown = (event: KeyboardEvent) => {\n if (!this.active) return\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n this.cancel()\n break\n case 'ArrowRight':\n event.preventDefault()\n this.next()\n break\n case 'ArrowLeft':\n event.preventDefault()\n this.back()\n break\n case 'Tab':\n this.trapTab(event)\n break\n }\n }\n\n // Keep Tab focus within the card while the tour is active.\n private trapTab (event: KeyboardEvent) {\n const focusable = Array.from(this.cardTarget.querySelectorAll<HTMLElement>(FOCUSABLE))\n .filter((el) => !el.hidden && el.offsetParent !== null && getComputedStyle(el).visibility !== 'hidden')\n if (focusable.length === 0) return\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n const active = document.activeElement\n\n if (event.shiftKey) {\n if (active === first || active === this.cardTarget || !this.cardTarget.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else if (active === last || !this.cardTarget.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onboarding_component_controller.js","sources":["../../../../../../../app/components/midwest/onboarding_component/onboarding_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'textarea:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])'\n].join(', ')\n\nconst GAP = 12 // px between the target and the card\n\ninterface StepConfig {\n el: HTMLElement\n name: string\n selector: string\n position: string\n title: string\n nextText: string\n backText: string\n completeText: string\n canClickTarget: boolean\n}\n\n// Native, dependency-free guided-tour engine. Reads the nested step config\n// carriers, then walks the user through them with a dimmed overlay, a card\n// positioned against each step's target element, and Back/Next/Done buttons.\nexport default class Onboarding extends Controller<HTMLElement> {\n static targets = ['step', 'overlay', 'card', 'title', 'body', 'back', 'next', 'done', 'arrow', 'motion']\n\n static values = {\n autoOpen: { type: Boolean, default: false }\n }\n\n declare readonly stepTargets: HTMLElement[]\n declare readonly overlayTarget: HTMLElement\n declare readonly cardTarget: HTMLElement\n declare readonly titleTarget: HTMLElement\n declare readonly bodyTarget: HTMLElement\n declare readonly backTarget: HTMLButtonElement\n declare readonly nextTarget: HTMLButtonElement\n declare readonly doneTarget: HTMLButtonElement\n declare readonly arrowTarget: HTMLElement\n declare readonly motionTarget: HTMLElement\n declare readonly hasMotionTarget: boolean\n declare autoOpenValue: boolean\n\n private steps: StepConfig[] = []\n private index = 0\n private active = false\n private justOpened = false\n private previousFocus: HTMLElement | null = null\n private highlighted: HTMLElement | null = null\n\n connect () {\n this.steps = this.stepTargets.map((el) => ({\n el,\n name: el.dataset.name ?? '',\n selector: el.dataset.selector ?? '',\n position: el.dataset.position ?? 'auto',\n title: el.dataset.title ?? '',\n nextText: el.dataset.nextText ?? 'Next',\n backText: el.dataset.backText ?? 'Back',\n completeText: el.dataset.completeText ?? 'Done',\n canClickTarget: el.dataset.canClickTarget === 'true'\n }))\n\n window.addEventListener('midwest-onboarding:open', this.handleOpen)\n\n if (this.autoOpenValue) this.start()\n }\n\n disconnect () {\n window.removeEventListener('midwest-onboarding:open', this.handleOpen)\n this.teardown()\n }\n\n start () {\n if (this.active || this.steps.length === 0) return\n this.active = true\n this.previousFocus = document.activeElement as HTMLElement | null\n this.overlayTarget.hidden = false\n this.cardTarget.hidden = false\n this.justOpened = true\n document.addEventListener('keydown', this.handleKeydown, true)\n window.addEventListener('resize', this.reposition)\n window.addEventListener('scroll', this.reposition, true)\n this.dispatch('start', { bubbles: true })\n this.render(0)\n }\n\n next () {\n if (this.index < this.steps.length - 1) this.render(this.index + 1)\n else this.complete()\n }\n\n back () {\n if (this.index > 0) this.render(this.index - 1)\n }\n\n // Jump to a step by its `name`.\n show (name: string) {\n const target = this.steps.findIndex((step) => step.name === name)\n if (target >= 0) {\n if (!this.active) this.start()\n this.render(target)\n }\n }\n\n complete () {\n if (!this.active) return\n this.teardown()\n this.dispatch('complete', { bubbles: true })\n }\n\n cancel () {\n if (!this.active) return\n this.teardown()\n this.dispatch('cancel', { bubbles: true })\n }\n\n private render (index: number) {\n this.index = index\n const step = this.steps[index]\n const replay = !this.justOpened\n this.justOpened = false\n\n this.clearHighlight()\n\n this.titleTarget.textContent = step.title\n this.renderBody(step)\n this.renderButtons(step, index)\n\n const target = step.selector\n ? document.querySelector<HTMLElement>(step.selector)\n : null\n\n if (target) {\n this.highlight(target, step.canClickTarget)\n this.position(target, step.position)\n } else {\n this.center()\n }\n\n if (replay && this.hasMotionTarget) {\n this.replayMotion(this.cardTarget.dataset.placement ?? 'center')\n }\n\n this.dispatch('show', { detail: { index, name: step.name }, bubbles: true })\n this.focusCard()\n }\n\n private renderBody (step: StepConfig) {\n this.bodyTarget.replaceChildren()\n const template = step.el.querySelector('template')\n if (template) this.bodyTarget.appendChild(template.content.cloneNode(true))\n }\n\n private renderButtons (step: StepConfig, index: number) {\n const isFirst = index === 0\n const isLast = index === this.steps.length - 1\n\n // Back keeps its layout box (visibility) so the forward button never shifts;\n // Next and Done are mutually exclusive, so exactly one fills the right slot.\n this.backTarget.textContent = step.backText\n this.backTarget.style.visibility = isFirst ? 'hidden' : ''\n\n // Inline display beats the button's own `display: inline-flex` rule.\n this.nextTarget.textContent = step.nextText\n this.nextTarget.style.display = isLast ? 'none' : ''\n\n this.doneTarget.textContent = step.completeText\n this.doneTarget.style.display = isLast ? '' : 'none'\n }\n\n private highlight (target: HTMLElement, canClickTarget: boolean) {\n target.classList.add('midwest-onboarding-highlight')\n target.classList.toggle('is-locked', !canClickTarget)\n this.highlighted = target\n target.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }\n\n private clearHighlight () {\n this.highlighted?.classList.remove('midwest-onboarding-highlight', 'is-locked')\n this.highlighted = null\n }\n\n // Places the card against the target, choosing a side when `position` is auto.\n private position (target: HTMLElement, position: string) {\n const rect = target.getBoundingClientRect()\n const card = this.cardTarget.getBoundingClientRect()\n const vw = window.innerWidth\n const vh = window.innerHeight\n\n let placement = position\n if (placement === 'auto') {\n if (rect.bottom + card.height + GAP <= vh) placement = 'bottom'\n else if (rect.top - card.height - GAP >= 0) placement = 'top'\n else if (rect.right + card.width + GAP <= vw) placement = 'right'\n else placement = 'left'\n }\n\n let top: number\n let left: number\n\n switch (placement) {\n case 'top':\n top = rect.top - card.height - GAP\n left = rect.left + rect.width / 2 - card.width / 2\n break\n case 'left':\n top = rect.top + rect.height / 2 - card.height / 2\n left = rect.left - card.width - GAP\n break\n case 'right':\n top = rect.top + rect.height / 2 - card.height / 2\n left = rect.right + GAP\n break\n default: // bottom\n top = rect.bottom + GAP\n left = rect.left + rect.width / 2 - card.width / 2\n break\n }\n\n // Keep the card fully on screen.\n left = Math.max(8, Math.min(left, vw - card.width - 8))\n top = Math.max(8, Math.min(top, vh - card.height - 8))\n\n this.cardTarget.style.top = `${top}px`\n this.cardTarget.style.left = `${left}px`\n this.cardTarget.dataset.placement = placement\n\n this.positionArrow(placement, rect, top, left)\n }\n\n // Nudges the arrow so it points at the target's center, not the card's.\n private positionArrow (placement: string, rect: DOMRect, top: number, left: number) {\n const card = this.cardTarget.getBoundingClientRect()\n const arrow = this.arrowTarget.style\n\n if (placement === 'top' || placement === 'bottom') {\n const targetCenter = rect.left + rect.width / 2\n const offset = Math.max(12, Math.min(targetCenter - left, card.width - 12))\n arrow.left = `${offset}px`\n arrow.top = ''\n } else {\n const targetCenter = rect.top + rect.height / 2\n const offset = Math.max(12, Math.min(targetCenter - top, card.height - 12))\n arrow.top = `${offset}px`\n arrow.left = ''\n }\n }\n\n private center () {\n const card = this.cardTarget.getBoundingClientRect()\n this.cardTarget.style.top = `${Math.max(8, window.innerHeight / 2 - card.height / 2)}px`\n this.cardTarget.style.left = `${Math.max(8, window.innerWidth / 2 - card.width / 2)}px`\n this.cardTarget.dataset.placement = 'center'\n }\n\n private focusCard () {\n requestAnimationFrame(() => {\n if (this.active) this.cardTarget.focus()\n })\n }\n\n // Re-triggers the midwest_motion @starting-style entry on step transitions.\n // The initial show is handled by @starting-style firing when the card's\n // `hidden` is removed; subsequent steps need an explicit re-trigger since the\n // card stays in the DOM. Toggling `hidden` on the motion element triggers\n // @starting-style again; the rAF ensures both DOM writes land in the same\n // paint so there is no blank-card flash.\n private replayMotion (placement: string) {\n const el = this.motionTarget\n const dir: Record<string, string> = { bottom: 'up', top: 'down', right: 'left', left: 'right' }\n\n el.classList.remove('from-up', 'from-down', 'from-left', 'from-right')\n const from = dir[placement]\n if (from) el.classList.add(`from-${from}`)\n\n el.hidden = true\n requestAnimationFrame(() => { if (this.active) el.hidden = false })\n }\n\n private teardown () {\n this.active = false\n this.clearHighlight()\n // Close any open confirmation popovers before hiding the card.\n this.element.querySelectorAll<HTMLElement>('[popover]').forEach((el) => {\n try { el.hidePopover() } catch { /* already hidden */ }\n })\n this.overlayTarget.hidden = true\n this.cardTarget.hidden = true\n document.removeEventListener('keydown', this.handleKeydown, true)\n window.removeEventListener('resize', this.reposition)\n window.removeEventListener('scroll', this.reposition, true)\n this.previousFocus?.focus()\n this.previousFocus = null\n }\n\n private handleOpen = (event: Event) => {\n const detail = (event as CustomEvent).detail ?? {}\n const id = String(detail.id ?? '').replace('#', '')\n if (id === this.element.id) this.start()\n }\n\n private reposition = () => {\n if (!this.active) return\n const step = this.steps[this.index]\n const target = step.selector ? document.querySelector<HTMLElement>(step.selector) : null\n if (target) this.position(target, step.position)\n else this.center()\n }\n\n private handleKeydown = (event: KeyboardEvent) => {\n if (!this.active) return\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n this.cancel()\n break\n case 'ArrowRight':\n event.preventDefault()\n this.next()\n break\n case 'ArrowLeft':\n event.preventDefault()\n this.back()\n break\n case 'Tab':\n this.trapTab(event)\n break\n }\n }\n\n // Keep Tab focus within the card while the tour is active.\n private trapTab (event: KeyboardEvent) {\n const focusable = Array.from(this.cardTarget.querySelectorAll<HTMLElement>(FOCUSABLE))\n .filter((el) => !el.hidden && el.offsetParent !== null && getComputedStyle(el).visibility !== 'hidden')\n if (focusable.length === 0) return\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n const active = document.activeElement\n\n if (event.shiftKey) {\n if (active === first || active === this.cardTarget || !this.cardTarget.contains(active)) {\n event.preventDefault()\n last.focus()\n }\n } else if (active === last || !this.cardTarget.contains(active)) {\n event.preventDefault()\n first.focus()\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
|
2
|
+
|
|
3
|
+
class PageTransition extends Controller {
|
|
4
|
+
static values = {
|
|
5
|
+
style: { type: String, default: "fade" },
|
|
6
|
+
duration: { type: String, default: "" },
|
|
7
|
+
easing: { type: String, default: "" }
|
|
8
|
+
};
|
|
9
|
+
injectedMeta = null;
|
|
10
|
+
connect() {
|
|
11
|
+
if (this.styleValue === "none")
|
|
12
|
+
return;
|
|
13
|
+
if (!document.querySelector('meta[name="view-transition"]')) {
|
|
14
|
+
const meta = document.createElement("meta");
|
|
15
|
+
meta.name = "view-transition";
|
|
16
|
+
meta.content = "same-origin";
|
|
17
|
+
document.head.appendChild(meta);
|
|
18
|
+
this.injectedMeta = meta;
|
|
19
|
+
}
|
|
20
|
+
document.documentElement.dataset.midwestPageTransition = this.styleValue;
|
|
21
|
+
if (this.durationValue) {
|
|
22
|
+
document.documentElement.style.setProperty("--page-transition-duration", this.durationValue);
|
|
23
|
+
}
|
|
24
|
+
if (this.easingValue) {
|
|
25
|
+
document.documentElement.style.setProperty("--page-transition-easing", this.easingValue);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
disconnect() {
|
|
29
|
+
this.injectedMeta?.remove();
|
|
30
|
+
this.injectedMeta = null;
|
|
31
|
+
delete document.documentElement.dataset.midwestPageTransition;
|
|
32
|
+
document.documentElement.style.removeProperty("--page-transition-duration");
|
|
33
|
+
document.documentElement.style.removeProperty("--page-transition-easing");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { PageTransition as default };
|
|
38
|
+
//# sourceMappingURL=page_transition_component_controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page_transition_component_controller.js","sources":["../../../../../../../app/components/midwest/page_transition_component/page_transition_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Enables Turbo View Transitions by injecting the <meta name=\"view-transition\">\n// tag that Turbo 8 requires to wrap navigations in document.startViewTransition(),\n// and by writing `data-midwest-page-transition` onto <html> so the CSS keyframe\n// rules scope to the chosen style. Custom duration/easing are pushed as CSS custom\n// properties on <html> so they win over the layer defaults without !important.\n//\n// Values\n// style — transition key, one of:\n// \"fade\" | \"slide-left\" | \"slide-right\" | \"slide-up\" |\n// \"slide-down\" | \"scale\" | \"none\"\n// duration — optional resolved CSS value (e.g. \"var(--duration-fast)\", \"200ms\")\n// easing — optional resolved CSS value (e.g. \"var(--ease-emphasized)\")\nexport default class PageTransition extends Controller<HTMLElement> {\n static values = {\n style: { type: String, default: 'fade' },\n duration: { type: String, default: '' },\n easing: { type: String, default: '' }\n }\n\n declare styleValue: string\n declare durationValue: string\n declare easingValue: string\n\n private injectedMeta: HTMLMetaElement | null = null\n\n connect () {\n // `style: :none` means \"install no transitions at all.\"\n if (this.styleValue === 'none') return\n\n // Inject the Turbo View Transitions meta tag if not already present. We\n // track what we injected so we can remove it precisely on disconnect.\n if (!document.querySelector('meta[name=\"view-transition\"]')) {\n const meta = document.createElement('meta')\n meta.name = 'view-transition'\n meta.content = 'same-origin'\n document.head.appendChild(meta)\n this.injectedMeta = meta\n }\n\n // The CSS uses this attribute to scope ::view-transition-* animations.\n document.documentElement.dataset.midwestPageTransition = this.styleValue\n\n // Per-call timing overrides — win over the layer defaults without !important.\n if (this.durationValue) {\n document.documentElement.style.setProperty('--page-transition-duration', this.durationValue)\n }\n if (this.easingValue) {\n document.documentElement.style.setProperty('--page-transition-easing', this.easingValue)\n }\n }\n\n disconnect () {\n this.injectedMeta?.remove()\n this.injectedMeta = null\n delete document.documentElement.dataset.midwestPageTransition\n document.documentElement.style.removeProperty('--page-transition-duration')\n document.documentElement.style.removeProperty('--page-transition-easing')\n }\n}\n"],"names":[],"mappings":";;AAcA,MAAqB,uBAAuB,UAAwB,CAAA;AAAA,EAClE,OAAO,MAAS,GAAA;AAAA,IACd,KAAO,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,MAAO,EAAA;AAAA,IACvC,QAAU,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IACtC,MAAQ,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,GACtC,CAAA;AAAA,EAMQ,YAAuC,GAAA,IAAA,CAAA;AAAA,EAE/C,OAAW,GAAA;AAET,IAAA,IAAI,KAAK,UAAe,KAAA,MAAA;AAAQ,MAAA,OAAA;AAIhC,IAAA,IAAI,CAAC,QAAA,CAAS,aAAc,CAAA,8BAA8B,CAAG,EAAA;AAC3D,MAAM,MAAA,IAAA,GAAO,QAAS,CAAA,aAAA,CAAc,MAAM,CAAA,CAAA;AAC1C,MAAA,IAAA,CAAK,IAAO,GAAA,iBAAA,CAAA;AACZ,MAAA,IAAA,CAAK,OAAU,GAAA,aAAA,CAAA;AACf,MAAS,QAAA,CAAA,IAAA,CAAK,YAAY,IAAI,CAAA,CAAA;AAC9B,MAAA,IAAA,CAAK,YAAe,GAAA,IAAA,CAAA;AAAA,KACtB;AAGA,IAAS,QAAA,CAAA,eAAA,CAAgB,OAAQ,CAAA,qBAAA,GAAwB,IAAK,CAAA,UAAA,CAAA;AAG9D,IAAA,IAAI,KAAK,aAAe,EAAA;AACtB,MAAA,QAAA,CAAS,eAAgB,CAAA,KAAA,CAAM,WAAY,CAAA,4BAAA,EAA8B,KAAK,aAAa,CAAA,CAAA;AAAA,KAC7F;AACA,IAAA,IAAI,KAAK,WAAa,EAAA;AACpB,MAAA,QAAA,CAAS,eAAgB,CAAA,KAAA,CAAM,WAAY,CAAA,0BAAA,EAA4B,KAAK,WAAW,CAAA,CAAA;AAAA,KACzF;AAAA,GACF;AAAA,EAEA,UAAc,GAAA;AACZ,IAAA,IAAA,CAAK,cAAc,MAAO,EAAA,CAAA;AAC1B,IAAA,IAAA,CAAK,YAAe,GAAA,IAAA,CAAA;AACpB,IAAO,OAAA,QAAA,CAAS,gBAAgB,OAAQ,CAAA,qBAAA,CAAA;AACxC,IAAS,QAAA,CAAA,eAAA,CAAgB,KAAM,CAAA,cAAA,CAAe,4BAA4B,CAAA,CAAA;AAC1E,IAAS,QAAA,CAAA,eAAA,CAAgB,KAAM,CAAA,cAAA,CAAe,0BAA0B,CAAA,CAAA;AAAA,GAC1E;AACF;;;;"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
|
2
|
+
|
|
3
|
+
class Popover extends Controller {
|
|
4
|
+
animating = false;
|
|
5
|
+
closeTimer = null;
|
|
6
|
+
connect() {
|
|
7
|
+
this.element.addEventListener("beforetoggle", this.onBeforeToggle);
|
|
8
|
+
}
|
|
9
|
+
disconnect() {
|
|
10
|
+
this.element.removeEventListener("beforetoggle", this.onBeforeToggle);
|
|
11
|
+
this.cleanUp();
|
|
12
|
+
}
|
|
13
|
+
onBeforeToggle = (event) => {
|
|
14
|
+
const toggle = event;
|
|
15
|
+
if (toggle.newState === "open") {
|
|
16
|
+
if (this.closeTimer) {
|
|
17
|
+
clearTimeout(this.closeTimer);
|
|
18
|
+
this.closeTimer = null;
|
|
19
|
+
}
|
|
20
|
+
this.element.classList.remove("is-closing");
|
|
21
|
+
this.animating = false;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (toggle.newState !== "closed")
|
|
25
|
+
return;
|
|
26
|
+
if (window.matchMedia("(width < 700px)").matches)
|
|
27
|
+
return;
|
|
28
|
+
if (!this.element.classList.contains("midwest-motion"))
|
|
29
|
+
return;
|
|
30
|
+
if (this.animating)
|
|
31
|
+
return;
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
this.animating = true;
|
|
34
|
+
this.element.classList.add("is-closing");
|
|
35
|
+
this.closeTimer = setTimeout(() => {
|
|
36
|
+
this.closeTimer = null;
|
|
37
|
+
this.element.style.display = "none";
|
|
38
|
+
this.element.style.transition = "none";
|
|
39
|
+
this.element.hidePopover();
|
|
40
|
+
this.animating = false;
|
|
41
|
+
requestAnimationFrame(() => {
|
|
42
|
+
this.element.style.removeProperty("display");
|
|
43
|
+
this.element.style.removeProperty("transition");
|
|
44
|
+
this.element.classList.remove("is-closing");
|
|
45
|
+
});
|
|
46
|
+
}, this.exitDuration());
|
|
47
|
+
};
|
|
48
|
+
cleanUp() {
|
|
49
|
+
if (this.closeTimer) {
|
|
50
|
+
clearTimeout(this.closeTimer);
|
|
51
|
+
this.closeTimer = null;
|
|
52
|
+
}
|
|
53
|
+
this.element.classList.remove("is-closing");
|
|
54
|
+
this.element.style.removeProperty("transition");
|
|
55
|
+
this.animating = false;
|
|
56
|
+
}
|
|
57
|
+
exitDuration() {
|
|
58
|
+
const durations = getComputedStyle(this.element).transitionDuration.split(",").map((s) => {
|
|
59
|
+
const n = parseFloat(s);
|
|
60
|
+
return s.trim().endsWith("ms") ? n : n * 1e3;
|
|
61
|
+
});
|
|
62
|
+
return Math.max(0, ...durations);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { Popover as default };
|
|
67
|
+
//# sourceMappingURL=popover_component_controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popover_component_controller.js","sources":["../../../../../../../app/components/midwest/popover_component/popover_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Plays the motion exit animation *before* the native popover close fires.\n// Without this, Chromium recalculates `position-try-fallbacks` the moment\n// `:popover-open` is removed, which jumps the popover to a different anchor\n// position while it is still visible. By deferring the actual close until after\n// the animation, the recalculation happens while the element is already\n// transparent — invisible to the user.\nexport default class Popover extends Controller<HTMLElement> {\n private animating = false\n private closeTimer: ReturnType<typeof setTimeout> | null = null\n\n connect () {\n this.element.addEventListener('beforetoggle', this.onBeforeToggle)\n }\n\n disconnect () {\n this.element.removeEventListener('beforetoggle', this.onBeforeToggle)\n this.cleanUp()\n }\n\n private onBeforeToggle = (event: Event) => {\n const toggle = event as ToggleEvent\n\n // If the popover reopens during the exit animation, cancel it cleanly.\n if (toggle.newState === 'open') {\n if (this.closeTimer) { clearTimeout(this.closeTimer); this.closeTimer = null }\n this.element.classList.remove('is-closing')\n this.animating = false\n return\n }\n\n if (toggle.newState !== 'closed') return\n // Anchor positioning is only active on desktop.\n if (window.matchMedia('(width < 700px)').matches) return\n // Only intercept motion-driven popovers; non-motion close is instant so there\n // is no visible jump to fix.\n if (!this.element.classList.contains('midwest-motion')) return\n // We are the one calling hidePopover() after the animation — let it through.\n if (this.animating) return\n\n event.preventDefault()\n this.animating = true\n this.element.classList.add('is-closing')\n\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null\n // Set display:none *before* hidePopover() so that when :popover-open is\n // removed and position-try-fallbacks recalculates, the element is already\n // out of the rendering tree — the recalculated position is never painted.\n this.element.style.display = 'none'\n this.element.style.transition = 'none'\n this.element.hidePopover()\n this.animating = false\n requestAnimationFrame(() => {\n this.element.style.removeProperty('display')\n this.element.style.removeProperty('transition')\n this.element.classList.remove('is-closing')\n })\n }, this.exitDuration())\n }\n\n private cleanUp () {\n if (this.closeTimer) { clearTimeout(this.closeTimer); this.closeTimer = null }\n this.element.classList.remove('is-closing')\n this.element.style.removeProperty('transition')\n this.animating = false\n }\n\n private exitDuration (): number {\n const durations = getComputedStyle(this.element)\n .transitionDuration.split(',')\n .map((s) => {\n const n = parseFloat(s)\n return s.trim().endsWith('ms') ? n : n * 1000\n })\n return Math.max(0, ...durations)\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/javascript/collection/app/components/midwest/table_component/load_more_controller.js
CHANGED
|
@@ -1,35 +1,31 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus';
|
|
2
|
+
import { observeViewport } from '../../../assets/javascript/midwest/viewport_observer.js';
|
|
2
3
|
|
|
3
4
|
class LoadMore extends Controller {
|
|
4
5
|
static values = {
|
|
5
6
|
url: String,
|
|
6
7
|
tbodyId: String
|
|
7
8
|
};
|
|
8
|
-
|
|
9
|
+
teardown = null;
|
|
9
10
|
loading = false;
|
|
10
11
|
connect() {
|
|
11
12
|
if (!this.urlValue)
|
|
12
13
|
return;
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// Start fetching 300px before the sentinel enters the viewport so rows
|
|
19
|
-
// appear before the user actually reaches the bottom.
|
|
20
|
-
{ rootMargin: "0px 0px 300px 0px" }
|
|
21
|
-
);
|
|
22
|
-
this.observer.observe(this.element);
|
|
14
|
+
this.teardown = observeViewport(this.element, {
|
|
15
|
+
rootMargin: "0px 0px 300px 0px",
|
|
16
|
+
once: true,
|
|
17
|
+
onEnter: () => this.load()
|
|
18
|
+
});
|
|
23
19
|
}
|
|
24
20
|
disconnect() {
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
21
|
+
this.teardown?.();
|
|
22
|
+
this.teardown = null;
|
|
27
23
|
}
|
|
28
24
|
async load() {
|
|
29
25
|
if (this.loading)
|
|
30
26
|
return;
|
|
31
27
|
this.loading = true;
|
|
32
|
-
this.
|
|
28
|
+
this.teardown?.();
|
|
33
29
|
try {
|
|
34
30
|
const response = await fetch(this.urlValue, {
|
|
35
31
|
headers: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load_more_controller.js","sources":["../../../../../../../app/components/midwest/table_component/load_more_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Enables infinite scroll on a `midwest-table` by observing a sentinel <tr>\n// element at the bottom of the tbody. When the sentinel scrolls near the\n// viewport, this controller fetches the next-page URL, extracts the new <tr>\n// elements from the returned HTML, and appends them (plus the new sentinel,\n// if present) to the current tbody — replacing itself in the process.\n//\n// Values\n// url — URL for the next page (built by TablePresenter#next_page_url)\n// tbodyId — DOM id of the <tbody> to append rows into\nexport default class LoadMore extends Controller<HTMLTableRowElement> {\n static values = {\n url: String,\n tbodyId: String,\n }\n\n declare urlValue: string\n declare tbodyIdValue: string\n\n private
|
|
1
|
+
{"version":3,"file":"load_more_controller.js","sources":["../../../../../../../app/components/midwest/table_component/load_more_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\nimport { observeViewport } from '../../../assets/javascript/midwest/viewport_observer'\n\n// Enables infinite scroll on a `midwest-table` by observing a sentinel <tr>\n// element at the bottom of the tbody. When the sentinel scrolls near the\n// viewport, this controller fetches the next-page URL, extracts the new <tr>\n// elements from the returned HTML, and appends them (plus the new sentinel,\n// if present) to the current tbody — replacing itself in the process.\n//\n// Values\n// url — URL for the next page (built by TablePresenter#next_page_url)\n// tbodyId — DOM id of the <tbody> to append rows into\nexport default class LoadMore extends Controller<HTMLTableRowElement> {\n static values = {\n url: String,\n tbodyId: String,\n }\n\n declare urlValue: string\n declare tbodyIdValue: string\n\n private teardown: (() => void) | null = null\n private loading = false\n\n connect () {\n // No URL means this is the last page — nothing to load.\n if (!this.urlValue) return\n\n // The sentinel loads exactly once, then removes itself and is replaced by\n // the next page's sentinel — so `once` matches the lifecycle. `rootMargin`\n // starts the fetch 300px early so rows appear before the user hits bottom.\n this.teardown = observeViewport(this.element, {\n rootMargin: '0px 0px 300px 0px',\n once: true,\n onEnter: () => this.load(),\n })\n }\n\n disconnect () {\n this.teardown?.()\n this.teardown = null\n }\n\n private async load () {\n if (this.loading) return\n this.loading = true\n this.teardown?.()\n\n try {\n const response = await fetch(this.urlValue, {\n headers: {\n Accept: 'text/html',\n 'X-Requested-With': 'XMLHttpRequest',\n },\n credentials: 'same-origin',\n })\n\n if (!response.ok) return\n\n const html = await response.text()\n const doc = new DOMParser().parseFromString(html, 'text/html')\n const tbody = document.getElementById(this.tbodyIdValue)\n const newRows = Array.from(\n doc.querySelectorAll<HTMLTableRowElement>('.midwest-table-body tr')\n )\n\n if (!tbody || newRows.length === 0) return\n\n // Remove the current sentinel before appending new rows so its position\n // doesn't shift the table layout during the DOM update.\n this.element.remove()\n\n // Import each row (including any new sentinel for the next page) into the\n // current document and append it to the live tbody.\n newRows.forEach(row => tbody.appendChild(document.importNode(row, true)))\n } catch {\n // Silently fail — the table remains fully functional, just without\n // auto-loading more rows.\n this.loading = false\n }\n }\n}\n"],"names":[],"mappings":";;;AAYA,MAAqB,iBAAiB,UAAgC,CAAA;AAAA,EACpE,OAAO,MAAS,GAAA;AAAA,IACd,GAAS,EAAA,MAAA;AAAA,IACT,OAAS,EAAA,MAAA;AAAA,GACX,CAAA;AAAA,EAKQ,QAAgC,GAAA,IAAA,CAAA;AAAA,EAChC,OAAU,GAAA,KAAA,CAAA;AAAA,EAElB,OAAW,GAAA;AAET,IAAA,IAAI,CAAC,IAAK,CAAA,QAAA;AAAU,MAAA,OAAA;AAKpB,IAAK,IAAA,CAAA,QAAA,GAAW,eAAgB,CAAA,IAAA,CAAK,OAAS,EAAA;AAAA,MAC5C,UAAY,EAAA,mBAAA;AAAA,MACZ,IAAM,EAAA,IAAA;AAAA,MACN,OAAA,EAAS,MAAM,IAAA,CAAK,IAAK,EAAA;AAAA,KAC1B,CAAA,CAAA;AAAA,GACH;AAAA,EAEA,UAAc,GAAA;AACZ,IAAA,IAAA,CAAK,QAAW,IAAA,CAAA;AAChB,IAAA,IAAA,CAAK,QAAW,GAAA,IAAA,CAAA;AAAA,GAClB;AAAA,EAEA,MAAc,IAAQ,GAAA;AACpB,IAAA,IAAI,IAAK,CAAA,OAAA;AAAS,MAAA,OAAA;AAClB,IAAA,IAAA,CAAK,OAAU,GAAA,IAAA,CAAA;AACf,IAAA,IAAA,CAAK,QAAW,IAAA,CAAA;AAEhB,IAAI,IAAA;AACF,MAAA,MAAM,QAAW,GAAA,MAAM,KAAM,CAAA,IAAA,CAAK,QAAU,EAAA;AAAA,QAC1C,OAAS,EAAA;AAAA,UACP,MAAmB,EAAA,WAAA;AAAA,UACnB,kBAAoB,EAAA,gBAAA;AAAA,SACtB;AAAA,QACA,WAAa,EAAA,aAAA;AAAA,OACd,CAAA,CAAA;AAED,MAAA,IAAI,CAAC,QAAS,CAAA,EAAA;AAAI,QAAA,OAAA;AAElB,MAAM,MAAA,IAAA,GAAU,MAAM,QAAA,CAAS,IAAK,EAAA,CAAA;AACpC,MAAA,MAAM,MAAU,IAAI,SAAA,EAAY,CAAA,eAAA,CAAgB,MAAM,WAAW,CAAA,CAAA;AACjE,MAAA,MAAM,KAAU,GAAA,QAAA,CAAS,cAAe,CAAA,IAAA,CAAK,YAAY,CAAA,CAAA;AACzD,MAAA,MAAM,UAAU,KAAM,CAAA,IAAA;AAAA,QACpB,GAAA,CAAI,iBAAsC,wBAAwB,CAAA;AAAA,OACpE,CAAA;AAEA,MAAI,IAAA,CAAC,KAAS,IAAA,OAAA,CAAQ,MAAW,KAAA,CAAA;AAAG,QAAA,OAAA;AAIpC,MAAA,IAAA,CAAK,QAAQ,MAAO,EAAA,CAAA;AAIpB,MAAQ,OAAA,CAAA,OAAA,CAAQ,SAAO,KAAM,CAAA,WAAA,CAAY,SAAS,UAAW,CAAA,GAAA,EAAK,IAAI,CAAC,CAAC,CAAA,CAAA;AAAA,KACxE,CAAA,MAAA;AAGA,MAAA,IAAA,CAAK,OAAU,GAAA,KAAA,CAAA;AAAA,KACjB;AAAA,GACF;AACF;;;;"}
|