Skip to content

Commit 0013452

Browse files
committed
refactor(cards): removed jquery
1 parent 1235e32 commit 0013452

File tree

5 files changed

+102
-233
lines changed

5 files changed

+102
-233
lines changed

docs/js/materialize.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cards.ts

+30-40
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,39 @@
1-
import $ from "cash-dom";
21
import anim from "animejs";
32

43
export class Cards {
54

65
static Init() {
7-
$(document).on('click', '.card', function(e) {
8-
if ($(this).children('.card-reveal').length) {
9-
const $card = $(e.target).closest('.card');
10-
if ($card.data('initialOverflow') === undefined) {
11-
$card.data(
12-
'initialOverflow',
13-
$card.css('overflow') === undefined ? '' : $card.css('overflow')
14-
);
15-
}
16-
let $cardReveal = $(this).find('.card-reveal');
17-
if (
18-
$(e.target).is($('.card-reveal .card-title')) ||
19-
$(e.target).is($('.card-reveal .card-title i'))
20-
) {
21-
// Make Reveal animate down and display none
22-
anim({
23-
targets: $cardReveal[0],
24-
translateY: 0,
25-
duration: 225,
26-
easing: 'easeInOutQuad',
27-
complete: function(anim) {
28-
let el = anim.animatables[0].target;
29-
$(el).css({ display: 'none' });
30-
$card.css('overflow', $card.data('initialOverflow'));
31-
}
32-
});
33-
}
34-
else if ($(e.target).is($('.card .activator')) || $(e.target).is($('.card .activator i'))) {
35-
$card.css('overflow', 'hidden');
36-
$cardReveal.css({ display: 'block' });
37-
anim({
38-
targets: $cardReveal[0],
39-
translateY: '-100%',
40-
duration: 300,
41-
easing: 'easeInOutQuad'
42-
});
43-
}
44-
}
6+
document.querySelectorAll('.card').forEach((card: HTMLElement) => {
7+
const cardReveal = <HTMLElement|null>Array.from(card.children).find(elem => elem.classList.contains('card-reveal'));
8+
if (!cardReveal) return;
9+
const initialOverflow = getComputedStyle(card).overflow;
10+
// Close Card
11+
const closeArea = cardReveal.querySelector('.card-reveal .card-title');
12+
closeArea?.addEventListener('click', e => {
13+
anim({
14+
targets: cardReveal,
15+
translateY: 0,
16+
duration: 225,
17+
easing: 'easeInOutQuad',
18+
complete: (anim) => {
19+
cardReveal.style.display = 'none';
20+
card.style.overflow = initialOverflow;
21+
}
22+
});
23+
});
24+
// Reveal Card
25+
const activators = card.querySelectorAll('.activator');
26+
activators.forEach(activator => activator.addEventListener('click', e => {
27+
card.style.overflow = 'hidden';
28+
cardReveal.style.display = 'block';
29+
anim({
30+
targets: cardReveal,
31+
translateY: '-100%',
32+
duration: 300,
33+
easing: 'easeInOutQuad'
34+
});
35+
}));
4536
});
4637
}
4738
}
48-
4939

src/tapTarget.ts

+40-112
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,33 @@
11
import { Component } from "./component";
2-
import $ from "cash-dom";
32
import { M } from "./global";
3+
import $ from "cash-dom";
44

55
let _defaults = {
66
onOpen: undefined,
77
onClose: undefined
88
};
99

10-
/**
11-
* @class
12-
*
13-
*/
1410
export class TapTarget extends Component {
15-
isOpen: any;
11+
isOpen: boolean;
1612
wrapper: any;
1713
private _handleDocumentClickBound: (this: HTMLElement, ev: MouseEvent) => any;
18-
$origin: any;
14+
_origin: HTMLElement;
1915
private _handleTargetClickBound: EventListenerOrEventListenerObject;
2016
originEl: any;
2117
private _handleOriginClickBound: any;
2218
private _handleThrottledResizeBound: any;
2319
waveEl: HTMLElement & Element & Node;
2420
contentEl: any;
25-
/**
26-
* Construct TapTarget instance
27-
* @constructor
28-
* @param {Element} el
29-
* @param {Object} options
30-
*/
21+
3122
constructor(el, options) {
3223
super(TapTarget, el, options);
33-
3424
(this.el as any).M_TapTarget = this;
35-
36-
/**
37-
* Options for the select
38-
* @member TapTarget#options
39-
* @prop {Function} onOpen - Callback function called when feature discovery is opened
40-
* @prop {Function} onClose - Callback function called when feature discovery is closed
41-
*/
42-
this.options = $.extend({}, TapTarget.defaults, options);
43-
25+
this.options = {...TapTarget.defaults, ...options};
4426
this.isOpen = false;
45-
4627
// setup
47-
this.$origin = $('#' + this.$el.attr('data-target'));
28+
this._origin = document.querySelector('#'+this.el.getAttribute('data-target'));
29+
// $('#' + this.$el.attr('data-target'));
4830
this._setup();
49-
5031
this._calculatePositioning();
5132
this._setupEventHandlers();
5233
}
@@ -59,155 +40,121 @@ import { M } from "./global";
5940
return super.init(this, els, options);
6041
}
6142

62-
/**
63-
* Get Instance
64-
*/
6543
static getInstance(el) {
6644
let domElem = !!el.jquery ? el[0] : el;
6745
return domElem.M_TapTarget;
6846
}
6947

70-
/**
71-
* Teardown component
72-
*/
7348
destroy() {
7449
this._removeEventHandlers();
7550
(this.el as any).TapTarget = undefined;
7651
}
7752

78-
/**
79-
* Setup Event Handlers
80-
*/
8153
_setupEventHandlers() {
8254
this._handleDocumentClickBound = this._handleDocumentClick.bind(this);
8355
this._handleTargetClickBound = this._handleTargetClick.bind(this);
8456
this._handleOriginClickBound = this._handleOriginClick.bind(this);
85-
8657
this.el.addEventListener('click', this._handleTargetClickBound);
8758
this.originEl.addEventListener('click', this._handleOriginClickBound);
88-
8959
// Resize
9060
let throttledResize = M.throttle(this._handleResize, 200);
9161
this._handleThrottledResizeBound = throttledResize.bind(this);
92-
9362
window.addEventListener('resize', this._handleThrottledResizeBound);
9463
}
9564

96-
/**
97-
* Remove Event Handlers
98-
*/
9965
_removeEventHandlers() {
10066
this.el.removeEventListener('click', this._handleTargetClickBound);
10167
this.originEl.removeEventListener('click', this._handleOriginClickBound);
10268
window.removeEventListener('resize', this._handleThrottledResizeBound);
10369
}
10470

105-
/**
106-
* Handle Target Click
107-
* @param {Event} e
108-
*/
10971
_handleTargetClick(e) {
11072
this.open();
11173
}
11274

113-
/**
114-
* Handle Origin Click
115-
* @param {Event} e
116-
*/
11775
_handleOriginClick(e) {
11876
this.close();
11977
}
12078

121-
/**
122-
* Handle Resize
123-
* @param {Event} e
124-
*/
12579
_handleResize(e) {
12680
this._calculatePositioning();
12781
}
12882

129-
/**
130-
* Handle Resize
131-
* @param {Event} e
132-
*/
13383
_handleDocumentClick(e) {
134-
if (!$(e.target).closest('.tap-target-wrapper').length) {
84+
if (!e.target.closest('.tap-target-wrapper')) {
13585
this.close();
13686
e.preventDefault();
13787
e.stopPropagation();
13888
}
13989
}
14090

141-
/**
142-
* Setup Tap Target
143-
*/
14491
_setup() {
14592
// Creating tap target
14693
this.wrapper = this.$el.parent()[0];
14794
this.waveEl = $(this.wrapper).find('.tap-target-wave')[0];
14895
this.originEl = $(this.wrapper).find('.tap-target-origin')[0];
14996
this.contentEl = this.$el.find('.tap-target-content')[0];
150-
15197
// Creating wrapper
15298
if (!$(this.wrapper).hasClass('.tap-target-wrapper')) {
15399
this.wrapper = document.createElement('div');
154100
this.wrapper.classList.add('tap-target-wrapper');
155101
this.$el.before($(this.wrapper));
156102
this.wrapper.append(this.el);
157103
}
158-
159104
// Creating content
160105
if (!this.contentEl) {
161106
this.contentEl = document.createElement('div');
162107
this.contentEl.classList.add('tap-target-content');
163108
this.$el.append(this.contentEl);
164109
}
165-
166110
// Creating foreground wave
167111
if (!this.waveEl) {
168112
this.waveEl = document.createElement('div');
169113
this.waveEl.classList.add('tap-target-wave');
170-
171114
// Creating origin
172115
if (!this.originEl) {
173-
this.originEl = this.$origin.clone(true, true);
174-
this.originEl.addClass('tap-target-origin');
175-
this.originEl.removeAttr('id');
176-
this.originEl.removeAttr('style');
177-
this.originEl = this.originEl[0];
116+
this.originEl = this._origin.cloneNode(true); // .clone(true, true);
117+
this.originEl.classList.add('tap-target-origin');
118+
this.originEl.removeAttribute('id');
119+
this.originEl.removeAttribute('style');
120+
//this.originEl = this.originEl;
178121
this.waveEl.append(this.originEl);
179122
}
180-
181123
this.wrapper.append(this.waveEl);
182124
}
183125
}
184126

185-
/**
186-
* Calculate positioning
187-
*/
127+
private _offset(el) {
128+
const box = el.getBoundingClientRect();
129+
const docElem = document.documentElement;
130+
return {
131+
top: box.top + window.pageYOffset - docElem.clientTop,
132+
left: box.left + window.pageXOffset - docElem.clientLeft
133+
};
134+
}
135+
188136
_calculatePositioning() {
189137
// Element or parent is fixed position?
190-
let isFixed = this.$origin.css('position') === 'fixed';
191-
if (!isFixed) {
192-
let parents = this.$origin.parents();
138+
let isFixed = this._origin.style.position === 'fixed';
139+
if (!isFixed) {
140+
let currentElem: any = this._origin;
141+
const parents = [];
142+
while ((currentElem = currentElem.parentNode) && currentElem !== document)
143+
parents.push(currentElem);
193144
for (let i = 0; i < parents.length; i++) {
194-
isFixed = $(parents[i]).css('position') == 'fixed';
195-
if (isFixed) {
196-
break;
197-
}
145+
isFixed = parents[i].style.position == 'fixed';
146+
if (isFixed) break;
198147
}
199148
}
200-
201149
// Calculating origin
202-
let originWidth = this.$origin.outerWidth();
203-
let originHeight = this.$origin.outerHeight();
150+
let originWidth = this._origin.offsetWidth;
151+
let originHeight = this._origin.offsetHeight;
204152
let originTop = isFixed
205-
? this.$origin.offset().top - M.getDocumentScrollTop()
206-
: this.$origin.offset().top;
153+
? this._offset(this._origin).top - M.getDocumentScrollTop()
154+
: this._offset(this._origin).top;
207155
let originLeft = isFixed
208-
? this.$origin.offset().left - M.getDocumentScrollLeft()
209-
: this.$origin.offset().left;
210-
156+
? this._offset(this._origin).left - M.getDocumentScrollLeft()
157+
: this._offset(this._origin).left;
211158
// Calculating screen
212159
let windowWidth = window.innerWidth;
213160
let windowHeight = window.innerHeight;
@@ -219,14 +166,12 @@ import { M } from "./global";
219166
let isTop = originTop <= centerY;
220167
let isBottom = originTop > centerY;
221168
let isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75;
222-
223169
// Calculating tap target
224170
let tapTargetWidth = this.$el.outerWidth();
225171
let tapTargetHeight = this.$el.outerHeight();
226172
let tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2;
227173
let tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2;
228174
let tapTargetPosition = isFixed ? 'fixed' : 'absolute';
229-
230175
// Calculating content
231176
let tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth;
232177
let tapTargetTextHeight = tapTargetHeight / 2;
@@ -236,7 +181,6 @@ import { M } from "./global";
236181
let tapTargetTextRight = 0;
237182
let tapTargetTextPadding = originWidth;
238183
let tapTargetTextAlign = isBottom ? 'bottom' : 'top';
239-
240184
// Calculating wave
241185
let tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2;
242186
let tapTargetWaveHeight = tapTargetWaveWidth;
@@ -279,42 +223,26 @@ import { M } from "./global";
279223
});
280224
}
281225

282-
/**
283-
* Open TapTarget
284-
*/
285226
open() {
286-
if (this.isOpen) {
287-
return;
288-
}
289-
227+
if (this.isOpen) return;
290228
// onOpen callback
291229
if (typeof this.options.onOpen === 'function') {
292-
this.options.onOpen.call(this, this.$origin[0]);
230+
this.options.onOpen.call(this, this._origin);
293231
}
294-
295232
this.isOpen = true;
296233
this.wrapper.classList.add('open');
297-
298234
document.body.addEventListener('click', this._handleDocumentClickBound, true);
299235
document.body.addEventListener('touchend', this._handleDocumentClickBound);
300236
}
301237

302-
/**
303-
* Close Tap Target
304-
*/
305238
close() {
306-
if (!this.isOpen) {
307-
return;
308-
}
309-
239+
if (!this.isOpen) return;
310240
// onClose callback
311241
if (typeof this.options.onClose === 'function') {
312-
this.options.onClose.call(this, this.$origin[0]);
242+
this.options.onClose.call(this, this._origin);
313243
}
314-
315244
this.isOpen = false;
316245
this.wrapper.classList.remove('open');
317-
318246
document.body.removeEventListener('click', this._handleDocumentClickBound, true);
319247
document.body.removeEventListener('touchend', this._handleDocumentClickBound);
320248
}

0 commit comments

Comments
 (0)