@kupola/kupola 1.5.2 → 1.5.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/js/dropdown.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { globalEvents } from './global-events.js';
2
2
  import { kupolaInitializer } from './initializer.js';
3
+ import { getUiConfig } from './kupola-config.js';
3
4
 
4
5
  class Dropdown {
5
6
  constructor(element, options = {}) {
@@ -8,22 +9,27 @@ class Dropdown {
8
9
  this.menu = element.querySelector('.ds-dropdown__menu');
9
10
  this.triggerText = this.trigger ? this.trigger.querySelector('span') : null;
10
11
  this.scope = `dropdown-${Math.random().toString(36).substr(2, 9)}`;
11
-
12
+
12
13
  // Options
14
+ const uiConfig = getUiConfig();
13
15
  this.triggerMode = options.trigger || element.getAttribute('data-dropdown-trigger') || 'click'; // click | hover
14
16
  this.hoverDelay = options.hoverDelay || parseInt(element.getAttribute('data-dropdown-hover-delay')) || 150;
15
17
  this.disabled = options.disabled || element.hasAttribute('data-dropdown-disabled');
16
18
  this.keyboardNav = options.keyboardNav !== false;
17
19
  this.autoPosition = options.autoPosition !== false;
20
+ this.closeOnClick = options.closeOnClick !== undefined ? options.closeOnClick : (uiConfig.dropdown?.closeOnClick !== undefined ? uiConfig.dropdown.closeOnClick : true);
21
+ this.appendToBody = options.appendToBody !== false;
18
22
  this.onSelect = options.onSelect || null;
19
23
  this.onShow = options.onShow || null;
20
24
  this.onHide = options.onHide || null;
21
-
25
+
22
26
  this.isOpen = false;
23
27
  this.focusIndex = -1;
24
28
  this._hoverTimer = null;
25
29
  this._hoverLeaveTimer = null;
26
-
30
+ this._originalParent = null;
31
+ this._originalPosition = null;
32
+
27
33
  this._triggerClickHandler = null;
28
34
  this._documentClickHandler = null;
29
35
  this._documentClickListener = null;
@@ -37,24 +43,26 @@ class Dropdown {
37
43
  }
38
44
 
39
45
  init() {
40
- if (!this.trigger || !this.menu) return;
41
- if (this.element.__kupolaInitialized) return;
46
+ if (!this.trigger || !this.menu) {return;}
47
+ if (this.element.__kupolaInitialized) {return;}
42
48
 
43
49
  // Item click handler
44
50
  this._itemClickHandler = (e) => {
45
51
  const item = e.currentTarget;
46
- if (item.classList.contains('is-disabled') || item.classList.contains('ds-dropdown__divider')) return;
47
-
52
+ if (item.classList.contains('is-disabled') || item.classList.contains('ds-dropdown__divider')) {return;}
53
+
48
54
  if (this.triggerText && !item.hasAttribute('data-no-update-trigger')) {
49
55
  this.triggerText.textContent = item.textContent.trim();
50
56
  }
51
-
57
+
52
58
  if (this.onSelect) {
53
59
  this.onSelect({ item, value: item.getAttribute('data-value'), text: item.textContent.trim() });
54
60
  }
55
-
56
- this.hideMenu();
57
- this.trigger.focus();
61
+
62
+ if (this.closeOnClick) {
63
+ this.hideMenu();
64
+ this.trigger.focus();
65
+ }
58
66
  };
59
67
 
60
68
  this._bindMenuItems();
@@ -62,73 +70,73 @@ class Dropdown {
62
70
  // Trigger click
63
71
  this._triggerClickHandler = (e) => {
64
72
  e.stopPropagation();
65
- if (this.disabled) return;
73
+ if (this.disabled) {return;}
66
74
  this.toggleMenu();
67
75
  };
68
76
 
69
77
  // Hover trigger
70
78
  this._triggerMouseenterHandler = () => {
71
- if (this.disabled || this.triggerMode !== 'hover') return;
79
+ if (this.disabled || this.triggerMode !== 'hover') {return;}
72
80
  clearTimeout(this._hoverLeaveTimer);
73
81
  this._hoverTimer = setTimeout(() => this.showMenu(), this.hoverDelay);
74
82
  };
75
83
 
76
84
  this._triggerMouseleaveHandler = () => {
77
- if (this.triggerMode !== 'hover') return;
85
+ if (this.triggerMode !== 'hover') {return;}
78
86
  clearTimeout(this._hoverTimer);
79
87
  this._hoverLeaveTimer = setTimeout(() => this.hideMenu(), this.hoverDelay);
80
88
  };
81
89
 
82
90
  this._mouseenterHandler = () => {
83
- if (this.disabled || this.triggerMode !== 'hover') return;
91
+ if (this.disabled || this.triggerMode !== 'hover') {return;}
84
92
  clearTimeout(this._hoverLeaveTimer);
85
93
  };
86
94
 
87
95
  this._mouseleaveHandler = () => {
88
- if (this.triggerMode !== 'hover') return;
96
+ if (this.triggerMode !== 'hover') {return;}
89
97
  this._hoverLeaveTimer = setTimeout(() => this.hideMenu(), this.hoverDelay);
90
98
  };
91
99
 
92
100
  // Keyboard navigation
93
101
  this._keydownHandler = (e) => {
94
- if (!this.isOpen || this.disabled) return;
95
-
102
+ if (!this.isOpen || this.disabled) {return;}
103
+
96
104
  const items = this._getNavigableItems();
97
- if (!items.length) return;
105
+ if (!items.length) {return;}
98
106
 
99
107
  switch (e.key) {
100
- case 'ArrowDown':
101
- e.preventDefault();
102
- this.focusIndex = Math.min(this.focusIndex + 1, items.length - 1);
103
- this._focusItem(items);
104
- break;
105
- case 'ArrowUp':
106
- e.preventDefault();
107
- this.focusIndex = Math.max(this.focusIndex - 1, 0);
108
- this._focusItem(items);
109
- break;
110
- case 'Enter':
111
- case ' ':
112
- e.preventDefault();
113
- if (this.focusIndex >= 0 && items[this.focusIndex]) {
114
- items[this.focusIndex].click();
115
- }
116
- break;
117
- case 'Escape':
118
- e.preventDefault();
119
- this.hideMenu();
120
- this.trigger.focus();
121
- break;
122
- case 'Home':
123
- e.preventDefault();
124
- this.focusIndex = 0;
125
- this._focusItem(items);
126
- break;
127
- case 'End':
128
- e.preventDefault();
129
- this.focusIndex = items.length - 1;
130
- this._focusItem(items);
131
- break;
108
+ case 'ArrowDown':
109
+ e.preventDefault();
110
+ this.focusIndex = Math.min(this.focusIndex + 1, items.length - 1);
111
+ this._focusItem(items);
112
+ break;
113
+ case 'ArrowUp':
114
+ e.preventDefault();
115
+ this.focusIndex = Math.max(this.focusIndex - 1, 0);
116
+ this._focusItem(items);
117
+ break;
118
+ case 'Enter':
119
+ case ' ':
120
+ e.preventDefault();
121
+ if (this.focusIndex >= 0 && items[this.focusIndex]) {
122
+ items[this.focusIndex].click();
123
+ }
124
+ break;
125
+ case 'Escape':
126
+ e.preventDefault();
127
+ this.hideMenu();
128
+ this.trigger.focus();
129
+ break;
130
+ case 'Home':
131
+ e.preventDefault();
132
+ this.focusIndex = 0;
133
+ this._focusItem(items);
134
+ break;
135
+ case 'End':
136
+ e.preventDefault();
137
+ this.focusIndex = items.length - 1;
138
+ this._focusItem(items);
139
+ break;
132
140
  }
133
141
  };
134
142
 
@@ -144,7 +152,7 @@ class Dropdown {
144
152
 
145
153
  // Keyboard on trigger
146
154
  this._triggerKeydownHandler = (e) => {
147
- if (this.disabled) return;
155
+ if (this.disabled) {return;}
148
156
  if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {
149
157
  e.preventDefault();
150
158
  this.showMenu();
@@ -156,7 +164,7 @@ class Dropdown {
156
164
 
157
165
  // Document click to close
158
166
  this._documentClickHandler = (e) => {
159
- if (!this.element.contains(e.target)) {
167
+ if (!this.element.contains(e.target) && !this.menu.contains(e.target)) {
160
168
  this.hideMenu();
161
169
  }
162
170
  };
@@ -188,64 +196,140 @@ class Dropdown {
188
196
  }
189
197
 
190
198
  _calculatePosition() {
191
- if (!this.autoPosition) return;
192
-
199
+ if (!this.autoPosition) {return;}
200
+
193
201
  const triggerRect = this.element.getBoundingClientRect();
194
202
  const menuRect = this.menu.getBoundingClientRect();
195
203
  const viewportHeight = window.innerHeight;
196
204
  const viewportWidth = window.innerWidth;
197
-
205
+
198
206
  // Reset
199
207
  this.menu.classList.remove('ds-dropdown--top', 'ds-dropdown--right', 'ds-dropdown--dropup');
200
-
201
- // Vertical: prefer below, flip to above if needed
202
- const spaceBelow = viewportHeight - triggerRect.bottom;
203
- const spaceAbove = triggerRect.top;
204
-
205
- if (spaceBelow < menuRect.height && spaceAbove > spaceBelow) {
206
- this.menu.classList.add('ds-dropdown--dropup');
207
- this.menu.style.top = 'auto';
208
- this.menu.style.bottom = '100%';
209
- this.menu.style.marginBottom = '4px';
210
- } else {
211
- this.menu.style.top = '100%';
212
- this.menu.style.bottom = 'auto';
213
- this.menu.style.marginBottom = '0';
214
- }
215
-
216
- // Horizontal: prevent overflow right
217
- if (triggerRect.left + menuRect.width > viewportWidth) {
218
- this.menu.style.left = 'auto';
219
- this.menu.style.right = '0';
208
+
209
+ if (this.appendToBody) {
210
+ this.menu.style.width = `${Math.max(triggerRect.width, menuRect.width)}px`;
211
+
212
+ const spaceBelow = viewportHeight - triggerRect.bottom;
213
+ const spaceAbove = triggerRect.top;
214
+
215
+ if (spaceBelow < menuRect.height && spaceAbove > spaceBelow) {
216
+ this.menu.style.top = `${triggerRect.top - menuRect.height - 4}px`;
217
+ this.menu.style.bottom = 'auto';
218
+ } else {
219
+ this.menu.style.top = `${triggerRect.bottom + 4}px`;
220
+ this.menu.style.bottom = 'auto';
221
+ }
222
+
223
+ if (triggerRect.left + menuRect.width > viewportWidth) {
224
+ this.menu.style.left = `${triggerRect.right - Math.max(triggerRect.width, menuRect.width)}px`;
225
+ this.menu.style.right = 'auto';
226
+ } else {
227
+ this.menu.style.left = `${triggerRect.left}px`;
228
+ this.menu.style.right = 'auto';
229
+ }
220
230
  } else {
221
- this.menu.style.left = '0';
222
- this.menu.style.right = 'auto';
231
+ const spaceBelow = viewportHeight - triggerRect.bottom;
232
+ const spaceAbove = triggerRect.top;
233
+
234
+ if (spaceBelow < menuRect.height && spaceAbove > spaceBelow) {
235
+ this.menu.classList.add('ds-dropdown--dropup');
236
+ this.menu.style.top = 'auto';
237
+ this.menu.style.bottom = '100%';
238
+ this.menu.style.marginBottom = '4px';
239
+ } else {
240
+ this.menu.style.top = '100%';
241
+ this.menu.style.bottom = 'auto';
242
+ this.menu.style.marginBottom = '0';
243
+ }
244
+
245
+ if (triggerRect.left + menuRect.width > viewportWidth) {
246
+ this.menu.style.left = 'auto';
247
+ this.menu.style.right = '0';
248
+ } else {
249
+ this.menu.style.left = '0';
250
+ this.menu.style.right = 'auto';
251
+ }
223
252
  }
224
253
  }
225
254
 
226
255
  showMenu() {
227
- if (this.disabled || this.isOpen) return;
256
+ if (this.disabled || this.isOpen) {return;}
228
257
  this.isOpen = true;
229
258
  this.focusIndex = -1;
230
- this.menu.style.display = 'block';
231
259
  this.element.classList.add('is-open');
260
+
261
+ if (this.appendToBody) {
262
+ this._appendMenuToBody();
263
+ this._addScrollListener();
264
+ }
265
+
266
+ this.menu.style.display = 'block';
232
267
  this._calculatePosition();
233
- if (this.onShow) this.onShow();
268
+ if (this.onShow) {this.onShow();}
234
269
  this.element.dispatchEvent(new CustomEvent('kupola:dropdown-show', { bubbles: true }));
235
270
  }
236
271
 
237
272
  hideMenu() {
238
- if (!this.isOpen) return;
273
+ if (!this.isOpen) {return;}
239
274
  this.isOpen = false;
240
275
  this.menu.style.display = 'none';
241
276
  this.element.classList.remove('is-open');
242
-
277
+
278
+ if (this.appendToBody) {
279
+ this._restoreMenuFromBody();
280
+ this._removeScrollListener();
281
+ }
282
+
243
283
  // Clear focus
244
284
  this.menu.querySelectorAll('.ds-dropdown__item').forEach(item => item.classList.remove('is-focused'));
245
- if (this.onHide) this.onHide();
285
+ if (this.onHide) {this.onHide();}
246
286
  this.element.dispatchEvent(new CustomEvent('kupola:dropdown-hide', { bubbles: true }));
247
287
  }
248
288
 
289
+ _appendMenuToBody() {
290
+ if (!this.menu) return;
291
+ this._originalParent = this.menu.parentNode;
292
+ this._originalPosition = this.menu.style.position;
293
+ this._originalTop = this.menu.style.top;
294
+ this._originalLeft = this.menu.style.left;
295
+ this._originalRight = this.menu.style.right;
296
+ this._originalBottom = this.menu.style.bottom;
297
+ this._originalMarginBottom = this.menu.style.marginBottom;
298
+ this._originalWidth = this.menu.style.width;
299
+
300
+ this.menu.style.position = 'fixed';
301
+ this.menu.style.zIndex = '9999';
302
+ document.body.appendChild(this.menu);
303
+ }
304
+
305
+ _restoreMenuFromBody() {
306
+ if (!this.menu || !this._originalParent) return;
307
+ this._originalParent.appendChild(this.menu);
308
+ this.menu.style.position = this._originalPosition || '';
309
+ this.menu.style.top = this._originalTop || '';
310
+ this.menu.style.left = this._originalLeft || '';
311
+ this.menu.style.right = this._originalRight || '';
312
+ this.menu.style.bottom = this._originalBottom || '';
313
+ this.menu.style.marginBottom = this._originalMarginBottom || '';
314
+ this.menu.style.width = this._originalWidth || '';
315
+ this.menu.style.zIndex = '';
316
+ this._originalParent = null;
317
+ }
318
+
319
+ _addScrollListener() {
320
+ this._scrollHandler = () => {
321
+ this.hideMenu();
322
+ };
323
+ window.addEventListener('scroll', this._scrollHandler, true);
324
+ }
325
+
326
+ _removeScrollListener() {
327
+ if (this._scrollHandler) {
328
+ window.removeEventListener('scroll', this._scrollHandler, true);
329
+ this._scrollHandler = null;
330
+ }
331
+ }
332
+
249
333
  toggleMenu() {
250
334
  if (this.isOpen) {
251
335
  this.hideMenu();
@@ -273,7 +357,7 @@ class Dropdown {
273
357
  item.removeEventListener('click', item._dropdownItemClickHandler);
274
358
  }
275
359
  });
276
-
360
+
277
361
  // Rebuild menu content
278
362
  this.menu.innerHTML = '';
279
363
  items.forEach(item => {
@@ -285,27 +369,27 @@ class Dropdown {
285
369
  const el = document.createElement('div');
286
370
  el.className = 'ds-dropdown__item' + (item.disabled ? ' is-disabled' : '') + (item.active ? ' is-selected' : '');
287
371
  el.textContent = item.text || item.label || '';
288
- if (item.value !== undefined) el.setAttribute('data-value', item.value);
289
- if (item.icon) el.innerHTML = item.icon + el.innerHTML;
290
- if (item.disabled) el.classList.add('is-disabled');
372
+ if (item.value !== undefined) {el.setAttribute('data-value', item.value);}
373
+ if (item.icon) {el.innerHTML = item.icon + el.innerHTML;}
374
+ if (item.disabled) {el.classList.add('is-disabled');}
291
375
  this.menu.appendChild(el);
292
376
  }
293
377
  });
294
-
378
+
295
379
  this._bindMenuItems();
296
380
  }
297
381
 
298
382
  destroy() {
299
- if (!this.element.__kupolaInitialized) return;
383
+ if (!this.element.__kupolaInitialized) {return;}
300
384
 
301
385
  clearTimeout(this._hoverTimer);
302
386
  clearTimeout(this._hoverLeaveTimer);
303
387
 
304
388
  if (this.trigger) {
305
- if (this._triggerClickHandler) this.trigger.removeEventListener('click', this._triggerClickHandler);
306
- if (this._triggerMouseenterHandler) this.trigger.removeEventListener('mouseenter', this._triggerMouseenterHandler);
307
- if (this._triggerMouseleaveHandler) this.trigger.removeEventListener('mouseleave', this._triggerMouseleaveHandler);
308
- if (this._triggerKeydownHandler) this.trigger.removeEventListener('keydown', this._triggerKeydownHandler);
389
+ if (this._triggerClickHandler) {this.trigger.removeEventListener('click', this._triggerClickHandler);}
390
+ if (this._triggerMouseenterHandler) {this.trigger.removeEventListener('mouseenter', this._triggerMouseenterHandler);}
391
+ if (this._triggerMouseleaveHandler) {this.trigger.removeEventListener('mouseleave', this._triggerMouseleaveHandler);}
392
+ if (this._triggerKeydownHandler) {this.trigger.removeEventListener('keydown', this._triggerKeydownHandler);}
309
393
  }
310
394
 
311
395
  if (this.menu) {
@@ -314,11 +398,11 @@ class Dropdown {
314
398
  item.removeEventListener('click', item._dropdownItemClickHandler);
315
399
  }
316
400
  });
317
- if (this._mouseenterHandler) this.menu.removeEventListener('mouseenter', this._mouseenterHandler);
318
- if (this._mouseleaveHandler) this.menu.removeEventListener('mouseleave', this._mouseleaveHandler);
401
+ if (this._mouseenterHandler) {this.menu.removeEventListener('mouseenter', this._mouseenterHandler);}
402
+ if (this._mouseleaveHandler) {this.menu.removeEventListener('mouseleave', this._mouseleaveHandler);}
319
403
  }
320
404
 
321
- if (this._keydownHandler) document.removeEventListener('keydown', this._keydownHandler);
405
+ if (this._keydownHandler) {document.removeEventListener('keydown', this._keydownHandler);}
322
406
 
323
407
  if (this._documentClickListener && this._documentClickListener.unsubscribe) {
324
408
  this._documentClickListener.unsubscribe();
@@ -326,6 +410,10 @@ class Dropdown {
326
410
  document.removeEventListener('click', this._documentClickHandler);
327
411
  }
328
412
 
413
+ if (this.appendToBody && this._originalParent) {
414
+ this._restoreMenuFromBody();
415
+ }
416
+
329
417
  this._documentClickHandler = null;
330
418
  this._documentClickListener = null;
331
419
  this._triggerClickHandler = null;
@@ -367,4 +455,4 @@ function cleanupAllDropdowns() {
367
455
 
368
456
  export { Dropdown, initDropdown, initDropdowns, cleanupDropdown, cleanupAllDropdowns };
369
457
 
370
- kupolaInitializer.register('dropdown', initDropdown, cleanupDropdown);
458
+ kupolaInitializer.register('dropdown', initDropdown, cleanupDropdown);
@@ -1,63 +1,87 @@
1
1
  const config = {
2
2
  paths: {
3
3
  icons: '/icons/',
4
- base: '/'
4
+ base: '/',
5
5
  },
6
6
  theme: {
7
7
  default: 'dark',
8
- brand: 'zengqing'
8
+ brand: 'zengqing',
9
9
  },
10
10
  i18n: {
11
11
  locale: 'zh-CN',
12
- fallbackLocale: 'en-US'
12
+ fallbackLocale: 'en-US',
13
13
  },
14
14
  http: {
15
15
  baseURL: '',
16
16
  timeout: 10000,
17
17
  headers: {},
18
- withCredentials: false
18
+ withCredentials: false,
19
19
  },
20
20
  ui: {
21
21
  defaultSize: 'md',
22
- defaultVariant: 'default'
22
+ modal: {
23
+ backdropClick: true,
24
+ },
25
+ dropdown: {
26
+ closeOnClick: true,
27
+ },
28
+ datepicker: {
29
+ weekStart: 1,
30
+ },
31
+ tooltip: {
32
+ delay: 300,
33
+ },
23
34
  },
24
35
  performance: {
25
- lazyLoad: true,
26
- debounceDelay: 300,
36
+ lazyLoad: false,
37
+ debounceDelay: 200,
27
38
  throttleDelay: 100,
28
- animationEnabled: true
39
+ animationEnabled: true,
29
40
  },
30
41
  security: {
31
42
  xssProtection: true,
32
43
  sanitizeHtml: {
33
44
  enabled: true,
34
- allowedTags: ['b', 'i', 'u', 'em', 'strong', 'a', 'br', 'p', 'span', 'div', 'img'],
45
+ allowedTags: [ 'b', 'i', 'u', 'em', 'strong', 'a', 'br', 'p', 'span', 'div', 'img' ],
35
46
  allowedAttributes: {
36
- 'a': ['href', 'target', 'rel'],
37
- 'img': ['src', 'alt', 'width', 'height'],
38
- 'span': ['class', 'style'],
39
- 'div': ['class', 'style']
40
- }
41
- }
47
+ 'a': [ 'href', 'target', 'rel' ],
48
+ 'img': [ 'src', 'alt', 'width', 'height' ],
49
+ 'span': [ 'class', 'style' ],
50
+ 'div': [ 'class', 'style' ],
51
+ },
52
+ },
53
+ maskData: {
54
+ enabled: true,
55
+ patterns: {
56
+ phone: { regex: '^(\\d{3})\\d{4}(\\d{4})$', replace: '$1****$2' },
57
+ email: { regex: '^(.)(.*)(@.*)$', replace: '$1***$3' },
58
+ idCard: { regex: '^(\\d{6})\\d{8}(\\d{4})$', replace: '$1********$2' },
59
+ bankCard: { regex: '^(\\d{4})\\d{8}(\\d{4})$', replace: '$1 **** **** $2' },
60
+ },
61
+ },
62
+ secureId: {
63
+ length: 16,
64
+ charset: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
65
+ },
66
+ },
67
+ message: {
68
+ duration: 3000,
69
+ position: 'top-right',
70
+ maxCount: 5,
42
71
  },
43
- dev: {
44
- debug: false,
45
- logLevel: 'warn'
72
+ notification: {
73
+ duration: 4500,
74
+ position: 'top-right',
46
75
  },
47
- extend: {
48
- themeVariables: {}
76
+ validation: {
77
+ defaultRules: [],
78
+ showErrors: true,
79
+ trigger: 'blur',
49
80
  },
50
81
  components: {
51
82
  autoInit: true,
52
- silentErrors: false
83
+ silentErrors: false,
53
84
  },
54
- store: {
55
- persist: true,
56
- prefix: 'kupola-'
57
- },
58
- events: {
59
- global: true
60
- }
61
85
  };
62
86
 
63
87
  export function setConfig(options) {
@@ -65,7 +89,7 @@ export function setConfig(options) {
65
89
  }
66
90
 
67
91
  export function getConfig(key) {
68
- if (!key) return config;
92
+ if (!key) {return config;}
69
93
  return getNestedValue(config, key);
70
94
  }
71
95
 
@@ -97,16 +121,20 @@ export function getSecurityConfig() {
97
121
  return config.security;
98
122
  }
99
123
 
100
- export function getDevConfig() {
101
- return config.dev;
102
- }
103
-
104
124
  export function getPerformanceConfig() {
105
125
  return config.performance;
106
126
  }
107
127
 
108
- export function getExtendConfig() {
109
- return config.extend;
128
+ export function getMessageConfig() {
129
+ return config.message;
130
+ }
131
+
132
+ export function getNotificationConfig() {
133
+ return config.notification;
134
+ }
135
+
136
+ export function getValidationConfig() {
137
+ return config.validation;
110
138
  }
111
139
 
112
140
  function mergeDeep(target, source) {
@@ -122,4 +150,4 @@ function mergeDeep(target, source) {
122
150
 
123
151
  function getNestedValue(obj, key) {
124
152
  return key.split('.').reduce((o, k) => (o && o[k]) !== undefined ? o[k] : undefined, obj);
125
- }
153
+ }