@unabridged/midwest 0.11.0 → 0.12.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/app/assets/javascript/midwest/index.ts +6 -0
- package/app/assets/javascript/midwest.js +118 -2
- package/app/assets/javascript/midwest.js.map +1 -1
- package/app/assets/stylesheets/midwest.css +1 -1
- package/app/assets/stylesheets/midwest.tailwind.css +6 -1
- package/dist/css/midwest.css +1 -1
- package/dist/javascript/collection/app/assets/javascript/midwest/index.js +6 -0
- package/dist/javascript/collection/app/assets/javascript/midwest/index.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/accordion_component/accordion_component_controller.js +30 -0
- package/dist/javascript/collection/app/components/midwest/accordion_component/accordion_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/avatar_group_component/avatar_group_component_controller.js +20 -0
- package/dist/javascript/collection/app/components/midwest/avatar_group_component/avatar_group_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/badge_component/badge_component_controller.js +10 -0
- package/dist/javascript/collection/app/components/midwest/badge_component/badge_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/carousel_component/carousel_component_controller.js +58 -1
- package/dist/javascript/collection/app/components/midwest/carousel_component/carousel_component_controller.js.map +1 -1
- package/dist/javascript/collection/app/components/midwest/confirmation_component/confirmation_component_controller.js +22 -0
- package/dist/javascript/collection/app/components/midwest/confirmation_component/confirmation_component_controller.js.map +1 -0
- package/dist/javascript/collection/app/components/midwest/tooltip_component/tooltip_component_controller.js +17 -1
- package/dist/javascript/collection/app/components/midwest/tooltip_component/tooltip_component_controller.js.map +1 -1
- package/dist/javascript/midwest.js +118 -2
- package/dist/javascript/midwest.js.map +1 -1
- package/package.json +1 -1
|
@@ -14,6 +14,9 @@ import FormLiveSummary from '../../../components/midwest/form/live_summary_compo
|
|
|
14
14
|
import Form from '../../../components/midwest/form/form_controller.js';
|
|
15
15
|
import CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller.js';
|
|
16
16
|
export { default as CountdownTimer } from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller.js';
|
|
17
|
+
import Badge from '../../../components/midwest/badge_component/badge_component_controller.js';
|
|
18
|
+
import ConfirmationController from '../../../components/midwest/confirmation_component/confirmation_component_controller.js';
|
|
19
|
+
import AvatarGroup from '../../../components/midwest/avatar_group_component/avatar_group_component_controller.js';
|
|
17
20
|
|
|
18
21
|
function registerMidwestControllers(application) {
|
|
19
22
|
application.register("midwest-card", Card);
|
|
@@ -29,6 +32,9 @@ function registerMidwestControllers(application) {
|
|
|
29
32
|
application.register("midwest-carousel", Carousel);
|
|
30
33
|
application.register("midwest-form-live-summary", FormLiveSummary);
|
|
31
34
|
application.register("midwest-form", Form);
|
|
35
|
+
application.register("midwest-badge", Badge);
|
|
36
|
+
application.register("midwest-confirmation", ConfirmationController);
|
|
37
|
+
application.register("midwest-avatar-group", AvatarGroup);
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
export { registerMidwestControllers };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../../app/assets/javascript/midwest/index.ts"],"sourcesContent":["import Card from '../../../components/midwest/card_component/card_component_controller'\nimport Banner from '../../../components/midwest/banner_component/banner_component_controller'\nimport Input from '../../../components/midwest/form/input_component/input_component_controller'\nimport File from '../../../components/midwest/form/file_component/file_component_controller'\nimport Dropdown from '../../../components/midwest/dropdown_component/dropdown_component_controller'\nimport Prose from '../../../components/midwest/prose_component/prose_component_controller'\nimport Dialog from '../../../components/midwest/dialog_component/dialog_component_controller'\nimport Tabs from '../../../components/midwest/tabs_component/tabs_component_controller'\nimport Tooltip from '../../../components/midwest/tooltip_component/tooltip_component_controller'\nimport Carousel from '../../../components/midwest/carousel_component/carousel_component_controller'\nimport FormLiveSummary from '../../../components/midwest/form/live_summary_component/live_summary_component_controller'\nimport Form from '../../../components/midwest/form/form_controller'\nimport CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer }\n\nexport function registerMidwestControllers (application: any) {\n application.register('midwest-card', Card)\n application.register('midwest-banner', Banner)\n application.register('midwest-countdown-timer', CountdownTimer)\n application.register('midwest-input', Input)\n application.register('midwest-file', File)\n application.register('midwest-dropdown', Dropdown)\n application.register('midwest-prose', Prose)\n application.register('midwest-dialog', Dialog)\n application.register('midwest-tabs', Tabs)\n application.register('midwest-tooltip', Tooltip)\n application.register('midwest-carousel', Carousel)\n application.register('midwest-form-live-summary', FormLiveSummary)\n application.register('midwest-form', Form)\n /* EXPORTS */\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../../app/assets/javascript/midwest/index.ts"],"sourcesContent":["import Card from '../../../components/midwest/card_component/card_component_controller'\nimport Banner from '../../../components/midwest/banner_component/banner_component_controller'\nimport Input from '../../../components/midwest/form/input_component/input_component_controller'\nimport File from '../../../components/midwest/form/file_component/file_component_controller'\nimport Dropdown from '../../../components/midwest/dropdown_component/dropdown_component_controller'\nimport Prose from '../../../components/midwest/prose_component/prose_component_controller'\nimport Dialog from '../../../components/midwest/dialog_component/dialog_component_controller'\nimport Tabs from '../../../components/midwest/tabs_component/tabs_component_controller'\nimport Tooltip from '../../../components/midwest/tooltip_component/tooltip_component_controller'\nimport Carousel from '../../../components/midwest/carousel_component/carousel_component_controller'\nimport FormLiveSummary from '../../../components/midwest/form/live_summary_component/live_summary_component_controller'\nimport Form from '../../../components/midwest/form/form_controller'\nimport CountdownTimer from '../../../components/midwest/countdown_timer_component/countdown_timer_component_controller'\nimport Badge from '../../../components/midwest/badge_component/badge_component_controller'\nimport Confirmation from '../../../components/midwest/confirmation_component/confirmation_component_controller'\nimport AvatarGroup from '../../../components/midwest/avatar_group_component/avatar_group_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer }\n\nexport function registerMidwestControllers (application: any) {\n application.register('midwest-card', Card)\n application.register('midwest-banner', Banner)\n application.register('midwest-countdown-timer', CountdownTimer)\n application.register('midwest-input', Input)\n application.register('midwest-file', File)\n application.register('midwest-dropdown', Dropdown)\n application.register('midwest-prose', Prose)\n application.register('midwest-dialog', Dialog)\n application.register('midwest-tabs', Tabs)\n application.register('midwest-tooltip', Tooltip)\n application.register('midwest-carousel', Carousel)\n application.register('midwest-form-live-summary', FormLiveSummary)\n application.register('midwest-form', Form)\n application.register('midwest-badge', Badge)\n application.register('midwest-confirmation', Confirmation)\n application.register('midwest-avatar-group', AvatarGroup)\n /* EXPORTS */\n}\n"],"names":["Confirmation"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoBO,SAAS,2BAA4B,WAAkB,EAAA;AAC5D,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,2BAA2B,cAAc,CAAA,CAAA;AAC9D,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,oBAAoB,QAAQ,CAAA,CAAA;AACjD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,kBAAkB,MAAM,CAAA,CAAA;AAC7C,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,mBAAmB,OAAO,CAAA,CAAA;AAC/C,EAAY,WAAA,CAAA,QAAA,CAAS,oBAAoB,QAAQ,CAAA,CAAA;AACjD,EAAY,WAAA,CAAA,QAAA,CAAS,6BAA6B,eAAe,CAAA,CAAA;AACjE,EAAY,WAAA,CAAA,QAAA,CAAS,gBAAgB,IAAI,CAAA,CAAA;AACzC,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwBA,sBAAY,CAAA,CAAA;AACzD,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwB,WAAW,CAAA,CAAA;AAE1D;;;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
|
2
|
+
|
|
3
|
+
class Accordion extends Controller {
|
|
4
|
+
static values = {
|
|
5
|
+
allowMultiple: { type: Boolean, default: false }
|
|
6
|
+
};
|
|
7
|
+
connect() {
|
|
8
|
+
this.element.addEventListener("click", this.handleClick);
|
|
9
|
+
}
|
|
10
|
+
disconnect() {
|
|
11
|
+
this.element.removeEventListener("click", this.handleClick);
|
|
12
|
+
}
|
|
13
|
+
handleClick = (event) => {
|
|
14
|
+
if (this.allowMultipleValue)
|
|
15
|
+
return;
|
|
16
|
+
const summary = event.target.closest("summary");
|
|
17
|
+
if (!summary)
|
|
18
|
+
return;
|
|
19
|
+
const clickedDetails = summary.closest("details");
|
|
20
|
+
if (!clickedDetails || clickedDetails.open)
|
|
21
|
+
return;
|
|
22
|
+
this.element.querySelectorAll("details[open]").forEach((details) => {
|
|
23
|
+
if (details !== clickedDetails)
|
|
24
|
+
details.open = false;
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { Accordion as default };
|
|
30
|
+
//# sourceMappingURL=accordion_component_controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accordion_component_controller.js","sources":["../../../../../../../app/components/midwest/accordion_component/accordion_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class Accordion extends Controller {\n static values = {\n allowMultiple: { type: Boolean, default: false }\n }\n\n declare allowMultipleValue: boolean\n\n connect () {\n this.element.addEventListener('click', this.handleClick)\n }\n\n disconnect () {\n this.element.removeEventListener('click', this.handleClick)\n }\n\n private handleClick = (event: Event) => {\n if (this.allowMultipleValue) return\n\n const summary = (event.target as Element).closest('summary')\n if (!summary) return\n\n const clickedDetails = summary.closest('details') as HTMLDetailsElement\n if (!clickedDetails || clickedDetails.open) return\n\n this.element.querySelectorAll<HTMLDetailsElement>('details[open]').forEach(details => {\n if (details !== clickedDetails) details.open = false\n })\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,kBAAkB,UAAW,CAAA;AAAA,EAChD,OAAO,MAAS,GAAA;AAAA,IACd,aAAe,EAAA,EAAE,IAAM,EAAA,OAAA,EAAS,SAAS,KAAM,EAAA;AAAA,GACjD,CAAA;AAAA,EAIA,OAAW,GAAA;AACT,IAAA,IAAA,CAAK,OAAQ,CAAA,gBAAA,CAAiB,OAAS,EAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAAA,GACzD;AAAA,EAEA,UAAc,GAAA;AACZ,IAAA,IAAA,CAAK,OAAQ,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,WAAW,CAAA,CAAA;AAAA,GAC5D;AAAA,EAEQ,WAAA,GAAc,CAAC,KAAiB,KAAA;AACtC,IAAA,IAAI,IAAK,CAAA,kBAAA;AAAoB,MAAA,OAAA;AAE7B,IAAA,MAAM,OAAW,GAAA,KAAA,CAAM,MAAmB,CAAA,OAAA,CAAQ,SAAS,CAAA,CAAA;AAC3D,IAAA,IAAI,CAAC,OAAA;AAAS,MAAA,OAAA;AAEd,IAAM,MAAA,cAAA,GAAiB,OAAQ,CAAA,OAAA,CAAQ,SAAS,CAAA,CAAA;AAChD,IAAI,IAAA,CAAC,kBAAkB,cAAe,CAAA,IAAA;AAAM,MAAA,OAAA;AAE5C,IAAA,IAAA,CAAK,OAAQ,CAAA,gBAAA,CAAqC,eAAe,CAAA,CAAE,QAAQ,CAAW,OAAA,KAAA;AACpF,MAAA,IAAI,OAAY,KAAA,cAAA;AAAgB,QAAA,OAAA,CAAQ,IAAO,GAAA,KAAA,CAAA;AAAA,KAChD,CAAA,CAAA;AAAA,GACH,CAAA;AACF;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
|
2
|
+
|
|
3
|
+
class AvatarGroup extends Controller {
|
|
4
|
+
static targets = ["overflow", "hidden"];
|
|
5
|
+
expand() {
|
|
6
|
+
this.element.classList.add("is-expanding");
|
|
7
|
+
this.hiddenTargets.forEach((wrapper) => {
|
|
8
|
+
wrapper.classList.add("is-visible");
|
|
9
|
+
});
|
|
10
|
+
if (this.hasOverflowTarget) {
|
|
11
|
+
this.overflowTarget.classList.add("avatar-overflow-hiding");
|
|
12
|
+
this.overflowTarget.addEventListener("transitionend", () => {
|
|
13
|
+
this.overflowTarget.remove();
|
|
14
|
+
}, { once: true });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { AvatarGroup as default };
|
|
20
|
+
//# sourceMappingURL=avatar_group_component_controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar_group_component_controller.js","sources":["../../../../../../../app/components/midwest/avatar_group_component/avatar_group_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class AvatarGroup extends Controller<HTMLElement> {\n static targets = ['overflow', 'hidden']\n\n declare readonly overflowTarget: HTMLElement\n declare readonly hiddenTargets: HTMLElement[]\n declare readonly hasOverflowTarget: boolean\n\n expand () {\n this.element.classList.add('is-expanding')\n\n this.hiddenTargets.forEach(wrapper => {\n wrapper.classList.add('is-visible')\n })\n\n if (this.hasOverflowTarget) {\n this.overflowTarget.classList.add('avatar-overflow-hiding')\n this.overflowTarget.addEventListener('transitionend', () => {\n this.overflowTarget.remove()\n }, { once: true })\n }\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,oBAAoB,UAAwB,CAAA;AAAA,EAC/D,OAAO,OAAA,GAAU,CAAC,UAAA,EAAY,QAAQ,CAAA,CAAA;AAAA,EAMtC,MAAU,GAAA;AACR,IAAK,IAAA,CAAA,OAAA,CAAQ,SAAU,CAAA,GAAA,CAAI,cAAc,CAAA,CAAA;AAEzC,IAAK,IAAA,CAAA,aAAA,CAAc,QAAQ,CAAW,OAAA,KAAA;AACpC,MAAQ,OAAA,CAAA,SAAA,CAAU,IAAI,YAAY,CAAA,CAAA;AAAA,KACnC,CAAA,CAAA;AAED,IAAA,IAAI,KAAK,iBAAmB,EAAA;AAC1B,MAAK,IAAA,CAAA,cAAA,CAAe,SAAU,CAAA,GAAA,CAAI,wBAAwB,CAAA,CAAA;AAC1D,MAAK,IAAA,CAAA,cAAA,CAAe,gBAAiB,CAAA,eAAA,EAAiB,MAAM;AAC1D,QAAA,IAAA,CAAK,eAAe,MAAO,EAAA,CAAA;AAAA,OAC1B,EAAA,EAAE,IAAM,EAAA,IAAA,EAAM,CAAA,CAAA;AAAA,KACnB;AAAA,GACF;AACF;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge_component_controller.js","sources":["../../../../../../../app/components/midwest/badge_component/badge_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class Badge extends Controller {\n remove () {\n this.element.remove()\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,cAAc,UAAW,CAAA;AAAA,EAC5C,MAAU,GAAA;AACR,IAAA,IAAA,CAAK,QAAQ,MAAO,EAAA,CAAA;AAAA,GACtB;AACF;;;;"}
|
|
@@ -12,18 +12,22 @@ const NON_SUBMITTING_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
|
12
12
|
"reset",
|
|
13
13
|
"submit"
|
|
14
14
|
]);
|
|
15
|
+
const FORM_ELEMENT_TAGS = /* @__PURE__ */ new Set(["INPUT", "TEXTAREA", "SELECT"]);
|
|
15
16
|
class Carousel extends Controller {
|
|
16
17
|
static targets = ["track", "prev", "next", "dot"];
|
|
17
18
|
static values = {
|
|
18
|
-
wizard: { type: Boolean, default: false }
|
|
19
|
+
wizard: { type: Boolean, default: false },
|
|
20
|
+
autoplay: { type: Number, default: 0 }
|
|
19
21
|
};
|
|
20
22
|
observer = null;
|
|
21
23
|
_currentIndex = 0;
|
|
22
24
|
_maxUnlocked = 0;
|
|
23
25
|
_lastTouchX = 0;
|
|
26
|
+
_autoplayTimer = null;
|
|
24
27
|
connect() {
|
|
25
28
|
this.setupObserver();
|
|
26
29
|
this.updateNavigation();
|
|
30
|
+
this.element.addEventListener("keydown", this.handleArrowKeys);
|
|
27
31
|
if (this.wizardValue) {
|
|
28
32
|
this.element.addEventListener("keydown", this.handleKeydown);
|
|
29
33
|
this.trackTarget.addEventListener("wheel", this.handleWheel, { passive: false });
|
|
@@ -31,13 +35,22 @@ class Carousel extends Controller {
|
|
|
31
35
|
this.trackTarget.addEventListener("touchmove", this.handleTouchMove, { passive: false });
|
|
32
36
|
this.updateSlideAccessibility();
|
|
33
37
|
}
|
|
38
|
+
if (this.autoplayValue > 0) {
|
|
39
|
+
this.startAutoplay();
|
|
40
|
+
this.element.addEventListener("mouseenter", this.pauseAutoplay);
|
|
41
|
+
this.element.addEventListener("mouseleave", this.resumeAutoplay);
|
|
42
|
+
}
|
|
34
43
|
}
|
|
35
44
|
disconnect() {
|
|
36
45
|
this.observer?.disconnect();
|
|
46
|
+
this.element.removeEventListener("keydown", this.handleArrowKeys);
|
|
37
47
|
this.element.removeEventListener("keydown", this.handleKeydown);
|
|
48
|
+
this.element.removeEventListener("mouseenter", this.pauseAutoplay);
|
|
49
|
+
this.element.removeEventListener("mouseleave", this.resumeAutoplay);
|
|
38
50
|
this.trackTarget.removeEventListener("wheel", this.handleWheel);
|
|
39
51
|
this.trackTarget.removeEventListener("touchstart", this.handleTouchStart);
|
|
40
52
|
this.trackTarget.removeEventListener("touchmove", this.handleTouchMove);
|
|
53
|
+
this.stopAutoplay();
|
|
41
54
|
}
|
|
42
55
|
next() {
|
|
43
56
|
this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: "smooth" });
|
|
@@ -73,6 +86,22 @@ class Carousel extends Controller {
|
|
|
73
86
|
this.updateNavigation();
|
|
74
87
|
}
|
|
75
88
|
// Arrow function so `this` is stable for add/removeEventListener pairing.
|
|
89
|
+
// Handles ArrowLeft/ArrowRight for keyboard slide navigation. Skips form
|
|
90
|
+
// elements so arrow keys continue to work normally inside inputs and selects.
|
|
91
|
+
handleArrowKeys = (event) => {
|
|
92
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
|
|
93
|
+
return;
|
|
94
|
+
const target = event.target;
|
|
95
|
+
if (FORM_ELEMENT_TAGS.has(target.tagName) || target.isContentEditable)
|
|
96
|
+
return;
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
if (event.key === "ArrowLeft") {
|
|
99
|
+
this.previous();
|
|
100
|
+
} else {
|
|
101
|
+
this.next();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
// Arrow function so `this` is stable for add/removeEventListener pairing.
|
|
76
105
|
handleKeydown = (event) => {
|
|
77
106
|
if (event.key !== "Enter")
|
|
78
107
|
return;
|
|
@@ -107,6 +136,34 @@ class Carousel extends Controller {
|
|
|
107
136
|
event.preventDefault();
|
|
108
137
|
}
|
|
109
138
|
};
|
|
139
|
+
pauseAutoplay = () => {
|
|
140
|
+
this.stopAutoplay();
|
|
141
|
+
};
|
|
142
|
+
resumeAutoplay = () => {
|
|
143
|
+
this.startAutoplay();
|
|
144
|
+
};
|
|
145
|
+
startAutoplay() {
|
|
146
|
+
if (this.autoplayValue <= 0 || this._autoplayTimer !== null)
|
|
147
|
+
return;
|
|
148
|
+
this._autoplayTimer = setInterval(() => {
|
|
149
|
+
this.autoplayAdvance();
|
|
150
|
+
}, this.autoplayValue);
|
|
151
|
+
}
|
|
152
|
+
stopAutoplay() {
|
|
153
|
+
if (this._autoplayTimer === null)
|
|
154
|
+
return;
|
|
155
|
+
clearInterval(this._autoplayTimer);
|
|
156
|
+
this._autoplayTimer = null;
|
|
157
|
+
}
|
|
158
|
+
autoplayAdvance() {
|
|
159
|
+
const atEnd = this._currentIndex >= this.slides.length - 1;
|
|
160
|
+
if (atEnd) {
|
|
161
|
+
const firstSlide = this.slides[0];
|
|
162
|
+
firstSlide?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
|
|
163
|
+
} else {
|
|
164
|
+
this.next();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
110
167
|
get slides() {
|
|
111
168
|
return Array.from(this.trackTarget.children);
|
|
112
169
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel_component_controller.js","sources":["../../../../../../../app/components/midwest/carousel_component/carousel_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Input types where pressing Enter in a form does NOT normally submit it.\n// For all other input types, Enter submits — so wizard mode intercepts it.\nconst NON_SUBMITTING_INPUT_TYPES = new Set([\n 'button', 'checkbox', 'color', 'file', 'hidden', 'image', 'radio', 'range', 'reset', 'submit'\n])\n\nexport default class Carousel extends Controller<HTMLElement> {\n static targets = ['track', 'prev', 'next', 'dot']\n static values = {\n wizard: { type: Boolean, default: false }\n }\n\n declare readonly trackTarget: HTMLElement\n declare readonly prevTarget: HTMLButtonElement\n declare readonly nextTarget: HTMLButtonElement\n declare readonly dotTargets: HTMLButtonElement[]\n declare readonly hasPrevTarget: boolean\n declare readonly hasNextTarget: boolean\n declare readonly hasDotTarget: boolean\n declare wizardValue: boolean\n\n private observer: IntersectionObserver | null = null\n private _currentIndex = 0\n private _maxUnlocked = 0\n private _lastTouchX = 0\n\n connect () {\n this.setupObserver()\n this.updateNavigation()\n if (this.wizardValue) {\n this.element.addEventListener('keydown', this.handleKeydown)\n this.trackTarget.addEventListener('wheel', this.handleWheel, { passive: false })\n this.trackTarget.addEventListener('touchstart', this.handleTouchStart, { passive: true })\n this.trackTarget.addEventListener('touchmove', this.handleTouchMove, { passive: false })\n this.updateSlideAccessibility()\n }\n }\n\n disconnect () {\n this.observer?.disconnect()\n this.element.removeEventListener('keydown', this.handleKeydown)\n this.trackTarget.removeEventListener('wheel', this.handleWheel)\n this.trackTarget.removeEventListener('touchstart', this.handleTouchStart)\n this.trackTarget.removeEventListener('touchmove', this.handleTouchMove)\n }\n\n next () {\n this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: 'smooth' })\n }\n\n previous () {\n this.trackTarget.scrollBy({ left: -this.trackTarget.clientWidth, behavior: 'smooth' })\n }\n\n goto (event: Event) {\n const button = event.currentTarget as HTMLButtonElement\n const index = parseInt(button.dataset.index ?? '0', 10)\n const slide = this.slides[index]\n slide?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })\n }\n\n // Unlocks the next slide and advances to it. Intended for wizard mode: wire\n // a \"Continue\" button inside a slide to this action so users progress\n // linearly through steps before the carousel nav becomes available.\n //\n // <button type=\"button\" data-action=\"click->midwest-carousel#unlockNext\">\n // Continue\n // </button>\n unlockNext () {\n const nextIndex = this._currentIndex + 1\n if (nextIndex > this._maxUnlocked) {\n this._maxUnlocked = nextIndex\n this.updateSlideAccessibility()\n }\n this.next()\n }\n\n scrolled () {\n if (this.wizardValue) this.clampToFrontier()\n this.updateCurrentIndex()\n this.updateNavigation()\n }\n\n // Arrow function so `this` is stable for add/removeEventListener pairing.\n private handleKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'Enter') return\n\n const target = event.target as HTMLElement\n // Only intercept Enter on text-like inputs; textarea newlines and button\n // activations should pass through untouched.\n if (target.tagName === 'TEXTAREA' || target.tagName !== 'INPUT') return\n if (NON_SUBMITTING_INPUT_TYPES.has((target as HTMLInputElement).type)) return\n\n // On the final step let Enter submit the form normally.\n if (this._currentIndex >= this.slides.length - 1) return\n\n event.preventDefault()\n this.unlockNext()\n }\n\n // Blocks wheel-based horizontal scrolling past the wizard frontier.\n private handleWheel = (event: WheelEvent) => {\n const maxLeft = this._maxUnlocked * this.trackTarget.clientWidth\n if (event.deltaX > 0 && this.trackTarget.scrollLeft >= maxLeft - 2) {\n event.preventDefault()\n }\n }\n\n private handleTouchStart = (event: TouchEvent) => {\n this._lastTouchX = event.touches[0].clientX\n }\n\n // Blocks touch-swipe scrolling past the wizard frontier. Tracks incremental\n // delta per move event so direction is accurate mid-gesture.\n private handleTouchMove = (event: TouchEvent) => {\n const currentX = event.touches[0].clientX\n const delta = currentX - this._lastTouchX // positive = swiping right (going back)\n this._lastTouchX = currentX\n\n const maxLeft = this._maxUnlocked * this.trackTarget.clientWidth\n if (delta < 0 && this.trackTarget.scrollLeft >= maxLeft - 2) {\n event.preventDefault()\n }\n }\n\n private get slides (): HTMLElement[] {\n return Array.from(this.trackTarget.children) as HTMLElement[]\n }\n\n // Snaps scroll position back to the frontier if the user somehow scrolled\n // past it (e.g. momentum after a partially-blocked gesture).\n private clampToFrontier () {\n const maxLeft = this._maxUnlocked * this.trackTarget.clientWidth\n if (this.trackTarget.scrollLeft > maxLeft + 2) {\n this.trackTarget.scrollLeft = maxLeft\n }\n }\n\n // Applies/removes `inert` on each slide based on the wizard frontier,\n // removing locked slides from the tab order and accessibility tree.\n private updateSlideAccessibility () {\n this.slides.forEach((slide, i) => {\n if (i > this._maxUnlocked) {\n slide.setAttribute('inert', '')\n } else {\n slide.removeAttribute('inert')\n }\n })\n }\n\n private updateCurrentIndex () {\n const track = this.trackTarget\n if (track.clientWidth > 0) {\n this._currentIndex = Math.round(track.scrollLeft / track.clientWidth)\n }\n }\n\n private setupObserver () {\n if (!this.hasDotTarget) return\n if (!('IntersectionObserver' in window)) return\n\n this.observer = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n const index = this.slides.indexOf(entry.target as HTMLElement)\n if (index >= 0) {\n const dot = this.dotTargets[index]\n if (!dot) return\n dot.classList.toggle('active', entry.isIntersecting)\n if (entry.isIntersecting) {\n dot.setAttribute('aria-current', 'true')\n } else {\n dot.removeAttribute('aria-current')\n }\n }\n })\n },\n { root: this.trackTarget, threshold: 0.5 }\n )\n\n this.slides.forEach(slide => this.observer?.observe(slide))\n }\n\n private updateNavigation () {\n const track = this.trackTarget\n const atStart = track.scrollLeft <= 0\n const atEnd = track.scrollLeft >= track.scrollWidth - track.clientWidth - 1\n\n if (this.hasPrevTarget) this.prevTarget.classList.toggle('hide', atStart)\n\n if (this.hasNextTarget) {\n const atLastSlide = this._currentIndex >= this.slides.length - 1\n const frontierReached = this.wizardValue && this._currentIndex >= this._maxUnlocked\n this.nextTarget.classList.toggle('hide', atEnd || atLastSlide || frontierReached)\n }\n\n if (this.wizardValue && this.hasDotTarget) {\n this.dotTargets.forEach((dot, i) => {\n const locked = i > this._maxUnlocked\n dot.disabled = locked\n dot.classList.toggle('locked', locked)\n })\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"carousel_component_controller.js","sources":["../../../../../../../app/components/midwest/carousel_component/carousel_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Input types where pressing Enter in a form does NOT normally submit it.\n// For all other input types, Enter submits — so wizard mode intercepts it.\nconst NON_SUBMITTING_INPUT_TYPES = new Set([\n 'button', 'checkbox', 'color', 'file', 'hidden', 'image', 'radio', 'range', 'reset', 'submit'\n])\n\n// Tags that should receive arrow key events without carousel interception.\nconst FORM_ELEMENT_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\nexport default class Carousel extends Controller<HTMLElement> {\n static targets = ['track', 'prev', 'next', 'dot']\n static values = {\n wizard: { type: Boolean, default: false },\n autoplay: { type: Number, default: 0 }\n }\n\n declare readonly trackTarget: HTMLElement\n declare readonly prevTarget: HTMLButtonElement\n declare readonly nextTarget: HTMLButtonElement\n declare readonly dotTargets: HTMLButtonElement[]\n declare readonly hasPrevTarget: boolean\n declare readonly hasNextTarget: boolean\n declare readonly hasDotTarget: boolean\n declare wizardValue: boolean\n declare autoplayValue: number\n\n private observer: IntersectionObserver | null = null\n private _currentIndex = 0\n private _maxUnlocked = 0\n private _lastTouchX = 0\n private _autoplayTimer: ReturnType<typeof setInterval> | null = null\n\n connect () {\n this.setupObserver()\n this.updateNavigation()\n this.element.addEventListener('keydown', this.handleArrowKeys)\n if (this.wizardValue) {\n this.element.addEventListener('keydown', this.handleKeydown)\n this.trackTarget.addEventListener('wheel', this.handleWheel, { passive: false })\n this.trackTarget.addEventListener('touchstart', this.handleTouchStart, { passive: true })\n this.trackTarget.addEventListener('touchmove', this.handleTouchMove, { passive: false })\n this.updateSlideAccessibility()\n }\n if (this.autoplayValue > 0) {\n this.startAutoplay()\n this.element.addEventListener('mouseenter', this.pauseAutoplay)\n this.element.addEventListener('mouseleave', this.resumeAutoplay)\n }\n }\n\n disconnect () {\n this.observer?.disconnect()\n this.element.removeEventListener('keydown', this.handleArrowKeys)\n this.element.removeEventListener('keydown', this.handleKeydown)\n this.element.removeEventListener('mouseenter', this.pauseAutoplay)\n this.element.removeEventListener('mouseleave', this.resumeAutoplay)\n this.trackTarget.removeEventListener('wheel', this.handleWheel)\n this.trackTarget.removeEventListener('touchstart', this.handleTouchStart)\n this.trackTarget.removeEventListener('touchmove', this.handleTouchMove)\n this.stopAutoplay()\n }\n\n next () {\n this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: 'smooth' })\n }\n\n previous () {\n this.trackTarget.scrollBy({ left: -this.trackTarget.clientWidth, behavior: 'smooth' })\n }\n\n goto (event: Event) {\n const button = event.currentTarget as HTMLButtonElement\n const index = parseInt(button.dataset.index ?? '0', 10)\n const slide = this.slides[index]\n slide?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })\n }\n\n // Unlocks the next slide and advances to it. Intended for wizard mode: wire\n // a \"Continue\" button inside a slide to this action so users progress\n // linearly through steps before the carousel nav becomes available.\n //\n // <button type=\"button\" data-action=\"click->midwest-carousel#unlockNext\">\n // Continue\n // </button>\n unlockNext () {\n const nextIndex = this._currentIndex + 1\n if (nextIndex > this._maxUnlocked) {\n this._maxUnlocked = nextIndex\n this.updateSlideAccessibility()\n }\n this.next()\n }\n\n scrolled () {\n if (this.wizardValue) this.clampToFrontier()\n this.updateCurrentIndex()\n this.updateNavigation()\n }\n\n // Arrow function so `this` is stable for add/removeEventListener pairing.\n // Handles ArrowLeft/ArrowRight for keyboard slide navigation. Skips form\n // elements so arrow keys continue to work normally inside inputs and selects.\n private handleArrowKeys = (event: KeyboardEvent) => {\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return\n\n const target = event.target as HTMLElement\n if (FORM_ELEMENT_TAGS.has(target.tagName) || target.isContentEditable) return\n\n event.preventDefault()\n if (event.key === 'ArrowLeft') {\n this.previous()\n } else {\n this.next()\n }\n }\n\n // Arrow function so `this` is stable for add/removeEventListener pairing.\n private handleKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'Enter') return\n\n const target = event.target as HTMLElement\n // Only intercept Enter on text-like inputs; textarea newlines and button\n // activations should pass through untouched.\n if (target.tagName === 'TEXTAREA' || target.tagName !== 'INPUT') return\n if (NON_SUBMITTING_INPUT_TYPES.has((target as HTMLInputElement).type)) return\n\n // On the final step let Enter submit the form normally.\n if (this._currentIndex >= this.slides.length - 1) return\n\n event.preventDefault()\n this.unlockNext()\n }\n\n // Blocks wheel-based horizontal scrolling past the wizard frontier.\n private handleWheel = (event: WheelEvent) => {\n const maxLeft = this._maxUnlocked * this.trackTarget.clientWidth\n if (event.deltaX > 0 && this.trackTarget.scrollLeft >= maxLeft - 2) {\n event.preventDefault()\n }\n }\n\n private handleTouchStart = (event: TouchEvent) => {\n this._lastTouchX = event.touches[0].clientX\n }\n\n // Blocks touch-swipe scrolling past the wizard frontier. Tracks incremental\n // delta per move event so direction is accurate mid-gesture.\n private handleTouchMove = (event: TouchEvent) => {\n const currentX = event.touches[0].clientX\n const delta = currentX - this._lastTouchX // positive = swiping right (going back)\n this._lastTouchX = currentX\n\n const maxLeft = this._maxUnlocked * this.trackTarget.clientWidth\n if (delta < 0 && this.trackTarget.scrollLeft >= maxLeft - 2) {\n event.preventDefault()\n }\n }\n\n private pauseAutoplay = () => {\n this.stopAutoplay()\n }\n\n private resumeAutoplay = () => {\n this.startAutoplay()\n }\n\n private startAutoplay () {\n if (this.autoplayValue <= 0 || this._autoplayTimer !== null) return\n this._autoplayTimer = setInterval(() => { this.autoplayAdvance() }, this.autoplayValue)\n }\n\n private stopAutoplay () {\n if (this._autoplayTimer === null) return\n clearInterval(this._autoplayTimer)\n this._autoplayTimer = null\n }\n\n private autoplayAdvance () {\n const atEnd = this._currentIndex >= this.slides.length - 1\n if (atEnd) {\n const firstSlide = this.slides[0]\n firstSlide?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })\n } else {\n this.next()\n }\n }\n\n private get slides (): HTMLElement[] {\n return Array.from(this.trackTarget.children) as HTMLElement[]\n }\n\n // Snaps scroll position back to the frontier if the user somehow scrolled\n // past it (e.g. momentum after a partially-blocked gesture).\n private clampToFrontier () {\n const maxLeft = this._maxUnlocked * this.trackTarget.clientWidth\n if (this.trackTarget.scrollLeft > maxLeft + 2) {\n this.trackTarget.scrollLeft = maxLeft\n }\n }\n\n // Applies/removes `inert` on each slide based on the wizard frontier,\n // removing locked slides from the tab order and accessibility tree.\n private updateSlideAccessibility () {\n this.slides.forEach((slide, i) => {\n if (i > this._maxUnlocked) {\n slide.setAttribute('inert', '')\n } else {\n slide.removeAttribute('inert')\n }\n })\n }\n\n private updateCurrentIndex () {\n const track = this.trackTarget\n if (track.clientWidth > 0) {\n this._currentIndex = Math.round(track.scrollLeft / track.clientWidth)\n }\n }\n\n private setupObserver () {\n if (!this.hasDotTarget) return\n if (!('IntersectionObserver' in window)) return\n\n this.observer = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n const index = this.slides.indexOf(entry.target as HTMLElement)\n if (index >= 0) {\n const dot = this.dotTargets[index]\n if (!dot) return\n dot.classList.toggle('active', entry.isIntersecting)\n if (entry.isIntersecting) {\n dot.setAttribute('aria-current', 'true')\n } else {\n dot.removeAttribute('aria-current')\n }\n }\n })\n },\n { root: this.trackTarget, threshold: 0.5 }\n )\n\n this.slides.forEach(slide => this.observer?.observe(slide))\n }\n\n private updateNavigation () {\n const track = this.trackTarget\n const atStart = track.scrollLeft <= 0\n const atEnd = track.scrollLeft >= track.scrollWidth - track.clientWidth - 1\n\n if (this.hasPrevTarget) this.prevTarget.classList.toggle('hide', atStart)\n\n if (this.hasNextTarget) {\n const atLastSlide = this._currentIndex >= this.slides.length - 1\n const frontierReached = this.wizardValue && this._currentIndex >= this._maxUnlocked\n this.nextTarget.classList.toggle('hide', atEnd || atLastSlide || frontierReached)\n }\n\n if (this.wizardValue && this.hasDotTarget) {\n this.dotTargets.forEach((dot, i) => {\n const locked = i > this._maxUnlocked\n dot.disabled = locked\n dot.classList.toggle('locked', locked)\n })\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus';
|
|
2
|
+
|
|
3
|
+
class ConfirmationController extends Controller {
|
|
4
|
+
static targets = ["input", "submitButton"];
|
|
5
|
+
static values = { confirmText: String };
|
|
6
|
+
connect() {
|
|
7
|
+
this.validate();
|
|
8
|
+
}
|
|
9
|
+
validate() {
|
|
10
|
+
const matches = this.inputTarget.value === this.confirmTextValue;
|
|
11
|
+
this.submitButtonTarget.classList.toggle("disabled", !matches);
|
|
12
|
+
this.submitButtonTarget.setAttribute("aria-disabled", String(!matches));
|
|
13
|
+
if (matches) {
|
|
14
|
+
this.submitButtonTarget.removeAttribute("tabindex");
|
|
15
|
+
} else {
|
|
16
|
+
this.submitButtonTarget.setAttribute("tabindex", "-1");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { ConfirmationController as default };
|
|
22
|
+
//# sourceMappingURL=confirmation_component_controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmation_component_controller.js","sources":["../../../../../../../app/components/midwest/confirmation_component/confirmation_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class ConfirmationController extends Controller {\n static targets = ['input', 'submitButton']\n static values = { confirmText: String }\n\n declare readonly inputTarget: HTMLInputElement\n declare readonly submitButtonTarget: HTMLElement\n declare confirmTextValue: string\n\n connect () {\n this.validate()\n }\n\n validate () {\n const matches = this.inputTarget.value === this.confirmTextValue\n this.submitButtonTarget.classList.toggle('disabled', !matches)\n this.submitButtonTarget.setAttribute('aria-disabled', String(!matches))\n\n if (matches) {\n this.submitButtonTarget.removeAttribute('tabindex')\n } else {\n this.submitButtonTarget.setAttribute('tabindex', '-1')\n }\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,+BAA+B,UAAW,CAAA;AAAA,EAC7D,OAAO,OAAA,GAAU,CAAC,OAAA,EAAS,cAAc,CAAA,CAAA;AAAA,EACzC,OAAO,MAAA,GAAS,EAAE,WAAA,EAAa,MAAO,EAAA,CAAA;AAAA,EAMtC,OAAW,GAAA;AACT,IAAA,IAAA,CAAK,QAAS,EAAA,CAAA;AAAA,GAChB;AAAA,EAEA,QAAY,GAAA;AACV,IAAA,MAAM,OAAU,GAAA,IAAA,CAAK,WAAY,CAAA,KAAA,KAAU,IAAK,CAAA,gBAAA,CAAA;AAChD,IAAA,IAAA,CAAK,kBAAmB,CAAA,SAAA,CAAU,MAAO,CAAA,UAAA,EAAY,CAAC,OAAO,CAAA,CAAA;AAC7D,IAAA,IAAA,CAAK,mBAAmB,YAAa,CAAA,eAAA,EAAiB,MAAO,CAAA,CAAC,OAAO,CAAC,CAAA,CAAA;AAEtE,IAAA,IAAI,OAAS,EAAA;AACX,MAAK,IAAA,CAAA,kBAAA,CAAmB,gBAAgB,UAAU,CAAA,CAAA;AAAA,KAC7C,MAAA;AACL,MAAK,IAAA,CAAA,kBAAA,CAAmB,YAAa,CAAA,UAAA,EAAY,IAAI,CAAA,CAAA;AAAA,KACvD;AAAA,GACF;AACF;;;;"}
|
|
@@ -2,21 +2,37 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
2
2
|
|
|
3
3
|
class Tooltip extends Controller {
|
|
4
4
|
static targets = ["popover"];
|
|
5
|
+
static values = {
|
|
6
|
+
delay: { type: Number, default: 0 }
|
|
7
|
+
};
|
|
8
|
+
showTimer = null;
|
|
5
9
|
connect() {
|
|
6
10
|
document.addEventListener("keydown", this.handleKeydown);
|
|
7
11
|
}
|
|
8
12
|
disconnect() {
|
|
9
13
|
document.removeEventListener("keydown", this.handleKeydown);
|
|
14
|
+
this.cancelShow();
|
|
10
15
|
}
|
|
11
16
|
show() {
|
|
12
|
-
this.
|
|
17
|
+
if (this.delayValue > 0) {
|
|
18
|
+
this.showTimer = setTimeout(() => this.popoverTarget.showPopover(), this.delayValue);
|
|
19
|
+
} else {
|
|
20
|
+
this.popoverTarget.showPopover();
|
|
21
|
+
}
|
|
13
22
|
}
|
|
14
23
|
hide() {
|
|
24
|
+
this.cancelShow();
|
|
15
25
|
try {
|
|
16
26
|
this.popoverTarget.hidePopover();
|
|
17
27
|
} catch {
|
|
18
28
|
}
|
|
19
29
|
}
|
|
30
|
+
cancelShow() {
|
|
31
|
+
if (this.showTimer !== null) {
|
|
32
|
+
clearTimeout(this.showTimer);
|
|
33
|
+
this.showTimer = null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
20
36
|
handleKeydown = (event) => {
|
|
21
37
|
if (event.key !== "Escape")
|
|
22
38
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip_component_controller.js","sources":["../../../../../../../app/components/midwest/tooltip_component/tooltip_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class Tooltip extends Controller<HTMLElement> {\n static targets = ['popover']\n\n declare readonly popoverTarget: HTMLElement\n\n connect () {\n document.addEventListener('keydown', this.handleKeydown)\n }\n\n disconnect () {\n document.removeEventListener('keydown', this.handleKeydown)\n }\n\n show () {\n this.popoverTarget.showPopover()\n }\n\n hide () {\n try {\n this.popoverTarget.hidePopover()\n } catch {\n // already hidden\n }\n }\n\n private handleKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return\n this.hide()\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,gBAAgB,UAAwB,CAAA;AAAA,EAC3D,OAAO,OAAU,GAAA,CAAC,SAAS,CAAA,CAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"tooltip_component_controller.js","sources":["../../../../../../../app/components/midwest/tooltip_component/tooltip_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class Tooltip extends Controller<HTMLElement> {\n static targets = ['popover']\n static values = {\n delay: { type: Number, default: 0 }\n }\n\n declare readonly popoverTarget: HTMLElement\n declare delayValue: number\n\n private showTimer: ReturnType<typeof setTimeout> | null = null\n\n connect () {\n document.addEventListener('keydown', this.handleKeydown)\n }\n\n disconnect () {\n document.removeEventListener('keydown', this.handleKeydown)\n this.cancelShow()\n }\n\n show () {\n if (this.delayValue > 0) {\n this.showTimer = setTimeout(() => this.popoverTarget.showPopover(), this.delayValue)\n } else {\n this.popoverTarget.showPopover()\n }\n }\n\n hide () {\n this.cancelShow()\n try {\n this.popoverTarget.hidePopover()\n } catch {\n // already hidden\n }\n }\n\n private cancelShow () {\n if (this.showTimer !== null) {\n clearTimeout(this.showTimer)\n this.showTimer = null\n }\n }\n\n private handleKeydown = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return\n this.hide()\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,gBAAgB,UAAwB,CAAA;AAAA,EAC3D,OAAO,OAAU,GAAA,CAAC,SAAS,CAAA,CAAA;AAAA,EAC3B,OAAO,MAAS,GAAA;AAAA,IACd,KAAO,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,CAAE,EAAA;AAAA,GACpC,CAAA;AAAA,EAKQ,SAAkD,GAAA,IAAA,CAAA;AAAA,EAE1D,OAAW,GAAA;AACT,IAAS,QAAA,CAAA,gBAAA,CAAiB,SAAW,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAAA,GACzD;AAAA,EAEA,UAAc,GAAA;AACZ,IAAS,QAAA,CAAA,mBAAA,CAAoB,SAAW,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAC1D,IAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAAA,GAClB;AAAA,EAEA,IAAQ,GAAA;AACN,IAAI,IAAA,IAAA,CAAK,aAAa,CAAG,EAAA;AACvB,MAAK,IAAA,CAAA,SAAA,GAAY,WAAW,MAAM,IAAA,CAAK,cAAc,WAAY,EAAA,EAAG,KAAK,UAAU,CAAA,CAAA;AAAA,KAC9E,MAAA;AACL,MAAA,IAAA,CAAK,cAAc,WAAY,EAAA,CAAA;AAAA,KACjC;AAAA,GACF;AAAA,EAEA,IAAQ,GAAA;AACN,IAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAChB,IAAI,IAAA;AACF,MAAA,IAAA,CAAK,cAAc,WAAY,EAAA,CAAA;AAAA,KAC/B,CAAA,MAAA;AAAA,KAEF;AAAA,GACF;AAAA,EAEQ,UAAc,GAAA;AACpB,IAAI,IAAA,IAAA,CAAK,cAAc,IAAM,EAAA;AAC3B,MAAA,YAAA,CAAa,KAAK,SAAS,CAAA,CAAA;AAC3B,MAAA,IAAA,CAAK,SAAY,GAAA,IAAA,CAAA;AAAA,KACnB;AAAA,GACF;AAAA,EAEQ,aAAA,GAAgB,CAAC,KAAyB,KAAA;AAChD,IAAA,IAAI,MAAM,GAAQ,KAAA,QAAA;AAAU,MAAA,OAAA;AAC5B,IAAA,IAAA,CAAK,IAAK,EAAA,CAAA;AAAA,GACZ,CAAA;AACF;;;;"}
|
|
@@ -3160,21 +3160,37 @@ class Tabs extends Controller {
|
|
|
3160
3160
|
|
|
3161
3161
|
class Tooltip extends Controller {
|
|
3162
3162
|
static targets = ["popover"];
|
|
3163
|
+
static values = {
|
|
3164
|
+
delay: { type: Number, default: 0 }
|
|
3165
|
+
};
|
|
3166
|
+
showTimer = null;
|
|
3163
3167
|
connect() {
|
|
3164
3168
|
document.addEventListener("keydown", this.handleKeydown);
|
|
3165
3169
|
}
|
|
3166
3170
|
disconnect() {
|
|
3167
3171
|
document.removeEventListener("keydown", this.handleKeydown);
|
|
3172
|
+
this.cancelShow();
|
|
3168
3173
|
}
|
|
3169
3174
|
show() {
|
|
3170
|
-
this.
|
|
3175
|
+
if (this.delayValue > 0) {
|
|
3176
|
+
this.showTimer = setTimeout(() => this.popoverTarget.showPopover(), this.delayValue);
|
|
3177
|
+
} else {
|
|
3178
|
+
this.popoverTarget.showPopover();
|
|
3179
|
+
}
|
|
3171
3180
|
}
|
|
3172
3181
|
hide() {
|
|
3182
|
+
this.cancelShow();
|
|
3173
3183
|
try {
|
|
3174
3184
|
this.popoverTarget.hidePopover();
|
|
3175
3185
|
} catch {
|
|
3176
3186
|
}
|
|
3177
3187
|
}
|
|
3188
|
+
cancelShow() {
|
|
3189
|
+
if (this.showTimer !== null) {
|
|
3190
|
+
clearTimeout(this.showTimer);
|
|
3191
|
+
this.showTimer = null;
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3178
3194
|
handleKeydown = (event) => {
|
|
3179
3195
|
if (event.key !== "Escape")
|
|
3180
3196
|
return;
|
|
@@ -3194,18 +3210,22 @@ const NON_SUBMITTING_INPUT_TYPES = /* @__PURE__ */ new Set([
|
|
|
3194
3210
|
"reset",
|
|
3195
3211
|
"submit"
|
|
3196
3212
|
]);
|
|
3213
|
+
const FORM_ELEMENT_TAGS = /* @__PURE__ */ new Set(["INPUT", "TEXTAREA", "SELECT"]);
|
|
3197
3214
|
class Carousel extends Controller {
|
|
3198
3215
|
static targets = ["track", "prev", "next", "dot"];
|
|
3199
3216
|
static values = {
|
|
3200
|
-
wizard: { type: Boolean, default: false }
|
|
3217
|
+
wizard: { type: Boolean, default: false },
|
|
3218
|
+
autoplay: { type: Number, default: 0 }
|
|
3201
3219
|
};
|
|
3202
3220
|
observer = null;
|
|
3203
3221
|
_currentIndex = 0;
|
|
3204
3222
|
_maxUnlocked = 0;
|
|
3205
3223
|
_lastTouchX = 0;
|
|
3224
|
+
_autoplayTimer = null;
|
|
3206
3225
|
connect() {
|
|
3207
3226
|
this.setupObserver();
|
|
3208
3227
|
this.updateNavigation();
|
|
3228
|
+
this.element.addEventListener("keydown", this.handleArrowKeys);
|
|
3209
3229
|
if (this.wizardValue) {
|
|
3210
3230
|
this.element.addEventListener("keydown", this.handleKeydown);
|
|
3211
3231
|
this.trackTarget.addEventListener("wheel", this.handleWheel, { passive: false });
|
|
@@ -3213,13 +3233,22 @@ class Carousel extends Controller {
|
|
|
3213
3233
|
this.trackTarget.addEventListener("touchmove", this.handleTouchMove, { passive: false });
|
|
3214
3234
|
this.updateSlideAccessibility();
|
|
3215
3235
|
}
|
|
3236
|
+
if (this.autoplayValue > 0) {
|
|
3237
|
+
this.startAutoplay();
|
|
3238
|
+
this.element.addEventListener("mouseenter", this.pauseAutoplay);
|
|
3239
|
+
this.element.addEventListener("mouseleave", this.resumeAutoplay);
|
|
3240
|
+
}
|
|
3216
3241
|
}
|
|
3217
3242
|
disconnect() {
|
|
3218
3243
|
this.observer?.disconnect();
|
|
3244
|
+
this.element.removeEventListener("keydown", this.handleArrowKeys);
|
|
3219
3245
|
this.element.removeEventListener("keydown", this.handleKeydown);
|
|
3246
|
+
this.element.removeEventListener("mouseenter", this.pauseAutoplay);
|
|
3247
|
+
this.element.removeEventListener("mouseleave", this.resumeAutoplay);
|
|
3220
3248
|
this.trackTarget.removeEventListener("wheel", this.handleWheel);
|
|
3221
3249
|
this.trackTarget.removeEventListener("touchstart", this.handleTouchStart);
|
|
3222
3250
|
this.trackTarget.removeEventListener("touchmove", this.handleTouchMove);
|
|
3251
|
+
this.stopAutoplay();
|
|
3223
3252
|
}
|
|
3224
3253
|
next() {
|
|
3225
3254
|
this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: "smooth" });
|
|
@@ -3255,6 +3284,22 @@ class Carousel extends Controller {
|
|
|
3255
3284
|
this.updateNavigation();
|
|
3256
3285
|
}
|
|
3257
3286
|
// Arrow function so `this` is stable for add/removeEventListener pairing.
|
|
3287
|
+
// Handles ArrowLeft/ArrowRight for keyboard slide navigation. Skips form
|
|
3288
|
+
// elements so arrow keys continue to work normally inside inputs and selects.
|
|
3289
|
+
handleArrowKeys = (event) => {
|
|
3290
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight")
|
|
3291
|
+
return;
|
|
3292
|
+
const target = event.target;
|
|
3293
|
+
if (FORM_ELEMENT_TAGS.has(target.tagName) || target.isContentEditable)
|
|
3294
|
+
return;
|
|
3295
|
+
event.preventDefault();
|
|
3296
|
+
if (event.key === "ArrowLeft") {
|
|
3297
|
+
this.previous();
|
|
3298
|
+
} else {
|
|
3299
|
+
this.next();
|
|
3300
|
+
}
|
|
3301
|
+
};
|
|
3302
|
+
// Arrow function so `this` is stable for add/removeEventListener pairing.
|
|
3258
3303
|
handleKeydown = (event) => {
|
|
3259
3304
|
if (event.key !== "Enter")
|
|
3260
3305
|
return;
|
|
@@ -3289,6 +3334,34 @@ class Carousel extends Controller {
|
|
|
3289
3334
|
event.preventDefault();
|
|
3290
3335
|
}
|
|
3291
3336
|
};
|
|
3337
|
+
pauseAutoplay = () => {
|
|
3338
|
+
this.stopAutoplay();
|
|
3339
|
+
};
|
|
3340
|
+
resumeAutoplay = () => {
|
|
3341
|
+
this.startAutoplay();
|
|
3342
|
+
};
|
|
3343
|
+
startAutoplay() {
|
|
3344
|
+
if (this.autoplayValue <= 0 || this._autoplayTimer !== null)
|
|
3345
|
+
return;
|
|
3346
|
+
this._autoplayTimer = setInterval(() => {
|
|
3347
|
+
this.autoplayAdvance();
|
|
3348
|
+
}, this.autoplayValue);
|
|
3349
|
+
}
|
|
3350
|
+
stopAutoplay() {
|
|
3351
|
+
if (this._autoplayTimer === null)
|
|
3352
|
+
return;
|
|
3353
|
+
clearInterval(this._autoplayTimer);
|
|
3354
|
+
this._autoplayTimer = null;
|
|
3355
|
+
}
|
|
3356
|
+
autoplayAdvance() {
|
|
3357
|
+
const atEnd = this._currentIndex >= this.slides.length - 1;
|
|
3358
|
+
if (atEnd) {
|
|
3359
|
+
const firstSlide = this.slides[0];
|
|
3360
|
+
firstSlide?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
|
|
3361
|
+
} else {
|
|
3362
|
+
this.next();
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3292
3365
|
get slides() {
|
|
3293
3366
|
return Array.from(this.trackTarget.children);
|
|
3294
3367
|
}
|
|
@@ -3543,6 +3616,46 @@ class CountdownTimer extends Controller {
|
|
|
3543
3616
|
}
|
|
3544
3617
|
}
|
|
3545
3618
|
|
|
3619
|
+
class Badge extends Controller {
|
|
3620
|
+
remove() {
|
|
3621
|
+
this.element.remove();
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3625
|
+
class ConfirmationController extends Controller {
|
|
3626
|
+
static targets = ["input", "submitButton"];
|
|
3627
|
+
static values = { confirmText: String };
|
|
3628
|
+
connect() {
|
|
3629
|
+
this.validate();
|
|
3630
|
+
}
|
|
3631
|
+
validate() {
|
|
3632
|
+
const matches = this.inputTarget.value === this.confirmTextValue;
|
|
3633
|
+
this.submitButtonTarget.classList.toggle("disabled", !matches);
|
|
3634
|
+
this.submitButtonTarget.setAttribute("aria-disabled", String(!matches));
|
|
3635
|
+
if (matches) {
|
|
3636
|
+
this.submitButtonTarget.removeAttribute("tabindex");
|
|
3637
|
+
} else {
|
|
3638
|
+
this.submitButtonTarget.setAttribute("tabindex", "-1");
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
|
|
3643
|
+
class AvatarGroup extends Controller {
|
|
3644
|
+
static targets = ["overflow", "hidden"];
|
|
3645
|
+
expand() {
|
|
3646
|
+
this.element.classList.add("is-expanding");
|
|
3647
|
+
this.hiddenTargets.forEach((wrapper) => {
|
|
3648
|
+
wrapper.classList.add("is-visible");
|
|
3649
|
+
});
|
|
3650
|
+
if (this.hasOverflowTarget) {
|
|
3651
|
+
this.overflowTarget.classList.add("avatar-overflow-hiding");
|
|
3652
|
+
this.overflowTarget.addEventListener("transitionend", () => {
|
|
3653
|
+
this.overflowTarget.remove();
|
|
3654
|
+
}, { once: true });
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3546
3659
|
function registerMidwestControllers(application) {
|
|
3547
3660
|
application.register("midwest-card", Card);
|
|
3548
3661
|
application.register("midwest-banner", Banner);
|
|
@@ -3557,6 +3670,9 @@ function registerMidwestControllers(application) {
|
|
|
3557
3670
|
application.register("midwest-carousel", Carousel);
|
|
3558
3671
|
application.register("midwest-form-live-summary", FormLiveSummary);
|
|
3559
3672
|
application.register("midwest-form", Form);
|
|
3673
|
+
application.register("midwest-badge", Badge);
|
|
3674
|
+
application.register("midwest-confirmation", ConfirmationController);
|
|
3675
|
+
application.register("midwest-avatar-group", AvatarGroup);
|
|
3560
3676
|
}
|
|
3561
3677
|
|
|
3562
3678
|
export { Banner, Card, CountdownTimer, registerMidwestControllers };
|