@materializecss/materialize 2.0.0-alpha → 2.0.2-alpha
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/Gruntfile.js +7 -4
- package/README.md +24 -12
- package/dist/css/materialize.css +90 -86
- package/dist/css/materialize.min.css +2 -2
- package/dist/js/materialize.js +2869 -2764
- package/dist/js/materialize.min.js +2 -2
- package/dist/js/materialize.min.js.map +1 -1
- package/package.json +1 -1
- package/sass/components/_collapsible.scss +0 -41
- package/sass/components/_global.scss +3 -2
- package/sass/components/_icons-material-design.scss +2 -1
- package/sass/components/_navbar.scss +6 -3
- package/sass/components/_sidenav.scss +66 -37
- package/sass/components/_theme_variables.scss +98 -0
- package/sass/components/_typography.scss +2 -2
- package/sass/components/forms/_input-fields.scss +4 -10
- package/sass/materialize.scss +0 -4
- package/src/autocomplete.ts +188 -94
- package/src/buttons.ts +225 -260
- package/src/cards.ts +5 -6
- package/src/carousel.ts +611 -542
- package/src/characterCounter.ts +50 -21
- package/src/chips.ts +152 -63
- package/src/collapsible.ts +97 -32
- package/src/component.ts +99 -10
- package/src/datepicker.ts +905 -726
- package/src/dropdown.ts +576 -484
- package/src/edges.ts +4 -4
- package/src/forms.ts +17 -14
- package/src/global.ts +56 -325
- package/src/materialbox.ts +354 -298
- package/src/modal.ts +296 -211
- package/src/parallax.ts +129 -105
- package/src/pushpin.ts +148 -103
- package/src/range.ts +166 -150
- package/src/scrollspy.ts +214 -174
- package/src/select.ts +434 -398
- package/src/sidenav.ts +447 -381
- package/src/slider.ts +421 -362
- package/src/tabs.ts +284 -227
- package/src/tapTarget.ts +246 -213
- package/src/timepicker.ts +738 -614
- package/src/toasts.ts +254 -230
- package/src/tooltip.ts +315 -252
- package/src/utils.ts +271 -0
- package/src/waves.ts +10 -10
package/src/sidenav.ts
CHANGED
|
@@ -1,8 +1,58 @@
|
|
|
1
|
-
import { Component } from "./component";
|
|
2
|
-
import { M } from "./global";
|
|
3
1
|
import anim from "animejs";
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
import { Utils } from "./utils";
|
|
4
|
+
import { Component, BaseOptions, InitElements, MElement, Openable } from "./component";
|
|
5
|
+
|
|
6
|
+
export interface SidenavOptions extends BaseOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Side of screen on which Sidenav appears.
|
|
9
|
+
* @default 'left'
|
|
10
|
+
*/
|
|
11
|
+
edge: 'left' | 'right';
|
|
12
|
+
/**
|
|
13
|
+
* Allow swipe gestures to open/close Sidenav.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
draggable: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Width of the area where you can start dragging.
|
|
19
|
+
* @default '10px'
|
|
20
|
+
*/
|
|
21
|
+
dragTargetWidth: string;
|
|
22
|
+
/**
|
|
23
|
+
* Length in ms of enter transition.
|
|
24
|
+
* @default 250
|
|
25
|
+
*/
|
|
26
|
+
inDuration: number;
|
|
27
|
+
/**
|
|
28
|
+
* Length in ms of exit transition.
|
|
29
|
+
* @default 200
|
|
30
|
+
*/
|
|
31
|
+
outDuration: number;
|
|
32
|
+
/**
|
|
33
|
+
* Prevent page from scrolling while sidenav is open.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
preventScrolling: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Function called when sidenav starts entering.
|
|
39
|
+
*/
|
|
40
|
+
onOpenStart: (elem: HTMLElement) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Function called when sidenav finishes entering.
|
|
43
|
+
*/
|
|
44
|
+
onOpenEnd: (elem: HTMLElement) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Function called when sidenav starts exiting.
|
|
47
|
+
*/
|
|
48
|
+
onCloseStart: (elem: HTMLElement) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Function called when sidenav finishes exiting.
|
|
51
|
+
*/
|
|
52
|
+
onCloseEnd: (elem: HTMLElement) => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const _defaults: SidenavOptions = {
|
|
6
56
|
edge: 'left',
|
|
7
57
|
draggable: true,
|
|
8
58
|
dragTargetWidth: '10px',
|
|
@@ -15,169 +65,230 @@ const _defaults = {
|
|
|
15
65
|
preventScrolling: true
|
|
16
66
|
};
|
|
17
67
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
export class Sidenav extends Component<SidenavOptions> implements Openable {
|
|
69
|
+
id: string;
|
|
70
|
+
/** Describes open/close state of Sidenav. */
|
|
71
|
+
isOpen: boolean;
|
|
72
|
+
/** Describes if sidenav is fixed. */
|
|
73
|
+
isFixed: boolean;
|
|
74
|
+
/** Describes if Sidenav is being dragged. */
|
|
75
|
+
isDragged: boolean;
|
|
76
|
+
lastWindowWidth: number;
|
|
77
|
+
lastWindowHeight: number;
|
|
78
|
+
static _sidenavs: Sidenav[];
|
|
79
|
+
private _overlay: HTMLElement;
|
|
80
|
+
dragTarget: Element;
|
|
81
|
+
private _startingXpos: number;
|
|
82
|
+
private _xPos: number;
|
|
83
|
+
private _time: number;
|
|
84
|
+
private _width: number;
|
|
85
|
+
private _initialScrollTop: number;
|
|
86
|
+
private _verticallyScrolling: boolean;
|
|
87
|
+
private deltaX: number;
|
|
88
|
+
private velocityX: number;
|
|
89
|
+
private percentOpen: number;
|
|
90
|
+
|
|
91
|
+
constructor(el: HTMLElement, options: Partial<SidenavOptions>) {
|
|
92
|
+
super(el, options, Sidenav);
|
|
93
|
+
(this.el as any).M_Sidenav = this;
|
|
94
|
+
|
|
95
|
+
this.options = {
|
|
96
|
+
...Sidenav.defaults,
|
|
97
|
+
...options
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
this.id = this.el.id;
|
|
101
|
+
this.isOpen = false;
|
|
102
|
+
this.isFixed = this.el.classList.contains('sidenav-fixed');
|
|
103
|
+
this.isDragged = false;
|
|
104
|
+
// Window size variables for window resize checks
|
|
105
|
+
this.lastWindowWidth = window.innerWidth;
|
|
106
|
+
this.lastWindowHeight = window.innerHeight;
|
|
107
|
+
this._createOverlay();
|
|
108
|
+
this._createDragTarget();
|
|
109
|
+
this._setupEventHandlers();
|
|
110
|
+
this._setupClasses();
|
|
111
|
+
this._setupFixed();
|
|
112
|
+
Sidenav._sidenavs.push(this);
|
|
113
|
+
}
|
|
63
114
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
115
|
+
static get defaults(): SidenavOptions {
|
|
116
|
+
return _defaults;
|
|
117
|
+
}
|
|
67
118
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Initializes instance of Sidenav.
|
|
121
|
+
* @param el HTML element.
|
|
122
|
+
* @param options Component options.
|
|
123
|
+
*/
|
|
124
|
+
static init(el: HTMLElement, options?: Partial<SidenavOptions>): Sidenav;
|
|
125
|
+
/**
|
|
126
|
+
* Initializes instances of Sidenav.
|
|
127
|
+
* @param els HTML elements.
|
|
128
|
+
* @param options Component options.
|
|
129
|
+
*/
|
|
130
|
+
static init(els: InitElements<MElement>, options?: Partial<SidenavOptions>): Sidenav[];
|
|
131
|
+
/**
|
|
132
|
+
* Initializes instances of Sidenav.
|
|
133
|
+
* @param els HTML elements.
|
|
134
|
+
* @param options Component options.
|
|
135
|
+
*/
|
|
136
|
+
static init(els: HTMLElement | InitElements<MElement>, options: Partial<SidenavOptions> = {}): Sidenav | Sidenav[] {
|
|
137
|
+
return super.init(els, options, Sidenav);
|
|
138
|
+
}
|
|
71
139
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
140
|
+
static getInstance(el: HTMLElement): Sidenav {
|
|
141
|
+
return (el as any).M_Sidenav;
|
|
142
|
+
}
|
|
76
143
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
144
|
+
destroy() {
|
|
145
|
+
this._removeEventHandlers();
|
|
146
|
+
this._enableBodyScrolling();
|
|
147
|
+
this._overlay.parentNode.removeChild(this._overlay);
|
|
148
|
+
this.dragTarget.parentNode.removeChild(this.dragTarget);
|
|
149
|
+
(this.el as any).M_Sidenav = undefined;
|
|
150
|
+
(this.el as HTMLElement).style.transform = '';
|
|
151
|
+
const index = Sidenav._sidenavs.indexOf(this);
|
|
152
|
+
if (index >= 0) {
|
|
153
|
+
Sidenav._sidenavs.splice(index, 1);
|
|
88
154
|
}
|
|
155
|
+
}
|
|
89
156
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
157
|
+
_createOverlay() {
|
|
158
|
+
this._overlay = document.createElement('div');
|
|
159
|
+
this._overlay.classList.add('sidenav-overlay');
|
|
160
|
+
this._overlay.addEventListener('click', this.close);
|
|
161
|
+
document.body.appendChild(this._overlay);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
_setupEventHandlers() {
|
|
165
|
+
if (Sidenav._sidenavs.length === 0) {
|
|
166
|
+
document.body.addEventListener('click', this._handleTriggerClick);
|
|
167
|
+
}
|
|
168
|
+
var passiveIfSupported: boolean = null;
|
|
169
|
+
this.dragTarget.addEventListener('touchmove', this._handleDragTargetDrag, passiveIfSupported);
|
|
170
|
+
this.dragTarget.addEventListener('touchend', this._handleDragTargetRelease);
|
|
171
|
+
this._overlay.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported);
|
|
172
|
+
this._overlay.addEventListener('touchend', this._handleCloseRelease);
|
|
173
|
+
this.el.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported);
|
|
174
|
+
this.el.addEventListener('touchend', this._handleCloseRelease);
|
|
175
|
+
this.el.addEventListener('click', this._handleCloseTriggerClick);
|
|
176
|
+
// Add resize for side nav fixed
|
|
177
|
+
if (this.isFixed) {
|
|
178
|
+
window.addEventListener('resize', this._handleWindowResize);
|
|
96
179
|
}
|
|
180
|
+
}
|
|
97
181
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
this._handleDragTargetDragBound = this._handleDragTargetDrag.bind(this);
|
|
103
|
-
this._handleDragTargetReleaseBound = this._handleDragTargetRelease.bind(this);
|
|
104
|
-
this._handleCloseDragBound = this._handleCloseDrag.bind(this);
|
|
105
|
-
this._handleCloseReleaseBound = this._handleCloseRelease.bind(this);
|
|
106
|
-
this._handleCloseTriggerClickBound = this._handleCloseTriggerClick.bind(this);
|
|
107
|
-
var passiveIfSupported: boolean = null;
|
|
108
|
-
this.dragTarget.addEventListener('touchmove', this._handleDragTargetDragBound, passiveIfSupported);
|
|
109
|
-
this.dragTarget.addEventListener('touchend', this._handleDragTargetReleaseBound);
|
|
110
|
-
this._overlay.addEventListener('touchmove', this._handleCloseDragBound, passiveIfSupported);
|
|
111
|
-
this._overlay.addEventListener('touchend', this._handleCloseReleaseBound);
|
|
112
|
-
this.el.addEventListener('touchmove', this._handleCloseDragBound, passiveIfSupported);
|
|
113
|
-
this.el.addEventListener('touchend', this._handleCloseReleaseBound);
|
|
114
|
-
this.el.addEventListener('click', this._handleCloseTriggerClickBound);
|
|
115
|
-
// Add resize for side nav fixed
|
|
116
|
-
if (this.isFixed) {
|
|
117
|
-
this._handleWindowResizeBound = this._handleWindowResize.bind(this);
|
|
118
|
-
window.addEventListener('resize', this._handleWindowResizeBound);
|
|
119
|
-
}
|
|
182
|
+
_removeEventHandlers() {
|
|
183
|
+
if (Sidenav._sidenavs.length === 1) {
|
|
184
|
+
document.body.removeEventListener('click', this._handleTriggerClick);
|
|
120
185
|
}
|
|
186
|
+
this.dragTarget.removeEventListener('touchmove', this._handleDragTargetDrag);
|
|
187
|
+
this.dragTarget.removeEventListener('touchend', this._handleDragTargetRelease);
|
|
188
|
+
this._overlay.removeEventListener('touchmove', this._handleCloseDrag);
|
|
189
|
+
this._overlay.removeEventListener('touchend', this._handleCloseRelease);
|
|
190
|
+
this.el.removeEventListener('touchmove', this._handleCloseDrag);
|
|
191
|
+
this.el.removeEventListener('touchend', this._handleCloseRelease);
|
|
192
|
+
this.el.removeEventListener('click', this._handleCloseTriggerClick);
|
|
121
193
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
this.dragTarget.removeEventListener('touchmove', this._handleDragTargetDragBound);
|
|
127
|
-
this.dragTarget.removeEventListener('touchend', this._handleDragTargetReleaseBound);
|
|
128
|
-
this._overlay.removeEventListener('touchmove', this._handleCloseDragBound);
|
|
129
|
-
this._overlay.removeEventListener('touchend', this._handleCloseReleaseBound);
|
|
130
|
-
this.el.removeEventListener('touchmove', this._handleCloseDragBound);
|
|
131
|
-
this.el.removeEventListener('touchend', this._handleCloseReleaseBound);
|
|
132
|
-
this.el.removeEventListener('click', this._handleCloseTriggerClickBound);
|
|
133
|
-
|
|
134
|
-
// Remove resize for side nav fixed
|
|
135
|
-
if (this.isFixed) {
|
|
136
|
-
window.removeEventListener('resize', this._handleWindowResizeBound);
|
|
137
|
-
}
|
|
194
|
+
// Remove resize for side nav fixed
|
|
195
|
+
if (this.isFixed) {
|
|
196
|
+
window.removeEventListener('resize', this._handleWindowResize);
|
|
138
197
|
}
|
|
198
|
+
}
|
|
139
199
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
e.preventDefault();
|
|
200
|
+
_handleTriggerClick(e) {
|
|
201
|
+
const trigger = e.target.closest('.sidenav-trigger');
|
|
202
|
+
if (e.target && trigger) {
|
|
203
|
+
const sidenavId = Utils.getIdFromTrigger(trigger);
|
|
204
|
+
const sidenavInstance = (document.getElementById(sidenavId) as any).M_Sidenav;
|
|
205
|
+
if (sidenavInstance) {
|
|
206
|
+
sidenavInstance.open(trigger);
|
|
149
207
|
}
|
|
208
|
+
e.preventDefault();
|
|
150
209
|
}
|
|
210
|
+
}
|
|
151
211
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
212
|
+
// Set variables needed at the beginning of drag and stop any current transition.
|
|
213
|
+
_startDrag(e) {
|
|
214
|
+
const clientX = e.targetTouches[0].clientX;
|
|
215
|
+
this.isDragged = true;
|
|
216
|
+
this._startingXpos = clientX;
|
|
217
|
+
this._xPos = this._startingXpos;
|
|
218
|
+
this._time = Date.now();
|
|
219
|
+
this._width = this.el.getBoundingClientRect().width;
|
|
220
|
+
this._overlay.style.display = 'block';
|
|
221
|
+
this._initialScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop();
|
|
222
|
+
this._verticallyScrolling = false;
|
|
223
|
+
anim.remove(this.el);
|
|
224
|
+
anim.remove(this._overlay);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
//Set variables needed at each drag move update tick
|
|
228
|
+
_dragMoveUpdate(e) {
|
|
229
|
+
const clientX = e.targetTouches[0].clientX;
|
|
230
|
+
const currentScrollTop = this.isOpen ? this.el.scrollTop : Utils.getDocumentScrollTop();
|
|
231
|
+
this.deltaX = Math.abs(this._xPos - clientX);
|
|
232
|
+
this._xPos = clientX;
|
|
233
|
+
this.velocityX = this.deltaX / (Date.now() - this._time);
|
|
234
|
+
this._time = Date.now();
|
|
235
|
+
if (this._initialScrollTop !== currentScrollTop) {
|
|
236
|
+
this._verticallyScrolling = true;
|
|
165
237
|
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
_handleDragTargetDrag = (e) => {
|
|
241
|
+
// Check if draggable
|
|
242
|
+
if (!this.options.draggable || this._isCurrentlyFixed() || this._verticallyScrolling) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
// If not being dragged, set initial drag start variables
|
|
246
|
+
if (!this.isDragged) {
|
|
247
|
+
this._startDrag(e);
|
|
248
|
+
}
|
|
249
|
+
// Run touchmove updates
|
|
250
|
+
this._dragMoveUpdate(e);
|
|
251
|
+
// Calculate raw deltaX
|
|
252
|
+
let totalDeltaX = this._xPos - this._startingXpos;
|
|
253
|
+
// dragDirection is the attempted user drag direction
|
|
254
|
+
const dragDirection = totalDeltaX > 0 ? 'right' : 'left';
|
|
255
|
+
// Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction
|
|
256
|
+
totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX));
|
|
257
|
+
if (this.options.edge === dragDirection) {
|
|
258
|
+
totalDeltaX = 0;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* transformX is the drag displacement
|
|
262
|
+
* transformPrefix is the initial transform placement
|
|
263
|
+
* Invert values if Sidenav is right edge
|
|
264
|
+
*/
|
|
265
|
+
let transformX = totalDeltaX;
|
|
266
|
+
let transformPrefix = 'translateX(-100%)';
|
|
267
|
+
if (this.options.edge === 'right') {
|
|
268
|
+
transformPrefix = 'translateX(100%)';
|
|
269
|
+
transformX = -transformX;
|
|
270
|
+
}
|
|
271
|
+
// Calculate open/close percentage of sidenav, with open = 1 and close = 0
|
|
272
|
+
this.percentOpen = Math.min(1, totalDeltaX / this._width);
|
|
273
|
+
// Set transform and opacity styles
|
|
274
|
+
(this.el as HTMLElement).style.transform = `${transformPrefix} translateX(${transformX}px)`;
|
|
275
|
+
this._overlay.style.opacity = this.percentOpen.toString();
|
|
276
|
+
}
|
|
166
277
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.velocityX = this.deltaX / (Date.now() - this._time);
|
|
174
|
-
this._time = Date.now();
|
|
175
|
-
if (this._initialScrollTop !== currentScrollTop) {
|
|
176
|
-
this._verticallyScrolling = true;
|
|
278
|
+
_handleDragTargetRelease = () => {
|
|
279
|
+
if (this.isDragged) {
|
|
280
|
+
if (this.percentOpen > 0.2) {
|
|
281
|
+
this.open();
|
|
282
|
+
} else {
|
|
283
|
+
this._animateOut();
|
|
177
284
|
}
|
|
285
|
+
this.isDragged = false;
|
|
286
|
+
this._verticallyScrolling = false;
|
|
178
287
|
}
|
|
288
|
+
}
|
|
179
289
|
|
|
180
|
-
|
|
290
|
+
_handleCloseDrag = (e) => {
|
|
291
|
+
if (this.isOpen) {
|
|
181
292
|
// Check if draggable
|
|
182
293
|
if (!this.options.draggable || this._isCurrentlyFixed() || this._verticallyScrolling) {
|
|
183
294
|
return;
|
|
@@ -191,287 +302,242 @@ const _defaults = {
|
|
|
191
302
|
// Calculate raw deltaX
|
|
192
303
|
let totalDeltaX = this._xPos - this._startingXpos;
|
|
193
304
|
// dragDirection is the attempted user drag direction
|
|
194
|
-
|
|
305
|
+
let dragDirection = totalDeltaX > 0 ? 'right' : 'left';
|
|
195
306
|
// Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction
|
|
196
307
|
totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX));
|
|
197
|
-
if (this.options.edge
|
|
308
|
+
if (this.options.edge !== dragDirection) {
|
|
198
309
|
totalDeltaX = 0;
|
|
199
310
|
}
|
|
200
|
-
|
|
201
|
-
* transformX is the drag displacement
|
|
202
|
-
* transformPrefix is the initial transform placement
|
|
203
|
-
* Invert values if Sidenav is right edge
|
|
204
|
-
*/
|
|
205
|
-
let transformX = totalDeltaX;
|
|
206
|
-
let transformPrefix = 'translateX(-100%)';
|
|
311
|
+
let transformX = -totalDeltaX;
|
|
207
312
|
if (this.options.edge === 'right') {
|
|
208
|
-
transformPrefix = 'translateX(100%)';
|
|
209
313
|
transformX = -transformX;
|
|
210
314
|
}
|
|
211
315
|
// Calculate open/close percentage of sidenav, with open = 1 and close = 0
|
|
212
|
-
this.percentOpen = Math.min(1, totalDeltaX / this._width);
|
|
316
|
+
this.percentOpen = Math.min(1, 1 - totalDeltaX / this._width);
|
|
213
317
|
// Set transform and opacity styles
|
|
214
|
-
(this.el as HTMLElement).style.transform =
|
|
318
|
+
(this.el as HTMLElement).style.transform = `translateX(${transformX}px)`;
|
|
215
319
|
this._overlay.style.opacity = this.percentOpen.toString();
|
|
216
320
|
}
|
|
321
|
+
}
|
|
217
322
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
this.isDragged = false;
|
|
226
|
-
this._verticallyScrolling = false;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
_handleCloseDrag(e) {
|
|
231
|
-
if (this.isOpen) {
|
|
232
|
-
// Check if draggable
|
|
233
|
-
if (!this.options.draggable || this._isCurrentlyFixed() || this._verticallyScrolling) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
// If not being dragged, set initial drag start variables
|
|
237
|
-
if (!this.isDragged) {
|
|
238
|
-
this._startDrag(e);
|
|
239
|
-
}
|
|
240
|
-
// Run touchmove updates
|
|
241
|
-
this._dragMoveUpdate(e);
|
|
242
|
-
// Calculate raw deltaX
|
|
243
|
-
let totalDeltaX = this._xPos - this._startingXpos;
|
|
244
|
-
// dragDirection is the attempted user drag direction
|
|
245
|
-
let dragDirection = totalDeltaX > 0 ? 'right' : 'left';
|
|
246
|
-
// Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction
|
|
247
|
-
totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX));
|
|
248
|
-
if (this.options.edge !== dragDirection) {
|
|
249
|
-
totalDeltaX = 0;
|
|
250
|
-
}
|
|
251
|
-
let transformX = -totalDeltaX;
|
|
252
|
-
if (this.options.edge === 'right') {
|
|
253
|
-
transformX = -transformX;
|
|
254
|
-
}
|
|
255
|
-
// Calculate open/close percentage of sidenav, with open = 1 and close = 0
|
|
256
|
-
this.percentOpen = Math.min(1, 1 - totalDeltaX / this._width);
|
|
257
|
-
// Set transform and opacity styles
|
|
258
|
-
(this.el as HTMLElement).style.transform = `translateX(${transformX}px)`;
|
|
259
|
-
this._overlay.style.opacity = this.percentOpen.toString();
|
|
323
|
+
_handleCloseRelease = () => {
|
|
324
|
+
if (this.isOpen && this.isDragged) {
|
|
325
|
+
if (this.percentOpen > 0.8) {
|
|
326
|
+
this._animateIn();
|
|
327
|
+
} else {
|
|
328
|
+
this.close();
|
|
260
329
|
}
|
|
330
|
+
this.isDragged = false;
|
|
331
|
+
this._verticallyScrolling = false;
|
|
261
332
|
}
|
|
333
|
+
}
|
|
262
334
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
this.close();
|
|
269
|
-
}
|
|
270
|
-
this.isDragged = false;
|
|
271
|
-
this._verticallyScrolling = false;
|
|
272
|
-
}
|
|
335
|
+
// Handles closing of Sidenav when element with class .sidenav-close
|
|
336
|
+
_handleCloseTriggerClick = (e) => {
|
|
337
|
+
const closeTrigger = e.target.closest('.sidenav-close');
|
|
338
|
+
if (closeTrigger && !this._isCurrentlyFixed()) {
|
|
339
|
+
this.close();
|
|
273
340
|
}
|
|
341
|
+
}
|
|
274
342
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (
|
|
343
|
+
_handleWindowResize = () => {
|
|
344
|
+
// Only handle horizontal resizes
|
|
345
|
+
if (this.lastWindowWidth !== window.innerWidth) {
|
|
346
|
+
if (window.innerWidth > 992) {
|
|
347
|
+
this.open();
|
|
348
|
+
} else {
|
|
279
349
|
this.close();
|
|
280
350
|
}
|
|
281
351
|
}
|
|
352
|
+
this.lastWindowWidth = window.innerWidth;
|
|
353
|
+
this.lastWindowHeight = window.innerHeight;
|
|
354
|
+
}
|
|
282
355
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
this.open();
|
|
288
|
-
} else {
|
|
289
|
-
this.close();
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
this.lastWindowWidth = window.innerWidth;
|
|
293
|
-
this.lastWindowHeight = window.innerHeight;
|
|
356
|
+
_setupClasses() {
|
|
357
|
+
if (this.options.edge === 'right') {
|
|
358
|
+
this.el.classList.add('right-aligned');
|
|
359
|
+
this.dragTarget.classList.add('right-aligned');
|
|
294
360
|
}
|
|
361
|
+
}
|
|
295
362
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
}
|
|
363
|
+
_removeClasses() {
|
|
364
|
+
this.el.classList.remove('right-aligned');
|
|
365
|
+
this.dragTarget.classList.remove('right-aligned');
|
|
366
|
+
}
|
|
302
367
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
368
|
+
_setupFixed() {
|
|
369
|
+
if (this._isCurrentlyFixed()) this.open();
|
|
370
|
+
}
|
|
307
371
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
372
|
+
_isCurrentlyFixed() {
|
|
373
|
+
return this.isFixed && window.innerWidth > 992;
|
|
374
|
+
}
|
|
311
375
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
376
|
+
_createDragTarget() {
|
|
377
|
+
const dragTarget = document.createElement('div');
|
|
378
|
+
dragTarget.classList.add('drag-target');
|
|
379
|
+
dragTarget.style.width = this.options.dragTargetWidth;
|
|
380
|
+
document.body.appendChild(dragTarget);
|
|
381
|
+
this.dragTarget = dragTarget;
|
|
382
|
+
}
|
|
315
383
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
dragTarget.style.width = this.options.dragTargetWidth;
|
|
320
|
-
document.body.appendChild(dragTarget);
|
|
321
|
-
this.dragTarget = dragTarget;
|
|
322
|
-
}
|
|
384
|
+
_preventBodyScrolling() {
|
|
385
|
+
document.body.style.overflow = 'hidden';
|
|
386
|
+
}
|
|
323
387
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
388
|
+
_enableBodyScrolling() {
|
|
389
|
+
document.body.style.overflow = '';
|
|
390
|
+
}
|
|
327
391
|
|
|
328
|
-
|
|
329
|
-
|
|
392
|
+
/**
|
|
393
|
+
* Opens Sidenav.
|
|
394
|
+
*/
|
|
395
|
+
open = () => {
|
|
396
|
+
if (this.isOpen === true) return;
|
|
397
|
+
this.isOpen = true;
|
|
398
|
+
// Run onOpenStart callback
|
|
399
|
+
if (typeof this.options.onOpenStart === 'function') {
|
|
400
|
+
this.options.onOpenStart.call(this, this.el);
|
|
401
|
+
}
|
|
402
|
+
// Handle fixed Sidenav
|
|
403
|
+
if (this._isCurrentlyFixed()) {
|
|
404
|
+
anim.remove(this.el);
|
|
405
|
+
anim({
|
|
406
|
+
targets: this.el,
|
|
407
|
+
translateX: 0,
|
|
408
|
+
duration: 0,
|
|
409
|
+
easing: 'easeOutQuad'
|
|
410
|
+
});
|
|
411
|
+
this._enableBodyScrolling();
|
|
412
|
+
this._overlay.style.display = 'none';
|
|
330
413
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (this.
|
|
334
|
-
|
|
335
|
-
// Run onOpenStart callback
|
|
336
|
-
if (typeof this.options.onOpenStart === 'function') {
|
|
337
|
-
this.options.onOpenStart.call(this, this.el);
|
|
338
|
-
}
|
|
339
|
-
// Handle fixed Sidenav
|
|
340
|
-
if (this._isCurrentlyFixed()) {
|
|
341
|
-
anim.remove(this.el);
|
|
342
|
-
anim({
|
|
343
|
-
targets: this.el,
|
|
344
|
-
translateX: 0,
|
|
345
|
-
duration: 0,
|
|
346
|
-
easing: 'easeOutQuad'
|
|
347
|
-
});
|
|
348
|
-
this._enableBodyScrolling();
|
|
349
|
-
this._overlay.style.display = 'none';
|
|
414
|
+
// Handle non-fixed Sidenav
|
|
415
|
+
else {
|
|
416
|
+
if (this.options.preventScrolling) {
|
|
417
|
+
this._preventBodyScrolling();
|
|
350
418
|
}
|
|
351
|
-
// Handle non-fixed Sidenav
|
|
352
|
-
else {
|
|
353
|
-
if (this.options.preventScrolling) {
|
|
354
|
-
this._preventBodyScrolling();
|
|
355
|
-
}
|
|
356
419
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
420
|
+
if (!this.isDragged || this.percentOpen != 1) {
|
|
421
|
+
this._animateIn();
|
|
360
422
|
}
|
|
361
423
|
}
|
|
424
|
+
}
|
|
362
425
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
426
|
+
/**
|
|
427
|
+
* Closes Sidenav.
|
|
428
|
+
*/
|
|
429
|
+
close = () => {
|
|
430
|
+
if (this.isOpen === false) return;
|
|
431
|
+
this.isOpen = false;
|
|
432
|
+
// Run onCloseStart callback
|
|
433
|
+
if (typeof this.options.onCloseStart === 'function') {
|
|
434
|
+
this.options.onCloseStart.call(this, this.el);
|
|
435
|
+
}
|
|
436
|
+
// Handle fixed Sidenav
|
|
437
|
+
if (this._isCurrentlyFixed()) {
|
|
438
|
+
const transformX = this.options.edge === 'left' ? '-105%' : '105%';
|
|
439
|
+
(this.el as HTMLElement).style.transform = `translateX(${transformX})`;
|
|
440
|
+
}
|
|
441
|
+
// Handle non-fixed Sidenav
|
|
442
|
+
else {
|
|
443
|
+
this._enableBodyScrolling();
|
|
444
|
+
if (!this.isDragged || this.percentOpen != 0) {
|
|
445
|
+
this._animateOut();
|
|
446
|
+
} else {
|
|
447
|
+
this._overlay.style.display = 'none';
|
|
383
448
|
}
|
|
384
449
|
}
|
|
450
|
+
}
|
|
385
451
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
452
|
+
_animateIn() {
|
|
453
|
+
this._animateSidenavIn();
|
|
454
|
+
this._animateOverlayIn();
|
|
455
|
+
}
|
|
390
456
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
457
|
+
_animateSidenavIn() {
|
|
458
|
+
let slideOutPercent = this.options.edge === 'left' ? -1 : 1;
|
|
459
|
+
if (this.isDragged) {
|
|
460
|
+
slideOutPercent =
|
|
461
|
+
this.options.edge === 'left'
|
|
462
|
+
? slideOutPercent + this.percentOpen
|
|
463
|
+
: slideOutPercent - this.percentOpen;
|
|
464
|
+
}
|
|
465
|
+
anim.remove(this.el);
|
|
466
|
+
anim({
|
|
467
|
+
targets: this.el,
|
|
468
|
+
translateX: [`${slideOutPercent * 100}%`, 0],
|
|
469
|
+
duration: this.options.inDuration,
|
|
470
|
+
easing: 'easeOutQuad',
|
|
471
|
+
complete: () => {
|
|
472
|
+
// Run onOpenEnd callback
|
|
473
|
+
if (typeof this.options.onOpenEnd === 'function') {
|
|
474
|
+
this.options.onOpenEnd.call(this, this.el);
|
|
410
475
|
}
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
_animateOverlayIn() {
|
|
415
|
-
let start = 0;
|
|
416
|
-
if (this.isDragged) {
|
|
417
|
-
start = this.percentOpen;
|
|
418
476
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
anim.remove(this._overlay);
|
|
423
|
-
anim({
|
|
424
|
-
targets: this._overlay,
|
|
425
|
-
opacity: [start, 1],
|
|
426
|
-
duration: this.options.inDuration,
|
|
427
|
-
easing: 'easeOutQuad'
|
|
428
|
-
});
|
|
429
|
-
}
|
|
477
|
+
});
|
|
478
|
+
}
|
|
430
479
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
480
|
+
_animateOverlayIn() {
|
|
481
|
+
let start = 0;
|
|
482
|
+
if (this.isDragged) {
|
|
483
|
+
start = this.percentOpen;
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
this._overlay.style.display = 'block';
|
|
434
487
|
}
|
|
488
|
+
anim.remove(this._overlay);
|
|
489
|
+
anim({
|
|
490
|
+
targets: this._overlay,
|
|
491
|
+
opacity: [start, 1],
|
|
492
|
+
duration: this.options.inDuration,
|
|
493
|
+
easing: 'easeOutQuad'
|
|
494
|
+
});
|
|
495
|
+
}
|
|
435
496
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
slideOutPercent =
|
|
441
|
-
this.options.edge === 'left'
|
|
442
|
-
? endPercent + this.percentOpen
|
|
443
|
-
: endPercent - this.percentOpen;
|
|
444
|
-
}
|
|
497
|
+
_animateOut() {
|
|
498
|
+
this._animateSidenavOut();
|
|
499
|
+
this._animateOverlayOut();
|
|
500
|
+
}
|
|
445
501
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
502
|
+
_animateSidenavOut() {
|
|
503
|
+
const endPercent = this.options.edge === 'left' ? -1 : 1;
|
|
504
|
+
let slideOutPercent = 0;
|
|
505
|
+
if (this.isDragged) {
|
|
506
|
+
slideOutPercent =
|
|
507
|
+
this.options.edge === 'left'
|
|
508
|
+
? endPercent + this.percentOpen
|
|
509
|
+
: endPercent - this.percentOpen;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
anim.remove(this.el);
|
|
513
|
+
anim({
|
|
514
|
+
targets: this.el,
|
|
515
|
+
translateX: [`${slideOutPercent * 100}%`, `${endPercent * 105}%`],
|
|
516
|
+
duration: this.options.outDuration,
|
|
517
|
+
easing: 'easeOutQuad',
|
|
518
|
+
complete: () => {
|
|
519
|
+
// Run onOpenEnd callback
|
|
520
|
+
if (typeof this.options.onCloseEnd === 'function') {
|
|
521
|
+
this.options.onCloseEnd.call(this, this.el);
|
|
457
522
|
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
}
|
|
460
526
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
527
|
+
_animateOverlayOut() {
|
|
528
|
+
anim.remove(this._overlay);
|
|
529
|
+
anim({
|
|
530
|
+
targets: this._overlay,
|
|
531
|
+
opacity: 0,
|
|
532
|
+
duration: this.options.outDuration,
|
|
533
|
+
easing: 'easeOutQuad',
|
|
534
|
+
complete: () => {
|
|
535
|
+
this._overlay.style.display = 'none';
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
}
|
|
473
539
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
540
|
+
static {
|
|
541
|
+
Sidenav._sidenavs = [];
|
|
477
542
|
}
|
|
543
|
+
}
|