hyperclayjs 1.0.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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/README.template.md +276 -0
  4. package/communication/behaviorCollector.js +230 -0
  5. package/communication/sendMessage.js +48 -0
  6. package/communication/uploadFile.js +348 -0
  7. package/core/adminContenteditable.js +36 -0
  8. package/core/adminInputs.js +58 -0
  9. package/core/adminOnClick.js +31 -0
  10. package/core/adminResources.js +33 -0
  11. package/core/adminSystem.js +15 -0
  12. package/core/editmode.js +8 -0
  13. package/core/editmodeSystem.js +18 -0
  14. package/core/enablePersistentFormInputValues.js +62 -0
  15. package/core/isAdminOfCurrentResource.js +13 -0
  16. package/core/optionVisibilityRuleGenerator.js +160 -0
  17. package/core/savePage.js +196 -0
  18. package/core/savePageCore.js +236 -0
  19. package/core/setPageTypeOnDocumentElement.js +23 -0
  20. package/custom-attributes/ajaxElements.js +94 -0
  21. package/custom-attributes/autosize.js +17 -0
  22. package/custom-attributes/domHelpers.js +175 -0
  23. package/custom-attributes/events.js +15 -0
  24. package/custom-attributes/inputHelpers.js +11 -0
  25. package/custom-attributes/onclickaway.js +27 -0
  26. package/custom-attributes/onclone.js +35 -0
  27. package/custom-attributes/onpagemutation.js +20 -0
  28. package/custom-attributes/onrender.js +30 -0
  29. package/custom-attributes/preventEnter.js +13 -0
  30. package/custom-attributes/sortable.js +76 -0
  31. package/dom-utilities/All.js +412 -0
  32. package/dom-utilities/getDataFromForm.js +60 -0
  33. package/dom-utilities/insertStyleTag.js +28 -0
  34. package/dom-utilities/onDomReady.js +7 -0
  35. package/dom-utilities/onLoad.js +7 -0
  36. package/hyperclay.js +465 -0
  37. package/module-dependency-graph.json +612 -0
  38. package/package.json +95 -0
  39. package/string-utilities/copy-to-clipboard.js +35 -0
  40. package/string-utilities/emmet-html.js +54 -0
  41. package/string-utilities/query.js +1 -0
  42. package/string-utilities/slugify.js +21 -0
  43. package/ui/info.js +39 -0
  44. package/ui/prompts.js +179 -0
  45. package/ui/theModal.js +677 -0
  46. package/ui/toast.js +273 -0
  47. package/utilities/cookie.js +45 -0
  48. package/utilities/debounce.js +12 -0
  49. package/utilities/mutation.js +403 -0
  50. package/utilities/nearest.js +97 -0
  51. package/utilities/pipe.js +1 -0
  52. package/utilities/throttle.js +21 -0
  53. package/vendor/Sortable.js +3351 -0
  54. package/vendor/idiomorph.min.js +8 -0
  55. package/vendor/tailwind-base.css +1471 -0
  56. package/vendor/tailwind-play.js +169 -0
package/ui/theModal.js ADDED
@@ -0,0 +1,677 @@
1
+ /*
2
+
3
+ theModal
4
+
5
+ // a pretty alternative to window.prompt
6
+
7
+ - set the content of the modal
8
+ - open it
9
+ - user confirms
10
+ - everything about the modal resets
11
+
12
+ themodal.html = content;
13
+ themodal.yes = content;
14
+ themodal.no = content;
15
+
16
+ themodal.disableFocus = true;
17
+ themodal.disableScroll = true;
18
+
19
+ themodal.onYes(content);
20
+ themodal.onNo(content);
21
+
22
+ themodal.open();
23
+ themodal.close();
24
+
25
+ */
26
+
27
+ /*
28
+
29
+ things you probably want to style
30
+
31
+ .micromodal {}
32
+ .micromodal .micromodal__container {}
33
+ .micromodal .micromodal__content {}
34
+ .micromodal .micromodal__heading {}
35
+ .micromodal .micromodal__input {}
36
+ .micromodal .micromodal__input:focus, .micromodal .micromodal__input:active {}
37
+ .micromodal .micromodal__buttons {}
38
+ .micromodal .micromodal__yes, .micromodal__no {}
39
+ .micromodal .micromodal__yes {}
40
+ .micromodal .micromodal__yes:focus, .micromodal__yes:hover {}
41
+ .micromodal .micromodal__no {}
42
+ .micromodal .micromodal__no:focus, .micromodal__no:hover {}
43
+ .micromodal .micromodal__close {}
44
+ .micromodal .micromodal__close:focus, .micromodal__close:hover {}
45
+
46
+ */
47
+
48
+
49
+
50
+
51
+
52
+
53
+ // MicroModal
54
+ // MIT License (c) 2017 Indrashish Ghosh
55
+ // MODIFIED: removed `this.activeElement.focus()` after modal is closed
56
+
57
+ const MicroModal = (() => {
58
+ 'use strict'
59
+
60
+ const FOCUSABLE_ELEMENTS = [
61
+ 'a[href]',
62
+ 'area[href]',
63
+ 'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
64
+ 'select:not([disabled]):not([aria-hidden])',
65
+ 'textarea:not([disabled]):not([aria-hidden])',
66
+ 'button:not([disabled]):not([aria-hidden])',
67
+ 'iframe',
68
+ 'object',
69
+ 'embed',
70
+ '[contenteditable]',
71
+ '[tabindex]:not([tabindex^="-"])'
72
+ ]
73
+
74
+ class Modal {
75
+ constructor ({
76
+ targetModal,
77
+ triggers = [],
78
+ onShow = () => { },
79
+ onClose = () => { },
80
+ openTrigger = 'data-micromodal-trigger',
81
+ closeTrigger = 'data-micromodal-close',
82
+ openClass = 'is-open',
83
+ disableScroll = false,
84
+ disableFocus = false,
85
+ awaitCloseAnimation = false,
86
+ awaitOpenAnimation = false,
87
+ debugMode = false
88
+ }) {
89
+ this.modal = document.getElementById(targetModal)
90
+
91
+ this.config = { debugMode, disableScroll, openTrigger, closeTrigger, openClass, onShow, onClose, awaitCloseAnimation, awaitOpenAnimation, disableFocus }
92
+
93
+ if (triggers.length > 0) this.registerTriggers(...triggers)
94
+
95
+ this.onClick = this.onClick.bind(this)
96
+ this.onKeydown = this.onKeydown.bind(this)
97
+ }
98
+
99
+ registerTriggers (...triggers) {
100
+ triggers.filter(Boolean).forEach(trigger => {
101
+ trigger.addEventListener('click', event => this.showModal(event))
102
+ })
103
+ }
104
+
105
+ showModal (event = null) {
106
+ this.activeElement = document.activeElement
107
+ this.modal.setAttribute('aria-hidden', 'false')
108
+ this.modal.classList.add(this.config.openClass)
109
+ this.scrollBehaviour('disable')
110
+ this.addEventListeners()
111
+
112
+ if (this.config.awaitOpenAnimation) {
113
+ const handler = () => {
114
+ this.modal.removeEventListener('animationend', handler, false)
115
+ this.setFocusToFirstNode()
116
+ }
117
+ this.modal.addEventListener('animationend', handler, false)
118
+ } else {
119
+ this.setFocusToFirstNode()
120
+ }
121
+
122
+ this.config.onShow(this.modal, this.activeElement, event)
123
+ }
124
+
125
+ closeModal (event = null) {
126
+ const modal = this.modal
127
+ this.modal.setAttribute('aria-hidden', 'true')
128
+ this.removeEventListeners()
129
+ this.scrollBehaviour('enable')
130
+ this.config.onClose(this.modal, this.activeElement, event)
131
+
132
+ if (this.config.awaitCloseAnimation) {
133
+ const openClass = this.config.openClass // <- old school ftw
134
+ this.modal.addEventListener('animationend', function handler () {
135
+ modal.classList.remove(openClass)
136
+ modal.removeEventListener('animationend', handler, false)
137
+ }, false)
138
+ } else {
139
+ modal.classList.remove(this.config.openClass)
140
+ }
141
+ }
142
+
143
+ closeModalById (targetModal) {
144
+ this.modal = document.getElementById(targetModal)
145
+ if (this.modal) this.closeModal()
146
+ }
147
+
148
+ scrollBehaviour (toggle) {
149
+ if (!this.config.disableScroll) return
150
+ const body = document.querySelector('body')
151
+ switch (toggle) {
152
+ case 'enable':
153
+ Object.assign(body.style, { overflow: '' })
154
+ break
155
+ case 'disable':
156
+ Object.assign(body.style, { overflow: 'hidden' })
157
+ break
158
+ default:
159
+ }
160
+ }
161
+
162
+ addEventListeners () {
163
+ this.modal.addEventListener('touchstart', this.onClick)
164
+ this.modal.addEventListener('click', this.onClick)
165
+ document.addEventListener('keydown', this.onKeydown)
166
+ }
167
+
168
+ removeEventListeners () {
169
+ this.modal.removeEventListener('touchstart', this.onClick)
170
+ this.modal.removeEventListener('click', this.onClick)
171
+ document.removeEventListener('keydown', this.onKeydown)
172
+ }
173
+
174
+ onClick (event) {
175
+ if (
176
+ event.target.hasAttribute(this.config.closeTrigger) ||
177
+ event.target.parentNode.hasAttribute(this.config.closeTrigger)
178
+ ) {
179
+ event.preventDefault()
180
+ event.stopPropagation()
181
+ this.closeModal(event)
182
+ }
183
+ }
184
+
185
+ onKeydown (event) {
186
+ if (event.keyCode === 27) this.closeModal(event) // esc
187
+ if (event.keyCode === 9) this.retainFocus(event) // tab
188
+ }
189
+
190
+ getFocusableNodes () {
191
+ const nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS)
192
+ return Array(...nodes)
193
+ }
194
+
195
+ setFocusToFirstNode () {
196
+ if (this.config.disableFocus) return
197
+
198
+ const focusableNodes = this.getFocusableNodes()
199
+
200
+ if (focusableNodes.length === 0) return
201
+
202
+ const nodesWhichAreNotCloseTargets = focusableNodes.filter(node => {
203
+ return !node.hasAttribute(this.config.closeTrigger)
204
+ })
205
+
206
+ if (nodesWhichAreNotCloseTargets.length > 0) nodesWhichAreNotCloseTargets[0].focus()
207
+ if (nodesWhichAreNotCloseTargets.length === 0) focusableNodes[0].focus()
208
+ }
209
+
210
+ retainFocus (event) {
211
+ let focusableNodes = this.getFocusableNodes()
212
+
213
+ if (focusableNodes.length === 0) return
214
+
215
+ focusableNodes = focusableNodes.filter(node => {
216
+ return (node.offsetParent !== null)
217
+ })
218
+
219
+ if (!this.modal.contains(document.activeElement)) {
220
+ focusableNodes[0].focus()
221
+ } else {
222
+ const focusedItemIndex = focusableNodes.indexOf(document.activeElement)
223
+
224
+ if (event.shiftKey && focusedItemIndex === 0) {
225
+ focusableNodes[focusableNodes.length - 1].focus()
226
+ event.preventDefault()
227
+ }
228
+
229
+ if (!event.shiftKey && focusableNodes.length > 0 && focusedItemIndex === focusableNodes.length - 1) {
230
+ focusableNodes[0].focus()
231
+ event.preventDefault()
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+
238
+ // Keep a reference to the opened modal
239
+ let activeModal = null
240
+
241
+ const generateTriggerMap = (triggers, triggerAttr) => {
242
+ const triggerMap = []
243
+
244
+ triggers.forEach(trigger => {
245
+ const targetModal = trigger.attributes[triggerAttr].value
246
+ if (triggerMap[targetModal] === undefined) triggerMap[targetModal] = []
247
+ triggerMap[targetModal].push(trigger)
248
+ })
249
+
250
+ return triggerMap
251
+ }
252
+
253
+ const validateModalPresence = id => {
254
+ if (!document.getElementById(id)) {
255
+ console.warn(`MicroModal: \u2757Seems like you have missed %c'${ id }'`, 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', 'ID somewhere in your code. Refer example below to resolve it.')
256
+ console.warn('%cExample:', 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', `<div class="modal" id="${ id }"></div>`)
257
+ return false
258
+ }
259
+ }
260
+
261
+ const validateTriggerPresence = triggers => {
262
+ if (triggers.length <= 0) {
263
+ console.warn('MicroModal: \u2757Please specify at least one %c\'micromodal-trigger\'', 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', 'data attribute.')
264
+ console.warn('%cExample:', 'background-color: #f8f9fa;color: #50596c;font-weight: bold;', '<a href="#" data-micromodal-trigger="my-modal"></a>')
265
+ return false
266
+ }
267
+ }
268
+
269
+ const validateArgs = (triggers, triggerMap) => {
270
+ validateTriggerPresence(triggers)
271
+ if (!triggerMap) return true
272
+ for (const id in triggerMap) validateModalPresence(id)
273
+ return true
274
+ }
275
+
276
+ const init = config => {
277
+ const options = Object.assign({}, { openTrigger: 'data-micromodal-trigger' }, config)
278
+
279
+ const triggers = [...document.querySelectorAll(`[${ options.openTrigger }]`)]
280
+
281
+ const triggerMap = generateTriggerMap(triggers, options.openTrigger)
282
+
283
+ if (options.debugMode === true && validateArgs(triggers, triggerMap) === false) return
284
+
285
+ for (const key in triggerMap) {
286
+ const value = triggerMap[key]
287
+ options.targetModal = key
288
+ options.triggers = [...value]
289
+ activeModal = new Modal(options) // eslint-disable-line no-new
290
+ }
291
+ }
292
+
293
+ const show = (targetModal, config) => {
294
+ const options = config || {}
295
+ options.targetModal = targetModal
296
+
297
+ if (options.debugMode === true && validateModalPresence(targetModal) === false) return
298
+
299
+ if (activeModal) activeModal.removeEventListeners()
300
+
301
+ activeModal = new Modal(options) // eslint-disable-line no-new
302
+ activeModal.showModal()
303
+ }
304
+
305
+ const close = targetModal => {
306
+ targetModal ? activeModal.closeModalById(targetModal) : activeModal.closeModal()
307
+ }
308
+
309
+ return { init, show, close }
310
+ })()
311
+
312
+
313
+
314
+ // themodal.js
315
+ // MIT License (c) 2023 David Miranda
316
+
317
+ const modalCss = `<style class="micromodal-css">
318
+ .micromodal {
319
+ display: none;
320
+ color: #fff;
321
+ }
322
+
323
+ .micromodal button:not(.custom-button) {
324
+ background: none;
325
+ color: inherit;
326
+ border: none;
327
+ padding: 0;
328
+ margin: 0;
329
+ width: auto;
330
+ overflow: visible;
331
+ font: inherit;
332
+ line-height: inherit;
333
+ text-transform: none;
334
+ text-align: center;
335
+ text-decoration: none;
336
+ cursor: pointer;
337
+ -webkit-appearance: none;
338
+ -moz-appearance: none;
339
+ appearance: none;
340
+ outline: 0;
341
+ }
342
+
343
+ .micromodal .micromodal__hide {
344
+ display: none;
345
+ }
346
+
347
+ .micromodal.is-open {
348
+ display: block;
349
+ }
350
+
351
+ .micromodal__overlay {
352
+ position: fixed;
353
+ top: 0;
354
+ left: 0;
355
+ right: 0;
356
+ bottom: 0;
357
+ display: flex;
358
+ justify-content: center;
359
+ align-items: center;
360
+ background: rgba(0,0,0,.65);
361
+ }
362
+
363
+ .micromodal__container {
364
+ position: relative;
365
+ box-sizing: border-box;
366
+ overflow-y: auto;
367
+ padding: 26px 40px 40px 40px;
368
+ border: 2px solid #FFFFFF;
369
+ background-color: #11131E;
370
+ overflow: visible;
371
+ }
372
+
373
+ @media (min-width: 640px) {
374
+ .micromodal .micromodal__container {
375
+ padding: 52px 64px 60px 64px;
376
+ }
377
+ }
378
+
379
+ .micromodal[aria-hidden="false"] .micromodal__overlay {
380
+ animation: microModalFadeIn .2s cubic-bezier(0.0, 0.0, 0.2, 1);
381
+ }
382
+
383
+ .micromodal[aria-hidden="false"] .micromodal__container {
384
+ animation: microModalSlideIn .2s cubic-bezier(0, 0, .2, 1);
385
+ }
386
+
387
+ .micromodal .micromodal__container,
388
+ .micromodal .micromodal__overlay {
389
+ will-change: transform;
390
+ }
391
+
392
+ @keyframes microModalFadeIn {
393
+ from { opacity: 0; }
394
+ to { opacity: 1; }
395
+ }
396
+
397
+ @keyframes microModalSlideIn {
398
+ from { transform: translateY(15%); }
399
+ to { transform: translateY(0); }
400
+ }
401
+
402
+ .micromodal .micromodal__content {
403
+ margin-bottom: 14px;
404
+ }
405
+
406
+ .micromodal .micromodal__heading {
407
+ display: flex;
408
+ flex-direction: column;
409
+ gap: 2px;
410
+ margin-bottom: 8px;
411
+ }
412
+
413
+ .micromodal .micromodal__input {
414
+ width: clamp(300px, calc(100vw - 100px), 420px);
415
+ padding: 6px 6px 7px;
416
+ font-size: 18px;
417
+ color: #000;
418
+ }
419
+
420
+ .micromodal .micromodal__input:focus, .micromodal .micromodal__input:active {
421
+ outline: 3px solid #6A73B6;
422
+ }
423
+
424
+ .micromodal button.micromodal__yes {
425
+ display: flex;
426
+ justify-content: center;
427
+ align-items: center;
428
+ width: 100%;
429
+ height: 39px;
430
+ border: 3px solid;
431
+ border-top-color: #94BA6F;
432
+ border-left-color: #94BA6F;
433
+ border-bottom-color: #1A3004;
434
+ border-right-color: #1A3004;
435
+ background-color: #49870B;
436
+ }
437
+
438
+ .micromodal button.micromodal__yes:focus,
439
+ .micromodal button.micromodal__yes:hover {
440
+ background-color: #549B0D;
441
+ }
442
+
443
+ .micromodal button.micromodal__yes:active {
444
+ border-top-color: #1A3004;
445
+ border-left-color: #1A3004;
446
+ border-bottom-color: #94BA6F;
447
+ border-right-color: #94BA6F;
448
+ }
449
+
450
+ .micromodal button.micromodal__close {
451
+ clip-path: polygon(0% 4%, 0% 0%, 100% 0%, 100% 100%, 94% 100%);
452
+ position: absolute;
453
+ top: -1px;
454
+ right: -1px;
455
+ width: 68px;
456
+ }
457
+ </style>`;
458
+
459
+ const modalHtml = `<div class="micromodal" id="micromodal" aria-hidden="true">
460
+ <div class="micromodal__overlay" tabindex="-1">
461
+ <form class="micromodal__container" role="dialog" aria-modal="true">
462
+ <div class="micromodal__content"></div>
463
+ <div class="micromodal__buttons">
464
+ <button class="micromodal__no" type="button"></button>
465
+ <button class="micromodal__yes" type="submit"></button>
466
+ </div>
467
+ <button class="micromodal__close" type="button" aria-label="Close modal"></button>
468
+ </form>
469
+ </div>
470
+ </div>`;
471
+
472
+ const themodal = (() => {
473
+ let html = "";
474
+ let yes = "";
475
+ let no = "";
476
+ let zIndex = "100";
477
+ let closeHtml = "";
478
+
479
+ let enableClickOutsideCloses = true;
480
+ let disableScroll = true;
481
+ let disableFocus = false;
482
+
483
+ let onYes = [];
484
+ let onNo = [];
485
+ let onOpen = [];
486
+
487
+ const themodalMain = {
488
+ isShowing: false,
489
+ open() {
490
+ document.body.insertAdjacentHTML("afterbegin", "<div save-ignore class='micromodal-parent'>" + modalCss + modalHtml + "</div>");
491
+
492
+ const modalOverlayElem = document.querySelector(".micromodal__overlay");
493
+ const modalContentElem = document.querySelector(".micromodal__content");
494
+ const modalButtonsElem = document.querySelector(".micromodal__buttons");
495
+ const modalYesElem = document.querySelector(".micromodal__yes");
496
+ const modalNoElem = document.querySelector(".micromodal__no");
497
+ const modalCloseElem = document.querySelector(".micromodal__close");
498
+
499
+ modalContentElem.innerHTML = html;
500
+ modalYesElem.innerHTML = yes;
501
+ modalNoElem.innerHTML = no;
502
+ modalOverlayElem.style.zIndex = zIndex;
503
+ modalCloseElem.innerHTML = closeHtml;
504
+
505
+ // MODIFIED so modal doesn't close if mousedown happened inside the modal
506
+ let mousedownOnBackdrop = false;
507
+
508
+ // MODIFIED so modal doesn't close if mousedown happened inside the modal
509
+ function handleMousedown(event) {
510
+ // Check if mousedown started on backdrop (overlay but not container)
511
+ mousedownOnBackdrop = event.target.closest(".micromodal__overlay") &&
512
+ !event.target.closest(".micromodal__container");
513
+ }
514
+
515
+ function handleClick(event) {
516
+ if (event.target.closest(".micromodal__no") || event.target.closest(".micromodal__close")) {
517
+ onNo.forEach(cb => cb());
518
+ MicroModal.close("micromodal");
519
+ // MODIFIED so modal doesn't close if mousedown happened inside the modal
520
+ } else if (enableClickOutsideCloses && mousedownOnBackdrop && !event.target.closest(".micromodal__container") && event.target.closest(".micromodal__overlay")) {
521
+ onNo.forEach(cb => cb());
522
+ MicroModal.close("micromodal");
523
+ }
524
+
525
+ // Reset after handling
526
+ mousedownOnBackdrop = false;
527
+ }
528
+
529
+ function handleSubmit(event) {
530
+ if (event.target.closest("#micromodal")) {
531
+ event.preventDefault();
532
+
533
+ // Execute callbacks and check if any return false or throw errors
534
+ let shouldClose = true;
535
+
536
+ for (const cb of onYes) {
537
+ try {
538
+ const result = cb();
539
+ // If callback explicitly returns false, don't close
540
+ if (result === false) {
541
+ shouldClose = false;
542
+ break;
543
+ }
544
+ } catch (error) {
545
+ // If callback throws an error, don't close
546
+ shouldClose = false;
547
+ // Could optionally bubble the error up or handle it here
548
+ break;
549
+ }
550
+ }
551
+
552
+ // Only close if all callbacks succeeded
553
+ if (shouldClose) {
554
+ MicroModal.close("micromodal");
555
+ }
556
+ }
557
+ }
558
+
559
+ // MODIFIED so modal doesn't close if mousedown happened inside the modal
560
+ document.addEventListener("mousedown", handleMousedown);
561
+ document.addEventListener("click", handleClick);
562
+ document.addEventListener("submit", handleSubmit);
563
+
564
+ function setButtonsVisibility () {
565
+ modalButtonsElem.classList.toggle("micromodal__hide", !yes && !no);
566
+ modalYesElem.classList.toggle("micromodal__hide", !yes);
567
+ modalNoElem.classList.toggle("micromodal__hide", !no);
568
+ }
569
+
570
+ setButtonsVisibility();
571
+
572
+ MicroModal.show("micromodal", {
573
+ disableScroll,
574
+ disableFocus: true, // we use our own
575
+ // reset everything on close
576
+ onClose: modal => {
577
+ document.querySelector(".micromodal-parent")?.remove();
578
+
579
+ html = "";
580
+ yes = "";
581
+ no = "";
582
+ zIndex = "100";
583
+ closeHtml = "";
584
+
585
+ // reset to defaults
586
+ enableClickOutsideCloses = true;
587
+ disableScroll = true;
588
+ disableFocus = false;
589
+
590
+ onYes = [];
591
+ onNo = [];
592
+ onOpen = [];
593
+
594
+ this.isShowing = false;
595
+
596
+ // MODIFIED so modal doesn't close if mousedown happened inside the modal
597
+ document.removeEventListener("mousedown", handleMousedown);
598
+ document.removeEventListener("click", handleClick);
599
+ document.removeEventListener("submit", handleSubmit);
600
+ }
601
+ });
602
+
603
+ this.isShowing = true;
604
+
605
+ if (!disableFocus) {
606
+ let firstInput = modalOverlayElem.querySelector(".micromodal__content :is(input,textarea,button):not(.micromodal__hide), .micromodal__buttons :is(input,textarea,button):not(.micromodal__hide)");
607
+ firstInput?.focus();
608
+ firstInput?.setSelectionRange?.(-1, -1);
609
+ }
610
+ },
611
+ close() {
612
+ onNo.forEach(cb => cb());
613
+ MicroModal.close("micromodal");
614
+ },
615
+ get html() {
616
+ return html;
617
+ },
618
+ set html(newVal) {
619
+ html = newVal;
620
+ },
621
+ get closeHtml() {
622
+ return closeHtml;
623
+ },
624
+ set closeHtml(newVal) {
625
+ closeHtml = newVal;
626
+ },
627
+ get yes() {
628
+ return yes;
629
+ },
630
+ set yes(newVal) {
631
+ yes = newVal;
632
+ },
633
+ get no() {
634
+ return no;
635
+ },
636
+ set no(newVal) {
637
+ no = newVal;
638
+ },
639
+ get zIndex() {
640
+ return zIndex;
641
+ },
642
+ set zIndex(newVal) {
643
+ zIndex = newVal;
644
+ },
645
+ get disableFocus() {
646
+ return disableFocus;
647
+ },
648
+ set disableFocus(newVal) {
649
+ disableFocus = newVal;
650
+ },
651
+ get disableScroll() {
652
+ return disableScroll;
653
+ },
654
+ set disableScroll(newVal) {
655
+ disableScroll = newVal;
656
+ },
657
+
658
+ onYes: (cb) => {
659
+ onYes.push(cb);
660
+ },
661
+ onNo: (cb) => {
662
+ onNo.push(cb);
663
+ },
664
+ onOpen: (cb) => {
665
+ onOpen.push(cb);
666
+ },
667
+ };
668
+
669
+ return themodalMain;
670
+ })();
671
+
672
+ // Export to window for global access
673
+ export function exportToWindow() {
674
+ window.themodal = themodal;
675
+ }
676
+
677
+ export default themodal;