@unabridged/midwest 0.21.1 → 0.22.1

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 (27) hide show
  1. package/README.md +63 -0
  2. package/app/assets/javascript/midwest/index.ts +8 -2
  3. package/app/assets/javascript/midwest.js +725 -20
  4. package/app/assets/javascript/midwest.js.map +1 -1
  5. package/app/assets/stylesheets/midwest.css +1 -1
  6. package/app/assets/stylesheets/midwest.tailwind.css +6 -1
  7. package/dist/css/midwest.css +1 -1
  8. package/dist/javascript/collection/app/assets/javascript/midwest/index.js +8 -2
  9. package/dist/javascript/collection/app/assets/javascript/midwest/index.js.map +1 -1
  10. package/dist/javascript/collection/app/components/midwest/code_block_component/code_block_component_controller.js +17 -0
  11. package/dist/javascript/collection/app/components/midwest/code_block_component/code_block_component_controller.js.map +1 -0
  12. package/dist/javascript/collection/app/components/midwest/dialog_component/dialog_component_controller.js.map +1 -1
  13. package/dist/javascript/collection/app/components/midwest/form/date_picker_component/date_picker_component_controller.js +243 -0
  14. package/dist/javascript/collection/app/components/midwest/form/date_picker_component/date_picker_component_controller.js.map +1 -0
  15. package/dist/javascript/collection/app/components/midwest/form/file_component/file_component_controller.js +35 -1
  16. package/dist/javascript/collection/app/components/midwest/form/file_component/file_component_controller.js.map +1 -1
  17. package/dist/javascript/collection/app/components/midwest/form/input_component/input_component_controller.js +72 -2
  18. package/dist/javascript/collection/app/components/midwest/form/input_component/input_component_controller.js.map +1 -1
  19. package/dist/javascript/collection/app/components/midwest/form/live_summary_component/live_summary_component_controller.js +12 -0
  20. package/dist/javascript/collection/app/components/midwest/form/live_summary_component/live_summary_component_controller.js.map +1 -1
  21. package/dist/javascript/collection/app/components/midwest/form/time_picker_component/time_picker_component_controller.js +164 -0
  22. package/dist/javascript/collection/app/components/midwest/form/time_picker_component/time_picker_component_controller.js.map +1 -0
  23. package/dist/javascript/collection/app/components/midwest/password_requirements_component/password_requirements_component_controller.js +194 -0
  24. package/dist/javascript/collection/app/components/midwest/password_requirements_component/password_requirements_component_controller.js.map +1 -0
  25. package/dist/javascript/midwest.js +725 -20
  26. package/dist/javascript/midwest.js.map +1 -1
  27. package/package.json +1 -1
@@ -21,10 +21,11 @@ const FORMATTERS = {
21
21
  }
22
22
  };
23
23
  class Input extends Controller {
24
- static targets = ["input", "counter", "capsLockWarning", "matchError"];
24
+ static targets = ["input", "counter", "capsLockWarning", "matchError", "validationError", "validationMessage"];
25
25
  static values = {
26
26
  match: { type: String, default: "" },
27
- autoformat: { type: String, default: "" }
27
+ autoformat: { type: String, default: "" },
28
+ validate: { type: Boolean, default: false }
28
29
  };
29
30
  updateClearButton = null;
30
31
  updateCounter = null;
@@ -35,6 +36,10 @@ class Input extends Controller {
35
36
  matchSourceListener = null;
36
37
  matchSourceElement = null;
37
38
  autoformatListener = null;
39
+ validateBlurListener = null;
40
+ validateInputListener = null;
41
+ validateInvalidListener = null;
42
+ hasTouched = false;
38
43
  connect() {
39
44
  this.applyColor();
40
45
  this.applySearchClear();
@@ -42,6 +47,7 @@ class Input extends Controller {
42
47
  this.applyPassword();
43
48
  this.applyMatch();
44
49
  this.applyAutoformat();
50
+ this.applyValidation();
45
51
  }
46
52
  disconnect() {
47
53
  if (this.updateClearButton) {
@@ -80,6 +86,18 @@ class Input extends Controller {
80
86
  this.inputTarget.removeEventListener("blur", this.autoformatListener);
81
87
  this.autoformatListener = null;
82
88
  }
89
+ if (this.validateBlurListener) {
90
+ this.inputTarget.removeEventListener("blur", this.validateBlurListener);
91
+ this.validateBlurListener = null;
92
+ }
93
+ if (this.validateInputListener) {
94
+ this.inputTarget.removeEventListener("input", this.validateInputListener);
95
+ this.validateInputListener = null;
96
+ }
97
+ if (this.validateInvalidListener) {
98
+ this.inputTarget.removeEventListener("invalid", this.validateInvalidListener);
99
+ this.validateInvalidListener = null;
100
+ }
83
101
  }
84
102
  increment() {
85
103
  const input = this.inputTarget;
@@ -240,6 +258,58 @@ class Input extends Controller {
240
258
  };
241
259
  this.inputTarget.addEventListener("blur", this.autoformatListener);
242
260
  }
261
+ // Shopify-style inline validation: validates on blur using the HTML5
262
+ // Constraint Validation API. Errors are shown inline after the first
263
+ // blur ("touched"), then re-validated on each input keystroke so the
264
+ // error clears as soon as the field becomes valid.
265
+ applyValidation() {
266
+ if (!this.validateValue)
267
+ return;
268
+ const showValidationError = (message) => {
269
+ this.element.classList.add("has-error", "theme-red");
270
+ this.element.classList.remove("is-valid");
271
+ if (this.hasValidationErrorTarget)
272
+ this.validationErrorTarget.hidden = false;
273
+ if (this.hasValidationMessageTarget)
274
+ this.validationMessageTarget.textContent = message;
275
+ };
276
+ const clearValidationError = () => {
277
+ this.element.classList.remove("has-error", "theme-red");
278
+ if (this.hasValidationErrorTarget)
279
+ this.validationErrorTarget.hidden = true;
280
+ if (this.hasValidationMessageTarget)
281
+ this.validationMessageTarget.textContent = "";
282
+ if (this.inputTarget.value) {
283
+ this.element.classList.add("is-valid");
284
+ } else {
285
+ this.element.classList.remove("is-valid");
286
+ }
287
+ };
288
+ const validate = () => {
289
+ if (!this.inputTarget.checkValidity()) {
290
+ showValidationError(this.inputTarget.validationMessage);
291
+ } else {
292
+ clearValidationError();
293
+ }
294
+ };
295
+ this.validateBlurListener = () => {
296
+ this.hasTouched = true;
297
+ validate();
298
+ };
299
+ this.validateInputListener = () => {
300
+ if (!this.hasTouched)
301
+ return;
302
+ validate();
303
+ };
304
+ this.validateInvalidListener = (e) => {
305
+ e.preventDefault();
306
+ this.hasTouched = true;
307
+ showValidationError(this.inputTarget.validationMessage);
308
+ };
309
+ this.inputTarget.addEventListener("blur", this.validateBlurListener);
310
+ this.inputTarget.addEventListener("input", this.validateInputListener);
311
+ this.inputTarget.addEventListener("invalid", this.validateInvalidListener);
312
+ }
243
313
  }
244
314
 
245
315
  export { Input as default };
@@ -1 +1 @@
1
- {"version":3,"file":"input_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/input_component/input_component_controller.ts"],"sourcesContent":["\nimport { Controller } from '@hotwired/stimulus'\n\n// Named formatters applied on blur when autoformat is set.\nconst FORMATTERS: Record<string, (value: string) => string> = {\n phone: (v: string) => {\n const d = v.replace(/\\D/g, '').slice(0, 10)\n if (d.length <= 3) return d\n if (d.length <= 6) return `(${d.slice(0, 3)}) ${d.slice(3)}`\n return `(${d.slice(0, 3)}) ${d.slice(3, 6)}-${d.slice(6)}`\n },\n credit_card: (v: string) => {\n const d = v.replace(/\\D/g, '').slice(0, 16)\n return d.match(/.{1,4}/g)?.join(' ') ?? d\n },\n zip: (v: string) => {\n const d = v.replace(/\\D/g, '')\n if (d.length <= 5) return d\n return `${d.slice(0, 5)}-${d.slice(5, 9)}`\n }\n}\n\nexport default class Input extends Controller<HTMLFormElement> {\n static targets = ['input', 'counter', 'capsLockWarning', 'matchError']\n static values = {\n match: { type: String, default: '' },\n autoformat: { type: String, default: '' }\n }\n\n declare readonly hasInputTarget: boolean\n declare readonly inputTarget: HTMLInputElement\n declare readonly inputTargets: HTMLInputElement[]\n declare readonly hasCounterTarget: boolean\n declare readonly counterTarget: HTMLElement\n declare readonly hasCapsLockWarningTarget: boolean\n declare readonly capsLockWarningTarget: HTMLElement\n declare readonly hasMatchErrorTarget: boolean\n declare readonly matchErrorTarget: HTMLElement\n declare matchValue: string\n declare autoformatValue: string\n\n private updateClearButton: (() => void) | null = null\n private updateCounter: (() => void) | null = null\n private updateCapsLock: ((e: KeyboardEvent | MouseEvent) => void) | null = null\n private hideCapsLock: (() => void) | null = null\n private matchListener: (() => void) | null = null\n private matchInvalidListener: ((e: Event) => void) | null = null\n private matchSourceListener: (() => void) | null = null\n private matchSourceElement: HTMLInputElement | null = null\n private autoformatListener: (() => void) | null = null\n\n connect () {\n this.applyColor()\n this.applySearchClear()\n this.applyCounter()\n this.applyPassword()\n this.applyMatch()\n this.applyAutoformat()\n }\n\n disconnect () {\n if (this.updateClearButton) {\n this.inputTarget.removeEventListener('input', this.updateClearButton)\n this.updateClearButton = null\n }\n if (this.updateCounter) {\n this.inputTarget.removeEventListener('input', this.updateCounter)\n this.updateCounter = null\n }\n if (this.updateCapsLock) {\n this.inputTarget.removeEventListener('keydown', this.updateCapsLock)\n this.inputTarget.removeEventListener('keyup', this.updateCapsLock)\n this.inputTarget.removeEventListener('mousedown', this.updateCapsLock)\n this.updateCapsLock = null\n }\n if (this.hideCapsLock) {\n this.inputTarget.removeEventListener('blur', this.hideCapsLock)\n this.hideCapsLock = null\n }\n if (this.matchListener) {\n this.inputTarget.removeEventListener('input', this.matchListener)\n this.inputTarget.removeEventListener('blur', this.matchListener)\n this.matchListener = null\n }\n if (this.matchInvalidListener) {\n this.inputTarget.removeEventListener('invalid', this.matchInvalidListener)\n this.matchInvalidListener = null\n }\n if (this.matchSourceListener && this.matchSourceElement) {\n this.matchSourceElement.removeEventListener('input', this.matchSourceListener)\n this.matchSourceListener = null\n this.matchSourceElement = null\n }\n if (this.autoformatListener) {\n this.inputTarget.removeEventListener('blur', this.autoformatListener)\n this.autoformatListener = null\n }\n }\n\n increment () {\n const input = this.inputTarget\n const step = parseFloat(input.step) || 1\n const max = input.max !== '' ? parseFloat(input.max) : Infinity\n const newValue = (parseFloat(input.value) || 0) + step\n if (newValue <= max) {\n input.value = String(newValue)\n input.dispatchEvent(new Event('input', { bubbles: true }))\n input.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n decrement () {\n const input = this.inputTarget\n const step = parseFloat(input.step) || 1\n const min = input.min !== '' ? parseFloat(input.min) : -Infinity\n const newValue = (parseFloat(input.value) || 0) - step\n if (newValue >= min) {\n input.value = String(newValue)\n input.dispatchEvent(new Event('input', { bubbles: true }))\n input.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n applyColor () {\n if (this.inputTarget.type !== 'color') {\n return\n }\n\n this.inputTarget.addEventListener('input', () => {\n this.inputTarget.setAttribute('value', this.inputTarget.value)\n })\n }\n\n private applyCounter () {\n if (!this.hasCounterTarget) return\n\n this.counterTarget.textContent = String(this.inputTarget.value.length)\n\n this.updateCounter = () => {\n this.counterTarget.textContent = String(this.inputTarget.value.length)\n }\n\n this.inputTarget.addEventListener('input', this.updateCounter)\n }\n\n private applyPassword () {\n if (!this.hasCapsLockWarningTarget) return\n\n this.updateCapsLock = (e: KeyboardEvent | MouseEvent) => {\n this.capsLockWarningTarget.hidden = !e.getModifierState('CapsLock')\n }\n\n this.hideCapsLock = () => {\n this.capsLockWarningTarget.hidden = true\n }\n\n this.inputTarget.addEventListener('keydown', this.updateCapsLock)\n this.inputTarget.addEventListener('keyup', this.updateCapsLock)\n this.inputTarget.addEventListener('mousedown', this.updateCapsLock)\n this.inputTarget.addEventListener('blur', this.hideCapsLock)\n }\n\n private applySearchClear () {\n if (this.inputTarget.type !== 'search') return\n // Browsers that natively render a cancel button (Chrome, Safari, Edge)\n // already handle clearing. Only inject for browsers that don't (Firefox).\n if (CSS.supports('selector(::-webkit-search-cancel-button)')) return\n\n const button = document.createElement('button')\n button.type = 'button'\n button.setAttribute('aria-label', 'Clear search')\n button.classList.add('midwest-input-search-clear')\n button.hidden = this.inputTarget.value.length === 0\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('aria-hidden', 'true')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('stroke-linecap', 'round')\n path.setAttribute('stroke-linejoin', 'round')\n path.setAttribute('d', 'M6 18L18 6M6 6l12 12')\n svg.appendChild(path)\n button.appendChild(svg)\n\n const wrapper = document.createElement('div')\n wrapper.classList.add('midwest-input-search-wrapper')\n this.inputTarget.parentElement?.insertBefore(wrapper, this.inputTarget)\n wrapper.appendChild(this.inputTarget)\n wrapper.appendChild(button)\n\n this.updateClearButton = () => {\n button.hidden = this.inputTarget.value.length === 0\n }\n\n this.inputTarget.addEventListener('input', this.updateClearButton)\n\n button.addEventListener('click', () => {\n this.inputTarget.value = ''\n button.hidden = true\n this.inputTarget.dispatchEvent(new Event('input', { bubbles: true }))\n this.inputTarget.focus()\n })\n }\n\n // Validates that this field's value matches the value of the element\n // identified by matchValue (a CSS selector). Uses setCustomValidity to\n // block form submission. Shows the error inline via the matchError target\n // rather than the browser's native tooltip (invalid event is suppressed).\n private applyMatch () {\n if (!this.matchValue) return\n\n const showError = () => {\n this.element.classList.add('has-error', 'theme-red')\n if (this.hasMatchErrorTarget) this.matchErrorTarget.hidden = false\n }\n\n const clearError = () => {\n this.element.classList.remove('has-error', 'theme-red')\n if (this.hasMatchErrorTarget) this.matchErrorTarget.hidden = true\n }\n\n const validate = () => {\n const other = document.querySelector<HTMLInputElement>(this.matchValue)\n if (!this.inputTarget.value) {\n this.inputTarget.setCustomValidity('')\n clearError()\n return\n }\n if (!other || this.inputTarget.value === other.value) {\n this.inputTarget.setCustomValidity('')\n clearError()\n } else {\n this.inputTarget.setCustomValidity('Values do not match')\n showError()\n }\n }\n\n this.matchListener = validate\n this.inputTarget.addEventListener('input', validate)\n this.inputTarget.addEventListener('blur', validate)\n\n // Suppress the browser's native validation tooltip on form submission;\n // our inline error element already shows the message.\n this.matchInvalidListener = (e: Event) => {\n e.preventDefault()\n showError()\n }\n this.inputTarget.addEventListener('invalid', this.matchInvalidListener)\n\n // Re-validate when the source field changes so the confirmation stays\n // in sync even if the user goes back and edits the original value.\n const other = document.querySelector<HTMLInputElement>(this.matchValue)\n if (other) {\n this.matchSourceElement = other\n this.matchSourceListener = validate\n other.addEventListener('input', validate)\n }\n }\n\n // Reformats the input value on blur using a named formatter from FORMATTERS.\n // Dispatches input + change events after reformatting so downstream\n // listeners (counters, form state) stay in sync.\n private applyAutoformat () {\n if (!this.autoformatValue) return\n const fmt = FORMATTERS[this.autoformatValue]\n if (!fmt) return\n\n this.autoformatListener = () => {\n const formatted = fmt(this.inputTarget.value)\n if (formatted !== this.inputTarget.value) {\n this.inputTarget.value = formatted\n this.inputTarget.dispatchEvent(new Event('input', { bubbles: true }))\n this.inputTarget.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n this.inputTarget.addEventListener('blur', this.autoformatListener)\n }\n}\n"],"names":["other"],"mappings":"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"}
1
+ {"version":3,"file":"input_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/input_component/input_component_controller.ts"],"sourcesContent":["\nimport { Controller } from '@hotwired/stimulus'\n\n// Named formatters applied on blur when autoformat is set.\nconst FORMATTERS: Record<string, (value: string) => string> = {\n phone: (v: string) => {\n const d = v.replace(/\\D/g, '').slice(0, 10)\n if (d.length <= 3) return d\n if (d.length <= 6) return `(${d.slice(0, 3)}) ${d.slice(3)}`\n return `(${d.slice(0, 3)}) ${d.slice(3, 6)}-${d.slice(6)}`\n },\n credit_card: (v: string) => {\n const d = v.replace(/\\D/g, '').slice(0, 16)\n return d.match(/.{1,4}/g)?.join(' ') ?? d\n },\n zip: (v: string) => {\n const d = v.replace(/\\D/g, '')\n if (d.length <= 5) return d\n return `${d.slice(0, 5)}-${d.slice(5, 9)}`\n }\n}\n\nexport default class Input extends Controller<HTMLFormElement> {\n static targets = ['input', 'counter', 'capsLockWarning', 'matchError', 'validationError', 'validationMessage']\n static values = {\n match: { type: String, default: '' },\n autoformat: { type: String, default: '' },\n validate: { type: Boolean, default: false }\n }\n\n declare readonly hasInputTarget: boolean\n declare readonly inputTarget: HTMLInputElement\n declare readonly inputTargets: HTMLInputElement[]\n declare readonly hasCounterTarget: boolean\n declare readonly counterTarget: HTMLElement\n declare readonly hasCapsLockWarningTarget: boolean\n declare readonly capsLockWarningTarget: HTMLElement\n declare readonly hasMatchErrorTarget: boolean\n declare readonly matchErrorTarget: HTMLElement\n declare readonly hasValidationErrorTarget: boolean\n declare readonly validationErrorTarget: HTMLElement\n declare readonly hasValidationMessageTarget: boolean\n declare readonly validationMessageTarget: HTMLElement\n declare matchValue: string\n declare autoformatValue: string\n declare validateValue: boolean\n\n private updateClearButton: (() => void) | null = null\n private updateCounter: (() => void) | null = null\n private updateCapsLock: ((e: KeyboardEvent | MouseEvent) => void) | null = null\n private hideCapsLock: (() => void) | null = null\n private matchListener: (() => void) | null = null\n private matchInvalidListener: ((e: Event) => void) | null = null\n private matchSourceListener: (() => void) | null = null\n private matchSourceElement: HTMLInputElement | null = null\n private autoformatListener: (() => void) | null = null\n private validateBlurListener: (() => void) | null = null\n private validateInputListener: (() => void) | null = null\n private validateInvalidListener: ((e: Event) => void) | null = null\n private hasTouched = false\n\n connect () {\n this.applyColor()\n this.applySearchClear()\n this.applyCounter()\n this.applyPassword()\n this.applyMatch()\n this.applyAutoformat()\n this.applyValidation()\n }\n\n disconnect () {\n if (this.updateClearButton) {\n this.inputTarget.removeEventListener('input', this.updateClearButton)\n this.updateClearButton = null\n }\n if (this.updateCounter) {\n this.inputTarget.removeEventListener('input', this.updateCounter)\n this.updateCounter = null\n }\n if (this.updateCapsLock) {\n this.inputTarget.removeEventListener('keydown', this.updateCapsLock)\n this.inputTarget.removeEventListener('keyup', this.updateCapsLock)\n this.inputTarget.removeEventListener('mousedown', this.updateCapsLock)\n this.updateCapsLock = null\n }\n if (this.hideCapsLock) {\n this.inputTarget.removeEventListener('blur', this.hideCapsLock)\n this.hideCapsLock = null\n }\n if (this.matchListener) {\n this.inputTarget.removeEventListener('input', this.matchListener)\n this.inputTarget.removeEventListener('blur', this.matchListener)\n this.matchListener = null\n }\n if (this.matchInvalidListener) {\n this.inputTarget.removeEventListener('invalid', this.matchInvalidListener)\n this.matchInvalidListener = null\n }\n if (this.matchSourceListener && this.matchSourceElement) {\n this.matchSourceElement.removeEventListener('input', this.matchSourceListener)\n this.matchSourceListener = null\n this.matchSourceElement = null\n }\n if (this.autoformatListener) {\n this.inputTarget.removeEventListener('blur', this.autoformatListener)\n this.autoformatListener = null\n }\n if (this.validateBlurListener) {\n this.inputTarget.removeEventListener('blur', this.validateBlurListener)\n this.validateBlurListener = null\n }\n if (this.validateInputListener) {\n this.inputTarget.removeEventListener('input', this.validateInputListener)\n this.validateInputListener = null\n }\n if (this.validateInvalidListener) {\n this.inputTarget.removeEventListener('invalid', this.validateInvalidListener)\n this.validateInvalidListener = null\n }\n }\n\n increment () {\n const input = this.inputTarget\n const step = parseFloat(input.step) || 1\n const max = input.max !== '' ? parseFloat(input.max) : Infinity\n const newValue = (parseFloat(input.value) || 0) + step\n if (newValue <= max) {\n input.value = String(newValue)\n input.dispatchEvent(new Event('input', { bubbles: true }))\n input.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n decrement () {\n const input = this.inputTarget\n const step = parseFloat(input.step) || 1\n const min = input.min !== '' ? parseFloat(input.min) : -Infinity\n const newValue = (parseFloat(input.value) || 0) - step\n if (newValue >= min) {\n input.value = String(newValue)\n input.dispatchEvent(new Event('input', { bubbles: true }))\n input.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n applyColor () {\n if (this.inputTarget.type !== 'color') {\n return\n }\n\n this.inputTarget.addEventListener('input', () => {\n this.inputTarget.setAttribute('value', this.inputTarget.value)\n })\n }\n\n private applyCounter () {\n if (!this.hasCounterTarget) return\n\n this.counterTarget.textContent = String(this.inputTarget.value.length)\n\n this.updateCounter = () => {\n this.counterTarget.textContent = String(this.inputTarget.value.length)\n }\n\n this.inputTarget.addEventListener('input', this.updateCounter)\n }\n\n private applyPassword () {\n if (!this.hasCapsLockWarningTarget) return\n\n this.updateCapsLock = (e: KeyboardEvent | MouseEvent) => {\n this.capsLockWarningTarget.hidden = !e.getModifierState('CapsLock')\n }\n\n this.hideCapsLock = () => {\n this.capsLockWarningTarget.hidden = true\n }\n\n this.inputTarget.addEventListener('keydown', this.updateCapsLock)\n this.inputTarget.addEventListener('keyup', this.updateCapsLock)\n this.inputTarget.addEventListener('mousedown', this.updateCapsLock)\n this.inputTarget.addEventListener('blur', this.hideCapsLock)\n }\n\n private applySearchClear () {\n if (this.inputTarget.type !== 'search') return\n // Browsers that natively render a cancel button (Chrome, Safari, Edge)\n // already handle clearing. Only inject for browsers that don't (Firefox).\n if (CSS.supports('selector(::-webkit-search-cancel-button)')) return\n\n const button = document.createElement('button')\n button.type = 'button'\n button.setAttribute('aria-label', 'Clear search')\n button.classList.add('midwest-input-search-clear')\n button.hidden = this.inputTarget.value.length === 0\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('aria-hidden', 'true')\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n path.setAttribute('stroke-linecap', 'round')\n path.setAttribute('stroke-linejoin', 'round')\n path.setAttribute('d', 'M6 18L18 6M6 6l12 12')\n svg.appendChild(path)\n button.appendChild(svg)\n\n const wrapper = document.createElement('div')\n wrapper.classList.add('midwest-input-search-wrapper')\n this.inputTarget.parentElement?.insertBefore(wrapper, this.inputTarget)\n wrapper.appendChild(this.inputTarget)\n wrapper.appendChild(button)\n\n this.updateClearButton = () => {\n button.hidden = this.inputTarget.value.length === 0\n }\n\n this.inputTarget.addEventListener('input', this.updateClearButton)\n\n button.addEventListener('click', () => {\n this.inputTarget.value = ''\n button.hidden = true\n this.inputTarget.dispatchEvent(new Event('input', { bubbles: true }))\n this.inputTarget.focus()\n })\n }\n\n // Validates that this field's value matches the value of the element\n // identified by matchValue (a CSS selector). Uses setCustomValidity to\n // block form submission. Shows the error inline via the matchError target\n // rather than the browser's native tooltip (invalid event is suppressed).\n private applyMatch () {\n if (!this.matchValue) return\n\n const showError = () => {\n this.element.classList.add('has-error', 'theme-red')\n if (this.hasMatchErrorTarget) this.matchErrorTarget.hidden = false\n }\n\n const clearError = () => {\n this.element.classList.remove('has-error', 'theme-red')\n if (this.hasMatchErrorTarget) this.matchErrorTarget.hidden = true\n }\n\n const validate = () => {\n const other = document.querySelector<HTMLInputElement>(this.matchValue)\n if (!this.inputTarget.value) {\n this.inputTarget.setCustomValidity('')\n clearError()\n return\n }\n if (!other || this.inputTarget.value === other.value) {\n this.inputTarget.setCustomValidity('')\n clearError()\n } else {\n this.inputTarget.setCustomValidity('Values do not match')\n showError()\n }\n }\n\n this.matchListener = validate\n this.inputTarget.addEventListener('input', validate)\n this.inputTarget.addEventListener('blur', validate)\n\n // Suppress the browser's native validation tooltip on form submission;\n // our inline error element already shows the message.\n this.matchInvalidListener = (e: Event) => {\n e.preventDefault()\n showError()\n }\n this.inputTarget.addEventListener('invalid', this.matchInvalidListener)\n\n // Re-validate when the source field changes so the confirmation stays\n // in sync even if the user goes back and edits the original value.\n const other = document.querySelector<HTMLInputElement>(this.matchValue)\n if (other) {\n this.matchSourceElement = other\n this.matchSourceListener = validate\n other.addEventListener('input', validate)\n }\n }\n\n // Reformats the input value on blur using a named formatter from FORMATTERS.\n // Dispatches input + change events after reformatting so downstream\n // listeners (counters, form state) stay in sync.\n private applyAutoformat () {\n if (!this.autoformatValue) return\n const fmt = FORMATTERS[this.autoformatValue]\n if (!fmt) return\n\n this.autoformatListener = () => {\n const formatted = fmt(this.inputTarget.value)\n if (formatted !== this.inputTarget.value) {\n this.inputTarget.value = formatted\n this.inputTarget.dispatchEvent(new Event('input', { bubbles: true }))\n this.inputTarget.dispatchEvent(new Event('change', { bubbles: true }))\n }\n }\n\n this.inputTarget.addEventListener('blur', this.autoformatListener)\n }\n\n // Shopify-style inline validation: validates on blur using the HTML5\n // Constraint Validation API. Errors are shown inline after the first\n // blur (\"touched\"), then re-validated on each input keystroke so the\n // error clears as soon as the field becomes valid.\n private applyValidation () {\n if (!this.validateValue) return\n\n const showValidationError = (message: string) => {\n this.element.classList.add('has-error', 'theme-red')\n this.element.classList.remove('is-valid')\n if (this.hasValidationErrorTarget) this.validationErrorTarget.hidden = false\n if (this.hasValidationMessageTarget) this.validationMessageTarget.textContent = message\n }\n\n const clearValidationError = () => {\n this.element.classList.remove('has-error', 'theme-red')\n if (this.hasValidationErrorTarget) this.validationErrorTarget.hidden = true\n if (this.hasValidationMessageTarget) this.validationMessageTarget.textContent = ''\n if (this.inputTarget.value) {\n this.element.classList.add('is-valid')\n } else {\n this.element.classList.remove('is-valid')\n }\n }\n\n const validate = () => {\n if (!this.inputTarget.checkValidity()) {\n showValidationError(this.inputTarget.validationMessage)\n } else {\n clearValidationError()\n }\n }\n\n this.validateBlurListener = () => {\n this.hasTouched = true\n validate()\n }\n\n this.validateInputListener = () => {\n if (!this.hasTouched) return\n validate()\n }\n\n this.validateInvalidListener = (e: Event) => {\n e.preventDefault()\n this.hasTouched = true\n showValidationError(this.inputTarget.validationMessage)\n }\n\n this.inputTarget.addEventListener('blur', this.validateBlurListener)\n this.inputTarget.addEventListener('input', this.validateInputListener)\n this.inputTarget.addEventListener('invalid', this.validateInvalidListener)\n }\n}\n"],"names":["other"],"mappings":";;AAIA,MAAM,UAAwD,GAAA;AAAA,EAC5D,KAAA,EAAO,CAAC,CAAc,KAAA;AACpB,IAAM,MAAA,CAAA,GAAI,EAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAE,CAAA,KAAA,CAAM,GAAG,EAAE,CAAA,CAAA;AAC1C,IAAA,IAAI,EAAE,MAAU,IAAA,CAAA;AAAG,MAAO,OAAA,CAAA,CAAA;AAC1B,IAAA,IAAI,EAAE,MAAU,IAAA,CAAA;AAAG,MAAO,OAAA,CAAA,CAAA,EAAI,EAAE,KAAM,CAAA,CAAA,EAAG,CAAC,CAAM,CAAA,EAAA,EAAA,CAAA,CAAE,MAAM,CAAC,CAAA,CAAA,CAAA,CAAA;AACzD,IAAA,OAAO,CAAI,CAAA,EAAA,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,CAAC,CAAA,CAAA,EAAA,EAAM,CAAE,CAAA,KAAA,CAAM,CAAG,EAAA,CAAC,CAAK,CAAA,CAAA,EAAA,CAAA,CAAE,MAAM,CAAC,CAAA,CAAA,CAAA,CAAA;AAAA,GACzD;AAAA,EACA,WAAA,EAAa,CAAC,CAAc,KAAA;AAC1B,IAAM,MAAA,CAAA,GAAI,EAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAE,CAAA,KAAA,CAAM,GAAG,EAAE,CAAA,CAAA;AAC1C,IAAA,OAAO,EAAE,KAAM,CAAA,SAAS,CAAG,EAAA,IAAA,CAAK,GAAG,CAAK,IAAA,CAAA,CAAA;AAAA,GAC1C;AAAA,EACA,GAAA,EAAK,CAAC,CAAc,KAAA;AAClB,IAAA,MAAM,CAAI,GAAA,CAAA,CAAE,OAAQ,CAAA,KAAA,EAAO,EAAE,CAAA,CAAA;AAC7B,IAAA,IAAI,EAAE,MAAU,IAAA,CAAA;AAAG,MAAO,OAAA,CAAA,CAAA;AAC1B,IAAO,OAAA,CAAA,EAAG,EAAE,KAAM,CAAA,CAAA,EAAG,CAAC,CAAK,CAAA,CAAA,EAAA,CAAA,CAAE,KAAM,CAAA,CAAA,EAAG,CAAC,CAAA,CAAA,CAAA,CAAA;AAAA,GACzC;AACF,CAAA,CAAA;AAEA,MAAqB,cAAc,UAA4B,CAAA;AAAA,EAC7D,OAAO,UAAU,CAAC,OAAA,EAAS,WAAW,iBAAmB,EAAA,YAAA,EAAc,mBAAmB,mBAAmB,CAAA,CAAA;AAAA,EAC7G,OAAO,MAAS,GAAA;AAAA,IACd,KAAO,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IACnC,UAAY,EAAA,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,EAAG,EAAA;AAAA,IACxC,QAAU,EAAA,EAAE,IAAM,EAAA,OAAA,EAAS,SAAS,KAAM,EAAA;AAAA,GAC5C,CAAA;AAAA,EAmBQ,iBAAyC,GAAA,IAAA,CAAA;AAAA,EACzC,aAAqC,GAAA,IAAA,CAAA;AAAA,EACrC,cAAmE,GAAA,IAAA,CAAA;AAAA,EACnE,YAAoC,GAAA,IAAA,CAAA;AAAA,EACpC,aAAqC,GAAA,IAAA,CAAA;AAAA,EACrC,oBAAoD,GAAA,IAAA,CAAA;AAAA,EACpD,mBAA2C,GAAA,IAAA,CAAA;AAAA,EAC3C,kBAA8C,GAAA,IAAA,CAAA;AAAA,EAC9C,kBAA0C,GAAA,IAAA,CAAA;AAAA,EAC1C,oBAA4C,GAAA,IAAA,CAAA;AAAA,EAC5C,qBAA6C,GAAA,IAAA,CAAA;AAAA,EAC7C,uBAAuD,GAAA,IAAA,CAAA;AAAA,EACvD,UAAa,GAAA,KAAA,CAAA;AAAA,EAErB,OAAW,GAAA;AACT,IAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAChB,IAAA,IAAA,CAAK,gBAAiB,EAAA,CAAA;AACtB,IAAA,IAAA,CAAK,YAAa,EAAA,CAAA;AAClB,IAAA,IAAA,CAAK,aAAc,EAAA,CAAA;AACnB,IAAA,IAAA,CAAK,UAAW,EAAA,CAAA;AAChB,IAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AACrB,IAAA,IAAA,CAAK,eAAgB,EAAA,CAAA;AAAA,GACvB;AAAA,EAEA,UAAc,GAAA;AACZ,IAAA,IAAI,KAAK,iBAAmB,EAAA;AAC1B,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,iBAAiB,CAAA,CAAA;AACpE,MAAA,IAAA,CAAK,iBAAoB,GAAA,IAAA,CAAA;AAAA,KAC3B;AACA,IAAA,IAAI,KAAK,aAAe,EAAA;AACtB,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAChE,MAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAA;AAAA,KACvB;AACA,IAAA,IAAI,KAAK,cAAgB,EAAA;AACvB,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,SAAW,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AACnE,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AACjE,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,WAAa,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AACrE,MAAA,IAAA,CAAK,cAAiB,GAAA,IAAA,CAAA;AAAA,KACxB;AACA,IAAA,IAAI,KAAK,YAAc,EAAA;AACrB,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,MAAQ,EAAA,IAAA,CAAK,YAAY,CAAA,CAAA;AAC9D,MAAA,IAAA,CAAK,YAAe,GAAA,IAAA,CAAA;AAAA,KACtB;AACA,IAAA,IAAI,KAAK,aAAe,EAAA;AACtB,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAChE,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,MAAQ,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAC/D,MAAA,IAAA,CAAK,aAAgB,GAAA,IAAA,CAAA;AAAA,KACvB;AACA,IAAA,IAAI,KAAK,oBAAsB,EAAA;AAC7B,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,SAAW,EAAA,IAAA,CAAK,oBAAoB,CAAA,CAAA;AACzE,MAAA,IAAA,CAAK,oBAAuB,GAAA,IAAA,CAAA;AAAA,KAC9B;AACA,IAAI,IAAA,IAAA,CAAK,mBAAuB,IAAA,IAAA,CAAK,kBAAoB,EAAA;AACvD,MAAA,IAAA,CAAK,kBAAmB,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,mBAAmB,CAAA,CAAA;AAC7E,MAAA,IAAA,CAAK,mBAAsB,GAAA,IAAA,CAAA;AAC3B,MAAA,IAAA,CAAK,kBAAqB,GAAA,IAAA,CAAA;AAAA,KAC5B;AACA,IAAA,IAAI,KAAK,kBAAoB,EAAA;AAC3B,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,MAAQ,EAAA,IAAA,CAAK,kBAAkB,CAAA,CAAA;AACpE,MAAA,IAAA,CAAK,kBAAqB,GAAA,IAAA,CAAA;AAAA,KAC5B;AACA,IAAA,IAAI,KAAK,oBAAsB,EAAA;AAC7B,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,MAAQ,EAAA,IAAA,CAAK,oBAAoB,CAAA,CAAA;AACtE,MAAA,IAAA,CAAK,oBAAuB,GAAA,IAAA,CAAA;AAAA,KAC9B;AACA,IAAA,IAAI,KAAK,qBAAuB,EAAA;AAC9B,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,OAAS,EAAA,IAAA,CAAK,qBAAqB,CAAA,CAAA;AACxE,MAAA,IAAA,CAAK,qBAAwB,GAAA,IAAA,CAAA;AAAA,KAC/B;AACA,IAAA,IAAI,KAAK,uBAAyB,EAAA;AAChC,MAAA,IAAA,CAAK,WAAY,CAAA,mBAAA,CAAoB,SAAW,EAAA,IAAA,CAAK,uBAAuB,CAAA,CAAA;AAC5E,MAAA,IAAA,CAAK,uBAA0B,GAAA,IAAA,CAAA;AAAA,KACjC;AAAA,GACF;AAAA,EAEA,SAAa,GAAA;AACX,IAAA,MAAM,QAAQ,IAAK,CAAA,WAAA,CAAA;AACnB,IAAA,MAAM,IAAO,GAAA,UAAA,CAAW,KAAM,CAAA,IAAI,CAAK,IAAA,CAAA,CAAA;AACvC,IAAA,MAAM,MAAM,KAAM,CAAA,GAAA,KAAQ,KAAK,UAAW,CAAA,KAAA,CAAM,GAAG,CAAI,GAAA,QAAA,CAAA;AACvD,IAAA,MAAM,QAAY,GAAA,CAAA,UAAA,CAAW,KAAM,CAAA,KAAK,KAAK,CAAK,IAAA,IAAA,CAAA;AAClD,IAAA,IAAI,YAAY,GAAK,EAAA;AACnB,MAAM,KAAA,CAAA,KAAA,GAAQ,OAAO,QAAQ,CAAA,CAAA;AAC7B,MAAM,KAAA,CAAA,aAAA,CAAc,IAAI,KAAM,CAAA,OAAA,EAAS,EAAE,OAAS,EAAA,IAAA,EAAM,CAAC,CAAA,CAAA;AACzD,MAAM,KAAA,CAAA,aAAA,CAAc,IAAI,KAAM,CAAA,QAAA,EAAU,EAAE,OAAS,EAAA,IAAA,EAAM,CAAC,CAAA,CAAA;AAAA,KAC5D;AAAA,GACF;AAAA,EAEA,SAAa,GAAA;AACX,IAAA,MAAM,QAAQ,IAAK,CAAA,WAAA,CAAA;AACnB,IAAA,MAAM,IAAO,GAAA,UAAA,CAAW,KAAM,CAAA,IAAI,CAAK,IAAA,CAAA,CAAA;AACvC,IAAA,MAAM,MAAM,KAAM,CAAA,GAAA,KAAQ,KAAK,UAAW,CAAA,KAAA,CAAM,GAAG,CAAI,GAAA,CAAA,QAAA,CAAA;AACvD,IAAA,MAAM,QAAY,GAAA,CAAA,UAAA,CAAW,KAAM,CAAA,KAAK,KAAK,CAAK,IAAA,IAAA,CAAA;AAClD,IAAA,IAAI,YAAY,GAAK,EAAA;AACnB,MAAM,KAAA,CAAA,KAAA,GAAQ,OAAO,QAAQ,CAAA,CAAA;AAC7B,MAAM,KAAA,CAAA,aAAA,CAAc,IAAI,KAAM,CAAA,OAAA,EAAS,EAAE,OAAS,EAAA,IAAA,EAAM,CAAC,CAAA,CAAA;AACzD,MAAM,KAAA,CAAA,aAAA,CAAc,IAAI,KAAM,CAAA,QAAA,EAAU,EAAE,OAAS,EAAA,IAAA,EAAM,CAAC,CAAA,CAAA;AAAA,KAC5D;AAAA,GACF;AAAA,EAEA,UAAc,GAAA;AACZ,IAAI,IAAA,IAAA,CAAK,WAAY,CAAA,IAAA,KAAS,OAAS,EAAA;AACrC,MAAA,OAAA;AAAA,KACF;AAEA,IAAK,IAAA,CAAA,WAAA,CAAY,gBAAiB,CAAA,OAAA,EAAS,MAAM;AAC/C,MAAA,IAAA,CAAK,WAAY,CAAA,YAAA,CAAa,OAAS,EAAA,IAAA,CAAK,YAAY,KAAK,CAAA,CAAA;AAAA,KAC9D,CAAA,CAAA;AAAA,GACH;AAAA,EAEQ,YAAgB,GAAA;AACtB,IAAA,IAAI,CAAC,IAAK,CAAA,gBAAA;AAAkB,MAAA,OAAA;AAE5B,IAAA,IAAA,CAAK,cAAc,WAAc,GAAA,MAAA,CAAO,IAAK,CAAA,WAAA,CAAY,MAAM,MAAM,CAAA,CAAA;AAErE,IAAA,IAAA,CAAK,gBAAgB,MAAM;AACzB,MAAA,IAAA,CAAK,cAAc,WAAc,GAAA,MAAA,CAAO,IAAK,CAAA,WAAA,CAAY,MAAM,MAAM,CAAA,CAAA;AAAA,KACvE,CAAA;AAEA,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,OAAS,EAAA,IAAA,CAAK,aAAa,CAAA,CAAA;AAAA,GAC/D;AAAA,EAEQ,aAAiB,GAAA;AACvB,IAAA,IAAI,CAAC,IAAK,CAAA,wBAAA;AAA0B,MAAA,OAAA;AAEpC,IAAK,IAAA,CAAA,cAAA,GAAiB,CAAC,CAAkC,KAAA;AACvD,MAAA,IAAA,CAAK,qBAAsB,CAAA,MAAA,GAAS,CAAC,CAAA,CAAE,iBAAiB,UAAU,CAAA,CAAA;AAAA,KACpE,CAAA;AAEA,IAAA,IAAA,CAAK,eAAe,MAAM;AACxB,MAAA,IAAA,CAAK,sBAAsB,MAAS,GAAA,IAAA,CAAA;AAAA,KACtC,CAAA;AAEA,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,SAAW,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AAChE,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,OAAS,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AAC9D,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,WAAa,EAAA,IAAA,CAAK,cAAc,CAAA,CAAA;AAClE,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,MAAQ,EAAA,IAAA,CAAK,YAAY,CAAA,CAAA;AAAA,GAC7D;AAAA,EAEQ,gBAAoB,GAAA;AAC1B,IAAI,IAAA,IAAA,CAAK,YAAY,IAAS,KAAA,QAAA;AAAU,MAAA,OAAA;AAGxC,IAAI,IAAA,GAAA,CAAI,SAAS,0CAA0C,CAAA;AAAG,MAAA,OAAA;AAE9D,IAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA,CAAA;AAC9C,IAAA,MAAA,CAAO,IAAO,GAAA,QAAA,CAAA;AACd,IAAO,MAAA,CAAA,YAAA,CAAa,cAAc,cAAc,CAAA,CAAA;AAChD,IAAO,MAAA,CAAA,SAAA,CAAU,IAAI,4BAA4B,CAAA,CAAA;AACjD,IAAA,MAAA,CAAO,MAAS,GAAA,IAAA,CAAK,WAAY,CAAA,KAAA,CAAM,MAAW,KAAA,CAAA,CAAA;AAElD,IAAA,MAAM,GAAM,GAAA,QAAA,CAAS,eAAgB,CAAA,4BAAA,EAA8B,KAAK,CAAA,CAAA;AACxE,IAAI,GAAA,CAAA,YAAA,CAAa,WAAW,WAAW,CAAA,CAAA;AACvC,IAAI,GAAA,CAAA,YAAA,CAAa,QAAQ,MAAM,CAAA,CAAA;AAC/B,IAAI,GAAA,CAAA,YAAA,CAAa,UAAU,cAAc,CAAA,CAAA;AACzC,IAAI,GAAA,CAAA,YAAA,CAAa,gBAAgB,GAAG,CAAA,CAAA;AACpC,IAAI,GAAA,CAAA,YAAA,CAAa,eAAe,MAAM,CAAA,CAAA;AACtC,IAAI,GAAA,CAAA,YAAA,CAAa,SAAS,IAAI,CAAA,CAAA;AAC9B,IAAI,GAAA,CAAA,YAAA,CAAa,UAAU,IAAI,CAAA,CAAA;AAE/B,IAAA,MAAM,IAAO,GAAA,QAAA,CAAS,eAAgB,CAAA,4BAAA,EAA8B,MAAM,CAAA,CAAA;AAC1E,IAAK,IAAA,CAAA,YAAA,CAAa,kBAAkB,OAAO,CAAA,CAAA;AAC3C,IAAK,IAAA,CAAA,YAAA,CAAa,mBAAmB,OAAO,CAAA,CAAA;AAC5C,IAAK,IAAA,CAAA,YAAA,CAAa,KAAK,sBAAsB,CAAA,CAAA;AAC7C,IAAA,GAAA,CAAI,YAAY,IAAI,CAAA,CAAA;AACpB,IAAA,MAAA,CAAO,YAAY,GAAG,CAAA,CAAA;AAEtB,IAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,KAAK,CAAA,CAAA;AAC5C,IAAQ,OAAA,CAAA,SAAA,CAAU,IAAI,8BAA8B,CAAA,CAAA;AACpD,IAAA,IAAA,CAAK,WAAY,CAAA,aAAA,EAAe,YAAa,CAAA,OAAA,EAAS,KAAK,WAAW,CAAA,CAAA;AACtE,IAAQ,OAAA,CAAA,WAAA,CAAY,KAAK,WAAW,CAAA,CAAA;AACpC,IAAA,OAAA,CAAQ,YAAY,MAAM,CAAA,CAAA;AAE1B,IAAA,IAAA,CAAK,oBAAoB,MAAM;AAC7B,MAAA,MAAA,CAAO,MAAS,GAAA,IAAA,CAAK,WAAY,CAAA,KAAA,CAAM,MAAW,KAAA,CAAA,CAAA;AAAA,KACpD,CAAA;AAEA,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,OAAS,EAAA,IAAA,CAAK,iBAAiB,CAAA,CAAA;AAEjE,IAAO,MAAA,CAAA,gBAAA,CAAiB,SAAS,MAAM;AACrC,MAAA,IAAA,CAAK,YAAY,KAAQ,GAAA,EAAA,CAAA;AACzB,MAAA,MAAA,CAAO,MAAS,GAAA,IAAA,CAAA;AAChB,MAAK,IAAA,CAAA,WAAA,CAAY,cAAc,IAAI,KAAA,CAAM,SAAS,EAAE,OAAA,EAAS,IAAK,EAAC,CAAC,CAAA,CAAA;AACpE,MAAA,IAAA,CAAK,YAAY,KAAM,EAAA,CAAA;AAAA,KACxB,CAAA,CAAA;AAAA,GACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,UAAc,GAAA;AACpB,IAAA,IAAI,CAAC,IAAK,CAAA,UAAA;AAAY,MAAA,OAAA;AAEtB,IAAA,MAAM,YAAY,MAAM;AACtB,MAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,CAAU,GAAI,CAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACnD,MAAA,IAAI,IAAK,CAAA,mBAAA;AAAqB,QAAA,IAAA,CAAK,iBAAiB,MAAS,GAAA,KAAA,CAAA;AAAA,KAC/D,CAAA;AAEA,IAAA,MAAM,aAAa,MAAM;AACvB,MAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,CAAU,MAAO,CAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACtD,MAAA,IAAI,IAAK,CAAA,mBAAA;AAAqB,QAAA,IAAA,CAAK,iBAAiB,MAAS,GAAA,IAAA,CAAA;AAAA,KAC/D,CAAA;AAEA,IAAA,MAAM,WAAW,MAAM;AACrB,MAAA,MAAMA,MAAQ,GAAA,QAAA,CAAS,aAAgC,CAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AACtE,MAAI,IAAA,CAAC,IAAK,CAAA,WAAA,CAAY,KAAO,EAAA;AAC3B,QAAK,IAAA,CAAA,WAAA,CAAY,kBAAkB,EAAE,CAAA,CAAA;AACrC,QAAW,UAAA,EAAA,CAAA;AACX,QAAA,OAAA;AAAA,OACF;AACA,MAAA,IAAI,CAACA,MAAS,IAAA,IAAA,CAAK,WAAY,CAAA,KAAA,KAAUA,OAAM,KAAO,EAAA;AACpD,QAAK,IAAA,CAAA,WAAA,CAAY,kBAAkB,EAAE,CAAA,CAAA;AACrC,QAAW,UAAA,EAAA,CAAA;AAAA,OACN,MAAA;AACL,QAAK,IAAA,CAAA,WAAA,CAAY,kBAAkB,qBAAqB,CAAA,CAAA;AACxD,QAAU,SAAA,EAAA,CAAA;AAAA,OACZ;AAAA,KACF,CAAA;AAEA,IAAA,IAAA,CAAK,aAAgB,GAAA,QAAA,CAAA;AACrB,IAAK,IAAA,CAAA,WAAA,CAAY,gBAAiB,CAAA,OAAA,EAAS,QAAQ,CAAA,CAAA;AACnD,IAAK,IAAA,CAAA,WAAA,CAAY,gBAAiB,CAAA,MAAA,EAAQ,QAAQ,CAAA,CAAA;AAIlD,IAAK,IAAA,CAAA,oBAAA,GAAuB,CAAC,CAAa,KAAA;AACxC,MAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,MAAU,SAAA,EAAA,CAAA;AAAA,KACZ,CAAA;AACA,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,SAAW,EAAA,IAAA,CAAK,oBAAoB,CAAA,CAAA;AAItE,IAAA,MAAM,KAAQ,GAAA,QAAA,CAAS,aAAgC,CAAA,IAAA,CAAK,UAAU,CAAA,CAAA;AACtE,IAAA,IAAI,KAAO,EAAA;AACT,MAAA,IAAA,CAAK,kBAAqB,GAAA,KAAA,CAAA;AAC1B,MAAA,IAAA,CAAK,mBAAsB,GAAA,QAAA,CAAA;AAC3B,MAAM,KAAA,CAAA,gBAAA,CAAiB,SAAS,QAAQ,CAAA,CAAA;AAAA,KAC1C;AAAA,GACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAmB,GAAA;AACzB,IAAA,IAAI,CAAC,IAAK,CAAA,eAAA;AAAiB,MAAA,OAAA;AAC3B,IAAM,MAAA,GAAA,GAAM,UAAW,CAAA,IAAA,CAAK,eAAe,CAAA,CAAA;AAC3C,IAAA,IAAI,CAAC,GAAA;AAAK,MAAA,OAAA;AAEV,IAAA,IAAA,CAAK,qBAAqB,MAAM;AAC9B,MAAA,MAAM,SAAY,GAAA,GAAA,CAAI,IAAK,CAAA,WAAA,CAAY,KAAK,CAAA,CAAA;AAC5C,MAAI,IAAA,SAAA,KAAc,IAAK,CAAA,WAAA,CAAY,KAAO,EAAA;AACxC,QAAA,IAAA,CAAK,YAAY,KAAQ,GAAA,SAAA,CAAA;AACzB,QAAK,IAAA,CAAA,WAAA,CAAY,cAAc,IAAI,KAAA,CAAM,SAAS,EAAE,OAAA,EAAS,IAAK,EAAC,CAAC,CAAA,CAAA;AACpE,QAAK,IAAA,CAAA,WAAA,CAAY,cAAc,IAAI,KAAA,CAAM,UAAU,EAAE,OAAA,EAAS,IAAK,EAAC,CAAC,CAAA,CAAA;AAAA,OACvE;AAAA,KACF,CAAA;AAEA,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,MAAQ,EAAA,IAAA,CAAK,kBAAkB,CAAA,CAAA;AAAA,GACnE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAmB,GAAA;AACzB,IAAA,IAAI,CAAC,IAAK,CAAA,aAAA;AAAe,MAAA,OAAA;AAEzB,IAAM,MAAA,mBAAA,GAAsB,CAAC,OAAoB,KAAA;AAC/C,MAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,CAAU,GAAI,CAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACnD,MAAK,IAAA,CAAA,OAAA,CAAQ,SAAU,CAAA,MAAA,CAAO,UAAU,CAAA,CAAA;AACxC,MAAA,IAAI,IAAK,CAAA,wBAAA;AAA0B,QAAA,IAAA,CAAK,sBAAsB,MAAS,GAAA,KAAA,CAAA;AACvE,MAAA,IAAI,IAAK,CAAA,0BAAA;AAA4B,QAAA,IAAA,CAAK,wBAAwB,WAAc,GAAA,OAAA,CAAA;AAAA,KAClF,CAAA;AAEA,IAAA,MAAM,uBAAuB,MAAM;AACjC,MAAA,IAAA,CAAK,OAAQ,CAAA,SAAA,CAAU,MAAO,CAAA,WAAA,EAAa,WAAW,CAAA,CAAA;AACtD,MAAA,IAAI,IAAK,CAAA,wBAAA;AAA0B,QAAA,IAAA,CAAK,sBAAsB,MAAS,GAAA,IAAA,CAAA;AACvE,MAAA,IAAI,IAAK,CAAA,0BAAA;AAA4B,QAAA,IAAA,CAAK,wBAAwB,WAAc,GAAA,EAAA,CAAA;AAChF,MAAI,IAAA,IAAA,CAAK,YAAY,KAAO,EAAA;AAC1B,QAAK,IAAA,CAAA,OAAA,CAAQ,SAAU,CAAA,GAAA,CAAI,UAAU,CAAA,CAAA;AAAA,OAChC,MAAA;AACL,QAAK,IAAA,CAAA,OAAA,CAAQ,SAAU,CAAA,MAAA,CAAO,UAAU,CAAA,CAAA;AAAA,OAC1C;AAAA,KACF,CAAA;AAEA,IAAA,MAAM,WAAW,MAAM;AACrB,MAAA,IAAI,CAAC,IAAA,CAAK,WAAY,CAAA,aAAA,EAAiB,EAAA;AACrC,QAAoB,mBAAA,CAAA,IAAA,CAAK,YAAY,iBAAiB,CAAA,CAAA;AAAA,OACjD,MAAA;AACL,QAAqB,oBAAA,EAAA,CAAA;AAAA,OACvB;AAAA,KACF,CAAA;AAEA,IAAA,IAAA,CAAK,uBAAuB,MAAM;AAChC,MAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAClB,MAAS,QAAA,EAAA,CAAA;AAAA,KACX,CAAA;AAEA,IAAA,IAAA,CAAK,wBAAwB,MAAM;AACjC,MAAA,IAAI,CAAC,IAAK,CAAA,UAAA;AAAY,QAAA,OAAA;AACtB,MAAS,QAAA,EAAA,CAAA;AAAA,KACX,CAAA;AAEA,IAAK,IAAA,CAAA,uBAAA,GAA0B,CAAC,CAAa,KAAA;AAC3C,MAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,MAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAClB,MAAoB,mBAAA,CAAA,IAAA,CAAK,YAAY,iBAAiB,CAAA,CAAA;AAAA,KACxD,CAAA;AAEA,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,MAAQ,EAAA,IAAA,CAAK,oBAAoB,CAAA,CAAA;AACnE,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,OAAS,EAAA,IAAA,CAAK,qBAAqB,CAAA,CAAA;AACrE,IAAA,IAAA,CAAK,WAAY,CAAA,gBAAA,CAAiB,SAAW,EAAA,IAAA,CAAK,uBAAuB,CAAA,CAAA;AAAA,GAC3E;AACF;;;;"}
@@ -136,6 +136,18 @@ class FormLiveSummary extends Controller {
136
136
  const selected = Array.from(ac.querySelectorAll(".midwest-autocomplete-tokens .value")).map((el) => el.textContent?.trim()).filter(Boolean).join(", ");
137
137
  fields.push({ label, value: selected || "\u2014" });
138
138
  });
139
+ form.querySelectorAll(".midwest-date-picker").forEach((picker) => {
140
+ if (this.element.contains(picker))
141
+ return;
142
+ const input = picker.querySelector('[data-midwest-date-picker-target="input"]');
143
+ if (!input?.name)
144
+ return;
145
+ const labelEl = picker.querySelector(".midwest-form-group__top label");
146
+ const label = labelEl?.textContent?.trim() || this.prettifyName(input.name.replace(/\[.*\]$/, ""));
147
+ const display = picker.querySelector('[data-midwest-date-picker-target="display"] .value');
148
+ const value = display?.textContent?.trim() || "";
149
+ fields.push({ label, value: value || "\u2014" });
150
+ });
139
151
  const seenTreeNames = /* @__PURE__ */ new Set();
140
152
  form.querySelectorAll(".midwest-tree-view").forEach((tree) => {
141
153
  if (this.element.contains(tree))
@@ -1 +1 @@
1
- {"version":3,"file":"live_summary_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/live_summary_component/live_summary_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Input types that should never appear in a form live summary.\nconst SKIPPED_INPUT_TYPES = new Set([\n 'hidden', 'submit', 'reset', 'button', 'image'\n])\n\ninterface FieldSummary {\n label: string\n value: string\n /** When set, a colour swatch is prepended to the value cell. */\n swatchColor?: string\n}\n\nexport default class FormLiveSummary extends Controller<HTMLElement> {\n static targets = ['list']\n\n declare readonly listTarget: HTMLElement\n\n connect () {\n this.render()\n this.form?.addEventListener('input', this.render)\n this.form?.addEventListener('change', this.render)\n this.form?.addEventListener('midwest-autocomplete:change', this.render)\n this.form?.addEventListener('midwest-color-picker:update', this.render)\n this.form?.addEventListener('midwest-repeatable:change', this.render)\n }\n\n disconnect () {\n this.form?.removeEventListener('input', this.render)\n this.form?.removeEventListener('change', this.render)\n this.form?.removeEventListener('midwest-autocomplete:change', this.render)\n this.form?.removeEventListener('midwest-color-picker:update', this.render)\n this.form?.removeEventListener('midwest-repeatable:change', this.render)\n }\n\n private get form (): HTMLFormElement | null {\n return this.element.closest('form')\n }\n\n private render = () => {\n const fields = this.collectFields()\n\n if (fields.length === 0) {\n this.listTarget.replaceChildren(\n Object.assign(document.createElement('p'), {\n className: 'midwest-form-live-summary-empty',\n textContent: 'No values to display.'\n })\n )\n return\n }\n\n const dl = document.createElement('dl')\n dl.className = 'midwest-form-live-summary-list'\n\n fields.forEach(({ label, value, swatchColor }) => {\n const dt = Object.assign(document.createElement('dt'), {\n className: 'midwest-form-live-summary-term',\n textContent: label\n })\n const dd = document.createElement('dd')\n dd.className = 'midwest-form-live-summary-definition'\n\n if (swatchColor !== undefined) {\n dd.append(this.buildSwatch(swatchColor), value || '—')\n } else {\n dd.textContent = value || '—'\n }\n\n dl.append(dt, dd)\n })\n\n this.listTarget.replaceChildren(dl)\n }\n\n private collectFields (): FieldSummary[] {\n const form = this.form\n if (!form) return []\n\n const fields: FieldSummary[] = []\n const seenRadioNames = new Set<string>()\n\n Array.from(form.elements).forEach(el => {\n const element = el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement\n\n if (!element.name) return\n\n // Skip elements that live inside the summary itself.\n if (this.element.contains(element)) return\n\n // Skip elements inside a hidden ShowIf fieldset — they are disabled\n // and excluded from form submission, so omit them from the summary.\n if (element.closest('fieldset.midwest-show-if[hidden]')) return\n\n // Skip all button elements regardless of how they are declared.\n if (element instanceof HTMLButtonElement) return\n\n // Skip tree-view checkboxes — they are collected separately below.\n if (element.closest('.midwest-tree-view')) return\n\n // Skip repeatable fields — templates, destroyed items, and active items\n // are all collected separately below as grouped summaries.\n if (element.closest('.midwest-repeatable')) return\n\n if (element instanceof HTMLInputElement) {\n if (SKIPPED_INPUT_TYPES.has(element.type)) return\n\n if (element.type === 'radio') {\n if (seenRadioNames.has(element.name)) return\n seenRadioNames.add(element.name)\n\n const checked = form.querySelector<HTMLInputElement>(\n `input[type=\"radio\"][name=\"${CSS.escape(element.name)}\"]:checked`\n )\n if (!checked) return\n\n fields.push({\n label: this.groupLabelFor(element),\n value: this.labelFor(checked) || checked.value\n })\n return\n }\n\n if (element.type === 'checkbox') {\n fields.push({\n label: this.labelFor(element),\n value: element.checked ? 'Yes' : 'No'\n })\n return\n }\n }\n\n if (element instanceof HTMLSelectElement) {\n fields.push({\n label: this.labelFor(element),\n value: Array.from(element.selectedOptions).map(o => o.text).join(', ') || '—'\n })\n return\n }\n\n // Text-like inputs and textareas only reach this point.\n fields.push({\n label: this.labelFor(element),\n value: element.value\n })\n })\n\n // Color picker components store their value in a hidden input tagged with\n // data-midwest-color-picker-target=\"input\". The standard loop skips hidden\n // inputs, so query them separately and render with an inline colour swatch.\n form.querySelectorAll<HTMLInputElement>('[data-midwest-color-picker-target=\"input\"]').forEach(input => {\n if (this.element.contains(input)) return\n if (!input.name) return\n\n // Prefer the label inside the picker's own form-group header; fall back\n // to a label[for] match or a prettified version of the input name.\n const picker = input.closest<HTMLElement>('.midwest-color-picker')\n const labelEl = picker?.querySelector<HTMLElement>('.midwest-form-group__top label') ??\n this.form?.querySelector<HTMLElement>(`label[for=\"${CSS.escape(input.id)}\"]`)\n const label = labelEl?.textContent?.trim() ||\n this.prettifyName(input.name.replace(/\\[.*\\]$/, ''))\n\n const value = input.value\n const display = value.startsWith('#') ? value : (value ? value.charAt(0).toUpperCase() + value.slice(1) : '—')\n\n fields.push({ label, value: display, swatchColor: value || undefined })\n })\n\n // Autocomplete components use a nameless combobox input + hidden inputs —\n // neither surfaces through the standard form.elements loop. Query them\n // separately so their selected badge labels appear in the summary.\n // Note: labelFor(input) doesn't work here because InputComponent assigns\n // its own id to the <input>, which won't match the <label>'s for attribute.\n form.querySelectorAll<HTMLElement>('.midwest-autocomplete').forEach(ac => {\n if (this.element.contains(ac)) return\n if (!ac.querySelector('[role=\"combobox\"]')) return\n\n const labelEl = ac.querySelector<HTMLElement>('label')\n const label = labelEl?.textContent?.trim() ||\n this.prettifyName((ac.dataset.name ?? '').replace(/\\[.*\\]$/, ''))\n\n const selected = Array.from(ac.querySelectorAll<HTMLElement>('.midwest-autocomplete-tokens .value'))\n .map(el => el.textContent?.trim())\n .filter(Boolean)\n .join(', ')\n fields.push({ label, value: selected || '—' })\n })\n\n // Tree view components render multiple checkboxes sharing the same name\n // (e.g. \"category_ids[]\"). Aggregate the checked nodes into a single\n // comma-separated summary row instead of listing each checkbox separately.\n const seenTreeNames = new Set<string>()\n form.querySelectorAll<HTMLElement>('.midwest-tree-view').forEach(tree => {\n if (this.element.contains(tree)) return\n\n const checked = Array.from(\n tree.querySelectorAll<HTMLInputElement>('.tree-node-checkbox:checked')\n )\n\n // Derive label from the first checkbox's name attribute.\n const firstName = checked[0]?.name || tree.querySelectorAll<HTMLInputElement>('.tree-node-checkbox')[0]?.name\n if (!firstName) return\n if (seenTreeNames.has(firstName)) return\n seenTreeNames.add(firstName)\n\n const label = this.prettifyName(firstName.replace(/\\[\\]$/, ''))\n const values = checked.map(cb => {\n const nodeLabel = cb.closest('.midwest-tree-node')\n ?.querySelector<HTMLElement>(':scope > .tree-node-trigger > .tree-node-label')\n return nodeLabel?.textContent?.trim() || cb.value\n })\n\n fields.push({ label, value: values.join(', ') || '—' })\n })\n\n // Repeatable components contain nested attribute fields grouped inside\n // item wrappers. Summarise each active item as its own row, skipping\n // the hidden clone template and any items marked for destruction.\n form.querySelectorAll<HTMLElement>('.midwest-repeatable').forEach(repeatable => {\n if (this.element.contains(repeatable)) return\n\n const groupLabel = repeatable.querySelector<HTMLElement>('.midwest-form-group__top .midwest-label')\n ?.textContent?.trim() || 'Items'\n\n const items = Array.from(\n repeatable.querySelectorAll<HTMLElement>('[data-midwest-repeatable-target=\"item\"]')\n ).filter(item => {\n const destroy = item.querySelector<HTMLInputElement>('[data-midwest-repeatable-target=\"destroy\"]')\n return destroy?.value !== '1'\n })\n\n items.forEach((item, i) => {\n const values = Array.from(\n item.querySelectorAll<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(\n 'input:not([type=\"hidden\"]), textarea, select'\n )\n )\n .map(input => {\n if (input instanceof HTMLSelectElement) {\n return Array.from(input.selectedOptions).map(o => o.text).join(', ')\n }\n return input.value\n })\n .filter(Boolean)\n\n fields.push({\n label: items.length > 1 ? `${groupLabel} ${i + 1}` : groupLabel,\n value: values.join(' · ') || '—'\n })\n })\n })\n\n return fields\n }\n\n // Builds a small inline colour swatch to display alongside a colour value.\n // Hex values are applied as an inline background-color; named theme colours\n // use a scoped theme-{color} class so the CSS variable cascade does the work.\n // An empty/transparent value renders a diagonal-stripe placeholder.\n private buildSwatch (color: string): HTMLElement {\n const swatch = document.createElement('span')\n swatch.className = 'midwest-form-live-summary-swatch'\n\n if (color.startsWith('#')) {\n swatch.style.backgroundColor = color\n } else if (color && color !== 'transparent') {\n swatch.classList.add(`theme-${color}`, 'bg-theme-6')\n } else {\n swatch.classList.add('is-transparent')\n }\n\n return swatch\n }\n\n // Finds the label associated with a specific element via `for` attribute,\n // wrapping label, or falls back to a prettified version of the element name.\n private labelFor (el: Element): string {\n const id = (el as HTMLElement).id\n if (id) {\n const label = this.form?.querySelector(`label[for=\"${CSS.escape(id)}\"]`)\n if (label) return label.textContent?.trim() ?? ''\n }\n const wrapper = el.closest('label')\n if (wrapper) return wrapper.textContent?.trim() ?? ''\n return this.prettifyName((el as HTMLInputElement).name ?? '')\n }\n\n // For radio groups, prefer the containing fieldset legend over the\n // individual radio's label, then fall back to prettifying the name.\n private groupLabelFor (el: Element): string {\n const legend = el.closest('fieldset')?.querySelector('legend')\n if (legend) return legend.textContent?.trim() ?? ''\n return this.prettifyName((el as HTMLInputElement).name ?? '')\n }\n\n // Converts \"user[first_name]\" or \"first_name\" into \"First name\".\n private prettifyName (name: string): string {\n return name\n .replace(/\\[.*?\\]/g, '')\n .replace(/_/g, ' ')\n .replace(/^\\w/, c => c.toUpperCase())\n .trim()\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"live_summary_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/live_summary_component/live_summary_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\n// Input types that should never appear in a form live summary.\nconst SKIPPED_INPUT_TYPES = new Set([\n 'hidden', 'submit', 'reset', 'button', 'image'\n])\n\ninterface FieldSummary {\n label: string\n value: string\n /** When set, a colour swatch is prepended to the value cell. */\n swatchColor?: string\n}\n\nexport default class FormLiveSummary extends Controller<HTMLElement> {\n static targets = ['list']\n\n declare readonly listTarget: HTMLElement\n\n connect () {\n this.render()\n this.form?.addEventListener('input', this.render)\n this.form?.addEventListener('change', this.render)\n this.form?.addEventListener('midwest-autocomplete:change', this.render)\n this.form?.addEventListener('midwest-color-picker:update', this.render)\n this.form?.addEventListener('midwest-repeatable:change', this.render)\n }\n\n disconnect () {\n this.form?.removeEventListener('input', this.render)\n this.form?.removeEventListener('change', this.render)\n this.form?.removeEventListener('midwest-autocomplete:change', this.render)\n this.form?.removeEventListener('midwest-color-picker:update', this.render)\n this.form?.removeEventListener('midwest-repeatable:change', this.render)\n }\n\n private get form (): HTMLFormElement | null {\n return this.element.closest('form')\n }\n\n private render = () => {\n const fields = this.collectFields()\n\n if (fields.length === 0) {\n this.listTarget.replaceChildren(\n Object.assign(document.createElement('p'), {\n className: 'midwest-form-live-summary-empty',\n textContent: 'No values to display.'\n })\n )\n return\n }\n\n const dl = document.createElement('dl')\n dl.className = 'midwest-form-live-summary-list'\n\n fields.forEach(({ label, value, swatchColor }) => {\n const dt = Object.assign(document.createElement('dt'), {\n className: 'midwest-form-live-summary-term',\n textContent: label\n })\n const dd = document.createElement('dd')\n dd.className = 'midwest-form-live-summary-definition'\n\n if (swatchColor !== undefined) {\n dd.append(this.buildSwatch(swatchColor), value || '—')\n } else {\n dd.textContent = value || '—'\n }\n\n dl.append(dt, dd)\n })\n\n this.listTarget.replaceChildren(dl)\n }\n\n private collectFields (): FieldSummary[] {\n const form = this.form\n if (!form) return []\n\n const fields: FieldSummary[] = []\n const seenRadioNames = new Set<string>()\n\n Array.from(form.elements).forEach(el => {\n const element = el as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement\n\n if (!element.name) return\n\n // Skip elements that live inside the summary itself.\n if (this.element.contains(element)) return\n\n // Skip elements inside a hidden ShowIf fieldset — they are disabled\n // and excluded from form submission, so omit them from the summary.\n if (element.closest('fieldset.midwest-show-if[hidden]')) return\n\n // Skip all button elements regardless of how they are declared.\n if (element instanceof HTMLButtonElement) return\n\n // Skip tree-view checkboxes — they are collected separately below.\n if (element.closest('.midwest-tree-view')) return\n\n // Skip repeatable fields — templates, destroyed items, and active items\n // are all collected separately below as grouped summaries.\n if (element.closest('.midwest-repeatable')) return\n\n if (element instanceof HTMLInputElement) {\n if (SKIPPED_INPUT_TYPES.has(element.type)) return\n\n if (element.type === 'radio') {\n if (seenRadioNames.has(element.name)) return\n seenRadioNames.add(element.name)\n\n const checked = form.querySelector<HTMLInputElement>(\n `input[type=\"radio\"][name=\"${CSS.escape(element.name)}\"]:checked`\n )\n if (!checked) return\n\n fields.push({\n label: this.groupLabelFor(element),\n value: this.labelFor(checked) || checked.value\n })\n return\n }\n\n if (element.type === 'checkbox') {\n fields.push({\n label: this.labelFor(element),\n value: element.checked ? 'Yes' : 'No'\n })\n return\n }\n }\n\n if (element instanceof HTMLSelectElement) {\n fields.push({\n label: this.labelFor(element),\n value: Array.from(element.selectedOptions).map(o => o.text).join(', ') || '—'\n })\n return\n }\n\n // Text-like inputs and textareas only reach this point.\n fields.push({\n label: this.labelFor(element),\n value: element.value\n })\n })\n\n // Color picker components store their value in a hidden input tagged with\n // data-midwest-color-picker-target=\"input\". The standard loop skips hidden\n // inputs, so query them separately and render with an inline colour swatch.\n form.querySelectorAll<HTMLInputElement>('[data-midwest-color-picker-target=\"input\"]').forEach(input => {\n if (this.element.contains(input)) return\n if (!input.name) return\n\n // Prefer the label inside the picker's own form-group header; fall back\n // to a label[for] match or a prettified version of the input name.\n const picker = input.closest<HTMLElement>('.midwest-color-picker')\n const labelEl = picker?.querySelector<HTMLElement>('.midwest-form-group__top label') ??\n this.form?.querySelector<HTMLElement>(`label[for=\"${CSS.escape(input.id)}\"]`)\n const label = labelEl?.textContent?.trim() ||\n this.prettifyName(input.name.replace(/\\[.*\\]$/, ''))\n\n const value = input.value\n const display = value.startsWith('#') ? value : (value ? value.charAt(0).toUpperCase() + value.slice(1) : '—')\n\n fields.push({ label, value: display, swatchColor: value || undefined })\n })\n\n // Autocomplete components use a nameless combobox input + hidden inputs —\n // neither surfaces through the standard form.elements loop. Query them\n // separately so their selected badge labels appear in the summary.\n // Note: labelFor(input) doesn't work here because InputComponent assigns\n // its own id to the <input>, which won't match the <label>'s for attribute.\n form.querySelectorAll<HTMLElement>('.midwest-autocomplete').forEach(ac => {\n if (this.element.contains(ac)) return\n if (!ac.querySelector('[role=\"combobox\"]')) return\n\n const labelEl = ac.querySelector<HTMLElement>('label')\n const label = labelEl?.textContent?.trim() ||\n this.prettifyName((ac.dataset.name ?? '').replace(/\\[.*\\]$/, ''))\n\n const selected = Array.from(ac.querySelectorAll<HTMLElement>('.midwest-autocomplete-tokens .value'))\n .map(el => el.textContent?.trim())\n .filter(Boolean)\n .join(', ')\n fields.push({ label, value: selected || '—' })\n })\n\n // Date picker components store their value in a hidden input tagged with\n // data-midwest-date-picker-target=\"input\". The standard loop skips hidden\n // inputs, so query the display badge for the human-readable value.\n form.querySelectorAll<HTMLElement>('.midwest-date-picker').forEach(picker => {\n if (this.element.contains(picker)) return\n\n const input = picker.querySelector<HTMLInputElement>('[data-midwest-date-picker-target=\"input\"]')\n if (!input?.name) return\n\n const labelEl = picker.querySelector<HTMLElement>('.midwest-form-group__top label')\n const label = labelEl?.textContent?.trim() ||\n this.prettifyName(input.name.replace(/\\[.*\\]$/, ''))\n\n const display = picker.querySelector<HTMLElement>('[data-midwest-date-picker-target=\"display\"] .value')\n const value = display?.textContent?.trim() || ''\n\n fields.push({ label, value: value || '—' })\n })\n\n // Tree view components render multiple checkboxes sharing the same name\n // (e.g. \"category_ids[]\"). Aggregate the checked nodes into a single\n // comma-separated summary row instead of listing each checkbox separately.\n const seenTreeNames = new Set<string>()\n form.querySelectorAll<HTMLElement>('.midwest-tree-view').forEach(tree => {\n if (this.element.contains(tree)) return\n\n const checked = Array.from(\n tree.querySelectorAll<HTMLInputElement>('.tree-node-checkbox:checked')\n )\n\n // Derive label from the first checkbox's name attribute.\n const firstName = checked[0]?.name || tree.querySelectorAll<HTMLInputElement>('.tree-node-checkbox')[0]?.name\n if (!firstName) return\n if (seenTreeNames.has(firstName)) return\n seenTreeNames.add(firstName)\n\n const label = this.prettifyName(firstName.replace(/\\[\\]$/, ''))\n const values = checked.map(cb => {\n const nodeLabel = cb.closest('.midwest-tree-node')\n ?.querySelector<HTMLElement>(':scope > .tree-node-trigger > .tree-node-label')\n return nodeLabel?.textContent?.trim() || cb.value\n })\n\n fields.push({ label, value: values.join(', ') || '—' })\n })\n\n // Repeatable components contain nested attribute fields grouped inside\n // item wrappers. Summarise each active item as its own row, skipping\n // the hidden clone template and any items marked for destruction.\n form.querySelectorAll<HTMLElement>('.midwest-repeatable').forEach(repeatable => {\n if (this.element.contains(repeatable)) return\n\n const groupLabel = repeatable.querySelector<HTMLElement>('.midwest-form-group__top .midwest-label')\n ?.textContent?.trim() || 'Items'\n\n const items = Array.from(\n repeatable.querySelectorAll<HTMLElement>('[data-midwest-repeatable-target=\"item\"]')\n ).filter(item => {\n const destroy = item.querySelector<HTMLInputElement>('[data-midwest-repeatable-target=\"destroy\"]')\n return destroy?.value !== '1'\n })\n\n items.forEach((item, i) => {\n const values = Array.from(\n item.querySelectorAll<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(\n 'input:not([type=\"hidden\"]), textarea, select'\n )\n )\n .map(input => {\n if (input instanceof HTMLSelectElement) {\n return Array.from(input.selectedOptions).map(o => o.text).join(', ')\n }\n return input.value\n })\n .filter(Boolean)\n\n fields.push({\n label: items.length > 1 ? `${groupLabel} ${i + 1}` : groupLabel,\n value: values.join(' · ') || '—'\n })\n })\n })\n\n return fields\n }\n\n // Builds a small inline colour swatch to display alongside a colour value.\n // Hex values are applied as an inline background-color; named theme colours\n // use a scoped theme-{color} class so the CSS variable cascade does the work.\n // An empty/transparent value renders a diagonal-stripe placeholder.\n private buildSwatch (color: string): HTMLElement {\n const swatch = document.createElement('span')\n swatch.className = 'midwest-form-live-summary-swatch'\n\n if (color.startsWith('#')) {\n swatch.style.backgroundColor = color\n } else if (color && color !== 'transparent') {\n swatch.classList.add(`theme-${color}`, 'bg-theme-6')\n } else {\n swatch.classList.add('is-transparent')\n }\n\n return swatch\n }\n\n // Finds the label associated with a specific element via `for` attribute,\n // wrapping label, or falls back to a prettified version of the element name.\n private labelFor (el: Element): string {\n const id = (el as HTMLElement).id\n if (id) {\n const label = this.form?.querySelector(`label[for=\"${CSS.escape(id)}\"]`)\n if (label) return label.textContent?.trim() ?? ''\n }\n const wrapper = el.closest('label')\n if (wrapper) return wrapper.textContent?.trim() ?? ''\n return this.prettifyName((el as HTMLInputElement).name ?? '')\n }\n\n // For radio groups, prefer the containing fieldset legend over the\n // individual radio's label, then fall back to prettifying the name.\n private groupLabelFor (el: Element): string {\n const legend = el.closest('fieldset')?.querySelector('legend')\n if (legend) return legend.textContent?.trim() ?? ''\n return this.prettifyName((el as HTMLInputElement).name ?? '')\n }\n\n // Converts \"user[first_name]\" or \"first_name\" into \"First name\".\n private prettifyName (name: string): string {\n return name\n .replace(/\\[.*?\\]/g, '')\n .replace(/_/g, ' ')\n .replace(/^\\w/, c => c.toUpperCase())\n .trim()\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
1
+ import { Controller } from '@hotwired/stimulus';
2
+
3
+ class TimePicker extends Controller {
4
+ static targets = ["input", "display", "trigger", "popover", "list", "periodGroup"];
5
+ static values = {
6
+ step: { type: Number, default: 15 },
7
+ period: { type: String, default: "AM" },
8
+ min: String,
9
+ max: String
10
+ };
11
+ selectedHour12 = null;
12
+ selectedMinutes = null;
13
+ connect() {
14
+ this.popoverTarget.addEventListener("toggle", this.handleToggle);
15
+ this.listTarget.addEventListener("keydown", this.handleKeydown);
16
+ const currentValue = this.inputTarget.value;
17
+ if (currentValue) {
18
+ const [h, m] = currentValue.split(":").map(Number);
19
+ this.periodValue = h >= 12 ? "PM" : "AM";
20
+ this.selectedHour12 = h % 12 || 12;
21
+ this.selectedMinutes = m;
22
+ }
23
+ }
24
+ disconnect() {
25
+ this.popoverTarget.removeEventListener("toggle", this.handleToggle);
26
+ this.listTarget.removeEventListener("keydown", this.handleKeydown);
27
+ }
28
+ handleToggle = (event) => {
29
+ const popover = event.target;
30
+ const open = popover.matches(":popover-open");
31
+ this.triggerTarget.setAttribute("aria-expanded", String(open));
32
+ if (open) {
33
+ requestAnimationFrame(() => this.focusSelectedOption());
34
+ } else {
35
+ this.triggerTarget.focus();
36
+ }
37
+ };
38
+ selectTime(event) {
39
+ const option = event.currentTarget;
40
+ this.selectOption(option);
41
+ }
42
+ setPeriod(event) {
43
+ const button = event.currentTarget;
44
+ const period = button.dataset.period;
45
+ if (!period)
46
+ return;
47
+ this.periodValue = period;
48
+ this.updatePeriodButtons();
49
+ this.commitValue();
50
+ }
51
+ selectOption(option) {
52
+ const hour = Number(option.dataset.hour);
53
+ const minutes = Number(option.dataset.minutes);
54
+ this.selectedHour12 = hour;
55
+ this.selectedMinutes = minutes;
56
+ this.updateSelectedOption(option);
57
+ this.commitValue();
58
+ this.popoverTarget.hidePopover();
59
+ }
60
+ commitValue() {
61
+ if (this.selectedHour12 === null || this.selectedMinutes === null)
62
+ return;
63
+ const hour24 = this.to24h(this.selectedHour12, this.periodValue);
64
+ const timeStr = `${String(hour24).padStart(2, "0")}:${String(this.selectedMinutes).padStart(2, "0")}`;
65
+ this.inputTarget.value = timeStr;
66
+ this.updateDisplayText(this.formatDisplay(this.selectedHour12, this.selectedMinutes, this.periodValue));
67
+ this.inputTarget.dispatchEvent(new Event("change", { bubbles: true }));
68
+ }
69
+ to24h(hour12, period) {
70
+ if (period === "AM") {
71
+ return hour12 === 12 ? 0 : hour12;
72
+ }
73
+ return hour12 === 12 ? 12 : hour12 + 12;
74
+ }
75
+ formatDisplay(hour12, minutes, period) {
76
+ return `${hour12}:${String(minutes).padStart(2, "0")} ${period}`;
77
+ }
78
+ updatePeriodButtons() {
79
+ this.periodGroupTarget.querySelectorAll(".time-picker-period-btn").forEach((btn) => {
80
+ const isActive = btn.dataset.period === this.periodValue;
81
+ btn.classList.toggle("is-active", isActive);
82
+ btn.setAttribute("aria-checked", String(isActive));
83
+ });
84
+ }
85
+ updateSelectedOption(selected) {
86
+ this.listTarget.querySelectorAll(".time-picker-option").forEach((opt) => {
87
+ const isMatch = opt === selected;
88
+ opt.classList.toggle("is-selected", isMatch);
89
+ opt.setAttribute("aria-selected", String(isMatch));
90
+ opt.tabIndex = isMatch ? 0 : -1;
91
+ });
92
+ }
93
+ focusSelectedOption() {
94
+ const selected = this.listTarget.querySelector(".is-selected");
95
+ const target = selected || this.listTarget.querySelector(".time-picker-option");
96
+ if (!target)
97
+ return;
98
+ if (!selected) {
99
+ target.tabIndex = 0;
100
+ }
101
+ target.focus();
102
+ this.scrollToOption(target);
103
+ }
104
+ scrollToOption(option) {
105
+ const container = this.listTarget;
106
+ const optionTop = option.offsetTop;
107
+ const optionHeight = option.offsetHeight;
108
+ const containerHeight = container.clientHeight;
109
+ const scrollTop = container.scrollTop;
110
+ if (optionTop < scrollTop) {
111
+ container.scrollTop = optionTop;
112
+ } else if (optionTop + optionHeight > scrollTop + containerHeight) {
113
+ container.scrollTop = optionTop + optionHeight - containerHeight;
114
+ }
115
+ }
116
+ handleKeydown = (event) => {
117
+ const current = event.target;
118
+ if (!current.classList.contains("time-picker-option"))
119
+ return;
120
+ if (event.key === "Enter" || event.key === " ") {
121
+ event.preventDefault();
122
+ this.selectOption(current);
123
+ return;
124
+ }
125
+ if (event.key === "Escape") {
126
+ event.preventDefault();
127
+ this.popoverTarget.hidePopover();
128
+ return;
129
+ }
130
+ const next = this.nextOptionForKey(event.key, current);
131
+ if (next) {
132
+ event.preventDefault();
133
+ current.tabIndex = -1;
134
+ next.tabIndex = 0;
135
+ next.focus();
136
+ this.scrollToOption(next);
137
+ }
138
+ };
139
+ nextOptionForKey(key, current) {
140
+ const options = Array.from(this.listTarget.querySelectorAll(".time-picker-option"));
141
+ const index = options.indexOf(current);
142
+ switch (key) {
143
+ case "ArrowDown":
144
+ return options[index + 1] || null;
145
+ case "ArrowUp":
146
+ return options[index - 1] || null;
147
+ case "Home":
148
+ return options[0] || null;
149
+ case "End":
150
+ return options[options.length - 1] || null;
151
+ default:
152
+ return null;
153
+ }
154
+ }
155
+ updateDisplayText(text) {
156
+ const valueEl = this.displayTarget.querySelector(".value");
157
+ if (valueEl) {
158
+ valueEl.textContent = text;
159
+ }
160
+ }
161
+ }
162
+
163
+ export { TimePicker as default };
164
+ //# sourceMappingURL=time_picker_component_controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time_picker_component_controller.js","sources":["../../../../../../../../app/components/midwest/form/time_picker_component/time_picker_component_controller.ts"],"sourcesContent":["import { Controller } from '@hotwired/stimulus'\n\nexport default class TimePicker extends Controller<HTMLElement> {\n static targets = ['input', 'display', 'trigger', 'popover', 'list', 'periodGroup']\n static values = {\n step: { type: Number, default: 15 },\n period: { type: String, default: 'AM' },\n min: String,\n max: String\n }\n\n declare readonly inputTarget: HTMLInputElement\n declare readonly displayTarget: HTMLElement\n declare readonly triggerTarget: HTMLElement\n declare readonly popoverTarget: HTMLElement\n declare readonly listTarget: HTMLElement\n declare readonly periodGroupTarget: HTMLElement\n declare stepValue: number\n declare periodValue: string\n declare minValue: string\n declare maxValue: string\n declare readonly hasMinValue: boolean\n declare readonly hasMaxValue: boolean\n\n private selectedHour12: number | null = null\n private selectedMinutes: number | null = null\n\n connect () {\n this.popoverTarget.addEventListener('toggle', this.handleToggle)\n this.listTarget.addEventListener('keydown', this.handleKeydown)\n\n // Restore selection state from current hidden input value\n const currentValue = this.inputTarget.value\n if (currentValue) {\n const [h, m] = currentValue.split(':').map(Number)\n this.periodValue = h >= 12 ? 'PM' : 'AM'\n this.selectedHour12 = h % 12 || 12\n this.selectedMinutes = m\n }\n }\n\n disconnect () {\n this.popoverTarget.removeEventListener('toggle', this.handleToggle)\n this.listTarget.removeEventListener('keydown', this.handleKeydown)\n }\n\n private handleToggle = (event: Event) => {\n const popover = event.target as HTMLElement\n const open = popover.matches(':popover-open')\n this.triggerTarget.setAttribute('aria-expanded', String(open))\n\n if (open) {\n requestAnimationFrame(() => this.focusSelectedOption())\n } else {\n this.triggerTarget.focus()\n }\n }\n\n selectTime (event: Event) {\n const option = event.currentTarget as HTMLElement\n this.selectOption(option)\n }\n\n setPeriod (event: Event) {\n const button = event.currentTarget as HTMLElement\n const period = button.dataset.period\n if (!period) return\n\n this.periodValue = period\n this.updatePeriodButtons()\n this.commitValue()\n }\n\n private selectOption (option: HTMLElement) {\n const hour = Number(option.dataset.hour)\n const minutes = Number(option.dataset.minutes)\n\n this.selectedHour12 = hour\n this.selectedMinutes = minutes\n this.updateSelectedOption(option)\n this.commitValue()\n this.popoverTarget.hidePopover()\n }\n\n private commitValue () {\n if (this.selectedHour12 === null || this.selectedMinutes === null) return\n\n const hour24 = this.to24h(this.selectedHour12, this.periodValue)\n const timeStr = `${String(hour24).padStart(2, '0')}:${String(this.selectedMinutes).padStart(2, '0')}`\n\n this.inputTarget.value = timeStr\n this.updateDisplayText(this.formatDisplay(this.selectedHour12, this.selectedMinutes, this.periodValue))\n this.inputTarget.dispatchEvent(new Event('change', { bubbles: true }))\n }\n\n private to24h (hour12: number, period: string): number {\n if (period === 'AM') {\n return hour12 === 12 ? 0 : hour12\n }\n return hour12 === 12 ? 12 : hour12 + 12\n }\n\n private formatDisplay (hour12: number, minutes: number, period: string): string {\n return `${hour12}:${String(minutes).padStart(2, '0')} ${period}`\n }\n\n private updatePeriodButtons () {\n this.periodGroupTarget.querySelectorAll<HTMLElement>('.time-picker-period-btn').forEach(btn => {\n const isActive = btn.dataset.period === this.periodValue\n btn.classList.toggle('is-active', isActive)\n btn.setAttribute('aria-checked', String(isActive))\n })\n }\n\n private updateSelectedOption (selected: HTMLElement) {\n this.listTarget.querySelectorAll<HTMLElement>('.time-picker-option').forEach(opt => {\n const isMatch = opt === selected\n opt.classList.toggle('is-selected', isMatch)\n opt.setAttribute('aria-selected', String(isMatch))\n opt.tabIndex = isMatch ? 0 : -1\n })\n }\n\n private focusSelectedOption () {\n const selected = this.listTarget.querySelector<HTMLElement>('.is-selected')\n const target = selected || this.listTarget.querySelector<HTMLElement>('.time-picker-option')\n if (!target) return\n\n if (!selected) {\n target.tabIndex = 0\n }\n\n target.focus()\n this.scrollToOption(target)\n }\n\n private scrollToOption (option: HTMLElement) {\n const container = this.listTarget\n const optionTop = option.offsetTop\n const optionHeight = option.offsetHeight\n const containerHeight = container.clientHeight\n const scrollTop = container.scrollTop\n\n if (optionTop < scrollTop) {\n container.scrollTop = optionTop\n } else if (optionTop + optionHeight > scrollTop + containerHeight) {\n container.scrollTop = optionTop + optionHeight - containerHeight\n }\n }\n\n private handleKeydown = (event: KeyboardEvent) => {\n const current = event.target as HTMLElement\n if (!current.classList.contains('time-picker-option')) return\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n this.selectOption(current)\n return\n }\n\n if (event.key === 'Escape') {\n event.preventDefault()\n this.popoverTarget.hidePopover()\n return\n }\n\n const next = this.nextOptionForKey(event.key, current)\n\n if (next) {\n event.preventDefault()\n current.tabIndex = -1\n next.tabIndex = 0\n next.focus()\n this.scrollToOption(next)\n }\n }\n\n private nextOptionForKey (key: string, current: HTMLElement): HTMLElement | null {\n const options = Array.from(this.listTarget.querySelectorAll<HTMLElement>('.time-picker-option'))\n const index = options.indexOf(current)\n\n switch (key) {\n case 'ArrowDown': return options[index + 1] || null\n case 'ArrowUp': return options[index - 1] || null\n case 'Home': return options[0] || null\n case 'End': return options[options.length - 1] || null\n default: return null\n }\n }\n\n private updateDisplayText (text: string) {\n const valueEl = this.displayTarget.querySelector('.value')\n if (valueEl) {\n valueEl.textContent = text\n }\n }\n}\n"],"names":[],"mappings":"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"}