@ulu/frontend 0.1.0-beta.12 → 0.1.0-beta.120

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 (343) hide show
  1. package/CHANGELOG.md +713 -0
  2. package/GEMINI.md +9 -0
  3. package/README.dev.md +3 -3
  4. package/README.md +14 -4
  5. package/dist/ulu-frontend.min.css +1 -1
  6. package/dist/ulu-frontend.min.js +36 -29
  7. package/docs-dev/.nojekyll +1 -0
  8. package/docs-dev/assets/main.js +832 -421
  9. package/docs-dev/assets/placeholder/icon-calendar.svg +1 -0
  10. package/docs-dev/assets/placeholder/icon-check.svg +1 -0
  11. package/docs-dev/assets/style.css +629 -233
  12. package/docs-dev/changelog/index.html +7613 -0
  13. package/docs-dev/changelog/updates-and-changes/index.html +5109 -0
  14. package/docs-dev/demos/accordion/index.html +1496 -358
  15. package/docs-dev/demos/badge/index.html +5895 -0
  16. package/docs-dev/demos/badge-stack/index.html +5876 -0
  17. package/docs-dev/demos/basic-hero/index.html +111 -0
  18. package/docs-dev/demos/breadcrumb/index.html +5930 -0
  19. package/docs-dev/demos/breakpoints-manager/index.html +5906 -0
  20. package/docs-dev/demos/button/index.html +1537 -343
  21. package/docs-dev/demos/button-group/index.html +5892 -0
  22. package/docs-dev/demos/button-verbose/index.html +5898 -0
  23. package/docs-dev/demos/callout/index.html +1559 -379
  24. package/docs-dev/demos/captioned-figure/index.html +1492 -339
  25. package/docs-dev/demos/card/index.html +1592 -800
  26. package/docs-dev/demos/card-grid/index.html +6017 -0
  27. package/docs-dev/demos/card-new/index.html +5088 -0
  28. package/docs-dev/demos/card-old/index.html +5223 -0
  29. package/docs-dev/demos/card.1/index.html +5223 -0
  30. package/docs-dev/demos/card.TRASH/index.html +5541 -0
  31. package/docs-dev/demos/counter-list/index.html +5900 -0
  32. package/docs-dev/demos/css-icons/index.html +1556 -380
  33. package/docs-dev/demos/data-grid/index.html +1492 -339
  34. package/docs-dev/demos/data-table/index.html +1634 -348
  35. package/docs-dev/demos/definition-list/index.html +6011 -0
  36. package/docs-dev/demos/details-group/index.html +5927 -0
  37. package/docs-dev/demos/donut-chart/index.html +5874 -0
  38. package/docs-dev/demos/file-save/index.html +1492 -339
  39. package/docs-dev/demos/flipcard/index.html +1492 -339
  40. package/docs-dev/demos/form-theme/index.html +1500 -347
  41. package/docs-dev/demos/headline-label/index.html +5862 -0
  42. package/docs-dev/demos/hero/index.html +12 -4
  43. package/docs-dev/demos/image-grid/index.html +12 -4
  44. package/docs-dev/demos/index.html +1493 -340
  45. package/docs-dev/demos/list-inline/index.html +1492 -339
  46. package/docs-dev/demos/list-lines/index.html +1492 -339
  47. package/docs-dev/demos/menu-stack/index.html +1652 -378
  48. package/docs-dev/demos/modals/index.html +1642 -366
  49. package/docs-dev/demos/nav-strip/index.html +1492 -339
  50. package/docs-dev/demos/overlay-section/index.html +1611 -388
  51. package/docs-dev/demos/panel/index.html +5922 -0
  52. package/docs-dev/demos/popovers/index.html +1752 -357
  53. package/docs-dev/demos/print/index.html +1492 -339
  54. package/docs-dev/demos/progress-bar/index.html +6030 -0
  55. package/docs-dev/demos/progress-circle/index.html +6197 -0
  56. package/docs-dev/demos/progress-donut/index.html +6107 -0
  57. package/docs-dev/demos/pull-quote/index.html +1492 -339
  58. package/docs-dev/demos/rail/index.html +5970 -0
  59. package/docs-dev/demos/rule/index.html +1509 -344
  60. package/docs-dev/demos/scroll-slider/index.html +72 -106
  61. package/docs-dev/demos/scrollpoints/index.html +1493 -340
  62. package/docs-dev/demos/skeleton/index.html +5918 -0
  63. package/docs-dev/demos/slider/index.html +12 -4
  64. package/docs-dev/demos/spoke-spinner/index.html +1492 -339
  65. package/docs-dev/demos/sticky-list/index.html +5883 -0
  66. package/docs-dev/demos/tabs/index.html +1565 -376
  67. package/docs-dev/demos/tag/index.html +1510 -345
  68. package/docs-dev/demos/theme-toggle/index.html +5939 -0
  69. package/docs-dev/demos/tile-grid-overlay/index.html +12 -4
  70. package/docs-dev/demos/tiles/index.html +1492 -339
  71. package/docs-dev/demos/tooltip/index.html +1492 -339
  72. package/docs-dev/demos/wysiwyg/index.html +5912 -0
  73. package/docs-dev/guide/building-stylesheet/index.html +1492 -339
  74. package/docs-dev/guide/developing-ulu-scss-module/index.html +1492 -339
  75. package/docs-dev/guide/index.html +1492 -339
  76. package/docs-dev/guide/updates-and-changes/index.html +5033 -0
  77. package/docs-dev/index.html +1492 -339
  78. package/docs-dev/javascript/events/index.html +1567 -376
  79. package/docs-dev/javascript/index.html +1492 -339
  80. package/docs-dev/javascript/settings/index.html +6065 -0
  81. package/docs-dev/javascript/ui-breakpoints/index.html +1506 -355
  82. package/docs-dev/javascript/ui-collapsible/index.html +1491 -340
  83. package/docs-dev/javascript/ui-details-group/index.html +5982 -0
  84. package/docs-dev/javascript/ui-dialog/index.html +1523 -357
  85. package/docs-dev/javascript/ui-flipcard/index.html +1552 -345
  86. package/docs-dev/javascript/ui-grid/index.html +1538 -413
  87. package/docs-dev/javascript/ui-modal-builder/index.html +1761 -470
  88. package/docs-dev/javascript/ui-overflow-scroller/index.html +1491 -340
  89. package/docs-dev/javascript/ui-overflow-scroller-pager/index.html +1491 -340
  90. package/docs-dev/javascript/ui-page/index.html +1491 -340
  91. package/docs-dev/javascript/ui-popover/index.html +1501 -354
  92. package/docs-dev/javascript/ui-print/index.html +1489 -346
  93. package/docs-dev/javascript/ui-print-details/index.html +1491 -340
  94. package/docs-dev/javascript/ui-programmatic-modal/index.html +1491 -340
  95. package/docs-dev/javascript/ui-proxy-click/index.html +1591 -355
  96. package/docs-dev/javascript/ui-resizer/index.html +1850 -434
  97. package/docs-dev/javascript/ui-scroll-slider/index.html +1531 -348
  98. package/docs-dev/javascript/ui-scrollpoint/index.html +1501 -357
  99. package/docs-dev/javascript/ui-slider/index.html +1708 -366
  100. package/docs-dev/javascript/ui-tabs/index.html +1523 -409
  101. package/docs-dev/javascript/ui-theme-toggle/index.html +6070 -0
  102. package/docs-dev/javascript/ui-tooltip/index.html +1501 -354
  103. package/docs-dev/javascript/utils-class-logger/index.html +1492 -341
  104. package/docs-dev/javascript/utils-css/index.html +5884 -0
  105. package/docs-dev/javascript/utils-dom/index.html +1523 -452
  106. package/docs-dev/javascript/utils-file-save/index.html +1491 -340
  107. package/docs-dev/javascript/utils-floating-ui/index.html +1491 -340
  108. package/docs-dev/javascript/utils-id/index.html +1491 -340
  109. package/docs-dev/javascript/utils-pause-youtube-video/index.html +1491 -340
  110. package/docs-dev/javascript/utils-system/index.html +6187 -0
  111. package/docs-dev/sass/base/color/index.html +1491 -340
  112. package/docs-dev/sass/base/elements/index.html +1492 -341
  113. package/docs-dev/sass/base/index/index.html +1492 -341
  114. package/docs-dev/sass/base/index.html +1492 -339
  115. package/docs-dev/sass/base/keyframes/index.html +1492 -341
  116. package/docs-dev/sass/base/layout/index.html +1492 -341
  117. package/docs-dev/sass/base/normalize/index.html +1491 -340
  118. package/docs-dev/sass/base/print/index.html +1492 -341
  119. package/docs-dev/sass/base/root/index.html +1495 -344
  120. package/docs-dev/sass/base/typography/index.html +1491 -340
  121. package/docs-dev/sass/components/accordion/index.html +1628 -436
  122. package/docs-dev/sass/components/adaptive-spacing/index.html +1491 -340
  123. package/docs-dev/sass/components/badge/index.html +1522 -353
  124. package/docs-dev/sass/components/badge-stack/index.html +6051 -0
  125. package/docs-dev/sass/components/basic-hero/index.html +6045 -0
  126. package/docs-dev/sass/components/breadcrumb/index.html +6092 -0
  127. package/docs-dev/sass/components/button/index.html +1491 -340
  128. package/docs-dev/sass/components/button-group/index.html +6043 -0
  129. package/docs-dev/sass/components/button-verbose/index.html +1613 -387
  130. package/docs-dev/sass/components/callout/index.html +1598 -388
  131. package/docs-dev/sass/components/captioned-figure/index.html +1491 -340
  132. package/docs-dev/sass/components/card/index.html +1601 -393
  133. package/docs-dev/sass/components/card-grid/index.html +1491 -340
  134. package/docs-dev/sass/components/counter-list/index.html +6127 -0
  135. package/docs-dev/sass/components/css-icon/index.html +1492 -341
  136. package/docs-dev/sass/components/data-grid/index.html +1511 -353
  137. package/docs-dev/sass/components/data-table/index.html +1510 -352
  138. package/docs-dev/sass/components/definition-list/index.html +6107 -0
  139. package/docs-dev/sass/components/fill-context/index.html +1491 -340
  140. package/docs-dev/sass/components/flipcard/index.html +1569 -387
  141. package/docs-dev/sass/components/flipcard-grid/index.html +1491 -340
  142. package/docs-dev/sass/components/form-theme/index.html +1718 -572
  143. package/docs-dev/sass/components/headline-label/index.html +6073 -0
  144. package/docs-dev/sass/components/hero/index.html +1499 -348
  145. package/docs-dev/sass/components/horizontal-rule/index.html +1491 -340
  146. package/docs-dev/sass/components/image-grid/index.html +1491 -340
  147. package/docs-dev/sass/components/index/index.html +1514 -349
  148. package/docs-dev/sass/components/index.html +1492 -339
  149. package/docs-dev/sass/components/links/index.html +1491 -340
  150. package/docs-dev/sass/components/list-inline/index.html +1491 -340
  151. package/docs-dev/sass/components/list-lines/index.html +1491 -340
  152. package/docs-dev/sass/components/list-ordered/index.html +1491 -340
  153. package/docs-dev/sass/components/list-unordered/index.html +1491 -340
  154. package/docs-dev/sass/components/menu-stack/index.html +1578 -378
  155. package/docs-dev/sass/components/modal/index.html +1576 -390
  156. package/docs-dev/sass/components/nav-strip/index.html +1499 -348
  157. package/docs-dev/sass/components/overlay-section/index.html +1499 -348
  158. package/docs-dev/sass/components/pager/index.html +1491 -340
  159. package/docs-dev/sass/components/panel/index.html +6273 -0
  160. package/docs-dev/sass/components/placeholder-block/index.html +1491 -340
  161. package/docs-dev/sass/components/popover/index.html +1561 -404
  162. package/docs-dev/sass/components/progress-bar/index.html +6252 -0
  163. package/docs-dev/sass/components/progress-circle/index.html +6144 -0
  164. package/docs-dev/sass/components/pull-quote/index.html +1491 -340
  165. package/docs-dev/sass/components/rail/index.html +6063 -0
  166. package/docs-dev/sass/components/ratio-box/index.html +1499 -348
  167. package/docs-dev/sass/components/rule/index.html +1492 -341
  168. package/docs-dev/sass/components/scroll-slider/index.html +1501 -362
  169. package/docs-dev/sass/components/skeleton/index.html +6101 -0
  170. package/docs-dev/sass/components/skip-link/index.html +1491 -340
  171. package/docs-dev/sass/components/slider/index.html +1581 -442
  172. package/docs-dev/sass/components/spoke-spinner/index.html +1493 -342
  173. package/docs-dev/sass/components/sticky-list/index.html +6263 -0
  174. package/docs-dev/sass/components/table-sticky/index.html +5707 -0
  175. package/docs-dev/sass/components/tabs/index.html +1519 -353
  176. package/docs-dev/sass/components/tag/index.html +1648 -403
  177. package/docs-dev/sass/components/tile-button/index.html +1491 -340
  178. package/docs-dev/sass/components/tile-grid/index.html +1491 -340
  179. package/docs-dev/sass/components/tile-grid-overlay/index.html +1491 -340
  180. package/docs-dev/sass/components/vignette/index.html +1499 -348
  181. package/docs-dev/sass/components/wysiwyg/index.html +1524 -355
  182. package/docs-dev/sass/core/breakpoint/index.html +1577 -374
  183. package/docs-dev/sass/core/button/index.html +1523 -370
  184. package/docs-dev/sass/core/color/index.html +1768 -485
  185. package/docs-dev/sass/core/cssvar/index.html +1491 -340
  186. package/docs-dev/sass/core/element/index.html +1837 -404
  187. package/docs-dev/sass/core/index.html +1491 -340
  188. package/docs-dev/sass/core/layout/index.html +1582 -412
  189. package/docs-dev/sass/core/path/index.html +1491 -340
  190. package/docs-dev/sass/core/selector/index.html +1491 -340
  191. package/docs-dev/sass/core/typography/index.html +1657 -448
  192. package/docs-dev/sass/core/units/index.html +1499 -342
  193. package/docs-dev/sass/core/utils/index.html +2781 -481
  194. package/docs-dev/sass/helpers/color/index.html +1491 -340
  195. package/docs-dev/sass/helpers/display/index.html +1492 -341
  196. package/docs-dev/sass/helpers/index/index.html +1491 -340
  197. package/docs-dev/sass/helpers/index.html +1492 -339
  198. package/docs-dev/sass/helpers/print/index.html +759 -298
  199. package/docs-dev/sass/helpers/typography/index.html +1491 -340
  200. package/docs-dev/sass/helpers/units/index.html +1491 -340
  201. package/docs-dev/sass/helpers/utilities/index.html +1495 -340
  202. package/docs-dev/sass/index.html +1492 -339
  203. package/js/events/index.js +17 -5
  204. package/js/index.js +1 -0
  205. package/js/settings.js +97 -0
  206. package/js/ui/breakpoints.js +19 -16
  207. package/js/ui/collapsible.js +8 -1
  208. package/js/ui/details-group.js +112 -0
  209. package/js/ui/dialog.js +103 -44
  210. package/js/ui/dialog.todo +2 -36
  211. package/js/ui/flipcard.js +37 -57
  212. package/js/ui/grid.js +15 -13
  213. package/js/ui/index.js +1 -0
  214. package/js/ui/modal-builder.js +127 -70
  215. package/js/ui/overflow-scroller.js +6 -4
  216. package/js/ui/page.js +2 -2
  217. package/js/ui/popover.js +38 -38
  218. package/js/ui/print.js +16 -25
  219. package/js/ui/programmatic-modal.js +9 -3
  220. package/js/ui/proxy-click.js +50 -36
  221. package/js/ui/resizer.js +408 -39
  222. package/js/ui/scroll-slider.js +24 -30
  223. package/js/ui/scrollpoint.js +29 -64
  224. package/js/ui/slider.js +108 -63
  225. package/js/ui/tabs.js +23 -36
  226. package/js/ui/theme-toggle.js +332 -94
  227. package/js/ui/tooltip.js +27 -32
  228. package/js/utils/class-logger.js +3 -3
  229. package/js/utils/css.js +13 -0
  230. package/js/utils/dom.js +23 -64
  231. package/js/utils/font-awesome.js +19 -0
  232. package/js/utils/index.js +2 -1
  233. package/js/utils/system.js +155 -0
  234. package/package.json +24 -9
  235. package/scss/README.md +9 -0
  236. package/scss/_breakpoint.scss +39 -5
  237. package/scss/_button.scss +7 -5
  238. package/scss/_color.scss +71 -40
  239. package/scss/_element.scss +124 -2
  240. package/scss/_layout.scss +7 -8
  241. package/scss/_typography.scss +15 -0
  242. package/scss/_units.scss +3 -2
  243. package/scss/_utils.scss +387 -16
  244. package/scss/base/_elements.scss +0 -1
  245. package/scss/base/_index.scss +1 -1
  246. package/scss/base/_keyframes.scss +15 -0
  247. package/scss/base/_layout.scss +1 -0
  248. package/scss/base/_print.scss +2 -0
  249. package/scss/base/_root.scss +2 -0
  250. package/scss/components/_accordion.scss +167 -110
  251. package/scss/components/_badge-stack.scss +84 -0
  252. package/scss/components/_badge.scss +30 -7
  253. package/scss/components/_basic-hero.scss +112 -0
  254. package/scss/components/_breadcrumb.scss +110 -0
  255. package/scss/components/_button-group.scss +90 -0
  256. package/scss/components/_button-verbose.scss +100 -18
  257. package/scss/components/_callout.scss +112 -53
  258. package/scss/components/_card.scss +216 -87
  259. package/scss/components/_counter-list.scss +151 -0
  260. package/scss/components/_css-icon.scss +27 -17
  261. package/scss/components/_data-grid.scss +55 -12
  262. package/scss/components/_data-table.scss +3 -0
  263. package/scss/components/_definition-list.scss +178 -0
  264. package/scss/components/_flipcard.scss +8 -3
  265. package/scss/components/_form-theme.scss +106 -95
  266. package/scss/components/_headline-label.scss +83 -0
  267. package/scss/components/_hero.scss +3 -10
  268. package/scss/components/_index.scss +79 -0
  269. package/scss/components/_menu-stack.scss +87 -23
  270. package/scss/components/_modal.scss +51 -23
  271. package/scss/components/_nav-strip.scss +2 -0
  272. package/scss/components/_overlay-section.scss +2 -5
  273. package/scss/components/_panel.scss +246 -0
  274. package/scss/components/_popover.scss +139 -38
  275. package/scss/components/_progress-bar.scss +260 -0
  276. package/scss/components/_progress-circle.scss +175 -0
  277. package/scss/components/_pull-quote.scss +1 -1
  278. package/scss/components/_rail.scss +127 -0
  279. package/scss/components/_ratio-box.scss +2 -5
  280. package/scss/components/_rule.scss +1 -0
  281. package/scss/components/_scroll-slider.scss +1 -5
  282. package/scss/components/_skeleton.scss +126 -0
  283. package/scss/components/_slider.scss +49 -72
  284. package/scss/components/_spoke-spinner.scss +2 -2
  285. package/scss/components/_sticky-list.scss +206 -0
  286. package/scss/components/_tabs.scss +22 -4
  287. package/scss/components/_tag.scss +49 -7
  288. package/scss/components/_vignette.scss +2 -5
  289. package/scss/components/_wysiwyg.scss +21 -13
  290. package/scss/helpers/_display.scss +15 -18
  291. package/scss/helpers/_print.scss +12 -7
  292. package/scss/helpers/_utilities.scss +62 -34
  293. package/types/events/index.d.ts +10 -1
  294. package/types/events/index.d.ts.map +1 -1
  295. package/types/index.d.ts +1 -0
  296. package/types/settings.d.ts +70 -0
  297. package/types/settings.d.ts.map +1 -0
  298. package/types/ui/breakpoints.d.ts +14 -14
  299. package/types/ui/breakpoints.d.ts.map +1 -1
  300. package/types/ui/collapsible.d.ts.map +1 -1
  301. package/types/ui/details-group.d.ts +38 -0
  302. package/types/ui/details-group.d.ts.map +1 -0
  303. package/types/ui/dialog.d.ts +20 -14
  304. package/types/ui/dialog.d.ts.map +1 -1
  305. package/types/ui/flipcard.d.ts +16 -10
  306. package/types/ui/flipcard.d.ts.map +1 -1
  307. package/types/ui/grid.d.ts +4 -6
  308. package/types/ui/grid.d.ts.map +1 -1
  309. package/types/ui/index.d.ts +1 -0
  310. package/types/ui/modal-builder.d.ts +116 -11
  311. package/types/ui/modal-builder.d.ts.map +1 -1
  312. package/types/ui/overflow-scroller.d.ts +2 -2
  313. package/types/ui/overflow-scroller.d.ts.map +1 -1
  314. package/types/ui/popover.d.ts +6 -7
  315. package/types/ui/popover.d.ts.map +1 -1
  316. package/types/ui/print.d.ts +0 -4
  317. package/types/ui/print.d.ts.map +1 -1
  318. package/types/ui/programmatic-modal.d.ts.map +1 -1
  319. package/types/ui/proxy-click.d.ts +19 -3
  320. package/types/ui/proxy-click.d.ts.map +1 -1
  321. package/types/ui/resizer.d.ts +116 -16
  322. package/types/ui/resizer.d.ts.map +1 -1
  323. package/types/ui/scroll-slider.d.ts +5 -7
  324. package/types/ui/scroll-slider.d.ts.map +1 -1
  325. package/types/ui/scrollpoint.d.ts +3 -8
  326. package/types/ui/scrollpoint.d.ts.map +1 -1
  327. package/types/ui/slider.d.ts +33 -14
  328. package/types/ui/slider.d.ts.map +1 -1
  329. package/types/ui/tabs.d.ts +6 -8
  330. package/types/ui/tabs.d.ts.map +1 -1
  331. package/types/ui/theme-toggle.d.ts +51 -7
  332. package/types/ui/theme-toggle.d.ts.map +1 -1
  333. package/types/ui/tooltip.d.ts +3 -5
  334. package/types/ui/tooltip.d.ts.map +1 -1
  335. package/types/utils/css.d.ts +11 -0
  336. package/types/utils/css.d.ts.map +1 -0
  337. package/types/utils/dom.d.ts +12 -32
  338. package/types/utils/dom.d.ts.map +1 -1
  339. package/types/utils/font-awesome.d.ts +5 -0
  340. package/types/utils/font-awesome.d.ts.map +1 -0
  341. package/types/utils/index.d.ts +1 -0
  342. package/types/utils/system.d.ts +113 -0
  343. package/types/utils/system.d.ts.map +1 -0
@@ -21,30 +21,31 @@ const events = {
21
21
  * - Is triggered by modules that were responsible for modifying the page
22
22
  */
23
23
  pageModified(context) {
24
- context.dispatchEvent(new CustomEvent(getName("pageModified"), { bubbles: true }));
24
+ context.dispatchEvent(createEvent("pageModified"));
25
25
  },
26
26
  /**
27
27
  * Event called when page is resized
28
28
  */
29
29
  pageResized(context) {
30
- context.dispatchEvent(new CustomEvent(getName("pageResized"), { bubbles: true }));
30
+ context.dispatchEvent(createEvent("pageResized"));
31
31
  },
32
32
  /**
33
33
  * Event dispatched before page print begins (teardown/restructure/hide things)
34
34
  */
35
35
  beforePrint(context) {
36
- context.dispatchEvent(new CustomEvent(getName("beforePrint"), { bubbles: true }));
36
+ context.dispatchEvent(createEvent("beforePrint"));
37
37
  },
38
38
  /**
39
39
  * Event dispatched after page print (cleanup)
40
40
  */
41
41
  afterPrint(context) {
42
- context.dispatchEvent(new CustomEvent(getName("afterPrint"), { bubbles: true }));
42
+ context.dispatchEvent(createEvent("afterPrint"));
43
43
  }
44
44
  };
45
45
 
46
46
  /**
47
- * Triggers one of our custom events
47
+ * Triggers one of our custom events (page/document level events)
48
+ * - UI components may dispatch their own events, this is just used for system wide events
48
49
  * @param {String} type Type of event to dispatch
49
50
  * @param {Node} context Element to trigger the event from
50
51
  * @example
@@ -62,6 +63,7 @@ export function dispatch(type, context) {
62
63
 
63
64
  /**
64
65
  * Namespaced event
66
+ * - Should be used for all ulu script/component events
65
67
  * @param {String} type Type of event to get the actual event name for
66
68
  * @returns {String}
67
69
  */
@@ -69,6 +71,16 @@ export function getName(type) {
69
71
  return "ulu:" + type;
70
72
  }
71
73
 
74
+ /**
75
+ * Create ulu namespaced custom event
76
+ * @param {String} type Event base name (not prefixed)
77
+ * @param {any} data Custom data to pass with the event (will be available as `event.detail`)
78
+ * @param {Object} options CustomEvent options default `{ bubbles: true }`. If `detail` is also provided, it will be merged with this options object and will override the 'data' argument for this function
79
+ */
80
+ export function createEvent(type, data = null, options = { bubbles: true }) {
81
+ return new CustomEvent(getName(type), { detail: data, ...options });
82
+ }
83
+
72
84
  /**
73
85
  * Setup resize handler/dispatch
74
86
  */
package/js/index.js CHANGED
@@ -5,6 +5,7 @@
5
5
  // - Will not include things that aren't used in every site (those would need to
6
6
  // imported manually
7
7
 
8
+ export * as settings from "./settings.js";
8
9
  export * as events from "./events/index.js";
9
10
  export * as ui from "./ui/index.js";
10
11
  export * as utils from "./utils/index.js";
package/js/settings.js ADDED
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @module settings
3
+ * @description Manages shared configuration for the library.
4
+ */
5
+
6
+ /**
7
+ * Default settings
8
+ * @typedef {object} Defaults
9
+ * @property {string} iconClassClose - The CSS class string for the close icon
10
+ * @property {string} iconClassDragX - The CSS class string for the drag X icon
11
+ * @property {string} iconClassDragBoth - The CSS class string for the dragging in both directions
12
+ * @property {string} iconClassPrevious - The CSS class string for the previous icon
13
+ * @property {string} iconClassNext - The CSS class string for the next icon
14
+ * @property {string} cssvarPrefix - The prefix to use for CSS custom properties
15
+ */
16
+
17
+ /**
18
+ * @type {Defaults}
19
+ */
20
+ const defaults = {
21
+ iconClassClose: "css-icon css-icon--close",
22
+ iconClassDragX: "css-icon css-icon--drag-x",
23
+ iconClassDragBoth: "css-icon css-icon--drag-both",
24
+ iconClassPrevious: "css-icon css-icon--angle-left",
25
+ iconClassNext: "css-icon css-icon--angle-right",
26
+ cssvarPrefix: "",
27
+ };
28
+
29
+ // Current configuration, initialized with defaults
30
+ let currentSettings = { ...defaults };
31
+
32
+ /**
33
+ * Retrieves a copy of the default settings.
34
+ * @returns {object} A copy of the default settings object.
35
+ */
36
+ export function getDefaultSettings() {
37
+ return { ...defaults };
38
+ }
39
+
40
+ /**
41
+ * Updates multiple configuration settings.
42
+ * @param {object} changes An object containing the settings to update.
43
+ */
44
+ export function updateSettings(changes) {
45
+ Object.assign(currentSettings, changes);
46
+ }
47
+
48
+ /**
49
+ * Retrieves a copy of the current configuration settings.
50
+ * @returns {object} A copy of the current settings object.
51
+ */
52
+ export function getSettings() {
53
+ return { ...currentSettings };
54
+ }
55
+
56
+ /**
57
+ * Retrieves a specific configuration setting by key.
58
+ * @param {string} key The key of the setting to retrieve.
59
+ * @returns {*} The value of the setting, or undefined if not found.
60
+ */
61
+ export function getSetting(key) {
62
+ if (!currentSettings.hasOwnProperty(key)) {
63
+ console.warn(`Attempted to access non-existent setting: ${key}`);
64
+ return undefined;
65
+ }
66
+ return currentSettings[key];
67
+ }
68
+
69
+ /**
70
+ * Updates a specific configuration setting.
71
+ * @param {string} key The key of the setting to update.
72
+ * @param {*} value The new value for the setting.
73
+ */
74
+ export function updateSetting(key, value) {
75
+ currentSettings[key] = value;
76
+ }
77
+
78
+ /**
79
+ * Creates a wrapped string representation of a configuration setting.
80
+ * This function returns an object with a `toString()` method that, when called,
81
+ * retrieves the current value of the specified setting. This allows the setting
82
+ * to be used as a string literal, dynamically retrieving its value.
83
+ *
84
+ * @param {String} key The key of the setting to wrap.
85
+ * @param {Function} transform Optional function to transform the setting's
86
+ * value when its string representation is requested.
87
+ * @returns {Object} An object with a `toString()` method that returns the
88
+ * (optionally transformed) setting value as a string.
89
+ */
90
+ export function wrapSettingString(key, transform) {
91
+ return {
92
+ toString() {
93
+ const value = getSetting(key);
94
+ return transform ? transform(value) : value;
95
+ }
96
+ };
97
+ }
@@ -5,8 +5,11 @@
5
5
  // Pass breakpoints from CSS to stylesheet, use this to attach behaviors on breakpoints
6
6
  import { removeArrayElement } from "@ulu/utils/array.js";
7
7
  import { getName } from "../events/index.js";
8
+ import { wrapSettingString } from "../settings.js";
9
+ import { getCustomProperty } from "../utils/css.js";
8
10
  import { log, logError } from "../utils/class-logger.js";
9
11
 
12
+ const getDefaultCustomProperty = prefix => getCustomProperty(prefix, "breakpoint");
10
13
 
11
14
  // Resize Handler to update breakpoints for all instances (Called after resize finished)
12
15
  window.addEventListener(getName("pageResized"), () => {
@@ -16,25 +19,26 @@ window.addEventListener(getName("pageResized"), () => {
16
19
  /**
17
20
  * @class
18
21
  * Class that provides method for retrieving and acting on breakpoints passed
19
- * from CSS (using element psuedo content prop)
22
+ * from CSS (using element pseudo content prop)
20
23
  */
21
24
  export class BreakpointManager {
22
25
  static instances = [];
23
26
  static defaults = {
24
27
  element: document?.documentElement,
25
- valueFromPsuedo: false,
28
+ valueFromPseudo: false,
26
29
  customProperty: "--breakpoint",
27
- psuedoSelector: ':before',
30
+ customProperty: wrapSettingString("cssvarPrefix", getDefaultCustomProperty),
31
+ pseudoSelector: ':before',
28
32
  order: ["none", "small", "medium", "large"],
29
33
  debug: false
30
34
  }
31
35
  /**
32
- * @param {Object} config Configruation object
36
+ * @param {Object} config Configuration object
33
37
  * @param {Array} config.order Array of strings that correspond to the breakpoints setup in the styles, Breakpoints from smallest to largest, defaults to [small, medium, large]
34
38
  * @param {Array} config.customProperty Property to grab breakpoint from (default is --breakpoint)
35
- * @param {Array} config.valueFromPsuedo Use the legacy method of grabbing breakpoint from psuedo element, default uses custom property
36
- * @param {Node} config.element The element to retrieve active breakpoint from stylesheet. (default is html) For using the old psuedo method, adjust this to document.body
37
- * @param {String} config.psuedoSelector Change psuedo selector used to get the breakpoint from the psuedo's content property
39
+ * @param {Array} config.valueFromPseudo Use the legacy method of grabbing breakpoint from pseudo element, default uses custom property
40
+ * @param {Node} config.element The element to retrieve active breakpoint from stylesheet. (default is html) For using the old pseudo method, adjust this to document.body
41
+ * @param {String} config.pseudoSelector Change pseudo selector used to get the breakpoint from the pseudo's content property
38
42
  */
39
43
  constructor(config) {
40
44
  Object.assign(this, BreakpointManager.defaults, config);
@@ -51,9 +55,9 @@ export class BreakpointManager {
51
55
  BreakpointManager.instances.push(this);
52
56
  }
53
57
  /**
54
- * Add a callback for everytime a breakpoint changes
58
+ * Add a callback for every time a breakpoint changes
55
59
  * - Not recommended, possibly use to watch for changes, etc
56
- * - For more control use intance.at(name) with breakpoint methods
60
+ * - For more control use instance.at(name) with breakpoint methods
57
61
  * @param {Function} callback Function to call, passed one argument current instance which can be used to get information about breakpoints
58
62
  */
59
63
  onChange(callback) {
@@ -67,10 +71,10 @@ export class BreakpointManager {
67
71
  removeArrayElement(this.onChangeCallbacks, callback);
68
72
  }
69
73
  /**
70
- * Get breakpoint from a psuedo element
74
+ * Get breakpoint from a pseudo element
71
75
  */
72
- getBreakpointInPsuedo() {
73
- return window.getComputedStyle(this.element, this.psuedoSelector).content.replace(/^"|"$/g, '');
76
+ getBreakpointInPseudo() {
77
+ return window.getComputedStyle(this.element, this.pseudoSelector).content.replace(/^"|"$/g, '');
74
78
  }
75
79
  /**
76
80
  * Get breakpoint from a custom property
@@ -82,8 +86,8 @@ export class BreakpointManager {
82
86
  * Get breakpoint from element (design note: user could override prototype)
83
87
  */
84
88
  getBreakpoint() {
85
- if (this.valueFromPsuedo) {
86
- return this.getBreakpointInPsuedo();
89
+ if (this.valueFromPseudo) {
90
+ return this.getBreakpointInPseudo();
87
91
  } else {
88
92
  return this.getBreakpointInProperty();
89
93
  }
@@ -97,9 +101,8 @@ export class BreakpointManager {
97
101
  logError(this, 'Unable to get current breakpoint, maybe order is incorrect? Breakpoint check skipped!');
98
102
  return;
99
103
  }
100
- // console.log('name:\n', name);
101
104
  if (name === this.active) return;
102
- // this.log(`current breakpoint: ${ name }`);
105
+
103
106
  // Update active and cache last
104
107
  this.previous = this.active;
105
108
  this.previousIndex = this.activeIndex;
@@ -71,7 +71,14 @@ export class Collapsible {
71
71
  }
72
72
  this.focusoutHandler = (event) => {
73
73
  if (focusoutCloses) {
74
- this.close(event);
74
+ // If closing on focus out we attach one-time event to
75
+ // see which element is focused next (in between focusout and focusin
76
+ // it's the body) so doing the logic in focusout won't work
77
+ document.addEventListener('focusin', () => {
78
+ if (!content.contains(document.activeElement)) {
79
+ this.close(event);
80
+ }
81
+ }, { once: true });
75
82
  }
76
83
  };
77
84
  trigger.addEventListener("click", this.clickHandler);
@@ -0,0 +1,112 @@
1
+ /**
2
+ * @module ui/details-group
3
+ * @description Manages groups of details (ie. onlyOneOpen at a time)
4
+ */
5
+
6
+ import { ComponentInitializer } from "../utils/system.js";
7
+
8
+ /**
9
+ * Dialog Component Initializer
10
+ */
11
+ export const initializer = new ComponentInitializer({
12
+ type: "details-group",
13
+ baseAttribute: "data-ulu-details-group"
14
+ });
15
+
16
+ const childInitAttr = initializer.getAttribute("child-init");
17
+ const defaults = {
18
+ onlyOneOpen: true,
19
+ childSelector: ":scope > details"
20
+ };
21
+
22
+ /**
23
+ * Initialize everything in document
24
+ * - This will only initialize elements once, it is safe to call on page changes
25
+ */
26
+ export function init() {
27
+ initializer.init({
28
+ withData: true,
29
+ events: ["pageModified"],
30
+ setup({ element, data, initialize }) {
31
+ setupGroup(element, data);
32
+ initialize();
33
+ }
34
+ });
35
+ }
36
+
37
+ /**
38
+ * @typedef {Object} DetailsGroupInstance
39
+ * @property {Function} destroy A function to remove event listeners and attributes.
40
+ * @property {HTMLElement} element The parent element.
41
+ * @property {Function} setupChildren A function to initialize the child details elements.
42
+ */
43
+
44
+ /**
45
+ * Sets up a single group of details elements to manage their behavior.
46
+ * @param {HTMLElement} element - The parent element containing the details elements.
47
+ * @param {Object} options - The options for this group
48
+ * @returns {DetailsGroupInstance}
49
+ */
50
+ export function setupGroup(element, userOptions) {
51
+ const options = Object.assign({}, defaults, userOptions);
52
+
53
+ // Added try because we are using querySelectorAll with :scope by default
54
+ // which will not work in Internet Explorer or early edge (some alt. browsers too)
55
+ try {
56
+ setupChildren();
57
+ } catch(error) {
58
+ console.error(error);
59
+ }
60
+
61
+ /**
62
+ * Queries all current children in element
63
+ * @ignore
64
+ */
65
+ function queryChildren() {
66
+ return element.querySelectorAll(options.childSelector);
67
+ }
68
+
69
+ /**
70
+ * Sets up any children not already setup in group
71
+ */
72
+ function setupChildren() {
73
+ queryChildren().forEach(child => {
74
+ if (child.hasAttribute(childInitAttr)) {
75
+ return;
76
+ } else {
77
+ child.setAttribute(childInitAttr, "");
78
+ }
79
+ child.addEventListener("toggle", toggleHandler);
80
+ });
81
+ }
82
+
83
+ /**
84
+ * Toggle handler for child details element
85
+ * - For things like one open at a time
86
+ * @ignore
87
+ */
88
+ function toggleHandler({ target }) {
89
+ if (options.onlyOneOpen) {
90
+ if (target.open) {
91
+ queryChildren().forEach(child => {
92
+ if (child !== target && child.open) {
93
+ child.open = false;
94
+ }
95
+ });
96
+ }
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Function removes all handlers and init attributes
102
+ */
103
+ function destroy() {
104
+ queryChildren().forEach(child => {
105
+ child.removeEventListener("toggle", toggleHandler);
106
+ child.removeAttribute(childInitAttr);
107
+ });
108
+ element.removeAttribute(initializer.getAttribute("init"));
109
+ }
110
+
111
+ return { destroy, element, setupChildren };
112
+ }
package/js/ui/dialog.js CHANGED
@@ -3,22 +3,24 @@
3
3
  */
4
4
 
5
5
  import { getName } from "../events/index.js";
6
- import { getDatasetJson, wasClickOutside } from "../utils/dom.js";
6
+ import { ComponentInitializer } from "../utils/system.js";
7
+ import { wasClickOutside, preventScroll as setupPreventScroll } from "@ulu/utils/browser/dom.js";
7
8
  import { pauseVideos as pauseYoutubeVideos, prepVideos as prepYoutubeVideos } from "../utils/pause-youtube-video.js";
9
+
8
10
  /**
9
- * Default data attributes
11
+ * Base attribute for a dialog
10
12
  */
11
- export const attrs = {
12
- init: "data-ulu-dialog-init",
13
- dialog: "data-ulu-dialog",
14
- trigger: "data-ulu-dialog-trigger",
15
- close: "data-ulu-dialog-close",
16
- };
13
+ export const baseAttribute = "data-ulu-dialog"; // Exposed for modal builder
14
+
15
+ /**
16
+ * Dialog Component Initializer
17
+ */
18
+ export const initializer = new ComponentInitializer({ type: "dialog", baseAttribute });
17
19
 
18
- // Utils for selecting things based on attributes
19
- const attrSelector = key => `[${ attrs[key] }]`;
20
- const attrSelectorInitial = key => `${ attrSelector(key) }:not([${ attrs.init }])`;
21
- const queryAllInitial = key => document.querySelectorAll(attrSelectorInitial(key));
20
+ /**
21
+ * Attribute for close buttons within a dialog
22
+ */
23
+ export const closeAttribute = initializer.getAttribute("close"); // Exposed for modal builder
22
24
 
23
25
  /**
24
26
  * Dialog Defaults
@@ -42,6 +44,15 @@ export const defaults = {
42
44
  * Whether or not to pause videos when dialog closes (currently just youtube and native)
43
45
  */
44
46
  pauseVideos: true,
47
+ /**
48
+ * When open and not non-modal, the body is prevented from scrolling (defaults to true).
49
+ */
50
+ preventScroll: true,
51
+ /**
52
+ * Compensate for layout shift when preventing scroll. Which adds padding equal to scrollbars
53
+ * width while dialog is open
54
+ */
55
+ preventScrollShift: true,
45
56
  };
46
57
 
47
58
 
@@ -49,7 +60,7 @@ export const defaults = {
49
60
  let currentDefaults = { ...defaults };
50
61
 
51
62
  /**
52
- * @param {Object} options Change options used as default for dialogs, can then be overriden by data attribute settings on element
63
+ * @param {Object} options Change options used as default for dialogs, can then be overridden by data attribute settings on element
53
64
  */
54
65
  export function setDefaults(options) {
55
66
  currentDefaults = Object.assign({}, currentDefaults, options);
@@ -60,35 +71,48 @@ export function setDefaults(options) {
60
71
  * - This will only initialize elements once, it is safe to call on page changes
61
72
  */
62
73
  export function init() {
63
- document.addEventListener(getName("pageModified"), setup);
64
- setup();
65
- }
66
-
67
- /**
68
- * Setup dialogs and triggers
69
- */
70
- export function setup() {
71
- // Then setup all dialogs (including those that were built)
72
- const dialogs = queryAllInitial("dialog");
73
- dialogs.forEach(setupDialog);
74
-
75
- const triggers = queryAllInitial("trigger");
76
- triggers.forEach(setupTrigger);
74
+ // Initialize all the dialogs
75
+ initializer.init({
76
+ events: ["pageModified"],
77
+ withData: true,
78
+ setup({ element, initialize, data }) {
79
+ setupDialog(element, data);
80
+ initialize();
81
+ }
82
+ });
83
+
84
+ // Initialize all triggers (things that trigger opening a dialog)
85
+ initializer.init({
86
+ key: "trigger",
87
+ events: ["pageModified"],
88
+ withData: true,
89
+ setup({ element, initialize, data: dialogId }) {
90
+ setupTrigger(element, dialogId);
91
+ initialize();
92
+ }
93
+ });
77
94
  }
78
95
 
79
96
  /**
80
97
  * Setup click handlers on a trigger
81
- * @param {Node} trigger
98
+ * @param {Node} trigger Trigger button element
99
+ * @param {String} dialogId The dialog's id to open
82
100
  */
83
- export function setupTrigger(trigger) {
101
+ export function setupTrigger(trigger, dialogId) {
84
102
  trigger.addEventListener("click", handleTrigger);
85
- trigger.setAttribute(attrs.init, "");
86
103
 
87
- function handleTrigger() {
88
- const id = trigger.dataset.uluDialogTrigger;
89
- const dialog = document.getElementById(id);
104
+ function handleTrigger(event) {
105
+
106
+ // If a link is used (not recommended) we need to prevent
107
+ // the page from scrolling
108
+ const closestLink = event.target.closest("a");
109
+ if (closestLink) {
110
+ event.preventDefault();
111
+ }
112
+
113
+ const dialog = document.getElementById(dialogId);
90
114
  if (!dialog) {
91
- console.error("Could not locate dialog (id)", id);
115
+ console.error("Could not locate dialog (id)", dialogId);
92
116
  return;
93
117
  }
94
118
  if (dialog?.tagName?.toLowerCase() !== "dialog") {
@@ -104,23 +128,49 @@ export function setupTrigger(trigger) {
104
128
  * Setup click handlers for a dialog
105
129
  * @param {Node} dialog
106
130
  */
107
- export function setupDialog(dialog) {
108
- const options = getDialogOptions(dialog);
131
+ export function setupDialog(dialog, userOptions) {
132
+ const options = Object.assign({}, currentDefaults, userOptions);
133
+ const body = document.body;
134
+ const { preventScrollShift: preventShift } = options;
135
+
136
+ // Stores active pointerId for resizer until after the whole pointer event series
137
+ // is finished which is after the click is complete
138
+ let activeResizePointer;
139
+
140
+ dialog.addEventListener(getName("resizer:start"), handleResizeStart);
141
+ dialog.addEventListener(getName("resizer:end"), handleResizeEnd);
109
142
  dialog.addEventListener("click", handleClicks);
110
- dialog.setAttribute(attrs.init, "");
143
+
111
144
  if (options.documentEnd) {
112
- document.body.appendChild(dialog);
145
+ body.appendChild(dialog);
113
146
  }
114
147
  if (options.pauseVideos) {
115
148
  prepVideos(dialog);
116
149
  }
117
150
 
151
+ // Allow preventScroll if it is a modal dialog
152
+ // Caching value of overflow before setting so we don't assume what it's initial value is
153
+ if (!options.nonModal && options.preventScroll) {
154
+ // Cache restore function
155
+ let restoreScroll;
156
+
157
+ // Toggle prevent scroll
158
+ dialog.addEventListener("toggle", (event) => {
159
+ const isOpen = event.newState === "open";
160
+ if (isOpen) {
161
+ restoreScroll = setupPreventScroll({ preventShift });
162
+ } else if (restoreScroll) {
163
+ restoreScroll();
164
+ }
165
+ });
166
+ }
167
+
118
168
  function handleClicks(event) {
119
169
  const { target } = event;
120
- const closeFromButton = target.closest("[data-ulu-dialog-close]");
121
- let closeFromOutside = options.clickOutsideCloses &&
122
- target === dialog &&
123
- wasClickOutside(dialog, event);
170
+ const targetIsDialog = target === dialog;
171
+ const closeFromButton = target.closest(initializer.attributeSelector("close"));
172
+ const allowCloseOutside = !activeResizePointer && options.clickOutsideCloses;
173
+ const closeFromOutside = allowCloseOutside && targetIsDialog && wasClickOutside(dialog, event);
124
174
  if (closeFromOutside || closeFromButton) {
125
175
  if (options.pauseVideos) {
126
176
  pauseVideos(dialog);
@@ -128,6 +178,15 @@ export function setupDialog(dialog) {
128
178
  dialog.close();
129
179
  }
130
180
  }
181
+ function handleResizeStart(event) {
182
+ activeResizePointer = event.pointerId;
183
+ }
184
+ function handleResizeEnd(event) {
185
+ if (activeResizePointer === event.pointerId) {
186
+ // next event cycle (after click/pointer events finish in current)
187
+ setTimeout(() => { activeResizePointer = null;}, 0);
188
+ }
189
+ }
131
190
  }
132
191
 
133
192
  /**
@@ -136,8 +195,7 @@ export function setupDialog(dialog) {
136
195
  * @returns {Object}
137
196
  */
138
197
  export function getDialogOptions(dialog) {
139
- const options = getDatasetJson(dialog, "uluDialog");
140
- return Object.assign({}, currentDefaults, options);
198
+ return Object.assign({}, currentDefaults, initializer.getData(dialog));
141
199
  }
142
200
 
143
201
  /**
@@ -146,6 +204,7 @@ export function getDialogOptions(dialog) {
146
204
  function prepVideos(dialog) {
147
205
  prepYoutubeVideos(dialog);
148
206
  }
207
+
149
208
  /**
150
209
  * Prep videos to be paused for a given dialog
151
210
  */
package/js/ui/dialog.todo CHANGED
@@ -1,37 +1,3 @@
1
- Styling:
2
- ✔ Animations? @done
3
- ☐ Check styling on left right
1
+ Dialog Todos:
4
2
  ☐ Setup fullscreen option / modifier
5
- Setup programmatic modal with new system
6
- ☐ Resizing
7
- ✔ Work out how this can work with native and click outside @done
8
- ✔ Figure out how to setup icon for the resizer for all sites @done
9
- * Fontawesome, or should this just be CSS so we don't need any icons for it
10
- * Same for close button should we just use CSS and omit any FA requirements
11
- * Or make it super easy to implement the icon only in the template (like default icon classses)
12
- * Then user can choose to implement their own (via class) or use the styles that come with it
13
- ☐ Prevent Browser Scroll
14
- ✔ How should height work? Should a centered modal expand to it's content's height (up to the viewport height) or always be cropped and scroll (static height)? @done
15
- Todos:
16
- ✔ How should the relationship between a dialog and it's trigger work @done
17
- * Think there should be no relationship? Just triggers are triggers just attach a handler to open DOM centric way (add errors when the dialog doesn't exist)
18
- * For the dialogs they should just have handlers attached for close
19
- * Init should find all one's that need to be built and build them, then it should initialize them the same way as non-built dialogs
20
- ✔ Support both modal and non-modal dialogs (rename)? @done
21
- ✘ Divide into 4 modules @cancelled
22
- 1. Initializer (data-attributes)
23
- 2. Templater (for Drupal projects and standard modals)
24
- 3. Open/Close Behaviors
25
- 4. Programmatic Modal
26
- * This is tough because its opionated towards our system in Drupal (jQuery)
27
- ✔ How should this all be structured @done
28
- * JS template dialogs?
29
- * Pros
30
- * Many users create the modals in content in CMS we don't want to make that difficult or get stuck with structure
31
- * Cons
32
- * Templating is in JS so dialogs don't make much sense on their own
33
- * Could continue the div to dialog conversion (so modal content is inline unless JS running). Don't want to optimize too much for no js anymore anyways
34
- * writing the dialog by hand makes sense for non defualt modal styles or users that have another structure but need the scripting part
35
- * Solution
36
- * Breakup module into two parts the underlying modal scripting (open close trigger) and (conversion modal templating [w. resizer] and as <div>)
37
- * Then we can have both without any extra code and seperation
3
+ Prevent Browser Scroll