@appartmint/mint 0.12.26 → 0.12.30

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/src/ts/util.ts ADDED
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Imports
3
+ */
4
+ import { mintSide } from './imports/enum';
5
+ import mintSettings from './imports/util/settings';
6
+
7
+ /**
8
+ * Utility functions
9
+ * @public
10
+ */
11
+ export abstract class mintUtil {
12
+ /**
13
+ * Returns the width of the window, including fractional pixels
14
+ * @returns the width of the window
15
+ */
16
+ static windowWidth () : number {
17
+ const decimal: number = document.body.getBoundingClientRect().width % 1;
18
+ return window.innerWidth + decimal;
19
+ }
20
+
21
+ /**
22
+ * Ensures that a function `func` is run only after not being called for `wait` milliseconds
23
+ * @param func - the function to debounce
24
+ * @param wait - the amount of time to wait before running the function
25
+ * @returns - the debounced function
26
+ */
27
+ static debounce (func: Function, wait: number = mintSettings.delay.default) : Function {
28
+ let timer: number;
29
+ return function (e: any) {
30
+ if (timer) {
31
+ clearTimeout(timer);
32
+ }
33
+ timer = setTimeout(func, wait, e);
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Ensures that a function `func` is run only after not being called for `wait` milliseconds
39
+ * @param func - the function to debounce
40
+ * @param wait - the amount of time to wait before running the function
41
+ * @returns - the debounced function as an EventListener
42
+ */
43
+ static debounceEvent (func: Function, wait: number = mintSettings.delay.default) : EventListener {
44
+ return mintUtil.debounce(func, wait) as EventListener;
45
+ }
46
+
47
+ /**
48
+ * Ensures that a function `func` is called at most every `wait` milliseconds with optional leading and trailing calls
49
+ * @param func - the function to throttle
50
+ * @param wait - the amount of time between function calls
51
+ * @param options - leading and trailing options: default = \{ leading: true, trailing, true \}
52
+ * @returns - the throttled function
53
+ */
54
+ static throttle (func: Function,
55
+ wait: number = mintSettings.delay.default,
56
+ options?: {[key: string]: boolean}) : Function {
57
+ let context: any, args: any, result: any,
58
+ timeout: number, previous: number = 0,
59
+ later: Function = function () {
60
+ previous = options?.leading === false ? 0 : new Date().getTime();
61
+ timeout = 0;
62
+ result = func.apply(context, args);
63
+ if (!timeout) {
64
+ context = args = null;
65
+ }
66
+ },
67
+ throttled: Function = function (this: any): any {
68
+ let now: number = new Date().getTime();
69
+ if (!previous && options?.leading === false) {
70
+ previous = now;
71
+ }
72
+ let remaining: number = wait - now + previous;
73
+ context = this;
74
+ args = arguments;
75
+ if (remaining <= 0 || remaining > wait) {
76
+ if (timeout) {
77
+ clearTimeout(timeout);
78
+ timeout = 0;
79
+ }
80
+ previous = now;
81
+ result = func.apply(context, args);
82
+ if (!timeout) {
83
+ context = args = null;
84
+ }
85
+ } else if (!timeout && options?.trailing !== false) {
86
+ timeout = window.setTimeout(later, remaining);
87
+ }
88
+ return result;
89
+ };
90
+
91
+ return throttled;
92
+ }
93
+
94
+ /**
95
+ * Ensures that a function `func` is called at most every `wait` milliseconds with optional leading and trailing calls
96
+ * @param func - the function to throttle
97
+ * @param wait - the amount of time between function calls
98
+ * @param options - leading and trailing options: default = \{ leading: true, trailing, true \}
99
+ * @returns - the throttled function as an EventListener
100
+ */
101
+ static throttleEvent (func: Function,
102
+ wait: number = mintSettings.delay.default,
103
+ options?: {[key: string]: boolean}) : EventListener {
104
+ return mintUtil.throttle(func, wait, options) as EventListener;
105
+ }
106
+
107
+ /**
108
+ * Sets the element's height to its `innerHeight`, then to `auto` after a delay
109
+ * @param el - the element whose height will be set
110
+ * @param delay - the amount of time in milliseconds that the show animation will be active
111
+ * @param from - the side that the element is animating from
112
+ */
113
+ static show (el?: HTMLElement | null, delay: number = mintSettings.delay.default, from: mintSide = mintSide.Top) : void {
114
+ if (el) {
115
+ el.style.display = '';
116
+ requestAnimationFrame(() => {
117
+ if (from === mintSide.Top || from === mintSide.Bottom) {
118
+ el.style.height = `${el.scrollHeight}px`;
119
+ } else {
120
+ el.style.width = `${el.scrollWidth}px`;
121
+ }
122
+
123
+ setTimeout(() => {
124
+ if (from === mintSide.Top || from === mintSide.Bottom) {
125
+ el.style.height = 'auto';
126
+ } else {
127
+ el.style.width = 'auto';
128
+ }
129
+ }, delay);
130
+ });
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Sets the element's height to 0
136
+ * @param el - the element whose height will be set
137
+ * @param delay - the amount of time in milliseconds that the show animation will be active
138
+ * @param from - the side that the element is animating from
139
+ */
140
+ static hide (el?: HTMLElement | null, delay: number = mintSettings.delay.default, from: mintSide = mintSide.Top) : void {
141
+ if (el) {
142
+ let height = el.scrollHeight,
143
+ width = el.scrollWidth,
144
+ transition = el.style.transition;
145
+ el.style.transition = '';
146
+ requestAnimationFrame(() => {
147
+ if (from === mintSide.Top || from === mintSide.Bottom) {
148
+ el.style.height = `${height}px`;
149
+ } else {
150
+ el.style.width = `${width}px`;
151
+ }
152
+
153
+ el.style.transition = transition;
154
+ requestAnimationFrame(() => {
155
+ if (from === mintSide.Top || from === mintSide.Bottom) {
156
+ el.style.height = '0';
157
+ } else {
158
+ el.style.width = '0';
159
+ }
160
+ });
161
+ });
162
+ setTimeout(() => {
163
+ el.style.display = 'none';
164
+ }, delay);
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Copies the provided text to the clipboard
170
+ * @param text - the text to copy
171
+ * @returns - true if the text was successfully copied to the clipboard; else false
172
+ */
173
+ static copyText (text: string) : boolean {
174
+ let textArea: HTMLTextAreaElement = document.createElement('textarea');
175
+
176
+ if (!text || !textArea) {
177
+ return false;
178
+ }
179
+
180
+ textArea.value = text;
181
+ textArea.style.cssText = `
182
+ position: fixed;
183
+ top: 0;
184
+ left: 0;
185
+ transform: translate(-100%, -100%);
186
+ opacity: 0;
187
+ z-index: -1;
188
+ `;
189
+
190
+ document.body.appendChild(textArea);
191
+ textArea.select();
192
+ textArea.setSelectionRange(0, 99999);
193
+ navigator.clipboard.writeText(textArea.value);
194
+ document.body.removeChild(textArea);
195
+
196
+ return true;
197
+ }
198
+
199
+ /**
200
+ * Tests the validity of an email address
201
+ * @see {@link https://stackoverflow.com/questions/201323/how-can-i-validate-an-email-address-using-a-regular-expression}
202
+ * @param text - the string to test
203
+ * @returns - true if the given string is an email address; false if not
204
+ */
205
+ static isEmail (text: string) : boolean {
206
+ return null !== text.match(/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/);
207
+ }
208
+ }
209
+ export default mintUtil;