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

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 (344) hide show
  1. package/CHANGELOG.md +717 -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-grid.scss +5 -2
  259. package/scss/components/_card.scss +216 -87
  260. package/scss/components/_counter-list.scss +151 -0
  261. package/scss/components/_css-icon.scss +27 -17
  262. package/scss/components/_data-grid.scss +55 -12
  263. package/scss/components/_data-table.scss +3 -0
  264. package/scss/components/_definition-list.scss +178 -0
  265. package/scss/components/_flipcard.scss +8 -3
  266. package/scss/components/_form-theme.scss +106 -95
  267. package/scss/components/_headline-label.scss +83 -0
  268. package/scss/components/_hero.scss +3 -10
  269. package/scss/components/_index.scss +79 -0
  270. package/scss/components/_menu-stack.scss +87 -23
  271. package/scss/components/_modal.scss +51 -23
  272. package/scss/components/_nav-strip.scss +2 -0
  273. package/scss/components/_overlay-section.scss +2 -5
  274. package/scss/components/_panel.scss +246 -0
  275. package/scss/components/_popover.scss +139 -38
  276. package/scss/components/_progress-bar.scss +260 -0
  277. package/scss/components/_progress-circle.scss +175 -0
  278. package/scss/components/_pull-quote.scss +1 -1
  279. package/scss/components/_rail.scss +127 -0
  280. package/scss/components/_ratio-box.scss +2 -5
  281. package/scss/components/_rule.scss +1 -0
  282. package/scss/components/_scroll-slider.scss +1 -5
  283. package/scss/components/_skeleton.scss +126 -0
  284. package/scss/components/_slider.scss +49 -72
  285. package/scss/components/_spoke-spinner.scss +2 -2
  286. package/scss/components/_sticky-list.scss +206 -0
  287. package/scss/components/_tabs.scss +22 -4
  288. package/scss/components/_tag.scss +49 -7
  289. package/scss/components/_vignette.scss +2 -5
  290. package/scss/components/_wysiwyg.scss +21 -13
  291. package/scss/helpers/_display.scss +15 -18
  292. package/scss/helpers/_print.scss +12 -7
  293. package/scss/helpers/_utilities.scss +62 -34
  294. package/types/events/index.d.ts +10 -1
  295. package/types/events/index.d.ts.map +1 -1
  296. package/types/index.d.ts +1 -0
  297. package/types/settings.d.ts +70 -0
  298. package/types/settings.d.ts.map +1 -0
  299. package/types/ui/breakpoints.d.ts +14 -14
  300. package/types/ui/breakpoints.d.ts.map +1 -1
  301. package/types/ui/collapsible.d.ts.map +1 -1
  302. package/types/ui/details-group.d.ts +38 -0
  303. package/types/ui/details-group.d.ts.map +1 -0
  304. package/types/ui/dialog.d.ts +20 -14
  305. package/types/ui/dialog.d.ts.map +1 -1
  306. package/types/ui/flipcard.d.ts +16 -10
  307. package/types/ui/flipcard.d.ts.map +1 -1
  308. package/types/ui/grid.d.ts +4 -6
  309. package/types/ui/grid.d.ts.map +1 -1
  310. package/types/ui/index.d.ts +1 -0
  311. package/types/ui/modal-builder.d.ts +116 -11
  312. package/types/ui/modal-builder.d.ts.map +1 -1
  313. package/types/ui/overflow-scroller.d.ts +2 -2
  314. package/types/ui/overflow-scroller.d.ts.map +1 -1
  315. package/types/ui/popover.d.ts +6 -7
  316. package/types/ui/popover.d.ts.map +1 -1
  317. package/types/ui/print.d.ts +0 -4
  318. package/types/ui/print.d.ts.map +1 -1
  319. package/types/ui/programmatic-modal.d.ts.map +1 -1
  320. package/types/ui/proxy-click.d.ts +19 -3
  321. package/types/ui/proxy-click.d.ts.map +1 -1
  322. package/types/ui/resizer.d.ts +116 -16
  323. package/types/ui/resizer.d.ts.map +1 -1
  324. package/types/ui/scroll-slider.d.ts +5 -7
  325. package/types/ui/scroll-slider.d.ts.map +1 -1
  326. package/types/ui/scrollpoint.d.ts +3 -8
  327. package/types/ui/scrollpoint.d.ts.map +1 -1
  328. package/types/ui/slider.d.ts +33 -14
  329. package/types/ui/slider.d.ts.map +1 -1
  330. package/types/ui/tabs.d.ts +6 -8
  331. package/types/ui/tabs.d.ts.map +1 -1
  332. package/types/ui/theme-toggle.d.ts +51 -7
  333. package/types/ui/theme-toggle.d.ts.map +1 -1
  334. package/types/ui/tooltip.d.ts +3 -5
  335. package/types/ui/tooltip.d.ts.map +1 -1
  336. package/types/utils/css.d.ts +11 -0
  337. package/types/utils/css.d.ts.map +1 -0
  338. package/types/utils/dom.d.ts +12 -32
  339. package/types/utils/dom.d.ts.map +1 -1
  340. package/types/utils/font-awesome.d.ts +5 -0
  341. package/types/utils/font-awesome.d.ts.map +1 -0
  342. package/types/utils/index.d.ts +1 -0
  343. package/types/utils/system.d.ts +113 -0
  344. package/types/utils/system.d.ts.map +1 -0
package/js/ui/flipcard.js CHANGED
@@ -2,14 +2,43 @@
2
2
  * @module ui/flipcard
3
3
  */
4
4
 
5
+ import { ComponentInitializer } from "../utils/system.js";
5
6
  import { trimWhitespace } from "@ulu/utils/string.js";
6
7
  import { log, logError } from "../utils/class-logger.js";
7
- import { getName } from "../events/index.js";
8
- import { getDatasetOptionalJson } from "../utils/dom.js";
9
- const debugMode = false; // Global dev debug
10
8
 
9
+ /**
10
+ * Flipcard Component Initializer
11
+ */
12
+ export const initializer = new ComponentInitializer({
13
+ type: "flipcard",
14
+ baseAttribute: "data-ulu-flipcard"
15
+ });
16
+
17
+ /**
18
+ * Initialize flipcards using data-ulu-flipcard attribute
19
+ */
20
+ export function init() {
21
+ initializer.init({
22
+ withData: true,
23
+ events: ["pageModified"],
24
+ setup({ element, data, initialize }) {
25
+ const options = Object.assign({}, data);
26
+ const front = element.querySelector(initializer.attributeSelector("front"));
27
+ const back = element.querySelector(initializer.attributeSelector("back"));
28
+ (new Flipcard(element, front, back, options));
29
+ initialize();
30
+ }
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Flipcard class (creates flipcard instance and behaviors)
36
+ */
11
37
  export class Flipcard {
12
38
  static instances = [];
39
+ /**
40
+ * Default options for Flipcard
41
+ */
13
42
  static defaults = {
14
43
  namespace: "Flipcard",
15
44
  proxyClick: {
@@ -18,25 +47,25 @@ export class Flipcard {
18
47
  exclude: "a, input, textarea, button" // Selectors to avoid closing a flipcard onProxyclick
19
48
  },
20
49
  };
21
- constructor(container, front, back, config, debug = false) {
50
+ constructor(container, front, back, config) {
22
51
  if (!container, !front, !back) {
23
52
  logError(this, 'Missing an element (container, front, back)');
24
53
  }
25
54
  this.options = Object.assign({}, Flipcard.defaults, config);
26
55
  const { namespace } = this.options;
56
+
27
57
  Flipcard.instances.push(this);
28
58
 
29
- this.debug = debugMode || debug;
30
59
  this.elements = { container, front, back };
31
60
  this.isOpen = false;
32
61
  this.uid = `${ namespace }-id-${ Flipcard.instances.length }`;
33
62
  this.stateAttr = `data-${ namespace }-state`.toLowerCase();
34
63
  this.setup();
35
- this.setVisiblity(false);
64
+ this.setVisibility(false);
36
65
  log(this, this);
37
66
  }
38
67
  toggle() {
39
- this.setVisiblity(!this.isOpen);
68
+ this.setVisibility(!this.isOpen);
40
69
  }
41
70
  setup() {
42
71
  const { uid } = this;
@@ -98,7 +127,7 @@ export class Flipcard {
98
127
  <span class="hidden-visually">Show More Information</span>
99
128
  `;
100
129
  }
101
- setVisiblity(visible) {
130
+ setVisibility(visible) {
102
131
  const { back, container, control } = this.elements;
103
132
  const state = visible ? "open" : "closed";
104
133
  back.style.zIndex = visible ? "10" : "1";
@@ -128,56 +157,7 @@ export class Flipcard {
128
157
  }
129
158
  }
130
159
 
131
- /**
132
- * Default data attributes
133
- */
134
- export const attrs = {
135
- init: "data-ulu-flipcard-init",
136
- flipcard: "data-ulu-flipcard",
137
- front: "data-ulu-flipcard-front",
138
- back: "data-ulu-flipcard-back",
139
- };
140
-
141
- // Utils for selecting things based on attributes
142
- const attrSelector = key => `[${ attrs[key] }]`;
143
- const attrSelectorInitial = key => `${ attrSelector(key) }:not([${ attrs.init }])`;
144
-
145
- // const containers = document.querySelectorAll('[data-ulu-flipcard]');
146
- const instances = [];
147
-
148
- export function init() {
149
- document.addEventListener(getName("pageModified"), setup);
150
- setup();
151
- }
152
160
 
153
- export function setup() {
154
- const builders = document.querySelectorAll(attrSelectorInitial("flipcard"));
155
- builders.forEach(setupFlipcard);
156
- }
157
-
158
- // containers.forEach(init);
159
-
160
- function setupFlipcard(container) {
161
- container.setAttribute(attrs.init, "");
162
- const options = getDatasetOptionalJson(container, "uluFlipcard");
163
- const config = Object.assign({}, options);
164
- const front = container.querySelector(attrSelectorInitial("front"));
165
- const back = container.querySelector(attrSelectorInitial("back"));
166
- instances.push(new Flipcard(container, front, back, config));
167
- }
168
-
169
- // getDatasetOptionalJson
170
- function setupSlider(container) {
171
- container.setAttribute(attrs.init, "");
172
- const options = getDatasetOptionalJson(container, "uluFlipcard");
173
- const config = Object.assign({}, options);
174
- const elements = {
175
- track: container.querySelector(attrSelector("track")),
176
- controls: container.querySelector(attrSelector("controls"))
177
- };
178
- // replace with OverflowScroller when finished removing sitescrollslider
179
- instances.push(new SiteScrollSlider(elements, config));
180
- }
181
161
 
182
162
  /**
183
163
  * Preliminary Notes:
package/js/ui/grid.js CHANGED
@@ -2,25 +2,27 @@
2
2
  * @module ui/grid
3
3
  */
4
4
 
5
+ import { ComponentInitializer } from "../utils/system.js";
5
6
  import { setPositionClasses } from "../utils/dom.js";
6
- import { getName } from "../events/index.js";
7
7
 
8
8
  /**
9
- * Sets up document for grid position classes
10
- * @param {String} selector The selector for the parent element
11
- * @param {Object} classes Classes (optional) @see setPositionClasses
9
+ * Dialog Component Initializer
12
10
  */
13
- export function init(selector = "[data-grid]", classes) {
14
- document.addEventListener(getName("pageModified"), () => setup(selector, classes));
15
- document.addEventListener(getName("pageResized"), () => setup(selector, classes));
16
- setup(selector, classes);
17
- }
11
+ export const initializer = new ComponentInitializer({
12
+ type: "grid",
13
+ baseAttribute: "data-grid"
14
+ });
18
15
 
19
16
  /**
20
- * Goes through document and finds elements that need to have positioning classes
21
- * @param {String} selector The selector for the parent element
17
+ * Sets up document for grid position classes
22
18
  * @param {Object} classes Classes (optional) @see setPositionClasses
23
19
  */
24
- export function setup(selector, classes) {
25
- document.querySelectorAll(selector).forEach(element => setPositionClasses(element, classes || undefined));
20
+ export function init(classes) {
21
+ initializer.init({
22
+ events: ["pageModified", "pageResized"],
23
+ setup({ element, initialize }) {
24
+ setPositionClasses(element, classes);
25
+ initialize();
26
+ }
27
+ });
26
28
  }
package/js/ui/index.js CHANGED
@@ -19,3 +19,4 @@ export * as print from "./print.js";
19
19
  export * as printDetails from "./print-details.js";
20
20
  export * as scrollSlider from "./scroll-slider.js";
21
21
  export * as themeToggle from "./theme-toggle.js";
22
+ export * as detailsGroup from "./details-group.js";
@@ -1,32 +1,68 @@
1
1
  /**
2
2
  * @module ui/modal-builder
3
+ * @description Note this module needs to be initialized before dialogs!
3
4
  */
4
5
 
5
- // Note this needs to be run before dialogs are initialized!
6
-
6
+ import { ComponentInitializer } from "../utils/system.js";
7
+ import { wrapSettingString } from "../settings.js";
7
8
  import { getName } from "../events/index.js";
8
- import { createElementFromHtml } from "@ulu/utils/browser/dom.js";
9
9
  import { Resizer } from "./resizer.js";
10
- import { getDatasetJson } from "../utils/dom.js";
11
- import { defaults as dialogDefaults, attrs as dialogAttrs } from "./dialog.js";
12
-
13
- const attrs = {
14
- builder: "data-ulu-modal-builder",
15
- body: "data-ulu-modal-builder-body",
16
- resizer: "data-ulu-modal-builder-resizer"
17
- };
10
+ import { baseAttribute, closeAttribute, defaults as dialogDefaults } from "./dialog.js";
11
+ import { getElement } from "@ulu/utils/browser/dom.js";
12
+ import { createElementFromHtml } from "@ulu/utils/browser/dom.js";
18
13
 
19
- const attrSelector = key => `[${ attrs[key] }]`;
14
+ /**
15
+ * Modal Builder Component Initializer
16
+ */
17
+ export const initializer = new ComponentInitializer({
18
+ type: "modal-builder",
19
+ baseAttribute: "data-ulu-modal-builder"
20
+ });
20
21
 
21
22
  /**
22
23
  * Default builder options (extends dialog defaults, watch name collisions)
23
24
  * - Decided to extend defaults so the interface in HTML is singular
24
- * - This is sometimes easier to template (merging and serializing options
25
- * in twig for example)
25
+ * - This is sometimes easier to template (merging and serializing options
26
+ * in twig for example)
27
+ * @typedef {object} DefaultModalOptions
28
+ * @property {string|null} title - The title of the modal. Defaults to `null`.
29
+ * @property {string|null} titleIcon - The class name for an icon to display in the title. Defaults to `null`.
30
+ * @property {string} titleClass - Extra class/classes to add to title
31
+ * @property {string} labelledby - Set the aria-labelledby attribute to a specific title within the modal, to connect to a custom title implementation, if using built in title this will be set automatically
32
+ * @property {string} describedby - Set the aria-describedby on the dialog, elements id, to tie a specific part of the content to be the accessible description
33
+ * @property {boolean} nonModal - If `true`, the modal will not prevent interaction with elements behind it. Defaults to `false`.
34
+ * @property {boolean} documentEnd - If `true`, the modal will be appended to the end of the `document.body`. Defaults to `true`.
35
+ * @property {boolean} allowResize - If `true`, the modal will be resizable. Defaults to `false`.
36
+ * @property {"center"|"top-left"|"top-center"|"top-right"|"bottom-left"|"bottom-center"|"bottom-right"} position - The initial position of the modal. Defaults to `"center"`.
37
+ * @property {boolean} bodyFills - If `true`, the modal body will fill the available space. Defaults to `false`.
38
+ * @property {boolean} noBackdrop - If `true`, no backdrop will be displayed behind the modal. Defaults to `false`.
39
+ * @property {"default"|"small"|"large"|"fullscreen"} size - The size of the modal. Defaults to `"default"`.
40
+ * @property {boolean} print - If `true`, the modal content will be optimized for printing. Defaults to `false`.
41
+ * @property {boolean} noMinHeight - If `true`, the modal will not have a minimum height. Defaults to `false`.
42
+ * @property {string} class - Additional CSS class(es) to add to the modal. Defaults to `""`.
43
+ * @property {string} baseClass - The base CSS class for the modal elements. Defaults to `"modal"`.
44
+ * @property {string} classCloseIcon - The class name for the close icon. Uses the wrapped setting string.
45
+ * @property {string} classResizerIcon - The class name for the resizer icon. Uses the wrapped setting string.
46
+ * @property {string|Node} footerElement - Element or selector to use as the footer (will be moved to dialog on creation, used for DOM API)
47
+ * @property {string|Node} footerHtml - Markup to use in the footer
48
+ * @property {boolean} debug - Enables debug logging. Defaults to `false`.
49
+ * @property {function(object): string} templateCloseIcon - A function that returns the HTML for the close icon.
50
+ * @property {function(object): string} templateCloseIcon.config - The resolved modal configuration object.
51
+ * @returns {string} The HTML string for the close icon.
52
+ * @property {function(object): string} templateResizerIcon - A function that returns the HTML for the resizer icon.
53
+ * @property {function(object): string} templateResizerIcon.config - The resolved modal configuration object.
54
+ * @returns {string} The HTML string for the resizer icon.
55
+ * @property {function(string, DefaultModalOptions): string} template - The default modal template function.
56
+ * @param {string} template.id - The ID for the new modal.
57
+ * @param {DefaultModalOptions} template.config - The resolved modal options.
58
+ * @returns {string} Markup for the modal.
26
59
  */
27
60
  export const defaults = {
28
61
  title: null,
29
62
  titleIcon: null,
63
+ titleClass: "",
64
+ labelledby: null,
65
+ describedby: null,
30
66
  nonModal: false,
31
67
  documentEnd: true,
32
68
  allowResize: false,
@@ -37,14 +73,21 @@ export const defaults = {
37
73
  print: false,
38
74
  noMinHeight: false,
39
75
  class: "",
40
- classCloseIcon: "css-icon css-icon--close",
41
- classResizerIcon: "css-icon css-icon--drag-x",
76
+ baseClass: "modal",
77
+ footerElement: null,
78
+ footerHtml: null,
79
+ classCloseIcon: wrapSettingString("iconClassClose"),
80
+ classResizerIcon: wrapSettingString("iconClassDragX"),
81
+ classResizerIconBoth: wrapSettingString("iconClassDragBoth"),
42
82
  debug: false,
43
83
  templateCloseIcon(config) {
44
- return `<span class="modal__close-icon ${ config.classCloseIcon }" aria-hidden="true"></span>`;
84
+ const { baseClass, classCloseIcon } = config;
85
+ return `<span class="${ baseClass }__close-icon ${ classCloseIcon }" aria-hidden="true"></span>`;
45
86
  },
46
87
  templateResizerIcon(config) {
47
- return `<span class="modal__resizer-icon ${ config.classResizerIcon }" aria-hidden="true"></span>`;
88
+ const { baseClass, classResizerIcon, classResizerIconBoth } = config;
89
+ const iconClass = config.position === "center" ? classResizerIconBoth : classResizerIcon;
90
+ return `<span class="${ baseClass }__resizer-icon ${ iconClass }" aria-hidden="true"></span>`;
48
91
  },
49
92
  /**
50
93
  * Default modal template
@@ -53,39 +96,47 @@ export const defaults = {
53
96
  * @returns {String} Markup for modal
54
97
  */
55
98
  template(id, config) {
99
+ const { baseClass, describedby, footerHtml } = config;
56
100
  const classes = [
57
- "modal",
58
- `modal--${ config.position }`,
59
- `modal--${ config.size }`,
60
- `modal--${ config.allowResize ? "resize" : "no-resize" }`,
61
- ...(!config.title ? ["modal--no-header"] : []),
62
- ...(config.bodyFills ? ["modal--body-fills"] : []),
63
- ...(config.noBackdrop ? ["modal--no-backdrop"] : []),
64
- ...(config.noMinHeight ? ["modal--no-min-height"] : [] ),
101
+ baseClass,
102
+ `${ baseClass }--${ config.position }`,
103
+ `${ baseClass }--${ config.size }`,
104
+ `${ baseClass }--${ config.allowResize ? "resize" : "no-resize" }`,
105
+ ...(!config.title ? [`${ baseClass }--no-header`] : []),
106
+ ...(config.bodyFills ? [`${ baseClass }--body-fills`] : []),
107
+ ...(config.noBackdrop ? [`${ baseClass }--no-backdrop`] : []),
108
+ ...(config.noMinHeight ? [`${ baseClass }--no-min-height`] : [] ),
65
109
  ...(config.class ? [config.class] : []),
66
110
  ];
111
+ const labelledby = config.title ? `${ id }--title` : config.labelledby;
67
112
  return `
68
- <dialog id="${ id }" class="${ classes.join(" ") }">
113
+ <dialog
114
+ id="${ id }"
115
+ class="${ classes.join(" ") }"
116
+ ${ labelledby ? `aria-labelledby="${ labelledby }"` : "" }
117
+ ${ describedby ? `aria-describedby="${ describedby }"` : "" }
118
+ >
69
119
  ${ config.title ? `
70
- <header class="modal__header">
71
- <h2 class="modal__title">
120
+ <header class="${ baseClass }__header">
121
+ <h2 id="${ labelledby }" class="${ baseClass }__title ${ config.titleClass }">
72
122
  ${ config.titleIcon ?
73
- `<span class="modal__title-icon ${ config.titleIcon }" aria-hidden="true"></span>` : ""
123
+ `<span class="${ baseClass }__title-icon ${ config.titleIcon }" aria-hidden="true"></span>` : ""
74
124
  }
75
- <span class="modal__title-text">${ config.title }</span>
125
+ <span class="${ baseClass }__title-text">${ config.title }</span>
76
126
  </h2>
77
- <button class="modal__close" aria-label="Close modal" ${ dialogAttrs.close } autofocus>
127
+ <button class="${ baseClass }__close" aria-label="Close modal" ${ closeAttribute } autofocus>
78
128
  ${ config.templateCloseIcon(config) }
79
129
  </button>
80
130
  </header>
81
131
  ` : "" }
82
- <div class="modal__body" ${ attrs.body }></div>
83
- ${ config.hasResizer ?
84
- `<div class="modal__resizer" ${ attrs.resizer }>
132
+ <div class="${ baseClass }__body" ${ initializer.getAttribute("body") }></div>
133
+ ${ footerHtml ? `<div class="${ baseClass }__footer">${ footerHtml }</div>`: "" }
134
+ ${ config.allowResize ?
135
+ `<button class="${ baseClass }__resizer" type="button" ${ initializer.getAttribute("resizer") }>
85
136
  ${ config.templateResizerIcon(config) }
86
- </div>` : ""
137
+ </button>` : ""
87
138
  }
88
- </div>
139
+ </dialog>
89
140
  `;
90
141
  }
91
142
  };
@@ -105,26 +156,13 @@ export function setDefaults(options) {
105
156
  * - This will only initialize elements once, it is safe to call on page changes
106
157
  */
107
158
  export function init() {
108
- document.addEventListener(getName("pageModified"), setup);
109
- setup();
110
- }
111
-
112
- /**
113
- * Query and setup all builder
114
- */
115
- export function setup() {
116
- const builders = document.querySelectorAll(attrSelector("builder"));
117
- builders.forEach(setupBuilder);
118
- }
119
-
120
- /**
121
- * Build a dialog for the given content
122
- * @param {Node} element
123
- */
124
- export function setupBuilder(element) {
125
- const options = getDatasetJson(element, "uluModalBuilder");
126
- element.removeAttribute(attrs.builder);
127
- buildModal(element, options);
159
+ initializer.init({
160
+ withData: true,
161
+ events: ["pageModified"],
162
+ setup({ element, data }) {
163
+ buildModal(element, data);
164
+ }
165
+ });
128
166
  }
129
167
 
130
168
  /**
@@ -136,11 +174,10 @@ export function buildModal(content, options) {
136
174
 
137
175
  const config = Object.assign({}, currentDefaults, options);
138
176
 
139
- if (config.position !== "center" && config.allowResize) {
140
- config.hasResizer = true;
141
- }
177
+ const { position } = config;
178
+
142
179
  if (config.debug) {
143
- console.log(config, content);
180
+ initializer.log(config, content);
144
181
  }
145
182
  if (!content.id) {
146
183
  throw new Error("Missing ID on modal");
@@ -148,25 +185,45 @@ export function buildModal(content, options) {
148
185
 
149
186
  const markup = config.template(content.id, config);
150
187
  const modal = createElementFromHtml(markup.trim());
151
- const selectChild = key => modal.querySelector(attrSelector(key));
188
+ const selectChild = key => modal.querySelector(initializer.attributeSelector(key));
152
189
  const body = selectChild("body");
153
- const resizer = selectChild("resizer");
190
+ const resizerElement = selectChild("resizer");
154
191
  const dialogOptions = separateDialogOptions(config);
155
192
 
156
193
  // Replace content with new dialog, and then insert the content into the new dialogs body
157
194
  content.removeAttribute("id");
158
195
  content.removeAttribute("hidden");
159
- content.removeAttribute(attrs.builder);
196
+ content.removeAttribute(initializer.getAttribute());
160
197
  content.parentNode.replaceChild(modal, content);
161
198
  body.appendChild(content);
162
199
 
163
200
  // Add dialog options for other scripts
164
- modal.setAttribute(dialogAttrs.dialog, JSON.stringify(dialogOptions));
201
+ modal.setAttribute(baseAttribute, JSON.stringify(dialogOptions));
202
+
203
+ // If they passed a footer element we need to move it in and
204
+ // make sure it has the class
205
+ if (config.footerElement) {
206
+ const footerElement = getElement(config.footerElement);
207
+ if (footerElement) {
208
+ footerElement.classList.add(`${ config.baseClass }__footer`);
209
+ body.after(footerElement);
210
+ }
211
+ }
165
212
 
166
- if (config.hasResizer) {
167
- new Resizer(modal, resizer, {
168
- fromLeft: config.position === "right"
169
- });
213
+ let resizer;
214
+ const resizablePositions = ["left", "right", "center"];
215
+ const isCenter = position === "center";
216
+ const isRight = position === "right";
217
+
218
+ if (config.allowResize) {
219
+ if (resizablePositions.includes(position)) {
220
+ const resizerOptions = isCenter ?
221
+ { fromX: "right", fromY: "bottom", multiplier: 2 } :
222
+ { fromX: isRight ? "left" : "right" };
223
+ resizer = new Resizer(modal, resizerElement, resizerOptions);
224
+ } else {
225
+ console.warn(`${ position } is not supported for resizing`);
226
+ }
170
227
  }
171
228
 
172
229
  if (config.print) {
@@ -179,7 +236,7 @@ export function buildModal(content, options) {
179
236
  printClone.remove();
180
237
  });
181
238
  }
182
- return { modal };
239
+ return { modal, resizer };
183
240
  }
184
241
 
185
242
  /**
@@ -10,6 +10,7 @@
10
10
  * @todo - Document that user could use something like [https://github.com/LachlanArthur/scroll-snap-api/tree/master/src] to have it go between items
11
11
  *
12
12
  */
13
+ import { wrapSettingString } from "../settings.js";
13
14
  import { hasRequiredProps } from '@ulu/utils/object.js';
14
15
  import { logError } from "../utils/class-logger.js";
15
16
  const requiredElements = [
@@ -26,14 +27,15 @@ export class OverflowScroller {
26
27
  offsetEnd: 100,
27
28
  amount: "auto",
28
29
  buttonClasses: ["button", "button--icon"],
29
- iconClassesPrevious: ["css-icon", "css-icon--angle-left"],
30
- iconClassesNext: ["css-icon", "css-icon--angle-right"]
30
+ iconClassPrevious: wrapSettingString("iconClassPrevious"),
31
+ iconClassNext: wrapSettingString("iconClassNext"),
31
32
  }
32
33
  constructor(elements, config) {
33
34
  this.options = Object.assign({}, OverflowScroller.defaults, config);
34
35
  if (!hasRequiredProps(requiredElements)) {
35
36
  logError(this, 'Missing a required Element');
36
37
  }
38
+ console.log(elements)
37
39
  this.elements = {
38
40
  ...elements,
39
41
  ...this.createControls(elements.controls)
@@ -87,10 +89,10 @@ export class OverflowScroller {
87
89
  return button;
88
90
  }
89
91
  getControlContent(action) {
90
- const classes = this.options[action === "next" ? "iconClassesNext" : "iconClassesPrevious"];
92
+ const classes = this.options[action === "next" ? "iconClassNext" : "iconClassPrevious"];
91
93
  return `
92
94
  <span class="hidden-visually">${ action }</span>
93
- <span class="${ classes.join(' ') }" aria-hidden="true"></span>
95
+ <span class="${ classes }" aria-hidden="true"></span>
94
96
  `;
95
97
  }
96
98
  onScroll(event) {
package/js/ui/page.js CHANGED
@@ -4,11 +4,11 @@
4
4
  * @module ui/page
5
5
  */
6
6
 
7
- import { addScrollbarProperty } from "../utils/dom";
7
+ import { addScrollbarCustomProperty } from "@ulu/utils/browser/dom.js";
8
8
 
9
9
  /**
10
10
  * Initialize page module
11
11
  */
12
12
  export function init() {
13
- addScrollbarProperty();
13
+ addScrollbarCustomProperty();
14
14
  }
package/js/ui/popover.js CHANGED
@@ -2,24 +2,27 @@
2
2
  * @module ui/popover
3
3
  */
4
4
 
5
- import { getName } from "../events/index.js";
5
+ import { ComponentInitializer } from "../utils/system.js";
6
6
  import { createFloatingUi } from "../utils/floating-ui.js";
7
7
  import { Collapsible } from "./collapsible.js";
8
8
 
9
9
  /**
10
- * Array of current instances
10
+ * Popover Component Initializer
11
11
  */
12
- export const instances = new WeakMap;
12
+ export const initializer = new ComponentInitializer({
13
+ type: "popover",
14
+ baseAttribute: "data-ulu-popover"
15
+ });
13
16
 
14
- const logError = (...msgs) => console.error("@ulu (popovers):", ...msgs);
17
+ const attrSelectorAnchor = initializer.attributeSelector("trigger-anchor");
18
+ const attrSelectorArrow = initializer.attributeSelector("arrow");
19
+ const attrContent = initializer.getAttribute("content");
20
+ const attrSelectorContent = initializer.attributeSelector("content");
15
21
 
16
- const attrs = {
17
- trigger: "data-ulu-popover-trigger",
18
- content: "data-ulu-popover-content",
19
- arrow: "data-ulu-popover-arrow",
20
- anchor: "data-ulu-popover-trigger-anchor",
21
- };
22
- const attrSelector = key => `[${ attrs[key] }]`;
22
+ /**
23
+ * Array of current instances
24
+ */
25
+ export const instances = new WeakMap;
23
26
 
24
27
  // This modules collapsible defaults
25
28
  const collapsibleDefaults = {
@@ -31,47 +34,44 @@ const collapsibleDefaults = {
31
34
  * Initialize default popover
32
35
  */
33
36
  export function init() {
34
- document.addEventListener(getName("pageModified"), setup);
35
- setup();
36
- }
37
+ initializer.init({
38
+ key: "trigger",
39
+ withData: true,
40
+ events: ["pageModified"],
41
+ setup({ element, data, initialize }) {
42
+ if (instances.has(element)) return;
43
+ const resolved = resolve(element, data);
37
44
 
38
- /**
39
- * Query all popovers on current page and set them up
40
- * - Use this manually if needed
41
- * - Won't setup a popover more than once
42
- */
43
- export function setup() {
44
- const triggers = document.querySelectorAll(attrSelector("trigger"));
45
- // Only triggers we don't have instances for
46
- const resolved = Array.from(triggers)
47
- .filter(trigger => !instances.has(trigger))
48
- .map(resolve)
49
- .filter(v => v);
45
+ if (!resolved) {
46
+ initializer.warn("Unable to resolve popover elements for trigger.", element);
47
+ return;
48
+ }
50
49
 
51
- resolved.forEach(({ elements, options, floatingOptions }) => {
52
- instances.set(elements.trigger, new Popover(elements, options, floatingOptions));
50
+ const { elements, options, floatingOptions } = resolved;
51
+ instances.set(elements, new Popover(elements, options, floatingOptions));
52
+ initialize();
53
+ }
53
54
  });
54
55
  }
55
56
 
56
57
  /**
57
58
  * Find the popover's elements
58
59
  */
59
- export function resolve(trigger) {
60
- const raw = trigger.dataset.uluPopoverTrigger;
61
- const options = raw?.length ? JSON.parse(raw) : {};
60
+ export function resolve(trigger, userOptions) {
61
+ const options = Object.assign({}, userOptions);
62
62
  const content = getContentByTrigger(trigger);
63
63
  const elements = {
64
64
  trigger,
65
65
  content,
66
- anchor: trigger.querySelector(attrSelector("anchor")) || trigger,
67
- contentArrow: content.querySelector(attrSelector("arrow"))
66
+ anchor: trigger.querySelector(attrSelectorAnchor) || trigger,
67
+ contentArrow: content.querySelector(attrSelectorArrow)
68
68
  };
69
69
  const floatingOptions = options.floating || {};
70
70
  delete options.floating;
71
71
  if (content) {
72
72
  return { elements, options, floatingOptions };
73
73
  } else {
74
- logError("Unable to make popover for", trigger);
74
+ initializer.logError("Unable to make popover for", trigger);
75
75
  return false;
76
76
  }
77
77
  }
@@ -85,17 +85,17 @@ export function getContentByTrigger(trigger) {
85
85
 
86
86
  if (ariaControls) {
87
87
  content = document.getElementById(ariaControls);
88
- } else if (trigger?.nextElementSibling?.hasAttribute(attrs.content)) {
88
+ } else if (trigger?.nextElementSibling?.hasAttribute(attrContent)) {
89
89
  content = trigger.nextElementSibling;
90
90
  // @todo - Consider removing this (non standard, users like this should be using aria-controls)
91
91
  } else {
92
92
  const children = Array.from(trigger.parentNode.children);
93
93
  const triggerIndex = children.findIndex(c => c === trigger);
94
94
  const childrenAfter = children.slice(triggerIndex);
95
- content = childrenAfter.find(child => child.matches(attrSelector("content")));
95
+ content = childrenAfter.find(child => child.matches(attrSelectorContent));
96
96
  }
97
97
  if (!content) {
98
- logError("Unable to resolve 'content' element for popover", trigger);
98
+ initializer.logError("Unable to resolve 'content' element for popover", trigger);
99
99
  }
100
100
  return content;
101
101
  }
@@ -123,7 +123,7 @@ export class Popover extends Collapsible {
123
123
  }
124
124
  createFloatingInstance() {
125
125
  const { content, anchor, contentArrow } = this.elements;
126
- const floatingElements = { trigger: anchor, contentArrow, content };
126
+ const floatingElements = { trigger: anchor, contentArrow, content };
127
127
  this.floatingCleanup = createFloatingUi(floatingElements, this.floatingOptions);
128
128
  }
129
129
  destroyFloatingInstance() {