@materializecss/materialize 2.0.3-beta → 2.0.4
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/LICENSE +1 -1
- package/README.md +16 -18
- package/dist/css/materialize.css +73 -26
- package/dist/css/materialize.min.css +3 -3
- package/dist/js/materialize.js +560 -2015
- package/dist/js/materialize.min.js +3 -3
- package/dist/js/materialize.min.js.map +1 -1
- package/dist/src/buttons.d.ts.map +1 -1
- package/dist/src/cards.d.ts.map +1 -1
- package/dist/src/collapsible.d.ts +1 -0
- package/dist/src/collapsible.d.ts.map +1 -1
- package/dist/src/dropdown.d.ts +1 -0
- package/dist/src/dropdown.d.ts.map +1 -1
- package/dist/src/global.d.ts.map +1 -1
- package/dist/src/materialbox.d.ts +14 -10
- package/dist/src/materialbox.d.ts.map +1 -1
- package/dist/src/modal.d.ts.map +1 -1
- package/dist/src/range.d.ts.map +1 -1
- package/dist/src/scrollspy.d.ts.map +1 -1
- package/dist/src/sidenav.d.ts +25 -25
- package/dist/src/sidenav.d.ts.map +1 -1
- package/dist/src/slider.d.ts +12 -12
- package/dist/src/slider.d.ts.map +1 -1
- package/dist/src/tabs.d.ts +1 -1
- package/dist/src/tabs.d.ts.map +1 -1
- package/dist/src/toasts.d.ts +7 -2
- package/dist/src/toasts.d.ts.map +1 -1
- package/dist/src/tooltip.d.ts.map +1 -1
- package/package.json +29 -44
- package/sass/components/_collapsible.scss +14 -2
- package/sass/components/_materialbox.scss +2 -2
- package/sass/components/_modal.scss +0 -1
- package/sass/components/_tooltip.scss +18 -8
- package/sass/components/_variables.scss +2 -2
- package/Gruntfile.js +0 -385
- package/src/autocomplete.ts +0 -553
- package/src/bounding.ts +0 -6
- package/src/buttons.ts +0 -260
- package/src/cards.ts +0 -53
- package/src/carousel.ts +0 -676
- package/src/characterCounter.ts +0 -117
- package/src/chips.ts +0 -439
- package/src/collapsible.ts +0 -249
- package/src/component.ts +0 -120
- package/src/datepicker.ts +0 -1076
- package/src/dropdown.ts +0 -644
- package/src/edges.ts +0 -6
- package/src/forms.ts +0 -132
- package/src/global.ts +0 -114
- package/src/index.ts +0 -26
- package/src/materialbox.ts +0 -404
- package/src/modal.ts +0 -341
- package/src/parallax.ts +0 -149
- package/src/pushpin.ts +0 -165
- package/src/range.ts +0 -198
- package/src/scrollspy.ts +0 -263
- package/src/select.ts +0 -484
- package/src/sidenav.ts +0 -543
- package/src/slider.ts +0 -474
- package/src/tabs.ts +0 -347
- package/src/tapTarget.ts +0 -273
- package/src/timepicker.ts +0 -832
- package/src/toasts.ts +0 -290
- package/src/tooltip.ts +0 -366
- package/src/utils.ts +0 -271
- package/src/waves.ts +0 -70
package/src/forms.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { Utils } from "./utils";
|
|
2
|
-
|
|
3
|
-
export class Forms {
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Resizes the given TextArea after updating the
|
|
7
|
-
* value content dynamically.
|
|
8
|
-
* @param textarea TextArea to be resized
|
|
9
|
-
*/
|
|
10
|
-
static textareaAutoResize(textarea: HTMLTextAreaElement){
|
|
11
|
-
if (!textarea) {
|
|
12
|
-
console.error('No textarea element found');
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
// Textarea Auto Resize
|
|
16
|
-
let hiddenDiv: HTMLDivElement = document.querySelector('.hiddendiv');
|
|
17
|
-
if (!hiddenDiv) {
|
|
18
|
-
hiddenDiv = document.createElement('div');
|
|
19
|
-
hiddenDiv.classList.add('hiddendiv', 'common');
|
|
20
|
-
document.body.append(hiddenDiv);
|
|
21
|
-
}
|
|
22
|
-
const style = getComputedStyle(textarea);
|
|
23
|
-
// Set font properties of hiddenDiv
|
|
24
|
-
const fontFamily = style.fontFamily; //textarea.css('font-family');
|
|
25
|
-
const fontSize = style.fontSize; //textarea.css('font-size');
|
|
26
|
-
const lineHeight = style.lineHeight; //textarea.css('line-height');
|
|
27
|
-
// Firefox can't handle padding shorthand.
|
|
28
|
-
const paddingTop = style.paddingTop; //getComputedStyle(textarea).css('padding-top');
|
|
29
|
-
const paddingRight = style.paddingRight; //textarea.css('padding-right');
|
|
30
|
-
const paddingBottom = style.paddingBottom; //textarea.css('padding-bottom');
|
|
31
|
-
const paddingLeft = style.paddingLeft; //textarea.css('padding-left');
|
|
32
|
-
|
|
33
|
-
if (fontSize) hiddenDiv.style.fontSize = fontSize; //('font-size', fontSize);
|
|
34
|
-
if (fontFamily) hiddenDiv.style.fontFamily = fontFamily; //css('font-family', fontFamily);
|
|
35
|
-
if (lineHeight) hiddenDiv.style.lineHeight = lineHeight; //css('line-height', lineHeight);
|
|
36
|
-
if (paddingTop) hiddenDiv.style.paddingTop = paddingTop; //ss('padding-top', paddingTop);
|
|
37
|
-
if (paddingRight) hiddenDiv.style.paddingRight = paddingRight; //css('padding-right', paddingRight);
|
|
38
|
-
if (paddingBottom) hiddenDiv.style.paddingBottom = paddingBottom; //css('padding-bottom', paddingBottom);
|
|
39
|
-
if (paddingLeft) hiddenDiv.style.paddingLeft = paddingLeft; //css('padding-left', paddingLeft);
|
|
40
|
-
|
|
41
|
-
// Set original-height, if none
|
|
42
|
-
if (!textarea.hasAttribute('original-height'))
|
|
43
|
-
textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());
|
|
44
|
-
|
|
45
|
-
if (textarea.getAttribute('wrap') === 'off') {
|
|
46
|
-
hiddenDiv.style.overflowWrap = 'normal'; // ('overflow-wrap', 'normal')
|
|
47
|
-
hiddenDiv.style.whiteSpace = 'pre'; //.css('white-space', 'pre');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
hiddenDiv.innerText = textarea.value + '\n';
|
|
51
|
-
|
|
52
|
-
const content = hiddenDiv.innerHTML.replace(/\n/g, '<br>');
|
|
53
|
-
hiddenDiv.innerHTML = content;
|
|
54
|
-
|
|
55
|
-
// When textarea is hidden, width goes crazy.
|
|
56
|
-
// Approximate with half of window size
|
|
57
|
-
if (textarea.offsetWidth > 0 && textarea.offsetHeight > 0) {
|
|
58
|
-
hiddenDiv.style.width = textarea.getBoundingClientRect().width +'px'; // ('width', textarea.width() + 'px');
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
hiddenDiv.style.width = (window.innerWidth / 2)+'px' //css('width', window.innerWidth / 2 + 'px');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Resize if the new height is greater than the
|
|
65
|
-
// original height of the textarea
|
|
66
|
-
const originalHeight = parseInt(textarea.getAttribute('original-height'));
|
|
67
|
-
const prevLength = parseInt(textarea.getAttribute('previous-length'));
|
|
68
|
-
if (isNaN(originalHeight)) return;
|
|
69
|
-
if (originalHeight <= hiddenDiv.clientHeight) {
|
|
70
|
-
textarea.style.height = hiddenDiv.clientHeight+'px'; //css('height', hiddenDiv.innerHeight() + 'px');
|
|
71
|
-
}
|
|
72
|
-
else if (textarea.value.length < prevLength) {
|
|
73
|
-
// In case the new height is less than original height, it
|
|
74
|
-
// means the textarea has less text than before
|
|
75
|
-
// So we set the height to the original one
|
|
76
|
-
textarea.style.height = originalHeight+'px';
|
|
77
|
-
}
|
|
78
|
-
textarea.setAttribute('previous-length', textarea.value.length.toString());
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
static Init(){
|
|
82
|
-
document.addEventListener("DOMContentLoaded", () => {
|
|
83
|
-
|
|
84
|
-
document.addEventListener('keyup', (e: KeyboardEvent) => {
|
|
85
|
-
const target = <HTMLInputElement>e.target;
|
|
86
|
-
// Radio and Checkbox focus class
|
|
87
|
-
if (target instanceof HTMLInputElement && ['radio','checkbox'].includes(target.type)) {
|
|
88
|
-
// TAB, check if tabbing to radio or checkbox.
|
|
89
|
-
if (Utils.keys.TAB.includes(e.key)) {
|
|
90
|
-
target.classList.add('tabbed');
|
|
91
|
-
target.addEventListener('blur', e => target.classList.remove('tabbed'), {once: true});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
document.querySelectorAll('.materialize-textarea').forEach((textArea: HTMLTextAreaElement) => {
|
|
97
|
-
Forms.textareaAutoResize(textArea);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// File Input Path
|
|
101
|
-
document.querySelectorAll('.file-field input[type="file"]').forEach((fileInput: HTMLInputElement) => {
|
|
102
|
-
Forms.InitFileInputPath(fileInput);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
static InitTextarea(textarea: HTMLTextAreaElement){
|
|
109
|
-
// Save Data in Element
|
|
110
|
-
textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());
|
|
111
|
-
textarea.setAttribute('previous-length', textarea.value.length.toString());
|
|
112
|
-
Forms.textareaAutoResize(textarea);
|
|
113
|
-
|
|
114
|
-
textarea.addEventListener('keyup', e => Forms.textareaAutoResize(textarea));
|
|
115
|
-
textarea.addEventListener('keydown', e => Forms.textareaAutoResize(textarea));
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
static InitFileInputPath(fileInput: HTMLInputElement){
|
|
119
|
-
fileInput.addEventListener('change', e => {
|
|
120
|
-
const fileField = fileInput.closest('.file-field');
|
|
121
|
-
const pathInput = <HTMLInputElement>fileField.querySelector('input.file-path');
|
|
122
|
-
const files = fileInput.files;
|
|
123
|
-
const filenames = [];
|
|
124
|
-
for (let i = 0; i < files.length; i++) {
|
|
125
|
-
filenames.push(files[i].name);
|
|
126
|
-
}
|
|
127
|
-
pathInput.value = filenames.join(', ');
|
|
128
|
-
pathInput.dispatchEvent(new Event('change',{bubbles:true, cancelable:true, composed:true}));
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
}
|
package/src/global.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { Autocomplete } from './autocomplete';
|
|
2
|
-
import { FloatingActionButton } from './buttons';
|
|
3
|
-
import { Cards } from './cards';
|
|
4
|
-
import { Carousel } from './carousel';
|
|
5
|
-
import { CharacterCounter } from './characterCounter';
|
|
6
|
-
import { Chips } from './chips';
|
|
7
|
-
import { Collapsible } from './collapsible';
|
|
8
|
-
import { Datepicker } from './datepicker';
|
|
9
|
-
import { Dropdown } from './dropdown';
|
|
10
|
-
import { Forms } from './forms';
|
|
11
|
-
import { Materialbox } from './materialbox';
|
|
12
|
-
import { Modal } from './modal';
|
|
13
|
-
import { Parallax } from './parallax';
|
|
14
|
-
import { Pushpin } from './pushpin';
|
|
15
|
-
import { ScrollSpy } from './scrollspy';
|
|
16
|
-
import { FormSelect } from './select';
|
|
17
|
-
import { Sidenav } from './sidenav';
|
|
18
|
-
import { Slider } from './slider';
|
|
19
|
-
import { Tabs } from './tabs';
|
|
20
|
-
import { TapTarget } from './tapTarget';
|
|
21
|
-
import { Timepicker } from './timepicker';
|
|
22
|
-
import { Toast, ToastOptions } from './toasts';
|
|
23
|
-
import { Tooltip } from './tooltip';
|
|
24
|
-
import { Waves } from './waves';
|
|
25
|
-
import { Range } from './range';
|
|
26
|
-
import { Utils } from './utils';
|
|
27
|
-
|
|
28
|
-
export class M {
|
|
29
|
-
static version = '2.0.3-beta';
|
|
30
|
-
|
|
31
|
-
static Autocomplete: typeof Autocomplete = Autocomplete;
|
|
32
|
-
static Tabs: typeof Tabs = Tabs;
|
|
33
|
-
static Carousel: typeof Carousel = Carousel;
|
|
34
|
-
static Dropdown: typeof Dropdown = Dropdown;
|
|
35
|
-
static FloatingActionButton: typeof FloatingActionButton = FloatingActionButton;
|
|
36
|
-
static Chips: typeof Chips = Chips;
|
|
37
|
-
static Collapsible: typeof Collapsible = Collapsible;
|
|
38
|
-
static Datepicker: typeof Datepicker = Datepicker;
|
|
39
|
-
static CharacterCounter: typeof CharacterCounter = CharacterCounter;
|
|
40
|
-
static Forms: typeof Forms = Forms;
|
|
41
|
-
static FormSelect: typeof FormSelect = FormSelect;
|
|
42
|
-
static Modal: typeof Modal = Modal;
|
|
43
|
-
static Pushpin: typeof Pushpin = Pushpin;
|
|
44
|
-
static Materialbox: typeof Materialbox = Materialbox;
|
|
45
|
-
static Parallax: typeof Parallax = Parallax;
|
|
46
|
-
static Slider: typeof Slider = Slider;
|
|
47
|
-
static Timepicker: typeof Timepicker = Timepicker;
|
|
48
|
-
/** Creates a toast. */
|
|
49
|
-
static toast: (opt: Partial<ToastOptions>) => Toast = (opt) => new Toast(opt) ;
|
|
50
|
-
static Tooltip: typeof Tooltip = Tooltip;
|
|
51
|
-
static Sidenav: typeof Sidenav = Sidenav;
|
|
52
|
-
static TapTarget: typeof TapTarget = TapTarget;
|
|
53
|
-
static ScrollSpy: typeof ScrollSpy = ScrollSpy;
|
|
54
|
-
static Range: typeof Range = Range;
|
|
55
|
-
static Waves: typeof Waves = Waves;
|
|
56
|
-
static Utils: typeof Utils = Utils;
|
|
57
|
-
|
|
58
|
-
static {
|
|
59
|
-
document.addEventListener('keydown', Utils.docHandleKeydown, true);
|
|
60
|
-
document.addEventListener('keyup', Utils.docHandleKeyup, true);
|
|
61
|
-
document.addEventListener('focus', Utils.docHandleFocus, true);
|
|
62
|
-
document.addEventListener('blur', Utils.docHandleBlur, true);
|
|
63
|
-
Cards.Init();
|
|
64
|
-
Forms.Init();
|
|
65
|
-
Chips.Init();
|
|
66
|
-
Waves.Init();
|
|
67
|
-
Range.Init();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Automatically initialize components.
|
|
72
|
-
* @param context Root element to initialize. Defaults to `document.body`.
|
|
73
|
-
*/
|
|
74
|
-
static AutoInit(context: HTMLElement = document.body) {
|
|
75
|
-
let registry = {
|
|
76
|
-
Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'),
|
|
77
|
-
Carousel: context.querySelectorAll('.carousel:not(.no-autoinit)'),
|
|
78
|
-
Chips: context.querySelectorAll('.chips:not(.no-autoinit)'),
|
|
79
|
-
Collapsible: context.querySelectorAll('.collapsible:not(.no-autoinit)'),
|
|
80
|
-
Datepicker: context.querySelectorAll('.datepicker:not(.no-autoinit)'),
|
|
81
|
-
Dropdown: context.querySelectorAll('.dropdown-trigger:not(.no-autoinit)'),
|
|
82
|
-
Materialbox: context.querySelectorAll('.materialboxed:not(.no-autoinit)'),
|
|
83
|
-
Modal: context.querySelectorAll('.modal:not(.no-autoinit)'),
|
|
84
|
-
Parallax: context.querySelectorAll('.parallax:not(.no-autoinit)'),
|
|
85
|
-
Pushpin: context.querySelectorAll('.pushpin:not(.no-autoinit)'),
|
|
86
|
-
ScrollSpy: context.querySelectorAll('.scrollspy:not(.no-autoinit)'),
|
|
87
|
-
FormSelect: context.querySelectorAll('select:not(.no-autoinit)'),
|
|
88
|
-
Sidenav: context.querySelectorAll('.sidenav:not(.no-autoinit)'),
|
|
89
|
-
Tabs: context.querySelectorAll('.tabs:not(.no-autoinit)'),
|
|
90
|
-
TapTarget: context.querySelectorAll('.tap-target:not(.no-autoinit)'),
|
|
91
|
-
Timepicker: context.querySelectorAll('.timepicker:not(.no-autoinit)'),
|
|
92
|
-
Tooltip: context.querySelectorAll('.tooltipped:not(.no-autoinit)'),
|
|
93
|
-
FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)'),
|
|
94
|
-
};
|
|
95
|
-
M.Autocomplete.init(registry.Autocomplete, {});
|
|
96
|
-
M.Carousel.init(registry.Carousel, {});
|
|
97
|
-
M.Chips.init(registry.Chips, {});
|
|
98
|
-
M.Collapsible.init(registry.Collapsible, {});
|
|
99
|
-
M.Datepicker.init(registry.Datepicker, {});
|
|
100
|
-
M.Dropdown.init(registry.Dropdown, {});
|
|
101
|
-
M.Materialbox.init(registry.Materialbox, {});
|
|
102
|
-
M.Modal.init(registry.Modal, {});
|
|
103
|
-
M.Parallax.init(registry.Parallax, {});
|
|
104
|
-
M.Pushpin.init(registry.Pushpin, {});
|
|
105
|
-
M.ScrollSpy.init(registry.ScrollSpy, {});
|
|
106
|
-
M.FormSelect.init(registry.FormSelect, {});
|
|
107
|
-
M.Sidenav.init(registry.Sidenav, {});
|
|
108
|
-
M.Tabs.init(registry.Tabs, {});
|
|
109
|
-
M.TapTarget.init(registry.TapTarget, {});
|
|
110
|
-
M.Timepicker.init(registry.Timepicker, {});
|
|
111
|
-
M.Tooltip.init(registry.Tooltip, {});
|
|
112
|
-
M.FloatingActionButton.init(registry.FloatingActionButton, {});
|
|
113
|
-
}
|
|
114
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export * from './global';
|
|
2
|
-
export { Autocomplete } from './autocomplete';
|
|
3
|
-
export { FloatingActionButton } from './buttons';
|
|
4
|
-
export { Cards } from './cards';
|
|
5
|
-
export { Carousel } from './carousel';
|
|
6
|
-
export { CharacterCounter } from './characterCounter';
|
|
7
|
-
export { Chips } from './chips';
|
|
8
|
-
export { Collapsible } from './collapsible';
|
|
9
|
-
export { Datepicker } from './datepicker';
|
|
10
|
-
export { Dropdown } from './dropdown';
|
|
11
|
-
export { Forms } from './forms';
|
|
12
|
-
export { Materialbox } from './materialbox';
|
|
13
|
-
export { Modal } from './modal';
|
|
14
|
-
export { Parallax } from './parallax';
|
|
15
|
-
export { Pushpin } from './pushpin';
|
|
16
|
-
export { ScrollSpy } from './scrollspy';
|
|
17
|
-
export { FormSelect } from './select';
|
|
18
|
-
export { Sidenav } from './sidenav';
|
|
19
|
-
export { Slider } from './slider';
|
|
20
|
-
export { Tabs } from './tabs';
|
|
21
|
-
export { TapTarget } from './tapTarget';
|
|
22
|
-
export { Timepicker } from './timepicker';
|
|
23
|
-
export { Toast } from './toasts';
|
|
24
|
-
export { Tooltip } from './tooltip';
|
|
25
|
-
export { Waves } from './waves';
|
|
26
|
-
export { Range } from './range';
|
package/src/materialbox.ts
DELETED
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import anim from "animejs";
|
|
2
|
-
|
|
3
|
-
import { Utils } from "./utils";
|
|
4
|
-
import { BaseOptions, Component, InitElements, MElement } from "./component";
|
|
5
|
-
|
|
6
|
-
export interface MaterialboxOptions extends BaseOptions {
|
|
7
|
-
/**
|
|
8
|
-
* Transition in duration in milliseconds.
|
|
9
|
-
* @default 275
|
|
10
|
-
*/
|
|
11
|
-
inDuration: number;
|
|
12
|
-
/**
|
|
13
|
-
* Transition out duration in milliseconds.
|
|
14
|
-
* @default 200
|
|
15
|
-
*/
|
|
16
|
-
outDuration: number;
|
|
17
|
-
/**
|
|
18
|
-
* Callback function called before materialbox is opened.
|
|
19
|
-
* @default null
|
|
20
|
-
*/
|
|
21
|
-
onOpenStart: (el: Element) => void;
|
|
22
|
-
/**
|
|
23
|
-
* Callback function called after materialbox is opened.
|
|
24
|
-
* @default null
|
|
25
|
-
*/
|
|
26
|
-
onOpenEnd: (el: Element) => void;
|
|
27
|
-
/**
|
|
28
|
-
* Callback function called before materialbox is closed.
|
|
29
|
-
* @default null
|
|
30
|
-
*/
|
|
31
|
-
onCloseStart: (el: Element) => void;
|
|
32
|
-
/**
|
|
33
|
-
* Callback function called after materialbox is closed.
|
|
34
|
-
* @default null
|
|
35
|
-
*/
|
|
36
|
-
onCloseEnd: (el: Element) => void;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const _defaults: MaterialboxOptions = {
|
|
40
|
-
inDuration: 275,
|
|
41
|
-
outDuration: 200,
|
|
42
|
-
onOpenStart: null,
|
|
43
|
-
onOpenEnd: null,
|
|
44
|
-
onCloseStart: null,
|
|
45
|
-
onCloseEnd: null
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export class Materialbox extends Component<MaterialboxOptions> {
|
|
49
|
-
/** If the materialbox overlay is showing. */
|
|
50
|
-
overlayActive: boolean;
|
|
51
|
-
/** If the materialbox is no longer being animated. */
|
|
52
|
-
doneAnimating: boolean;
|
|
53
|
-
/** Caption, if specified. */
|
|
54
|
-
caption: string;
|
|
55
|
-
/** Original width of image. */
|
|
56
|
-
originalWidth: number;
|
|
57
|
-
/** Original height of image. */
|
|
58
|
-
originalHeight: number;
|
|
59
|
-
private originInlineStyles: string;
|
|
60
|
-
private placeholder: HTMLElement;
|
|
61
|
-
private _changedAncestorList: HTMLElement[];
|
|
62
|
-
private newHeight: number;
|
|
63
|
-
private newWidth: number;
|
|
64
|
-
private windowWidth: number;
|
|
65
|
-
private windowHeight: number;
|
|
66
|
-
private attrWidth: string;
|
|
67
|
-
private attrHeight: string;
|
|
68
|
-
private _overlay: HTMLElement;
|
|
69
|
-
private _photoCaption: HTMLElement;
|
|
70
|
-
|
|
71
|
-
constructor(el: HTMLElement, options: Partial<MaterialboxOptions>) {
|
|
72
|
-
super(el, options, Materialbox);
|
|
73
|
-
(this.el as any).M_Materialbox = this;
|
|
74
|
-
|
|
75
|
-
this.options = {
|
|
76
|
-
...Materialbox.defaults,
|
|
77
|
-
...options
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
this.overlayActive = false;
|
|
81
|
-
this.doneAnimating = true;
|
|
82
|
-
this.placeholder = document.createElement('div');
|
|
83
|
-
this.placeholder.classList.add('material-placeholder');
|
|
84
|
-
this.originalWidth = 0;
|
|
85
|
-
this.originalHeight = 0;
|
|
86
|
-
this.originInlineStyles = this.el.getAttribute('style');
|
|
87
|
-
this.caption = this.el.getAttribute('data-caption') || '';
|
|
88
|
-
// Wrap
|
|
89
|
-
this.el.before(this.placeholder);
|
|
90
|
-
this.placeholder.append(this.el);
|
|
91
|
-
this._setupEventHandlers();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
static get defaults(): MaterialboxOptions {
|
|
95
|
-
return _defaults;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Initializes instance of MaterialBox.
|
|
100
|
-
* @param el HTML element.
|
|
101
|
-
* @param options Component options.
|
|
102
|
-
*/
|
|
103
|
-
static init(el: HTMLElement, options?: Partial<MaterialboxOptions>): Materialbox;
|
|
104
|
-
/**
|
|
105
|
-
* Initializes instances of MaterialBox.
|
|
106
|
-
* @param els HTML elements.
|
|
107
|
-
* @param options Component options.
|
|
108
|
-
*/
|
|
109
|
-
static init(els: InitElements<MElement>, options?: Partial<MaterialboxOptions>): Materialbox[];
|
|
110
|
-
/**
|
|
111
|
-
* Initializes instances of MaterialBox.
|
|
112
|
-
* @param els HTML elements.
|
|
113
|
-
* @param options Component options.
|
|
114
|
-
*/
|
|
115
|
-
static init(els: HTMLElement | InitElements<MElement>, options: Partial<MaterialboxOptions> = {}): Materialbox | Materialbox[]{
|
|
116
|
-
return super.init(els, options, Materialbox);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
static getInstance(el: HTMLElement): Materialbox {
|
|
120
|
-
return (el as any).M_Materialbox;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
destroy() {
|
|
124
|
-
this._removeEventHandlers();
|
|
125
|
-
(this.el as any).M_Materialbox = undefined;
|
|
126
|
-
// Unwrap image
|
|
127
|
-
//this.placeholder.after(this.el).remove();
|
|
128
|
-
this.placeholder.remove();
|
|
129
|
-
this.el.removeAttribute('style');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
_setupEventHandlers() {
|
|
133
|
-
this.el.addEventListener('click', this._handleMaterialboxClick);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
_removeEventHandlers() {
|
|
137
|
-
this.el.removeEventListener('click', this._handleMaterialboxClick);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
_handleMaterialboxClick = () => {
|
|
141
|
-
// If already modal, return to original
|
|
142
|
-
if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating))
|
|
143
|
-
this.close();
|
|
144
|
-
else
|
|
145
|
-
this.open();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
_handleWindowScroll = () => {
|
|
149
|
-
if (this.overlayActive) this.close();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
_handleWindowResize = () => {
|
|
153
|
-
if (this.overlayActive) this.close();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
_handleWindowEscape = (e: KeyboardEvent) => {
|
|
157
|
-
if (Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) this.close();
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
_makeAncestorsOverflowVisible() {
|
|
161
|
-
this._changedAncestorList = [];
|
|
162
|
-
let ancestor = this.placeholder.parentNode;
|
|
163
|
-
while (ancestor !== null && ancestor !== document) {
|
|
164
|
-
const curr = <HTMLElement>ancestor;
|
|
165
|
-
if (curr.style.overflow !== 'visible') {
|
|
166
|
-
curr.style.overflow = 'visible';
|
|
167
|
-
this._changedAncestorList.push(curr);
|
|
168
|
-
}
|
|
169
|
-
ancestor = ancestor.parentNode;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
private _offset(el: HTMLElement) {
|
|
174
|
-
const box = el.getBoundingClientRect();
|
|
175
|
-
const docElem = document.documentElement;
|
|
176
|
-
return {
|
|
177
|
-
top: box.top + window.pageYOffset - docElem.clientTop,
|
|
178
|
-
left: box.left + window.pageXOffset - docElem.clientLeft
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
_animateImageIn() {
|
|
183
|
-
this.el.style.maxHeight = this.newHeight.toString()+'px';
|
|
184
|
-
this.el.style.maxWidth = this.newWidth.toString()+'px';
|
|
185
|
-
|
|
186
|
-
const animOptions = {
|
|
187
|
-
targets: this.el, // image
|
|
188
|
-
height: [this.originalHeight, this.newHeight],
|
|
189
|
-
width: [this.originalWidth, this.newWidth],
|
|
190
|
-
left:
|
|
191
|
-
Utils.getDocumentScrollLeft() +
|
|
192
|
-
this.windowWidth / 2 -
|
|
193
|
-
this._offset(this.placeholder).left -
|
|
194
|
-
this.newWidth / 2,
|
|
195
|
-
top:
|
|
196
|
-
Utils.getDocumentScrollTop() +
|
|
197
|
-
this.windowHeight / 2 -
|
|
198
|
-
this._offset(this.placeholder).top -
|
|
199
|
-
this.newHeight / 2,
|
|
200
|
-
duration: this.options.inDuration,
|
|
201
|
-
easing: 'easeOutQuad',
|
|
202
|
-
complete: () => {
|
|
203
|
-
this.doneAnimating = true;
|
|
204
|
-
// onOpenEnd callback
|
|
205
|
-
if (typeof this.options.onOpenEnd === 'function') {
|
|
206
|
-
this.options.onOpenEnd.call(this, this.el);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
// Override max-width or max-height if needed
|
|
211
|
-
//const elStyle = this.el.style;
|
|
212
|
-
//console.log('mh', elStyle.maxHeight, '->', this.newHeight);
|
|
213
|
-
//console.log('mw', elStyle.maxWidth, '->', this.newWidth);
|
|
214
|
-
//if (elStyle.maxWidth !== 'none') animOptions.maxWidth = this.newWidth;
|
|
215
|
-
//if (elStyle.maxHeight !== 'none') animOptions.maxHeight = this.newHeight;
|
|
216
|
-
//console.log('>>> animate');
|
|
217
|
-
//console.log(JSON.stringify(animOptions));
|
|
218
|
-
anim(animOptions);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
_animateImageOut() {
|
|
222
|
-
const animOptions = {
|
|
223
|
-
targets: this.el,
|
|
224
|
-
width: this.originalWidth,
|
|
225
|
-
height: this.originalHeight,
|
|
226
|
-
left: 0,
|
|
227
|
-
top: 0,
|
|
228
|
-
duration: this.options.outDuration,
|
|
229
|
-
easing: 'easeOutQuad',
|
|
230
|
-
complete: () => {
|
|
231
|
-
this.placeholder.style.height = '';
|
|
232
|
-
this.placeholder.style.width = '';
|
|
233
|
-
this.placeholder.style.position = '';
|
|
234
|
-
this.placeholder.style.top = '';
|
|
235
|
-
this.placeholder.style.left = '';
|
|
236
|
-
// Revert to width or height attribute
|
|
237
|
-
if (this.attrWidth) this.el.setAttribute('width', this.attrWidth.toString());
|
|
238
|
-
if (this.attrHeight) this.el.setAttribute('height', this.attrHeight.toString());
|
|
239
|
-
this.el.removeAttribute('style');
|
|
240
|
-
this.originInlineStyles && this.el.setAttribute('style', this.originInlineStyles);
|
|
241
|
-
// Remove class
|
|
242
|
-
this.el.classList.remove('active');
|
|
243
|
-
this.doneAnimating = true;
|
|
244
|
-
// Remove overflow overrides on ancestors
|
|
245
|
-
this._changedAncestorList.forEach(anchestor => anchestor.style.overflow = '');
|
|
246
|
-
// onCloseEnd callback
|
|
247
|
-
if (typeof this.options.onCloseEnd === 'function') {
|
|
248
|
-
this.options.onCloseEnd.call(this, this.el);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
anim(animOptions);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
_updateVars() {
|
|
256
|
-
this.windowWidth = window.innerWidth;
|
|
257
|
-
this.windowHeight = window.innerHeight;
|
|
258
|
-
this.caption = this.el.getAttribute('data-caption') || '';
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Open materialbox.
|
|
263
|
-
*/
|
|
264
|
-
open = () => {
|
|
265
|
-
this._updateVars();
|
|
266
|
-
this.originalWidth = this.el.getBoundingClientRect().width;
|
|
267
|
-
this.originalHeight = this.el.getBoundingClientRect().height;
|
|
268
|
-
// Set states
|
|
269
|
-
this.doneAnimating = false;
|
|
270
|
-
this.el.classList.add('active');
|
|
271
|
-
this.overlayActive = true;
|
|
272
|
-
// onOpenStart callback
|
|
273
|
-
if (typeof this.options.onOpenStart === 'function') {
|
|
274
|
-
this.options.onOpenStart.call(this, this.el);
|
|
275
|
-
}
|
|
276
|
-
// Set positioning for placeholder
|
|
277
|
-
this.placeholder.style.width = this.placeholder.getBoundingClientRect().width+'px';
|
|
278
|
-
this.placeholder.style.height = this.placeholder.getBoundingClientRect().height+'px';
|
|
279
|
-
this.placeholder.style.position = 'relative';
|
|
280
|
-
this.placeholder.style.top = '0';
|
|
281
|
-
this.placeholder.style.left = '0';
|
|
282
|
-
this._makeAncestorsOverflowVisible();
|
|
283
|
-
// Set css on origin
|
|
284
|
-
this.el.style.position = 'absolute';
|
|
285
|
-
this.el.style.zIndex = '1000';
|
|
286
|
-
this.el.style.willChange = 'left, top, width, height';
|
|
287
|
-
// Change from width or height attribute to css
|
|
288
|
-
this.attrWidth = this.el.getAttribute('width');
|
|
289
|
-
this.attrHeight = this.el.getAttribute('height');
|
|
290
|
-
if (this.attrWidth) {
|
|
291
|
-
this.el.style.width = this.attrWidth+'px';
|
|
292
|
-
this.el.removeAttribute('width');
|
|
293
|
-
}
|
|
294
|
-
if (this.attrHeight) {
|
|
295
|
-
this.el.style.width = this.attrHeight+'px';
|
|
296
|
-
this.el.removeAttribute('height');
|
|
297
|
-
}
|
|
298
|
-
// Add overlay
|
|
299
|
-
this._overlay = document.createElement('div');
|
|
300
|
-
this._overlay.id = 'materialbox-overlay';
|
|
301
|
-
this._overlay.style.opacity = '0';
|
|
302
|
-
this._overlay.addEventListener('click', e => {
|
|
303
|
-
if (this.doneAnimating) this.close();
|
|
304
|
-
}, {once: true});
|
|
305
|
-
// Put before in origin image to preserve z-index layering.
|
|
306
|
-
this.el.before(this._overlay);
|
|
307
|
-
// Set dimensions if needed
|
|
308
|
-
const overlayOffset = this._overlay.getBoundingClientRect();
|
|
309
|
-
this._overlay.style.width = this.windowWidth+'px';
|
|
310
|
-
this._overlay.style.height = this.windowHeight+'px';
|
|
311
|
-
this._overlay.style.left = -1 * overlayOffset.left+'px';
|
|
312
|
-
this._overlay.style.top = -1 * overlayOffset.top+'px';
|
|
313
|
-
anim.remove(this.el);
|
|
314
|
-
anim.remove(this._overlay);
|
|
315
|
-
// Animate Overlay
|
|
316
|
-
anim({
|
|
317
|
-
targets: this._overlay,
|
|
318
|
-
opacity: 1,
|
|
319
|
-
duration: this.options.inDuration,
|
|
320
|
-
easing: 'easeOutQuad'
|
|
321
|
-
});
|
|
322
|
-
// Add and animate caption if it exists
|
|
323
|
-
if (this.caption !== '') {
|
|
324
|
-
if (this._photoCaption) anim.remove(this._photoCaption);
|
|
325
|
-
this._photoCaption = document.createElement('div');
|
|
326
|
-
this._photoCaption.classList.add('materialbox-caption');
|
|
327
|
-
this._photoCaption.innerText = this.caption;
|
|
328
|
-
document.body.append(this._photoCaption);
|
|
329
|
-
this._photoCaption.style.display = 'inline';
|
|
330
|
-
anim({
|
|
331
|
-
targets: this._photoCaption,
|
|
332
|
-
opacity: 1,
|
|
333
|
-
duration: this.options.inDuration,
|
|
334
|
-
easing: 'easeOutQuad'
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Resize Image
|
|
339
|
-
const widthPercent = this.originalWidth / this.windowWidth;
|
|
340
|
-
const heightPercent = this.originalHeight / this.windowHeight;
|
|
341
|
-
this.newWidth = 0;
|
|
342
|
-
this.newHeight = 0;
|
|
343
|
-
if (widthPercent > heightPercent) {
|
|
344
|
-
// Width first
|
|
345
|
-
const ratio = this.originalHeight / this.originalWidth;
|
|
346
|
-
this.newWidth = this.windowWidth * 0.9;
|
|
347
|
-
this.newHeight = this.windowWidth * 0.9 * ratio;
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
// Height first
|
|
351
|
-
const ratio = this.originalWidth / this.originalHeight;
|
|
352
|
-
this.newWidth = this.windowHeight * 0.9 * ratio;
|
|
353
|
-
this.newHeight = this.windowHeight * 0.9;
|
|
354
|
-
}
|
|
355
|
-
this._animateImageIn();
|
|
356
|
-
|
|
357
|
-
// Handle Exit triggers
|
|
358
|
-
window.addEventListener('scroll', this._handleWindowScroll);
|
|
359
|
-
window.addEventListener('resize', this._handleWindowResize);
|
|
360
|
-
window.addEventListener('keyup', this._handleWindowEscape);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Close materialbox.
|
|
365
|
-
*/
|
|
366
|
-
close = () => {
|
|
367
|
-
this._updateVars();
|
|
368
|
-
this.doneAnimating = false;
|
|
369
|
-
// onCloseStart callback
|
|
370
|
-
if (typeof this.options.onCloseStart === 'function') {
|
|
371
|
-
this.options.onCloseStart.call(this, this.el);
|
|
372
|
-
}
|
|
373
|
-
anim.remove(this.el);
|
|
374
|
-
anim.remove(this._overlay);
|
|
375
|
-
if (this.caption !== '') anim.remove(this._photoCaption);
|
|
376
|
-
// disable exit handlers
|
|
377
|
-
window.removeEventListener('scroll', this._handleWindowScroll);
|
|
378
|
-
window.removeEventListener('resize', this._handleWindowResize);
|
|
379
|
-
window.removeEventListener('keyup', this._handleWindowEscape);
|
|
380
|
-
anim({
|
|
381
|
-
targets: this._overlay,
|
|
382
|
-
opacity: 0,
|
|
383
|
-
duration: this.options.outDuration,
|
|
384
|
-
easing: 'easeOutQuad',
|
|
385
|
-
complete: () => {
|
|
386
|
-
this.overlayActive = false;
|
|
387
|
-
this._overlay.remove();
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
this._animateImageOut();
|
|
391
|
-
// Remove Caption + reset css settings on image
|
|
392
|
-
if (this.caption !== '') {
|
|
393
|
-
anim({
|
|
394
|
-
targets: this._photoCaption,
|
|
395
|
-
opacity: 0,
|
|
396
|
-
duration: this.options.outDuration,
|
|
397
|
-
easing: 'easeOutQuad',
|
|
398
|
-
complete: () => {
|
|
399
|
-
this._photoCaption.remove();
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|