@unabridged/midwest 0.16.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/app/assets/javascript/midwest/index.ts +6 -0
  2. package/app/assets/javascript/midwest.js +970 -39
  3. package/app/assets/javascript/midwest.js.map +1 -1
  4. package/app/assets/stylesheets/midwest.css +1 -1
  5. package/app/assets/stylesheets/midwest.tailwind.css +6 -1
  6. package/dist/css/midwest.css +1 -1
  7. package/dist/javascript/collection/app/assets/javascript/midwest/index.js +6 -0
  8. package/dist/javascript/collection/app/assets/javascript/midwest/index.js.map +1 -1
  9. package/dist/javascript/collection/app/components/midwest/carousel_component/carousel_component_controller.js +17 -5
  10. package/dist/javascript/collection/app/components/midwest/carousel_component/carousel_component_controller.js.map +1 -1
  11. package/dist/javascript/collection/app/components/midwest/color_picker_component/color_picker_component_controller.js +135 -0
  12. package/dist/javascript/collection/app/components/midwest/color_picker_component/color_picker_component_controller.js.map +1 -0
  13. package/dist/javascript/collection/app/components/midwest/countdown_timer_component/countdown_timer_component_controller.js +27 -6
  14. package/dist/javascript/collection/app/components/midwest/countdown_timer_component/countdown_timer_component_controller.js.map +1 -1
  15. package/dist/javascript/collection/app/components/midwest/form/autocomplete_component/autocomplete_component_controller.js +109 -21
  16. package/dist/javascript/collection/app/components/midwest/form/autocomplete_component/autocomplete_component_controller.js.map +1 -1
  17. package/dist/javascript/collection/app/components/midwest/form/color_picker_component/color_picker_component_controller.js +129 -0
  18. package/dist/javascript/collection/app/components/midwest/form/color_picker_component/color_picker_component_controller.js.map +1 -0
  19. package/dist/javascript/collection/app/components/midwest/form/input_component/input_component_controller.js +50 -1
  20. package/dist/javascript/collection/app/components/midwest/form/input_component/input_component_controller.js.map +1 -1
  21. package/dist/javascript/collection/app/components/midwest/form/live_summary_component/live_summary_component_controller.js +38 -5
  22. package/dist/javascript/collection/app/components/midwest/form/live_summary_component/live_summary_component_controller.js.map +1 -1
  23. package/dist/javascript/collection/app/components/midwest/image_component/color_thief.js +490 -0
  24. package/dist/javascript/collection/app/components/midwest/image_component/color_thief.js.map +1 -0
  25. package/dist/javascript/collection/app/components/midwest/image_component/image_component_controller.js +47 -0
  26. package/dist/javascript/collection/app/components/midwest/image_component/image_component_controller.js.map +1 -0
  27. package/dist/javascript/collection/app/components/midwest/notification_component/notification_component_controller.js +60 -0
  28. package/dist/javascript/collection/app/components/midwest/notification_component/notification_component_controller.js.map +1 -0
  29. package/dist/javascript/collection/app/components/midwest/tabs_component/tabs_component_controller.js +15 -1
  30. package/dist/javascript/collection/app/components/midwest/tabs_component/tabs_component_controller.js.map +1 -1
  31. package/dist/javascript/midwest.d.ts +5 -0
  32. package/dist/javascript/midwest.js +970 -39
  33. package/dist/javascript/midwest.js.map +1 -1
  34. package/package.json +1 -1
@@ -22,6 +22,9 @@ export { default as Chart } from '../../../components/midwest/chart_component/ch
22
22
  import Range from '../../../components/midwest/form/range_component/range_component_controller.js';
23
23
  import Rating from '../../../components/midwest/rating_component/rating_component_controller.js';
24
24
  import Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller.js';
25
+ import Image from '../../../components/midwest/image_component/image_component_controller.js';
26
+ import ColorPicker from '../../../components/midwest/form/color_picker_component/color_picker_component_controller.js';
27
+ import Notification from '../../../components/midwest/notification_component/notification_component_controller.js';
25
28
 
26
29
  function registerMidwestControllers(application) {
27
30
  application.register("midwest-card", Card);
@@ -44,6 +47,9 @@ function registerMidwestControllers(application) {
44
47
  application.register("midwest-range", Range);
45
48
  application.register("midwest-rating", Rating);
46
49
  application.register("midwest-autocomplete", Autocomplete);
50
+ application.register("midwest-image", Image);
51
+ application.register("midwest-color-picker", ColorPicker);
52
+ application.register("midwest-notification", Notification);
47
53
  }
48
54
 
49
55
  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'\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'\nimport Chart from '../../../components/midwest/chart_component/chart_component_controller'\nimport Range from '../../../components/midwest/form/range_component/range_component_controller'\nimport Rating from '../../../components/midwest/rating_component/rating_component_controller'\nimport Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer, Chart }\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 application.register('midwest-chart', Chart)\n application.register('midwest-range', Range)\n application.register('midwest-rating', Rating)\n application.register('midwest-autocomplete', Autocomplete)\n /* EXPORTS */\n}\n"],"names":["Confirmation"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAwBO,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;AACxD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,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,wBAAwB,YAAY,CAAA,CAAA;AAE3D;;;;"}
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'\nimport Chart from '../../../components/midwest/chart_component/chart_component_controller'\nimport Range from '../../../components/midwest/form/range_component/range_component_controller'\nimport Rating from '../../../components/midwest/rating_component/rating_component_controller'\nimport Autocomplete from '../../../components/midwest/form/autocomplete_component/autocomplete_component_controller'\nimport Image from '../../../components/midwest/image_component/image_component_controller'\nimport ColorPicker from '../../../components/midwest/form/color_picker_component/color_picker_component_controller'\nimport Notification from '../../../components/midwest/notification_component/notification_component_controller'\n/* IMPORTS */\n\nexport { Card, Banner, CountdownTimer, Chart }\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 application.register('midwest-chart', Chart)\n application.register('midwest-range', Range)\n application.register('midwest-rating', Rating)\n application.register('midwest-autocomplete', Autocomplete)\n application.register('midwest-image', Image)\n application.register('midwest-color-picker', ColorPicker)\n application.register('midwest-notification', Notification)\n /* EXPORTS */\n}\n"],"names":["Confirmation"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,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;AACxD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,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,wBAAwB,YAAY,CAAA,CAAA;AACzD,EAAY,WAAA,CAAA,QAAA,CAAS,iBAAiB,KAAK,CAAA,CAAA;AAC3C,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwB,WAAW,CAAA,CAAA;AACxD,EAAY,WAAA,CAAA,QAAA,CAAS,wBAAwB,YAAY,CAAA,CAAA;AAE3D;;;;"}
@@ -17,7 +17,8 @@ class Carousel extends Controller {
17
17
  static targets = ["track", "prev", "next", "dot"];
18
18
  static values = {
19
19
  wizard: { type: Boolean, default: false },
20
- autoplay: { type: Number, default: 0 }
20
+ autoplay: { type: Number, default: 0 },
21
+ loop: { type: Boolean, default: false }
21
22
  };
22
23
  observer = null;
23
24
  _currentIndex = 0;
@@ -53,10 +54,21 @@ class Carousel extends Controller {
53
54
  this.stopAutoplay();
54
55
  }
55
56
  next() {
56
- this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: "smooth" });
57
+ const atEnd = this._currentIndex >= this.slides.length - 1;
58
+ if (this.loopValue && atEnd) {
59
+ this.slides[0]?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
60
+ } else {
61
+ this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: "smooth" });
62
+ }
57
63
  }
58
64
  previous() {
59
- this.trackTarget.scrollBy({ left: -this.trackTarget.clientWidth, behavior: "smooth" });
65
+ const atStart = this._currentIndex <= 0;
66
+ if (this.loopValue && atStart) {
67
+ const last = this.slides[this.slides.length - 1];
68
+ last?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
69
+ } else {
70
+ this.trackTarget.scrollBy({ left: -this.trackTarget.clientWidth, behavior: "smooth" });
71
+ }
60
72
  }
61
73
  goto(event) {
62
74
  const button = event.currentTarget;
@@ -223,11 +235,11 @@ class Carousel extends Controller {
223
235
  const atStart = track.scrollLeft <= 0;
224
236
  const atEnd = track.scrollLeft >= track.scrollWidth - track.clientWidth - 1;
225
237
  if (this.hasPrevTarget)
226
- this.prevTarget.classList.toggle("hide", atStart);
238
+ this.prevTarget.classList.toggle("hide", atStart && !this.loopValue);
227
239
  if (this.hasNextTarget) {
228
240
  const atLastSlide = this._currentIndex >= this.slides.length - 1;
229
241
  const frontierReached = this.wizardValue && this._currentIndex >= this._maxUnlocked;
230
- this.nextTarget.classList.toggle("hide", atEnd || atLastSlide || frontierReached);
242
+ this.nextTarget.classList.toggle("hide", (atEnd || atLastSlide || frontierReached) && !this.loopValue);
231
243
  }
232
244
  if (this.wizardValue && this.hasDotTarget) {
233
245
  this.dotTargets.forEach((dot, i) => {
@@ -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\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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"}
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 loop: { 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 declare autoplayValue: number\n declare loopValue: boolean\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 const atEnd = this._currentIndex >= this.slides.length - 1\n if (this.loopValue && atEnd) {\n this.slides[0]?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })\n } else {\n this.trackTarget.scrollBy({ left: this.trackTarget.clientWidth, behavior: 'smooth' })\n }\n }\n\n previous () {\n const atStart = this._currentIndex <= 0\n if (this.loopValue && atStart) {\n const last = this.slides[this.slides.length - 1]\n last?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' })\n } else {\n this.trackTarget.scrollBy({ left: -this.trackTarget.clientWidth, behavior: 'smooth' })\n }\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 && !this.loopValue)\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) && !this.loopValue)\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,135 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+
3
+ class ColorPicker extends Controller {
4
+ static targets = ["input", "swatch", "customSwatch", "colorInput"];
5
+ onCustomColorChange = null;
6
+ get scaleTarget() {
7
+ return this.element.dataset.scaleTarget ?? "theme";
8
+ }
9
+ connect() {
10
+ if (this.hasColorInputTarget) {
11
+ this.onCustomColorChange = (e) => this.handleCustomColor(e);
12
+ this.colorInputTarget.addEventListener("input", this.onCustomColorChange);
13
+ }
14
+ if (this.hasInputTarget && this.inputTarget.value.startsWith("#")) {
15
+ this.restoreCustom(this.inputTarget.value);
16
+ }
17
+ }
18
+ disconnect() {
19
+ if (this.hasColorInputTarget && this.onCustomColorChange) {
20
+ this.colorInputTarget.removeEventListener("input", this.onCustomColorChange);
21
+ this.onCustomColorChange = null;
22
+ }
23
+ }
24
+ select(e) {
25
+ const button = e.currentTarget;
26
+ const color = button.dataset.color ?? "";
27
+ this.applySelection(color);
28
+ this.dispatch("update", { detail: { color, scaleTarget: this.scaleTarget } });
29
+ }
30
+ openCustom(e) {
31
+ e.preventDefault();
32
+ this.colorInputTarget.click();
33
+ }
34
+ handleCustomColor(e) {
35
+ const hex = e.target.value;
36
+ if (this.hasCustomSwatchTarget) {
37
+ this.customSwatchTarget.dataset.color = hex;
38
+ this.customSwatchTarget.style.background = hex;
39
+ }
40
+ const scale = this.generateScale(hex);
41
+ this.applyScale(scale);
42
+ this.applySelection(hex);
43
+ this.dispatch("update", { detail: { color: hex, scale, scaleTarget: this.scaleTarget } });
44
+ }
45
+ restoreCustom(hex) {
46
+ if (this.hasColorInputTarget) {
47
+ this.colorInputTarget.value = hex;
48
+ }
49
+ if (this.hasCustomSwatchTarget) {
50
+ this.customSwatchTarget.style.background = hex;
51
+ }
52
+ const scale = this.generateScale(hex);
53
+ this.applyScale(scale);
54
+ }
55
+ applySelection(color) {
56
+ if (this.hasInputTarget) {
57
+ this.inputTarget.value = color;
58
+ }
59
+ this.swatchTargets.forEach((swatch) => {
60
+ const isSelected = swatch.dataset.color === color;
61
+ swatch.classList.toggle("is-selected", isSelected);
62
+ swatch.setAttribute("aria-pressed", String(isSelected));
63
+ });
64
+ }
65
+ // Generates 13 RGB channel strings (space-separated, matching --{color}-{n}-channels format)
66
+ // from a hex color by fixing the hue/saturation and distributing lightness across the scale.
67
+ generateScale(hex) {
68
+ const [h, s] = this.hexToHsl(hex);
69
+ const lightnessSteps = [97, 90, 82, 74, 65, 56, 48, 40, 33, 26, 18, 10, 3];
70
+ return Object.fromEntries(
71
+ lightnessSteps.map((l, i) => {
72
+ const [r, g, b] = this.hslToRgb(h, s, l);
73
+ return [String(i), `${r} ${g} ${b}`];
74
+ })
75
+ );
76
+ }
77
+ applyScale(scale) {
78
+ const el = this.element;
79
+ Object.entries(scale).forEach(([step, channels]) => {
80
+ el.style.setProperty(`--${this.scaleTarget}-${step}-channels`, channels);
81
+ });
82
+ }
83
+ hexToHsl(hex) {
84
+ const r = parseInt(hex.slice(1, 3), 16) / 255;
85
+ const g = parseInt(hex.slice(3, 5), 16) / 255;
86
+ const b = parseInt(hex.slice(5, 7), 16) / 255;
87
+ const max = Math.max(r, g, b);
88
+ const min = Math.min(r, g, b);
89
+ const l = (max + min) / 2;
90
+ if (max === min)
91
+ return [0, 0, l * 100];
92
+ const d = max - min;
93
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
94
+ let h = 0;
95
+ if (max === r)
96
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
97
+ else if (max === g)
98
+ h = ((b - r) / d + 2) / 6;
99
+ else
100
+ h = ((r - g) / d + 4) / 6;
101
+ return [h * 360, s * 100, l * 100];
102
+ }
103
+ hslToRgb(h, s, l) {
104
+ h /= 360;
105
+ s /= 100;
106
+ l /= 100;
107
+ if (s === 0) {
108
+ const v = Math.round(l * 255);
109
+ return [v, v, v];
110
+ }
111
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
112
+ const p = 2 * l - q;
113
+ return [
114
+ Math.round(this.hue2rgb(p, q, h + 1 / 3) * 255),
115
+ Math.round(this.hue2rgb(p, q, h) * 255),
116
+ Math.round(this.hue2rgb(p, q, h - 1 / 3) * 255)
117
+ ];
118
+ }
119
+ hue2rgb(p, q, t) {
120
+ if (t < 0)
121
+ t += 1;
122
+ if (t > 1)
123
+ t -= 1;
124
+ if (t < 1 / 6)
125
+ return p + (q - p) * 6 * t;
126
+ if (t < 1 / 2)
127
+ return q;
128
+ if (t < 2 / 3)
129
+ return p + (q - p) * (2 / 3 - t) * 6;
130
+ return p;
131
+ }
132
+ }
133
+
134
+ export { ColorPicker as default };
135
+ //# sourceMappingURL=color_picker_component_controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color_picker_component_controller.js","sources":["../../../../../../../app/components/midwest/color_picker_component/color_picker_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class ColorPicker extends Controller {\n static targets = ['input', 'swatch', 'customSwatch', 'colorInput']\n\n declare readonly hasInputTarget: boolean\n declare readonly inputTarget: HTMLInputElement\n declare readonly swatchTargets: HTMLElement[]\n declare readonly hasCustomSwatchTarget: boolean\n declare readonly customSwatchTarget: HTMLButtonElement\n declare readonly hasColorInputTarget: boolean\n declare readonly colorInputTarget: HTMLInputElement\n\n private onCustomColorChange: ((e: Event) => void) | null = null\n\n get scaleTarget (): string {\n return (this.element as HTMLElement).dataset.scaleTarget ?? 'theme'\n }\n\n connect () {\n if (this.hasColorInputTarget) {\n this.onCustomColorChange = (e: Event) => this.handleCustomColor(e)\n this.colorInputTarget.addEventListener('input', this.onCustomColorChange)\n }\n\n // Restore state when initial value is a custom hex color\n if (this.hasInputTarget && this.inputTarget.value.startsWith('#')) {\n this.restoreCustom(this.inputTarget.value)\n }\n }\n\n disconnect () {\n if (this.hasColorInputTarget && this.onCustomColorChange) {\n this.colorInputTarget.removeEventListener('input', this.onCustomColorChange)\n this.onCustomColorChange = null\n }\n }\n\n select (e: Event) {\n const button = e.currentTarget as HTMLElement\n const color = button.dataset.color ?? ''\n this.applySelection(color)\n this.dispatch('update', { detail: { color, scaleTarget: this.scaleTarget } })\n }\n\n openCustom (e: Event) {\n e.preventDefault()\n this.colorInputTarget.click()\n }\n\n private handleCustomColor (e: Event) {\n const hex = (e.target as HTMLInputElement).value\n\n if (this.hasCustomSwatchTarget) {\n this.customSwatchTarget.dataset.color = hex\n this.customSwatchTarget.style.background = hex\n }\n\n const scale = this.generateScale(hex)\n this.applyScale(scale)\n this.applySelection(hex)\n this.dispatch('update', { detail: { color: hex, scale, scaleTarget: this.scaleTarget } })\n }\n\n private restoreCustom (hex: string) {\n if (this.hasColorInputTarget) {\n this.colorInputTarget.value = hex\n }\n if (this.hasCustomSwatchTarget) {\n this.customSwatchTarget.style.background = hex\n }\n const scale = this.generateScale(hex)\n this.applyScale(scale)\n }\n\n private applySelection (color: string) {\n if (this.hasInputTarget) {\n this.inputTarget.value = color\n }\n\n this.swatchTargets.forEach(swatch => {\n const isSelected = swatch.dataset.color === color\n swatch.classList.toggle('is-selected', isSelected)\n swatch.setAttribute('aria-pressed', String(isSelected))\n })\n }\n\n // Generates 13 RGB channel strings (space-separated, matching --{color}-{n}-channels format)\n // from a hex color by fixing the hue/saturation and distributing lightness across the scale.\n private generateScale (hex: string): Record<string, string> {\n const [h, s] = this.hexToHsl(hex)\n\n // Lightness curve derived from the built-in named color scales (0 = lightest, 12 = darkest)\n const lightnessSteps = [97, 90, 82, 74, 65, 56, 48, 40, 33, 26, 18, 10, 3]\n\n return Object.fromEntries(\n lightnessSteps.map((l, i) => {\n const [r, g, b] = this.hslToRgb(h, s, l)\n return [String(i), `${r} ${g} ${b}`]\n })\n )\n }\n\n private applyScale (scale: Record<string, string>) {\n const el = this.element as HTMLElement\n Object.entries(scale).forEach(([step, channels]) => {\n el.style.setProperty(`--${this.scaleTarget}-${step}-channels`, channels)\n })\n }\n\n private hexToHsl (hex: string): [number, number, number] {\n const r = parseInt(hex.slice(1, 3), 16) / 255\n const g = parseInt(hex.slice(3, 5), 16) / 255\n const b = parseInt(hex.slice(5, 7), 16) / 255\n\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const l = (max + min) / 2\n\n if (max === min) return [0, 0, l * 100]\n\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min)\n\n let h = 0\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n else if (max === g) h = ((b - r) / d + 2) / 6\n else h = ((r - g) / d + 4) / 6\n\n return [h * 360, s * 100, l * 100]\n }\n\n private hslToRgb (h: number, s: number, l: number): [number, number, number] {\n h /= 360\n s /= 100\n l /= 100\n\n if (s === 0) {\n const v = Math.round(l * 255)\n return [v, v, v]\n }\n\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n\n return [\n Math.round(this.hue2rgb(p, q, h + 1 / 3) * 255),\n Math.round(this.hue2rgb(p, q, h) * 255),\n Math.round(this.hue2rgb(p, q, h - 1 / 3) * 255)\n ]\n }\n\n private hue2rgb (p: number, q: number, t: number): number {\n if (t < 0) t += 1\n if (t > 1) t -= 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n }\n}\n"],"names":[],"mappings":"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"}
@@ -5,16 +5,37 @@ class CountdownTimer extends Controller {
5
5
  seconds: { type: Number, default: 5 }
6
6
  };
7
7
  timer = null;
8
+ remaining = 0;
9
+ startTime = 0;
8
10
  connect() {
9
- this.timer = setTimeout(() => {
10
- this.dispatch("complete", { bubbles: true });
11
- }, this.secondsValue * 1e3);
11
+ this.remaining = this.secondsValue * 1e3;
12
+ this.resume();
12
13
  }
13
14
  disconnect() {
14
- if (this.timer !== null) {
15
- clearTimeout(this.timer);
15
+ this.pause();
16
+ }
17
+ pause() {
18
+ if (this.timer === null)
19
+ return;
20
+ clearTimeout(this.timer);
21
+ this.timer = null;
22
+ this.remaining = Math.max(0, this.remaining - (Date.now() - this.startTime));
23
+ this.setPlayState("paused");
24
+ }
25
+ resume() {
26
+ if (this.timer !== null)
27
+ return;
28
+ this.startTime = Date.now();
29
+ this.timer = setTimeout(() => {
16
30
  this.timer = null;
17
- }
31
+ this.dispatch("complete", { bubbles: true });
32
+ }, this.remaining);
33
+ this.setPlayState("running");
34
+ }
35
+ setPlayState(state) {
36
+ const progress = this.element.querySelector(".midwest-countdown-timer__progress");
37
+ if (progress)
38
+ progress.style.animationPlayState = state;
18
39
  }
19
40
  }
20
41
 
@@ -1 +1 @@
1
- {"version":3,"file":"countdown_timer_component_controller.js","sources":["../../../../../../../app/components/midwest/countdown_timer_component/countdown_timer_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class CountdownTimer extends Controller {\n static values = {\n seconds: { type: Number, default: 5 }\n }\n\n declare secondsValue: number\n\n private timer: ReturnType<typeof setTimeout> | null = null\n\n connect () {\n this.timer = setTimeout(() => {\n this.dispatch('complete', { bubbles: true })\n }, this.secondsValue * 1000)\n }\n\n disconnect () {\n if (this.timer !== null) {\n clearTimeout(this.timer)\n this.timer = null\n }\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,uBAAuB,UAAW,CAAA;AAAA,EACrD,OAAO,MAAS,GAAA;AAAA,IACd,OAAS,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,CAAE,EAAA;AAAA,GACtC,CAAA;AAAA,EAIQ,KAA8C,GAAA,IAAA,CAAA;AAAA,EAEtD,OAAW,GAAA;AACT,IAAK,IAAA,CAAA,KAAA,GAAQ,WAAW,MAAM;AAC5B,MAAA,IAAA,CAAK,QAAS,CAAA,UAAA,EAAY,EAAE,OAAA,EAAS,MAAM,CAAA,CAAA;AAAA,KAC7C,EAAG,IAAK,CAAA,YAAA,GAAe,GAAI,CAAA,CAAA;AAAA,GAC7B;AAAA,EAEA,UAAc,GAAA;AACZ,IAAI,IAAA,IAAA,CAAK,UAAU,IAAM,EAAA;AACvB,MAAA,YAAA,CAAa,KAAK,KAAK,CAAA,CAAA;AACvB,MAAA,IAAA,CAAK,KAAQ,GAAA,IAAA,CAAA;AAAA,KACf;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"countdown_timer_component_controller.js","sources":["../../../../../../../app/components/midwest/countdown_timer_component/countdown_timer_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class CountdownTimer extends Controller {\n static values = {\n seconds: { type: Number, default: 5 }\n }\n\n declare secondsValue: number\n\n private timer: ReturnType<typeof setTimeout> | null = null\n private remaining = 0\n private startTime = 0\n\n connect () {\n this.remaining = this.secondsValue * 1000\n this.resume()\n }\n\n disconnect () {\n this.pause()\n }\n\n pause () {\n if (this.timer === null) return\n clearTimeout(this.timer)\n this.timer = null\n this.remaining = Math.max(0, this.remaining - (Date.now() - this.startTime))\n this.setPlayState('paused')\n }\n\n resume () {\n if (this.timer !== null) return // already running\n this.startTime = Date.now()\n this.timer = setTimeout(() => {\n this.timer = null\n this.dispatch('complete', { bubbles: true })\n }, this.remaining)\n this.setPlayState('running')\n }\n\n private setPlayState (state: 'running' | 'paused') {\n const progress = this.element.querySelector<SVGElement>('.midwest-countdown-timer__progress')\n if (progress) progress.style.animationPlayState = state\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAqB,uBAAuB,UAAW,CAAA;AAAA,EACrD,OAAO,MAAS,GAAA;AAAA,IACd,OAAS,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,CAAE,EAAA;AAAA,GACtC,CAAA;AAAA,EAIQ,KAA8C,GAAA,IAAA,CAAA;AAAA,EAC9C,SAAY,GAAA,CAAA,CAAA;AAAA,EACZ,SAAY,GAAA,CAAA,CAAA;AAAA,EAEpB,OAAW,GAAA;AACT,IAAK,IAAA,CAAA,SAAA,GAAY,KAAK,YAAe,GAAA,GAAA,CAAA;AACrC,IAAA,IAAA,CAAK,MAAO,EAAA,CAAA;AAAA,GACd;AAAA,EAEA,UAAc,GAAA;AACZ,IAAA,IAAA,CAAK,KAAM,EAAA,CAAA;AAAA,GACb;AAAA,EAEA,KAAS,GAAA;AACP,IAAA,IAAI,KAAK,KAAU,KAAA,IAAA;AAAM,MAAA,OAAA;AACzB,IAAA,YAAA,CAAa,KAAK,KAAK,CAAA,CAAA;AACvB,IAAA,IAAA,CAAK,KAAQ,GAAA,IAAA,CAAA;AACb,IAAK,IAAA,CAAA,SAAA,GAAY,IAAK,CAAA,GAAA,CAAI,CAAG,EAAA,IAAA,CAAK,aAAa,IAAK,CAAA,GAAA,EAAQ,GAAA,IAAA,CAAK,SAAU,CAAA,CAAA,CAAA;AAC3E,IAAA,IAAA,CAAK,aAAa,QAAQ,CAAA,CAAA;AAAA,GAC5B;AAAA,EAEA,MAAU,GAAA;AACR,IAAA,IAAI,KAAK,KAAU,KAAA,IAAA;AAAM,MAAA,OAAA;AACzB,IAAK,IAAA,CAAA,SAAA,GAAY,KAAK,GAAI,EAAA,CAAA;AAC1B,IAAK,IAAA,CAAA,KAAA,GAAQ,WAAW,MAAM;AAC5B,MAAA,IAAA,CAAK,KAAQ,GAAA,IAAA,CAAA;AACb,MAAA,IAAA,CAAK,QAAS,CAAA,UAAA,EAAY,EAAE,OAAA,EAAS,MAAM,CAAA,CAAA;AAAA,KAC7C,EAAG,KAAK,SAAS,CAAA,CAAA;AACjB,IAAA,IAAA,CAAK,aAAa,SAAS,CAAA,CAAA;AAAA,GAC7B;AAAA,EAEQ,aAAc,KAA6B,EAAA;AACjD,IAAA,MAAM,QAAW,GAAA,IAAA,CAAK,OAAQ,CAAA,aAAA,CAA0B,oCAAoC,CAAA,CAAA;AAC5F,IAAI,IAAA,QAAA;AAAU,MAAA,QAAA,CAAS,MAAM,kBAAqB,GAAA,KAAA,CAAA;AAAA,GACpD;AACF;;;;"}