vgapp 0.0.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/.gitattributes +1 -0
- package/CHANGELOG.md +0 -0
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/app/modules/base-module.js +97 -0
- package/app/modules/module-fn.js +119 -0
- package/app/modules/vgcollapse/js/vgcollapse.js +219 -0
- package/app/modules/vgdropdown/js/vgdropdown.js +279 -0
- package/app/modules/vgdropdown/scss/_variables.scss +9 -0
- package/app/modules/vgdropdown/scss/vgdropdown.scss +41 -0
- package/app/modules/vgformsender/js/vgformsender.js +400 -0
- package/app/modules/vgformsender/scss/vgformsender.scss +19 -0
- package/app/modules/vgmodal/js/vgmodal.js +346 -0
- package/app/modules/vgmodal/scss/_variables.scss +25 -0
- package/app/modules/vgmodal/scss/vgmodal.scss +111 -0
- package/app/modules/vgnav/js/vgnav.js +498 -0
- package/app/modules/vgnav/scss/_breakpoints.scss +127 -0
- package/app/modules/vgnav/scss/_hamburger.scss +62 -0
- package/app/modules/vgnav/scss/_placement.scss +70 -0
- package/app/modules/vgnav/scss/_toggle.scss +20 -0
- package/app/modules/vgnav/scss/_variables.scss +68 -0
- package/app/modules/vgnav/scss/vgnav.scss +150 -0
- package/app/modules/vgsidebar/js/vgsidebar.js +165 -0
- package/app/modules/vgsidebar/scss/_variables.scss +19 -0
- package/app/modules/vgsidebar/scss/vgsidebar.scss +90 -0
- package/app/utils/js/components/backdrop.js +54 -0
- package/app/utils/js/components/overflow.js +28 -0
- package/app/utils/js/components/params.js +44 -0
- package/app/utils/js/components/placement.js +59 -0
- package/app/utils/js/components/responsive.js +83 -0
- package/app/utils/js/components/scrollbar.js +114 -0
- package/app/utils/js/dom/data.js +51 -0
- package/app/utils/js/dom/event.js +331 -0
- package/app/utils/js/dom/manipulator.js +62 -0
- package/app/utils/js/dom/selectors.js +65 -0
- package/app/utils/js/functions.js +272 -0
- package/app/utils/scss/animate.scss +4074 -0
- package/app/utils/scss/default.scss +277 -0
- package/app/utils/scss/functions.scss +3 -0
- package/app/utils/scss/mixin.scss +11 -0
- package/app/utils/scss/variables.scss +80 -0
- package/build/vgapp.css +4538 -0
- package/build/vgapp.css.map +1 -0
- package/build/vgapp.js +3230 -0
- package/build/vgapp.js.map +1 -0
- package/index.js +29 -0
- package/package.json +43 -0
- package/webpack.config.js +63 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Работа с DOM
|
|
3
|
+
* @param selector
|
|
4
|
+
* @returns {*}
|
|
5
|
+
*/
|
|
6
|
+
import {isElement} from "../functions";
|
|
7
|
+
|
|
8
|
+
const parseSelector = selector => {
|
|
9
|
+
if (selector && window.CSS && window.CSS.escape) {
|
|
10
|
+
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return selector
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const getSelector = element => {
|
|
17
|
+
let selector = element.getAttribute('data-vg-target');
|
|
18
|
+
|
|
19
|
+
if (!selector || selector === '#') {
|
|
20
|
+
let hrefAttribute = element.getAttribute('href');
|
|
21
|
+
if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
|
|
26
|
+
hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const Selectors = {
|
|
36
|
+
find(selector, element = document.documentElement) {
|
|
37
|
+
if (isElement(selector)) {
|
|
38
|
+
return selector;
|
|
39
|
+
} else {
|
|
40
|
+
return Element.prototype.querySelector.call(element, selector);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
findAll(selector, container = document.documentElement) {
|
|
45
|
+
return [].concat(...Element.prototype.querySelectorAll.call(container, selector));
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
getSelectorFromElement(element) {
|
|
49
|
+
const selector = getSelector(element);
|
|
50
|
+
if (selector) return Selectors.find(selector) ? selector : null
|
|
51
|
+
return null
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
getElementFromSelector(element) {
|
|
55
|
+
const selector = getSelector(element);
|
|
56
|
+
return selector ? Selectors.find(selector) : null
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
getMultipleElementsFromSelector(element) {
|
|
60
|
+
const selector = getSelector(element);
|
|
61
|
+
return selector ? Selectors.findAll(selector) : []
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default Selectors;
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Набор скриптов для широкого применения
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Если что-нибудь в объекте
|
|
7
|
+
* @param obj
|
|
8
|
+
* @returns {boolean}
|
|
9
|
+
*/
|
|
10
|
+
function isEmptyObj(obj) {
|
|
11
|
+
for (let prop in obj) {
|
|
12
|
+
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return true
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* isElement
|
|
22
|
+
* @param object
|
|
23
|
+
* @returns {boolean}
|
|
24
|
+
*/
|
|
25
|
+
const isElement = object => {
|
|
26
|
+
if (!isObject(object)) {
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return typeof object.nodeType !== 'undefined'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* isDisabled
|
|
35
|
+
* @param element
|
|
36
|
+
* @returns {boolean}
|
|
37
|
+
*/
|
|
38
|
+
const isDisabled = element => {
|
|
39
|
+
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (element.classList.contains('disabled')) {
|
|
44
|
+
return true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (typeof element.disabled !== 'undefined') {
|
|
48
|
+
return element.disabled
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function isVisible (element) {
|
|
55
|
+
if (!isElement(element) || element.getClientRects().length === 0) {
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'
|
|
60
|
+
const closedDetails = element.closest('details:not([open])')
|
|
61
|
+
|
|
62
|
+
if (!closedDetails) {
|
|
63
|
+
return elementIsVisible
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (closedDetails !== element) {
|
|
67
|
+
const summary = element.closest('summary')
|
|
68
|
+
if (summary && summary.parentNode !== closedDetails) {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (summary === null) {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return elementIsVisible
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* isObject
|
|
82
|
+
* @param obj
|
|
83
|
+
* @returns {boolean}
|
|
84
|
+
*/
|
|
85
|
+
function isObject(obj) {
|
|
86
|
+
return obj && typeof obj === 'object'
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Приводим в порядок типы данных
|
|
91
|
+
* @param value
|
|
92
|
+
* @returns {any}
|
|
93
|
+
*/
|
|
94
|
+
function normalizeData(value) {
|
|
95
|
+
if (value === 'true') {
|
|
96
|
+
return true
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (value === 'false') {
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (value === Number(value).toString()) {
|
|
104
|
+
return Number(value)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (value === '' || value === 'null') {
|
|
108
|
+
return null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (typeof value !== 'string') {
|
|
112
|
+
return value
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(decodeURIComponent(value))
|
|
117
|
+
} catch {
|
|
118
|
+
return value
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Удаляем элементы с массива
|
|
124
|
+
* @param arr
|
|
125
|
+
* @param el
|
|
126
|
+
*/
|
|
127
|
+
function removeElementArray(arr, el) {
|
|
128
|
+
return arr.filter((item) => !el.includes(item));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Глубокое объединение объектов
|
|
133
|
+
* @param objects
|
|
134
|
+
* @returns {*}
|
|
135
|
+
*/
|
|
136
|
+
function mergeDeepObject(...objects) {
|
|
137
|
+
const isObject = obj => obj && typeof obj === 'object';
|
|
138
|
+
|
|
139
|
+
return objects.reduce((prev, obj) => {
|
|
140
|
+
Object.keys(obj).forEach(key => {
|
|
141
|
+
const pVal = prev[key];
|
|
142
|
+
const oVal = obj[key];
|
|
143
|
+
|
|
144
|
+
if (Array.isArray(pVal) && Array.isArray(oVal)) {
|
|
145
|
+
prev[key] = pVal.concat(...oVal);
|
|
146
|
+
}
|
|
147
|
+
else if (isObject(pVal) && isObject(oVal)) {
|
|
148
|
+
prev[key] = mergeDeepObject(pVal, oVal);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
prev[key] = oVal;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
return prev;
|
|
156
|
+
}, {});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Callback
|
|
161
|
+
* @param possibleCallback
|
|
162
|
+
* @param args
|
|
163
|
+
* @param defaultValue
|
|
164
|
+
* @returns {*}
|
|
165
|
+
*/
|
|
166
|
+
function execute(possibleCallback, args = [], defaultValue = possibleCallback) {
|
|
167
|
+
return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Transition
|
|
172
|
+
* @param callback
|
|
173
|
+
* @param transitionElement
|
|
174
|
+
* @param waitForTransition
|
|
175
|
+
*/
|
|
176
|
+
const TRANSITION_END = 'transitionend';
|
|
177
|
+
const MILLISECONDS_MULTIPLIER = 1000;
|
|
178
|
+
|
|
179
|
+
function executeAfterTransition (callback, transitionElement, waitForTransition = true, timeOutMs) {
|
|
180
|
+
if (!waitForTransition) {
|
|
181
|
+
execute(callback)
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const durationPadding = 5
|
|
186
|
+
const emulatedDuration = timeOutMs ? timeOutMs : getTransitionDurationFromElement(transitionElement) + durationPadding;
|
|
187
|
+
|
|
188
|
+
let called = false
|
|
189
|
+
|
|
190
|
+
const handler = ({ target }) => {
|
|
191
|
+
if (target !== transitionElement) {
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
called = true
|
|
196
|
+
transitionElement.removeEventListener(TRANSITION_END, handler)
|
|
197
|
+
execute(callback)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
transitionElement.addEventListener(TRANSITION_END, handler)
|
|
201
|
+
setTimeout(() => {
|
|
202
|
+
if (!called) {
|
|
203
|
+
triggerTransitionEnd(transitionElement)
|
|
204
|
+
}
|
|
205
|
+
}, emulatedDuration)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const getTransitionDurationFromElement = element => {
|
|
209
|
+
if (!element) {
|
|
210
|
+
return 0
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Get transition-duration of the element
|
|
214
|
+
let { transitionDuration, transitionDelay } = window.getComputedStyle(element)
|
|
215
|
+
|
|
216
|
+
const floatTransitionDuration = Number.parseFloat(transitionDuration)
|
|
217
|
+
const floatTransitionDelay = Number.parseFloat(transitionDelay)
|
|
218
|
+
|
|
219
|
+
// Return 0 if element or transition duration is not found
|
|
220
|
+
if (!floatTransitionDuration && !floatTransitionDelay) {
|
|
221
|
+
return 0
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// If multiple durations are defined, take the first
|
|
225
|
+
transitionDuration = transitionDuration.split(',')[0]
|
|
226
|
+
transitionDelay = transitionDelay.split(',')[0]
|
|
227
|
+
|
|
228
|
+
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const triggerTransitionEnd = element => {
|
|
232
|
+
element.dispatchEvent(new Event(TRANSITION_END))
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Трюк для перезапуска анимации элемента
|
|
237
|
+
*
|
|
238
|
+
* @param {HTMLElement} element
|
|
239
|
+
* @return void
|
|
240
|
+
*
|
|
241
|
+
* @смотри https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
|
242
|
+
*/
|
|
243
|
+
const reflow = element => {
|
|
244
|
+
element.offsetHeight // eslint-disable-line no-unused-expressions
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Noop
|
|
249
|
+
*/
|
|
250
|
+
const noop = () => {};
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Генерация случайной строки
|
|
254
|
+
*/
|
|
255
|
+
function makeRandomString(length = 7) {
|
|
256
|
+
let result = '';
|
|
257
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
258
|
+
const charactersLength = characters.length;
|
|
259
|
+
let counter = 0;
|
|
260
|
+
while (counter < length) {
|
|
261
|
+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
262
|
+
counter += 1;
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
*
|
|
269
|
+
*/
|
|
270
|
+
const isRTL = () => document.documentElement.dir === 'rtl'
|
|
271
|
+
|
|
272
|
+
export {isElement, isVisible, isDisabled, isObject, isEmptyObj, mergeDeepObject, removeElementArray, normalizeData, execute, executeAfterTransition, reflow, noop, makeRandomString, isRTL}
|