@ulu/frontend 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.dev.md +16 -0
  2. package/dist/es/ui/dialog.d.ts +3 -1
  3. package/dist/es/ui/dialog.d.ts.map +1 -1
  4. package/dist/es/ui/dialog.js +57 -51
  5. package/dist/es/ui/modal-builder.d.ts +6 -0
  6. package/dist/es/ui/modal-builder.d.ts.map +1 -1
  7. package/dist/es/ui/modal-builder.js +53 -45
  8. package/dist/es/utils/dialog.d.ts +14 -0
  9. package/dist/es/utils/dialog.d.ts.map +1 -0
  10. package/dist/es/utils/dialog.js +16 -0
  11. package/dist/es/utils/iframe.d.ts +15 -0
  12. package/dist/es/utils/iframe.d.ts.map +1 -0
  13. package/dist/es/utils/iframe.js +33 -0
  14. package/dist/umd/frontend.css +1 -1
  15. package/dist/umd/ulu-frontend.umd.js +12 -12
  16. package/lib/js/ui/dialog.js +23 -3
  17. package/lib/js/ui/modal-builder.js +21 -0
  18. package/lib/js/utils/dialog.js +29 -0
  19. package/lib/js/utils/iframe.js +59 -0
  20. package/lib/scss/_color.scss +1 -1
  21. package/lib/scss/_element.scss +15 -0
  22. package/lib/scss/_utils.scss +22 -0
  23. package/lib/scss/base/_elements.scss +3 -0
  24. package/lib/scss/components/_accordion.scss +7 -2
  25. package/lib/scss/components/_badge.scss +1 -1
  26. package/lib/scss/components/_button-group.scss +8 -3
  27. package/lib/scss/components/_card-grid.scss +8 -14
  28. package/lib/scss/components/_card.scss +15 -13
  29. package/lib/scss/components/_data-list.scss +270 -0
  30. package/lib/scss/components/_data-table.scss +3 -1
  31. package/lib/scss/components/_index.scss +12 -0
  32. package/lib/scss/components/_menu-stack.scss +1 -1
  33. package/lib/scss/components/_modal.scss +97 -19
  34. package/lib/scss/components/_ratio-box.scss +11 -10
  35. package/lib/scss/components/_table-scroller.scss +63 -0
  36. package/lib/scss/helpers/_utilities.scss +23 -1
  37. package/package.json +4 -1
package/README.dev.md CHANGED
@@ -22,6 +22,22 @@ The library is designed with a clear separation between styles (SCSS) and behavi
22
22
 
23
23
  In short, the SCSS defines what components and their different states *look like*, while the JavaScript is responsible for activating components and changing their states based on user interaction. This creates a flexible and efficient system.
24
24
 
25
+ ## SCSS Development Conventions
26
+
27
+ When developing new SCSS components or maintaining existing ones, adhere to the following architectural patterns:
28
+
29
+ 1. **Configuration Property Naming:**
30
+ * Modifier-specific properties must begin with the modifier name.
31
+ * *Correct:* `clickable-background-color-hover`
32
+ * *Incorrect:* `background-color-clickable-hover`
33
+ * Responsive state variables should describe the *behavior*, not a hardcoded viewport/breakpoint name if possible. Example a component that stacks when on smaller screens might refer to that breakpoint as `stacked-breakpoint`
34
+
35
+ TODO: This section should be added to... (sassdoc type naming, etc). Formatting...
36
+
37
+ ## Documentation
38
+
39
+ - `site/`: Contains the source code for the documentation website (Eleventy). **Edit files here.**
40
+ - `docs/`: The build output for GitHub Pages. **Do not edit files here directly.**
25
41
 
26
42
  ## Benchmark Notes
27
43
 
@@ -18,7 +18,9 @@ export function setupTrigger(trigger: Node, dialogId: string): void;
18
18
  * Setup click handlers for a dialog
19
19
  * @param {Node} dialog
20
20
  */
21
- export function setupDialog(dialog: Node, userOptions: any): void;
21
+ export function setupDialog(dialog: Node, userOptions: any): {
22
+ destroy: () => void;
23
+ };
22
24
  /**
23
25
  * For a given dialog, get it's options (from data attribute)
24
26
  * @param {Node} dialog
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../lib/js/ui/dialog.js"],"names":[],"mappings":"AA6DA;;GAEG;AACH,qCAFW,MAAM,QAIhB;AAED;;;GAGG;AACH,6BAqBC;AAED;;;;GAIG;AACH,sCAHW,IAAI,0BA2Bd;AAED;;;GAGG;AACH,oCAFW,IAAI,0BA6Dd;AAED;;;;GAIG;AACH,yCAHW,IAAI,GACF,MAAM,CAIlB;AA7LD;;GAEG;AACH,4BAA6B,iBAAiB,CAAC;AAE/C;;GAEG;AACH,+CAAuF;AAEvF;;GAEG;AACH,oCAAgE;;;;;;;;;qCAjB3B,sBAAsB"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../lib/js/ui/dialog.js"],"names":[],"mappings":"AA8DA;;GAEG;AACH,qCAFW,MAAM,QAIhB;AAED;;;GAGG;AACH,6BAqBC;AAED;;;;GAIG;AACH,sCAHW,IAAI,0BA2Bd;AAED;;;GAGG;AACH,oCAFW,IAAI;;EAgFd;AAED;;;;GAIG;AACH,yCAHW,IAAI,GACF,MAAM,CAIlB;AAhND;;GAEG;AACH,4BAA6B,iBAAiB,CAAC;AAE/C;;GAEG;AACH,+CAAuF;AAEvF;;GAEG;AACH,oCAAgE;;;;;;;;;qCAlB3B,sBAAsB"}
@@ -1,19 +1,20 @@
1
- var O = Object.defineProperty;
2
- var f = Object.getOwnPropertySymbols;
3
- var S = Object.prototype.hasOwnProperty, b = Object.prototype.propertyIsEnumerable;
4
- var m = (e, o, t) => o in e ? O(e, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[o] = t, g = (e, o) => {
1
+ var S = Object.defineProperty;
2
+ var p = Object.getOwnPropertySymbols;
3
+ var D = Object.prototype.hasOwnProperty, O = Object.prototype.propertyIsEnumerable;
4
+ var f = (e, o, t) => o in e ? S(e, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[o] = t, m = (e, o) => {
5
5
  for (var t in o || (o = {}))
6
- S.call(o, t) && m(e, t, o[t]);
7
- if (f)
8
- for (var t of f(o))
9
- b.call(o, t) && m(e, t, o[t]);
6
+ D.call(o, t) && f(e, t, o[t]);
7
+ if (p)
8
+ for (var t of p(o))
9
+ O.call(o, t) && f(e, t, o[t]);
10
10
  return e;
11
11
  };
12
- import { getUluEventName as v } from "../core/events.js";
12
+ import { getUluEventName as g } from "../core/events.js";
13
13
  import { ComponentInitializer as V } from "../core/component.js";
14
- import { preventScroll as w, wasClickOutside as C } from "@ulu/utils/browser/dom.js";
15
- import { prepVideos as D, pauseVideos as k } from "../utils/pause-youtube-video.js";
16
- const L = "data-ulu-dialog", i = new V({ type: "dialog", baseAttribute: L }), x = i.getAttribute("close"), y = {
14
+ import { wasClickOutside as C, preventScroll as k } from "@ulu/utils/browser/dom.js";
15
+ import { prepVideos as w, pauseVideos as y } from "../utils/pause-youtube-video.js";
16
+ import { observeDialogToggle as z } from "../utils/dialog.js";
17
+ const L = "data-ulu-dialog", r = new V({ type: "dialog", baseAttribute: L }), G = r.getAttribute("close"), M = {
17
18
  /**
18
19
  * Use non-modal interface for dialog
19
20
  */
@@ -41,31 +42,31 @@ const L = "data-ulu-dialog", i = new V({ type: "dialog", baseAttribute: L }), x
41
42
  */
42
43
  preventScrollShift: !0
43
44
  };
44
- let a = g({}, y);
45
- function P(e) {
45
+ let a = m({}, M);
46
+ function H(e) {
46
47
  a = Object.assign({}, a, e);
47
48
  }
48
- function U() {
49
- i.init({
49
+ function J() {
50
+ r.init({
50
51
  coreEvents: ["pageModified"],
51
52
  withData: !0,
52
53
  setup({ element: e, initialize: o, data: t }) {
53
- M(e, t), o();
54
+ I(e, t), o();
54
55
  }
55
- }), i.init({
56
+ }), r.init({
56
57
  key: "trigger",
57
58
  coreEvents: ["pageModified"],
58
59
  withData: !0,
59
60
  setup({ element: e, initialize: o, data: t }) {
60
- z(e, t), o();
61
+ A(e, t), o();
61
62
  }
62
63
  });
63
64
  }
64
- function z(e, o) {
65
+ function A(e, o) {
65
66
  e.addEventListener("click", t);
66
- function t(r) {
67
+ function t(l) {
67
68
  var c;
68
- r.target.closest("a") && r.preventDefault();
69
+ l.target.closest("a") && l.preventDefault();
69
70
  const n = document.getElementById(o);
70
71
  if (!n) {
71
72
  console.error("Could not locate dialog (id)", o);
@@ -75,49 +76,54 @@ function z(e, o) {
75
76
  console.error("Attempted to trigger non <dialog> element. Did you mean to use modal builder?");
76
77
  return;
77
78
  }
78
- const u = A(n);
79
- n[u.nonModal ? "show" : "showModal"]();
79
+ const i = R(n);
80
+ n[i.nonModal ? "show" : "showModal"]();
80
81
  }
81
82
  }
82
- function M(e, o) {
83
- const t = Object.assign({}, a, o), r = document.body, { preventScrollShift: d } = t;
84
- let n;
85
- if (e.addEventListener(v("resizer:start"), c), e.addEventListener(v("resizer:end"), h), e.addEventListener("click", u), t.documentEnd && r.appendChild(e), t.pauseVideos && I(e), !t.nonModal && t.preventScroll) {
83
+ function I(e, o) {
84
+ const t = Object.assign({}, a, o), l = document.body, { preventScrollShift: d } = t;
85
+ let n = null, i;
86
+ if (e.addEventListener(g("resizer:start"), v), e.addEventListener(g("resizer:end"), b), e.addEventListener("click", c), t.documentEnd && l.appendChild(e), t.pauseVideos && T(e), !t.nonModal && t.preventScroll) {
86
87
  let s;
87
- e.addEventListener("toggle", (l) => {
88
- l.newState === "open" ? s = w({ preventShift: d }) : s && s();
88
+ n = z(e, (u) => {
89
+ u ? s = k({ preventShift: d }) : s && (s(), s = null);
89
90
  });
90
91
  }
91
- function u(s) {
92
- const { target: l } = s, p = l === e, E = l.closest(i.attributeSelector("close"));
93
- (!n && t.clickOutsideCloses && p && C(e, s) || E) && (t.pauseVideos && j(e), e.close());
94
- }
95
92
  function c(s) {
96
- n = s.pointerId;
93
+ const { target: u } = s, h = u === e, E = u.closest(r.attributeSelector("close"));
94
+ (!i && t.clickOutsideCloses && h && C(e, s) || E) && (t.pauseVideos && j(e), e.close());
95
+ }
96
+ function v(s) {
97
+ i = s.pointerId;
97
98
  }
98
- function h(s) {
99
- n === s.pointerId && setTimeout(() => {
100
- n = null;
99
+ function b(s) {
100
+ i === s.pointerId && setTimeout(() => {
101
+ i = null;
101
102
  }, 0);
102
103
  }
104
+ return {
105
+ destroy: () => {
106
+ n && n.destroy();
107
+ }
108
+ };
103
109
  }
104
- function A(e) {
105
- return Object.assign({}, a, i.getData(e));
110
+ function R(e) {
111
+ return Object.assign({}, a, r.getData(e));
106
112
  }
107
- function I(e) {
108
- D(e);
113
+ function T(e) {
114
+ w(e);
109
115
  }
110
116
  function j(e) {
111
- k(e), e.querySelectorAll("video").forEach((t) => t.pause());
117
+ y(e), e.querySelectorAll("video").forEach((t) => t.pause());
112
118
  }
113
119
  export {
114
120
  L as baseAttribute,
115
- x as closeAttribute,
116
- y as defaults,
117
- A as getDialogOptions,
118
- U as init,
119
- i as initializer,
120
- P as setDefaults,
121
- M as setupDialog,
122
- z as setupTrigger
121
+ G as closeAttribute,
122
+ M as defaults,
123
+ R as getDialogOptions,
124
+ J as init,
125
+ r as initializer,
126
+ H as setDefaults,
127
+ I as setupDialog,
128
+ A as setupTrigger
123
129
  };
@@ -37,6 +37,7 @@ export namespace defaults {
37
37
  export let size: string;
38
38
  export let print: boolean;
39
39
  export let noMinHeight: boolean;
40
+ export let fullscreenMobile: boolean;
40
41
  let _class: string;
41
42
  export { _class as class };
42
43
  export let baseClass: string;
@@ -47,6 +48,7 @@ export namespace defaults {
47
48
  export let classResizerIcon: Object;
48
49
  export let classResizerIconBoth: Object;
49
50
  export let debug: boolean;
51
+ export let autoIframe: boolean;
50
52
  export function templateCloseIcon(config: any): string;
51
53
  export function templateResizerIcon(config: any): string;
52
54
  /**
@@ -152,6 +154,10 @@ export type DefaultModalOptions = {
152
154
  * - Enables debug logging. Defaults to `false`.
153
155
  */
154
156
  debug: boolean;
157
+ /**
158
+ * - Opt-in convenience behavior. If the modal body's sole content is an iframe, it automatically applies layout fixes. If the iframe has static width/height attributes (like YouTube), it retains that aspect ratio responsively. Otherwise, it forces the iframe to fill the modal. Defaults to `false`.
159
+ */
160
+ autoIframe: boolean;
155
161
  /**
156
162
  * - A function that returns the HTML for the close icon.
157
163
  */
@@ -1 +1 @@
1
- {"version":3,"file":"modal-builder.d.ts","sourceRoot":"","sources":["../../../lib/js/ui/modal-builder.js"],"names":[],"mappings":"AAoJA;;GAEG;AACH,qCAFW,MAAM,QAIhB;AAED;;;GAGG;AACH,6BAQC;AAED;;;;GAIG;AACH,oCAHW,IAAI,WACJ,MAAM;;;EAqEhB;AApOD;;GAEG;AACH,+CAGG;;;;;;;;;;;;;;;;;;;;;;;;;;IAiED,uDAGC;IACD,yDAIC;IACD;;;;;OAKG;IACH,6CAHW,MAAM,UA8ChB;;;;;;;;;;;;WAnHW,MAAM,GAAC,IAAI;;;;eACX,MAAM,GAAC,IAAI;;;;gBACX,MAAM;;;;gBACN,MAAM;;;;iBACN,MAAM;;;;cACN,OAAO;;;;iBACP,OAAO;;;;iBACP,OAAO;;;;cACP,QAAQ,GAAC,UAAU,GAAC,YAAY,GAAC,WAAW,GAAC,aAAa,GAAC,eAAe,GAAC,cAAc;;;;eACzF,OAAO;;;;gBACP,OAAO;;;;UACP,SAAS,GAAC,OAAO,GAAC,OAAO,GAAC,YAAY;;;;WACtC,OAAO;;;;iBACP,OAAO;;;;WACP,MAAM;;;;eACN,MAAM;;;;gBACN,MAAM;;;;oBACN,MAAM;;;;sBACN,MAAM;;;;mBACN,MAAM,GAAC,IAAI;;;;gBACX,MAAM,GAAC,IAAI;;;;WACX,OAAO;;;;uBACP,CAAS,IAAM,EAAN,MAAM,KAAG,MAAM;;;;YACxB,CAAS,IAAM,EAAN,MAAM,KAAG,MAAM;;wBA1Cd,cAAc;qCAHD,sBAAsB"}
1
+ {"version":3,"file":"modal-builder.d.ts","sourceRoot":"","sources":["../../../lib/js/ui/modal-builder.js"],"names":[],"mappings":"AAyJA;;GAEG;AACH,qCAFW,MAAM,QAIhB;AAED;;;GAGG;AACH,6BAQC;AAED;;;;GAIG;AACH,oCAHW,IAAI,WACJ,MAAM;;;EAqFhB;AAxPD;;GAEG;AACH,+CAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoED,uDAGC;IACD,yDAIC;IACD;;;;;OAKG;IACH,6CAHW,MAAM,UA+ChB;;;;;;;;;;;;WAvHW,MAAM,GAAC,IAAI;;;;eACX,MAAM,GAAC,IAAI;;;;gBACX,MAAM;;;;gBACN,MAAM;;;;iBACN,MAAM;;;;cACN,OAAO;;;;iBACP,OAAO;;;;iBACP,OAAO;;;;cACP,QAAQ,GAAC,UAAU,GAAC,YAAY,GAAC,WAAW,GAAC,aAAa,GAAC,eAAe,GAAC,cAAc;;;;eACzF,OAAO;;;;gBACP,OAAO;;;;UACP,SAAS,GAAC,OAAO,GAAC,OAAO,GAAC,YAAY;;;;WACtC,OAAO;;;;iBACP,OAAO;;;;WACP,MAAM;;;;eACN,MAAM;;;;gBACN,MAAM;;;;oBACN,MAAM;;;;sBACN,MAAM;;;;mBACN,MAAM,GAAC,IAAI;;;;gBACX,MAAM,GAAC,IAAI;;;;WACX,OAAO;;;;gBACP,OAAO;;;;uBACP,CAAS,IAAM,EAAN,MAAM,KAAG,MAAM;;;;YACxB,CAAS,IAAM,EAAN,MAAM,KAAG,MAAM;;wBA5Cd,cAAc;qCAHD,sBAAsB"}
@@ -1,24 +1,25 @@
1
1
  var I = Object.defineProperty;
2
2
  var m = Object.getOwnPropertySymbols;
3
- var E = Object.prototype.hasOwnProperty, v = Object.prototype.propertyIsEnumerable;
3
+ var R = Object.prototype.hasOwnProperty, E = Object.prototype.propertyIsEnumerable;
4
4
  var p = (s, t, e) => t in s ? I(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e, $ = (s, t) => {
5
5
  for (var e in t || (t = {}))
6
- E.call(t, e) && p(s, e, t[e]);
6
+ R.call(t, e) && p(s, e, t[e]);
7
7
  if (m)
8
8
  for (var e of m(t))
9
- v.call(t, e) && p(s, e, t[e]);
9
+ E.call(t, e) && p(s, e, t[e]);
10
10
  return s;
11
11
  };
12
- import { ComponentInitializer as R } from "../core/component.js";
13
- import { wrapSettingString as d } from "../core/settings.js";
12
+ import { ComponentInitializer as v } from "../core/component.js";
13
+ import { wrapSettingString as c } from "../core/settings.js";
14
14
  import { getCoreEventName as f } from "../core/events.js";
15
15
  import { Resizer as w } from "./resizer.js";
16
- import { baseAttribute as A, closeAttribute as g, defaults as D } from "./dialog.js";
17
- import { createElementFromHtml as O, getElement as M } from "@ulu/utils/browser/dom.js";
18
- const n = new R({
16
+ import { baseAttribute as g, closeAttribute as A, defaults as H } from "./dialog.js";
17
+ import { createElementFromHtml as M, getElement as S } from "@ulu/utils/browser/dom.js";
18
+ import { getSoleIframeLayout as D } from "../utils/iframe.js";
19
+ const n = new v({
19
20
  type: "modal-builder",
20
21
  baseAttribute: "data-ulu-modal-builder"
21
- }), B = {
22
+ }), L = {
22
23
  title: null,
23
24
  titleIcon: null,
24
25
  titleClass: "",
@@ -33,22 +34,24 @@ const n = new R({
33
34
  size: "default",
34
35
  print: !1,
35
36
  noMinHeight: !1,
37
+ fullscreenMobile: !1,
36
38
  class: "",
37
39
  baseClass: "modal",
38
40
  footerElement: null,
39
41
  footerHtml: null,
40
42
  classClose: "button button--icon",
41
- classCloseIcon: d("iconClassClose", (s) => `${s} button__icon`),
42
- classResizerIcon: d("iconClassDragX"),
43
- classResizerIconBoth: d("iconClassDragBoth"),
43
+ classCloseIcon: c("iconClassClose", (s) => `${s} button__icon`),
44
+ classResizerIcon: c("iconClassDragX"),
45
+ classResizerIconBoth: c("iconClassDragBoth"),
44
46
  debug: !1,
47
+ autoIframe: !1,
45
48
  templateCloseIcon(s) {
46
49
  const { baseClass: t, classCloseIcon: e } = s;
47
50
  return `<span class="${t}__close-icon ${e}" aria-hidden="true"></span>`;
48
51
  },
49
52
  templateResizerIcon(s) {
50
- const { baseClass: t, classResizerIcon: e, classResizerIconBoth: i } = s, r = s.position === "center" ? i : e;
51
- return `<span class="${t}__resizer-icon ${r}" aria-hidden="true"></span>`;
53
+ const { baseClass: t, classResizerIcon: e, classResizerIconBoth: a } = s, o = s.position === "center" ? a : e;
54
+ return `<span class="${t}__resizer-icon ${o}" aria-hidden="true"></span>`;
52
55
  },
53
56
  /**
54
57
  * Default modal template
@@ -57,7 +60,7 @@ const n = new R({
57
60
  * @returns {String} Markup for modal
58
61
  */
59
62
  template(s, t) {
60
- const { baseClass: e, describedby: i, footerHtml: r } = t, o = [
63
+ const { baseClass: e, describedby: a, footerHtml: o } = t, i = [
61
64
  e,
62
65
  `${e}--${t.position}`,
63
66
  `${e}--${t.size}`,
@@ -66,28 +69,29 @@ const n = new R({
66
69
  ...t.bodyFills ? [`${e}--body-fills`] : [],
67
70
  ...t.noBackdrop ? [`${e}--no-backdrop`] : [],
68
71
  ...t.noMinHeight ? [`${e}--no-min-height`] : [],
72
+ ...t.fullscreenMobile ? [`${e}--fullscreen-mobile`] : [],
69
73
  ...t.class ? [t.class] : []
70
- ], a = t.title ? `${s}--title` : t.labelledby;
74
+ ], r = t.title ? `${s}--title` : t.labelledby;
71
75
  return `
72
76
  <dialog
73
77
  id="${s}"
74
- class="${o.join(" ")}"
75
- ${a ? `aria-labelledby="${a}"` : ""}
76
- ${i ? `aria-describedby="${i}"` : ""}
78
+ class="${i.join(" ")}"
79
+ ${r ? `aria-labelledby="${r}"` : ""}
80
+ ${a ? `aria-describedby="${a}"` : ""}
77
81
  >
78
82
  ${t.title ? `
79
83
  <header class="${e}__header">
80
- <h2 id="${a}" class="${e}__title ${t.titleClass}">
84
+ <h2 id="${r}" class="${e}__title ${t.titleClass}">
81
85
  ${t.titleIcon ? `<span class="${e}__title-icon ${t.titleIcon}" aria-hidden="true"></span>` : ""}
82
86
  <span class="${e}__title-text">${t.title}</span>
83
87
  </h2>
84
- <button class="${e}__close ${t.classClose}" aria-label="Close modal" ${g} autofocus>
88
+ <button class="${e}__close ${t.classClose}" aria-label="Close modal" ${A} autofocus>
85
89
  ${t.templateCloseIcon(t)}
86
90
  </button>
87
91
  </header>
88
92
  ` : ""}
89
93
  <div class="${e}__body" ${n.getAttribute("body")}></div>
90
- ${r ? `<div class="${e}__footer">${r}</div>` : ""}
94
+ ${o ? `<div class="${e}__footer">${o}</div>` : ""}
91
95
  ${t.allowResize ? `<button class="${e}__resizer" type="button" ${n.getAttribute("resizer")}>
92
96
  ${t.templateResizerIcon(t)}
93
97
  </button>` : ""}
@@ -95,53 +99,57 @@ const n = new R({
95
99
  `;
96
100
  }
97
101
  };
98
- let c = $({}, B);
99
- function x(s) {
100
- c = Object.assign({}, c, s);
102
+ let u = $({}, L);
103
+ function J(s) {
104
+ u = Object.assign({}, u, s);
101
105
  }
102
- function q() {
106
+ function Y() {
103
107
  n.init({
104
108
  withData: !0,
105
109
  coreEvents: ["pageModified"],
106
110
  setup({ element: s, data: t }) {
107
- H(s, t);
111
+ O(s, t);
108
112
  }
109
113
  });
110
114
  }
111
- function H(s, t) {
112
- const e = Object.assign({}, c, t), { position: i } = e;
115
+ function O(s, t) {
116
+ const e = Object.assign({}, u, t), { position: a } = e;
113
117
  if (e.debug && n.log(e, s), !s.id)
114
118
  throw new Error("Missing ID on modal");
115
- const r = e.template(s.id, e), o = O(r.trim()), a = (l) => o.querySelector(n.attributeSelector(l)), u = a("body"), h = a("resizer"), z = S(e);
116
- if (s.removeAttribute("id"), s.removeAttribute("hidden"), s.removeAttribute(n.getAttribute()), s.parentNode.replaceChild(o, s), u.appendChild(s), o.setAttribute(A, JSON.stringify(z)), e.footerElement) {
117
- const l = M(e.footerElement);
118
- l && (l.classList.add(`${e.baseClass}__footer`), u.after(l));
119
+ const o = e.template(s.id, e), i = M(o.trim()), r = (l) => i.querySelector(n.attributeSelector(l)), d = r("body"), h = r("resizer"), C = B(e);
120
+ if (s.removeAttribute("id"), s.removeAttribute("hidden"), s.removeAttribute(n.getAttribute()), s.parentNode.replaceChild(i, s), d.appendChild(s), i.setAttribute(g, JSON.stringify(C)), e.footerElement) {
121
+ const l = S(e.footerElement);
122
+ l && (l.classList.add(`${e.baseClass}__footer`), d.after(l));
123
+ }
124
+ if (e.autoIframe) {
125
+ const l = D(s);
126
+ l && (l.iframe.classList.add(`${e.baseClass}__frame-content`), l.isStaticSize ? (i.classList.add(`${e.baseClass}--frame-ratio`), d.style.aspectRatio = l.aspectRatio) : (i.classList.add(`${e.baseClass}--frame-fill`), l.fillHeight && (d.style.minHeight = l.fillHeight)));
119
127
  }
120
128
  let b;
121
- const C = ["left", "right", "center"], _ = i === "center", y = i === "right";
129
+ const z = ["left", "right", "center"], _ = a === "center", y = a === "right";
122
130
  if (e.allowResize)
123
- if (C.includes(i)) {
131
+ if (z.includes(a)) {
124
132
  const l = _ ? { fromX: "right", fromY: "bottom", multiplier: 2 } : { fromX: y ? "left" : "right" };
125
- b = new w(o, h, l);
133
+ b = new w(i, h, l);
126
134
  } else
127
- console.warn(`${i} is not supported for resizing`);
135
+ console.warn(`${a} is not supported for resizing`);
128
136
  if (e.print) {
129
137
  let l;
130
138
  document.addEventListener(f("beforePrint"), () => {
131
- l = s.cloneNode(!0), o.after(l);
139
+ l = s.cloneNode(!0), i.after(l);
132
140
  }), document.addEventListener(f("afterPrint"), () => {
133
141
  l.remove();
134
142
  });
135
143
  }
136
- return { modal: o, resizer: b };
144
+ return { modal: i, resizer: b };
137
145
  }
138
- function S(s) {
139
- return Object.keys(D).reduce((t, e) => (e in s && (t[e] = s[e]), t), {});
146
+ function B(s) {
147
+ return Object.keys(H).reduce((t, e) => (e in s && (t[e] = s[e]), t), {});
140
148
  }
141
149
  export {
142
- H as buildModal,
143
- B as defaults,
144
- q as init,
150
+ O as buildModal,
151
+ L as defaults,
152
+ Y as init,
145
153
  n as initializer,
146
- x as setDefaults
154
+ J as setDefaults
147
155
  };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Utility functions for dialogs
3
+ * @module utils/dialog
4
+ */
5
+ /**
6
+ * Workaround for poor Safari support of the dialog 'toggle' event.
7
+ * Watches for changes to the 'open' attribute and fires a callback.
8
+ *
9
+ * @param {HTMLDialogElement} dialog The dialog element to observe
10
+ * @param {Function} callback Function to call when the open state changes. Receives boolean indicating open state.
11
+ * @returns {Object} Object with a destroy method to disconnect the observer
12
+ */
13
+ export function observeDialogToggle(dialog: HTMLDialogElement, callback: Function): Object;
14
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../../lib/js/utils/dialog.js"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,4CAJW,iBAAiB,uBAEf,MAAM,CAiBlB"}
@@ -0,0 +1,16 @@
1
+ function i(e, r) {
2
+ const t = new MutationObserver((o) => {
3
+ o.forEach((n) => {
4
+ if (n.attributeName === "open") {
5
+ const s = e.hasAttribute("open");
6
+ r(s);
7
+ }
8
+ });
9
+ });
10
+ return t.observe(e, { attributes: !0, attributeFilter: ["open"] }), {
11
+ destroy: () => t.disconnect()
12
+ };
13
+ }
14
+ export {
15
+ i as observeDialogToggle
16
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Checks if an element's sole content is an iframe, and determines its layout type.
3
+ * Useful for determining if layout fixes should be applied to containers.
4
+ * @param {HTMLElement} container The container to check
5
+ * @returns {{iframe: HTMLIFrameElement, isStaticSize: boolean, width: string|null, height: string|null, aspectRatio: string|null, fillHeight: string|null}|null} Returns an object with iframe details, or null if not a sole iframe
6
+ */
7
+ export function getSoleIframeLayout(container: HTMLElement): {
8
+ iframe: HTMLIFrameElement;
9
+ isStaticSize: boolean;
10
+ width: string | null;
11
+ height: string | null;
12
+ aspectRatio: string | null;
13
+ fillHeight: string | null;
14
+ } | null;
15
+ //# sourceMappingURL=iframe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iframe.d.ts","sourceRoot":"","sources":["../../../lib/js/utils/iframe.js"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,+CAHW,WAAW,GACT;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAC,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAC,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,GAAC,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,GAAC,IAAI,CAAA;CAAC,GAAC,IAAI,CA8C/J"}
@@ -0,0 +1,33 @@
1
+ import { separateCssUnit as u } from "@ulu/utils/string.js";
2
+ const o = /^\d+$/;
3
+ function h(a) {
4
+ const c = a.querySelectorAll("iframe");
5
+ if (c.length === 1 && a.textContent.trim() === "") {
6
+ const n = c[0], l = n.getAttribute("width"), t = n.getAttribute("height"), e = !!(l && t && o.test(l) && o.test(t));
7
+ let s = null;
8
+ if (!e) {
9
+ const i = n.style.height || t;
10
+ if (i)
11
+ if (o.test(i))
12
+ s = `${i}px`;
13
+ else
14
+ try {
15
+ const r = u(i);
16
+ r && r.unit && r.unit !== "%" && (s = i);
17
+ } catch (r) {
18
+ }
19
+ }
20
+ return {
21
+ iframe: n,
22
+ isStaticSize: e,
23
+ width: e ? l : null,
24
+ height: e ? t : null,
25
+ aspectRatio: e ? `${l} / ${t}` : null,
26
+ fillHeight: s
27
+ };
28
+ }
29
+ return null;
30
+ }
31
+ export {
32
+ h as getSoleIframeLayout
33
+ };