@ulu/frontend 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.dev.md +16 -0
- package/dist/es/index.js +18 -16
- package/dist/es/ui/dialog.d.ts +3 -1
- package/dist/es/ui/dialog.d.ts.map +1 -1
- package/dist/es/ui/dialog.js +57 -51
- package/dist/es/ui/modal-builder.d.ts +6 -0
- package/dist/es/ui/modal-builder.d.ts.map +1 -1
- package/dist/es/ui/modal-builder.js +53 -45
- package/dist/es/utils/dialog.d.ts +14 -0
- package/dist/es/utils/dialog.d.ts.map +1 -0
- package/dist/es/utils/dialog.js +16 -0
- package/dist/es/utils/iframe.d.ts +15 -0
- package/dist/es/utils/iframe.d.ts.map +1 -0
- package/dist/es/utils/iframe.js +33 -0
- package/dist/es/utils/index.d.ts +1 -0
- package/dist/umd/frontend.css +1 -1
- package/dist/umd/ulu-frontend.umd.js +12 -12
- package/lib/js/exports.md +1 -0
- package/lib/js/ui/dialog.js +23 -3
- package/lib/js/ui/modal-builder.js +21 -0
- package/lib/js/utils/dialog.js +29 -0
- package/lib/js/utils/iframe.js +59 -0
- package/lib/js/utils/index.js +4 -1
- package/lib/scss/_color.scss +1 -1
- package/lib/scss/_element.scss +15 -0
- package/lib/scss/_utils.scss +22 -0
- package/lib/scss/base/_elements.scss +3 -0
- package/lib/scss/components/_accordion.scss +7 -2
- package/lib/scss/components/_badge.scss +1 -1
- package/lib/scss/components/_button-group.scss +8 -3
- package/lib/scss/components/_card-grid.scss +8 -14
- package/lib/scss/components/_card.scss +15 -13
- package/lib/scss/components/_data-list.scss +270 -0
- package/lib/scss/components/_data-table.scss +3 -1
- package/lib/scss/components/_index.scss +12 -0
- package/lib/scss/components/_menu-stack.scss +1 -1
- package/lib/scss/components/_modal.scss +97 -19
- package/lib/scss/components/_ratio-box.scss +11 -10
- package/lib/scss/components/_table-scroller.scss +63 -0
- package/lib/scss/helpers/_utilities.scss +23 -1
- 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
|
|
package/dist/es/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import { createUluEvent as i, dispatchCoreEvent as r, getCoreEventName as a, get
|
|
|
2
2
|
import { getDefaultSettings as l, getSetting as n, getSettings as p, updateSetting as g, updateSettings as u, wrapSettingString as f } from "./core/settings.js";
|
|
3
3
|
import { ComponentInitializer as m } from "./core/component.js";
|
|
4
4
|
import { BreakpointManager as I } from "./ui/breakpoints.js";
|
|
5
|
-
import { Collapsible as
|
|
5
|
+
import { Collapsible as S } from "./ui/collapsible.js";
|
|
6
6
|
import { init as D, initializer as C, setupGroup as v } from "./ui/details-group.js";
|
|
7
|
-
import { baseAttribute as
|
|
7
|
+
import { baseAttribute as y, closeAttribute as T, defaults as B, getDialogOptions as P, init as h, initializer as A, setDefaults as L, setupDialog as k, setupTrigger as G } from "./ui/dialog.js";
|
|
8
8
|
import { Flipcard as M, init as w, initializer as U } from "./ui/flipcard.js";
|
|
9
9
|
import { init as F, initializer as O } from "./ui/grid.js";
|
|
10
10
|
import { buildModal as N, defaults as R, init as W, initializer as K, setDefaults as j } from "./ui/modal-builder.js";
|
|
@@ -15,11 +15,11 @@ import { init as $ } from "./ui/page.js";
|
|
|
15
15
|
import { Popover as te, getContentByTrigger as ie, init as re, initializer as ae, instances as oe, resolve as se } from "./ui/popover.js";
|
|
16
16
|
import { attrs as ne, init as pe } from "./ui/print-details.js";
|
|
17
17
|
import { init as ue } from "./ui/print.js";
|
|
18
|
-
import { attachHandlers as de, defaults as me, init as xe, initializer as Ie, setDefaults as ce, setupProxy as
|
|
18
|
+
import { attachHandlers as de, defaults as me, init as xe, initializer as Ie, setDefaults as ce, setupProxy as Se } from "./ui/proxy-click.js";
|
|
19
19
|
import { Resizer as De } from "./ui/resizer.js";
|
|
20
20
|
import { init as ve, initializer as be } from "./ui/scroll-slider.js";
|
|
21
|
-
import { Scrollpoint as
|
|
22
|
-
import { Slider as Ae, init as
|
|
21
|
+
import { Scrollpoint as Te, init as Be, initializer as Pe } from "./ui/scrollpoint.js";
|
|
22
|
+
import { Slider as Ae, init as Le, initializer as ke, setupSlider as Ge } from "./ui/slider.js";
|
|
23
23
|
import { TabManager as Me } from "./ui/tab-manager.js";
|
|
24
24
|
import { init as Ue, initializer as Ve, instances as Fe, setup as Oe } from "./ui/tabs.js";
|
|
25
25
|
import { defaults as Ne, init as Re, initializer as We, setDefaults as Ke, setupToggle as je } from "./ui/theme-toggle.js";
|
|
@@ -31,9 +31,10 @@ import { createFloatingUi as nt, defaults as pt } from "./utils/floating-ui.js";
|
|
|
31
31
|
import { configureIcons as ut } from "./utils/font-awesome.js";
|
|
32
32
|
import { ensureId as dt, newId as mt } from "./utils/id.js";
|
|
33
33
|
import { pauseVideos as It, prepVideos as ct } from "./utils/pause-youtube-video.js";
|
|
34
|
+
import { getSoleIframeLayout as zt } from "./utils/iframe.js";
|
|
34
35
|
export {
|
|
35
36
|
I as BreakpointManager,
|
|
36
|
-
|
|
37
|
+
S as Collapsible,
|
|
37
38
|
m as ComponentInitializer,
|
|
38
39
|
st as FileSave,
|
|
39
40
|
M as Flipcard,
|
|
@@ -41,7 +42,7 @@ export {
|
|
|
41
42
|
te as Popover,
|
|
42
43
|
J as ProgrammaticModalManager,
|
|
43
44
|
De as Resizer,
|
|
44
|
-
|
|
45
|
+
Te as Scrollpoint,
|
|
45
46
|
Ae as Slider,
|
|
46
47
|
Me as TabManager,
|
|
47
48
|
Je as Tooltip,
|
|
@@ -55,15 +56,15 @@ export {
|
|
|
55
56
|
D as detailsGroupInit,
|
|
56
57
|
C as detailsGroupInitializer,
|
|
57
58
|
v as detailsGroupSetupGroup,
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
y as dialogBaseAttribute,
|
|
60
|
+
T as dialogCloseAttribute,
|
|
60
61
|
B as dialogDefaults,
|
|
61
62
|
P as dialogGetDialogOptions,
|
|
62
63
|
h as dialogInit,
|
|
63
64
|
A as dialogInitializer,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
L as dialogSetDefaults,
|
|
66
|
+
k as dialogSetupDialog,
|
|
67
|
+
G as dialogSetupTrigger,
|
|
67
68
|
r as dispatchCoreEvent,
|
|
68
69
|
dt as ensureId,
|
|
69
70
|
w as flipcardInit,
|
|
@@ -74,6 +75,7 @@ export {
|
|
|
74
75
|
l as getDefaultSettings,
|
|
75
76
|
n as getSetting,
|
|
76
77
|
p as getSettings,
|
|
78
|
+
zt as getSoleIframeLayout,
|
|
77
79
|
o as getUluEventName,
|
|
78
80
|
F as gridInit,
|
|
79
81
|
O as gridInitializer,
|
|
@@ -98,16 +100,16 @@ export {
|
|
|
98
100
|
xe as proxyClickInit,
|
|
99
101
|
Ie as proxyClickInitializer,
|
|
100
102
|
ce as proxyClickSetDefaults,
|
|
101
|
-
|
|
103
|
+
Se as proxyClickSetupProxy,
|
|
102
104
|
rt as resolveClasses,
|
|
103
105
|
ve as scrollSliderInit,
|
|
104
106
|
be as scrollSliderInitializer,
|
|
105
107
|
Be as scrollpointInit,
|
|
106
108
|
Pe as scrollpointInitializer,
|
|
107
109
|
at as setPositionClasses,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
Le as sliderInit,
|
|
111
|
+
ke as sliderInitializer,
|
|
112
|
+
Ge as sliderSetupSlider,
|
|
111
113
|
Ue as tabsInit,
|
|
112
114
|
Ve as tabsInitializer,
|
|
113
115
|
Fe as tabsInstances,
|
package/dist/es/ui/dialog.d.ts
CHANGED
|
@@ -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):
|
|
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":"
|
|
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"}
|
package/dist/es/ui/dialog.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
var
|
|
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
|
-
|
|
7
|
-
if (
|
|
8
|
-
for (var t of
|
|
9
|
-
|
|
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
|
|
12
|
+
import { getUluEventName as g } from "../core/events.js";
|
|
13
13
|
import { ComponentInitializer as V } from "../core/component.js";
|
|
14
|
-
import {
|
|
15
|
-
import { prepVideos as
|
|
16
|
-
|
|
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 =
|
|
45
|
-
function
|
|
45
|
+
let a = m({}, M);
|
|
46
|
+
function H(e) {
|
|
46
47
|
a = Object.assign({}, a, e);
|
|
47
48
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
49
|
+
function J() {
|
|
50
|
+
r.init({
|
|
50
51
|
coreEvents: ["pageModified"],
|
|
51
52
|
withData: !0,
|
|
52
53
|
setup({ element: e, initialize: o, data: t }) {
|
|
53
|
-
|
|
54
|
+
I(e, t), o();
|
|
54
55
|
}
|
|
55
|
-
}),
|
|
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
|
-
|
|
61
|
+
A(e, t), o();
|
|
61
62
|
}
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
|
-
function
|
|
65
|
+
function A(e, o) {
|
|
65
66
|
e.addEventListener("click", t);
|
|
66
|
-
function t(
|
|
67
|
+
function t(l) {
|
|
67
68
|
var c;
|
|
68
|
-
|
|
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
|
|
79
|
-
n[
|
|
79
|
+
const i = R(n);
|
|
80
|
+
n[i.nonModal ? "show" : "showModal"]();
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
|
-
function
|
|
83
|
-
const t = Object.assign({}, a, o),
|
|
84
|
-
let n;
|
|
85
|
-
if (e.addEventListener(
|
|
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
|
|
88
|
-
|
|
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
|
-
|
|
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
|
|
99
|
-
|
|
100
|
-
|
|
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
|
|
105
|
-
return Object.assign({}, a,
|
|
110
|
+
function R(e) {
|
|
111
|
+
return Object.assign({}, a, r.getData(e));
|
|
106
112
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
113
|
+
function T(e) {
|
|
114
|
+
w(e);
|
|
109
115
|
}
|
|
110
116
|
function j(e) {
|
|
111
|
-
|
|
117
|
+
y(e), e.querySelectorAll("video").forEach((t) => t.pause());
|
|
112
118
|
}
|
|
113
119
|
export {
|
|
114
120
|
L as baseAttribute,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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":"
|
|
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
|
|
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
|
-
|
|
6
|
+
R.call(t, e) && p(s, e, t[e]);
|
|
7
7
|
if (m)
|
|
8
8
|
for (var e of m(t))
|
|
9
|
-
|
|
9
|
+
E.call(t, e) && p(s, e, t[e]);
|
|
10
10
|
return s;
|
|
11
11
|
};
|
|
12
|
-
import { ComponentInitializer as
|
|
13
|
-
import { wrapSettingString as
|
|
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
|
|
17
|
-
import { createElementFromHtml as
|
|
18
|
-
|
|
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
|
-
}),
|
|
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:
|
|
42
|
-
classResizerIcon:
|
|
43
|
-
classResizerIconBoth:
|
|
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:
|
|
51
|
-
return `<span class="${t}__resizer-icon ${
|
|
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:
|
|
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
|
-
],
|
|
74
|
+
], r = t.title ? `${s}--title` : t.labelledby;
|
|
71
75
|
return `
|
|
72
76
|
<dialog
|
|
73
77
|
id="${s}"
|
|
74
|
-
class="${
|
|
75
|
-
${
|
|
76
|
-
${
|
|
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="${
|
|
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" ${
|
|
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
|
-
${
|
|
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
|
|
99
|
-
function
|
|
100
|
-
|
|
102
|
+
let u = $({}, L);
|
|
103
|
+
function J(s) {
|
|
104
|
+
u = Object.assign({}, u, s);
|
|
101
105
|
}
|
|
102
|
-
function
|
|
106
|
+
function Y() {
|
|
103
107
|
n.init({
|
|
104
108
|
withData: !0,
|
|
105
109
|
coreEvents: ["pageModified"],
|
|
106
110
|
setup({ element: s, data: t }) {
|
|
107
|
-
|
|
111
|
+
O(s, t);
|
|
108
112
|
}
|
|
109
113
|
});
|
|
110
114
|
}
|
|
111
|
-
function
|
|
112
|
-
const e = Object.assign({},
|
|
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
|
|
116
|
-
if (s.removeAttribute("id"), s.removeAttribute("hidden"), s.removeAttribute(n.getAttribute()), s.parentNode.replaceChild(
|
|
117
|
-
const l =
|
|
118
|
-
l && (l.classList.add(`${e.baseClass}__footer`),
|
|
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
|
|
129
|
+
const z = ["left", "right", "center"], _ = a === "center", y = a === "right";
|
|
122
130
|
if (e.allowResize)
|
|
123
|
-
if (
|
|
131
|
+
if (z.includes(a)) {
|
|
124
132
|
const l = _ ? { fromX: "right", fromY: "bottom", multiplier: 2 } : { fromX: y ? "left" : "right" };
|
|
125
|
-
b = new w(
|
|
133
|
+
b = new w(i, h, l);
|
|
126
134
|
} else
|
|
127
|
-
console.warn(`${
|
|
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),
|
|
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:
|
|
144
|
+
return { modal: i, resizer: b };
|
|
137
145
|
}
|
|
138
|
-
function
|
|
139
|
-
return Object.keys(
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
O as buildModal,
|
|
151
|
+
L as defaults,
|
|
152
|
+
Y as init,
|
|
145
153
|
n as initializer,
|
|
146
|
-
|
|
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
|
+
};
|
package/dist/es/utils/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { FileSave } from './file-save.js';
|
|
2
2
|
export { configureIcons as fontAwesomeConfigureIcons } from './font-awesome.js';
|
|
3
|
+
export { getSoleIframeLayout } from './iframe.js';
|
|
3
4
|
export { set as classLoggerSet, log as classLoggerLog, logWarning as classLoggerLogWarning, logError as classLoggerLogError } from './class-logger.js';
|
|
4
5
|
export { dataAttributeToDatasetKey, setPositionClasses, resolveClasses } from './dom.js';
|
|
5
6
|
export { defaults as floatingUiDefaults, createFloatingUi } from './floating-ui.js';
|