vgapp 1.5.7 → 1.5.9

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.
Files changed (111) hide show
  1. package/app/langs/en/buttons.json +17 -17
  2. package/app/langs/en/messages.json +36 -36
  3. package/app/langs/ru/buttons.json +17 -17
  4. package/app/langs/ru/messages.json +1 -1
  5. package/app/modules/vgalert/js/vgalert.js +15 -12
  6. package/app/modules/vgalert/scss/_variables.scss +16 -16
  7. package/app/modules/vgalert/scss/vgalert.scss +13 -6
  8. package/app/modules/vgcollapse/scss/_variables.scss +7 -7
  9. package/app/modules/vgcollapse/scss/vgcollapse.scss +5 -5
  10. package/app/modules/vgdropdown/scss/_variables.scss +14 -14
  11. package/app/modules/vgdropdown/scss/vgdropdown.scss +5 -5
  12. package/app/modules/vgfilepreview/js/i18n.js +56 -56
  13. package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
  14. package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
  15. package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
  16. package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
  17. package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
  18. package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
  19. package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
  20. package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
  21. package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
  22. package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
  23. package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
  24. package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
  25. package/app/modules/vgfilepreview/readme.md +68 -68
  26. package/app/modules/vgfiles/js/base.js +198 -198
  27. package/app/modules/vgfiles/js/droppable.js +17 -17
  28. package/app/modules/vgfiles/js/render.js +153 -153
  29. package/app/modules/vgfiles/js/sortable.js +52 -52
  30. package/app/modules/vgfiles/js/vgfiles.js +43 -43
  31. package/app/modules/vgfiles/readme.md +123 -123
  32. package/app/modules/vgfiles/scss/_mixins.scss +13 -13
  33. package/app/modules/vgfiles/scss/_variables.scss +10 -10
  34. package/app/modules/vgfiles/scss/vgfiles.scss +28 -28
  35. package/app/modules/vgformsender/js/hideshowpass.js +22 -22
  36. package/app/modules/vgformsender/readme.md +1 -1
  37. package/app/modules/vgformsender/scss/_variables.scss +5 -5
  38. package/app/modules/vgformsender/scss/vgformsender.scss +42 -42
  39. package/app/modules/vglawcookie/js/vglawcookie.js +19 -19
  40. package/app/modules/vglawcookie/scss/_variables.scss +13 -13
  41. package/app/modules/vglawcookie/scss/vglawcookie.scss +5 -5
  42. package/app/modules/vgmodal/js/vgmodal.interaction.js +216 -216
  43. package/app/modules/vgmodal/js/vgmodal.js +9 -9
  44. package/app/modules/vgmodal/js/vgmodal.minimized.js +227 -227
  45. package/app/modules/vgmodal/scss/_variables.scss +17 -17
  46. package/app/modules/vgmodal/scss/vgmodal.scss +77 -77
  47. package/app/modules/vgnav/js/vgnav.js +137 -84
  48. package/app/modules/vgnav/scss/_breakpoints.scss +36 -36
  49. package/app/modules/vgnav/scss/_hamburger.scss +5 -5
  50. package/app/modules/vgnav/scss/_placement.scss +5 -5
  51. package/app/modules/vgnav/scss/_toggle.scss +5 -5
  52. package/app/modules/vgnav/scss/_variables.scss +26 -26
  53. package/app/modules/vgnav/scss/vgnav.scss +41 -41
  54. package/app/modules/vgnestable/README.md +39 -39
  55. package/app/modules/vgrangeslider/js/skins.js +8 -8
  56. package/app/modules/vgrangeslider/js/vgrangeslider.js +29 -29
  57. package/app/modules/vgrangeslider/scss/_variables.scss +55 -55
  58. package/app/modules/vgrangeslider/scss/vgrangeslider.scss +239 -239
  59. package/app/modules/vgrollup/js/vgrollup.js +15 -15
  60. package/app/modules/vgrollup/scss/_variables.scss +15 -15
  61. package/app/modules/vgrollup/scss/vgrollup.scss +6 -6
  62. package/app/modules/vgselect/js/handlers.js +6 -6
  63. package/app/modules/vgselect/js/vgselect.js +167 -123
  64. package/app/modules/vgselect/readme.md +11 -11
  65. package/app/modules/vgselect/scss/_variables.scss +51 -51
  66. package/app/modules/vgselect/scss/vgselect.scss +1 -1
  67. package/app/modules/vgsidebar/js/vgsidebar.js +21 -21
  68. package/app/modules/vgsidebar/scss/_variables.scss +10 -10
  69. package/app/modules/vgsidebar/scss/vgsidebar.scss +5 -5
  70. package/app/modules/vgspy/js/vgspy.js +43 -43
  71. package/app/modules/vgtable/js/_filters.js +10 -6
  72. package/app/modules/vgtable/js/_options.js +16 -16
  73. package/app/modules/vgtable/js/_pagination.js +118 -118
  74. package/app/modules/vgtable/js/_responsive.js +79 -79
  75. package/app/modules/vgtable/js/_sticky-header.js +349 -280
  76. package/app/modules/vgtable/js/vgtable.js +98 -98
  77. package/app/modules/vgtable/scss/_fixed-columns.scss +23 -25
  78. package/app/modules/vgtable/scss/_sorting.scss +6 -6
  79. package/app/modules/vgtable/scss/_sticky-header.scss +31 -31
  80. package/app/modules/vgtable/scss/_variables.scss +6 -4
  81. package/app/modules/vgtable/scss/vgtable.scss +8 -4
  82. package/app/modules/vgtabs/js/vgtabs.js +91 -91
  83. package/app/modules/vgtabs/scss/_variables.scss +23 -23
  84. package/app/modules/vgtabs/scss/vgtabs.scss +5 -5
  85. package/app/modules/vgtoast/js/vgtoast.js +4 -4
  86. package/app/modules/vgtoast/scss/_variables.scss +13 -13
  87. package/app/modules/vgtoast/scss/vgtoast.scss +5 -5
  88. package/app/modules/vgtooltip/js/vgtooltip.js +127 -127
  89. package/app/modules/vgtooltip/scss/_variables.scss +10 -10
  90. package/app/modules/vgtooltip/scss/vgtooltip.scss +5 -5
  91. package/app/utils/js/components/audio-metadata.js +240 -240
  92. package/app/utils/js/components/backdrop.js +116 -116
  93. package/app/utils/js/components/file-icon.js +7 -7
  94. package/app/utils/js/components/file-preview.js +304 -304
  95. package/app/utils/js/components/responsive.js +165 -165
  96. package/app/utils/js/components/sanitize.js +150 -150
  97. package/app/utils/js/components/video-metadata.js +140 -140
  98. package/app/utils/scss/_backdrop.scss +5 -5
  99. package/app/utils/scss/_theme-default.scss +12 -12
  100. package/app/utils/scss/_theme.scss +7 -7
  101. package/app/utils/scss/default.scss +9 -9
  102. package/app/utils/scss/functions.scss +21 -21
  103. package/app/utils/scss/index.scss +4 -4
  104. package/app/utils/scss/mixin.scss +16 -16
  105. package/app/utils/scss/variables.scss +147 -147
  106. package/build/vgapp.css +1 -1
  107. package/build/vgapp.css.map +1 -1
  108. package/build/vgapp.js +1 -1
  109. package/build/vgapp.js.map +1 -1
  110. package/index.js +7 -7
  111. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Описание: локальная и remote-пагинация строк базовой таблицы VGTable.
3
- * Возможности: выбор страницы и размера, серверная meta, лимит кнопок, responsive-представление без запросов, многоточия, быстрый переход и сохранение.
3
+ * Возможности: выбор страницы и размера, серверная meta, лимит кнопок, responsive-представление без запросов, многоточия, быстрый переход и сохранение.
4
4
  */
5
5
  import EventHandler from "../../../utils/js/dom/event";
6
6
  import VGDropdown from "../../vgdropdown";
@@ -16,10 +16,10 @@ class _pagination {
16
16
  this._options = options;
17
17
  this._host = table.closest('.vg-table-wrapper') || table.parentElement;
18
18
  this._containers = [];
19
- this._dropdowns = [];
20
- this._externalVisibility = new Map();
21
- this._manageExternalVisibility = options.responsive === true;
22
- this._updatingPresentation = false;
19
+ this._dropdowns = [];
20
+ this._externalVisibility = new Map();
21
+ this._manageExternalVisibility = options.responsive === true;
22
+ this._updatingPresentation = false;
23
23
  this._page = this._positiveInt(options.page, 1);
24
24
  this._perPage = this._clampPerPage(options.per);
25
25
  this._remote = options.remote === true;
@@ -32,24 +32,24 @@ class _pagination {
32
32
  this._boundFocusOut = this._handleFocusOut.bind(this);
33
33
  }
34
34
 
35
- init() {
36
- this._restoreState();
37
- this._containers = this._resolveContainers();
38
- this._bindContainers();
39
- this.refresh();
40
- }
41
-
42
- _bindContainers() {
43
- this._containers.forEach((container) => {
35
+ init() {
36
+ this._restoreState();
37
+ this._containers = this._resolveContainers();
38
+ this._bindContainers();
39
+ this.refresh();
40
+ }
41
+
42
+ _bindContainers() {
43
+ this._containers.forEach((container) => {
44
44
  container.addEventListener('click', this._boundClick);
45
45
  container.addEventListener('change', this._boundChange);
46
46
  container.addEventListener('keydown', this._boundKeydown);
47
47
  container.addEventListener('focusin', this._boundFocusIn);
48
48
  container.addEventListener('focusout', this._boundFocusOut);
49
49
  });
50
- }
51
-
52
- _releaseContainers() {
50
+ }
51
+
52
+ _releaseContainers() {
53
53
  this._disposeDropdowns();
54
54
  this._containers.forEach((container) => {
55
55
  container.removeEventListener('click', this._boundClick);
@@ -57,69 +57,69 @@ class _pagination {
57
57
  container.removeEventListener('keydown', this._boundKeydown);
58
58
  container.removeEventListener('focusin', this._boundFocusIn);
59
59
  container.removeEventListener('focusout', this._boundFocusOut);
60
- if (container.hasAttribute(GENERATED_ATTRIBUTE)) container.remove();
61
- });
62
- this._containers = [];
63
- }
64
-
65
- dispose() {
66
- this._releaseContainers();
67
- this._externalVisibility.forEach((hidden, container) => { container.hidden = hidden; });
68
- this._externalVisibility.clear();
60
+ if (container.hasAttribute(GENERATED_ATTRIBUTE)) container.remove();
61
+ });
62
+ this._containers = [];
63
+ }
64
+
65
+ dispose() {
66
+ this._releaseContainers();
67
+ this._externalVisibility.forEach((hidden, container) => { container.hidden = hidden; });
68
+ this._externalVisibility.clear();
69
69
  this._rows().forEach((row) => {
70
70
  row.hidden = row.getAttribute('data-vg-table-expand-hidden') === 'true'
71
71
  || row.hasAttribute('data-vg-table-filter-hidden');
72
72
  row.removeAttribute('data-vg-table-page-row');
73
73
  });
74
- this._containers = [];
75
- }
76
-
77
- /** Обновляет только панели: не трогает строки, page/per, storage, scroll или onChange. */
78
- updatePresentation(options) {
79
- const focus = this._captureFocus();
80
- const position = this._position();
81
- this._updatingPresentation = true;
82
- try {
83
- this._options = {...this._options, ...options};
84
- if (position !== this._position()) {
85
- this._manageExternalVisibility = true;
86
- this._releaseContainers();
87
- this._containers = this._resolveContainers();
88
- this._bindContainers();
89
- }
90
- this._renderControls();
91
- } finally {
92
- this._updatingPresentation = false;
93
- }
94
- this._restoreFocus(focus);
95
- }
96
-
97
- _captureFocus() {
98
- const active = this._table.ownerDocument.activeElement;
99
- const container = this._containers.find((item) => item.contains(active));
100
- if (!container) return null;
101
- const attribute = ['data-pagination-page', 'data-pagination-per-page', 'data-pagination-quick-input', 'data-pagination-quick-button']
102
- .find((name) => active.hasAttribute(name));
103
- return {
104
- position: this._positionFor(container), attribute, value: attribute ? active.getAttribute(attribute) : null,
105
- inputValue: active.tagName === 'INPUT' ? active.value : null,
106
- start: active.selectionStart, end: active.selectionEnd,
107
- };
108
- }
109
-
110
- _restoreFocus(focus) {
111
- if (!focus) return;
112
- const container = this._containers.find((item) => this._positionFor(item) === focus.position) || this._containers[0];
113
- if (!container) return;
114
- const matching = focus.attribute ? Array.from(container.querySelectorAll(`[${focus.attribute}]`))
115
- .find((item) => !item.disabled && item.getAttribute(focus.attribute) === focus.value) : null;
116
- const target = matching || container.querySelector('[aria-current="page"]');
117
- target?.focus({preventScroll: true});
118
- if (matching && focus.inputValue !== null) {
119
- matching.value = focus.inputValue;
120
- if (focus.start !== null && focus.start !== undefined) matching.setSelectionRange(focus.start, focus.end);
121
- }
122
- }
74
+ this._containers = [];
75
+ }
76
+
77
+ /** Обновляет только панели: не трогает строки, page/per, storage, scroll или onChange. */
78
+ updatePresentation(options) {
79
+ const focus = this._captureFocus();
80
+ const position = this._position();
81
+ this._updatingPresentation = true;
82
+ try {
83
+ this._options = {...this._options, ...options};
84
+ if (position !== this._position()) {
85
+ this._manageExternalVisibility = true;
86
+ this._releaseContainers();
87
+ this._containers = this._resolveContainers();
88
+ this._bindContainers();
89
+ }
90
+ this._renderControls();
91
+ } finally {
92
+ this._updatingPresentation = false;
93
+ }
94
+ this._restoreFocus(focus);
95
+ }
96
+
97
+ _captureFocus() {
98
+ const active = this._table.ownerDocument.activeElement;
99
+ const container = this._containers.find((item) => item.contains(active));
100
+ if (!container) return null;
101
+ const attribute = ['data-pagination-page', 'data-pagination-per-page', 'data-pagination-quick-input', 'data-pagination-quick-button']
102
+ .find((name) => active.hasAttribute(name));
103
+ return {
104
+ position: this._positionFor(container), attribute, value: attribute ? active.getAttribute(attribute) : null,
105
+ inputValue: active.tagName === 'INPUT' ? active.value : null,
106
+ start: active.selectionStart, end: active.selectionEnd,
107
+ };
108
+ }
109
+
110
+ _restoreFocus(focus) {
111
+ if (!focus) return;
112
+ const container = this._containers.find((item) => this._positionFor(item) === focus.position) || this._containers[0];
113
+ if (!container) return;
114
+ const matching = focus.attribute ? Array.from(container.querySelectorAll(`[${focus.attribute}]`))
115
+ .find((item) => !item.disabled && item.getAttribute(focus.attribute) === focus.value) : null;
116
+ const target = matching || container.querySelector('[aria-current="page"]');
117
+ target?.focus({preventScroll: true});
118
+ if (matching && focus.inputValue !== null) {
119
+ matching.value = focus.inputValue;
120
+ if (focus.start !== null && focus.start !== undefined) matching.setSelectionRange(focus.start, focus.end);
121
+ }
122
+ }
123
123
 
124
124
  setPage(page, emit = false, source = 'api') {
125
125
  const nextPage = this._clampPage(page);
@@ -192,11 +192,11 @@ class _pagination {
192
192
  });
193
193
  }
194
194
 
195
- this._renderControls();
196
- }
197
-
198
- _renderControls() {
199
- const markup = this._buildMarkup();
195
+ this._renderControls();
196
+ }
197
+
198
+ _renderControls() {
199
+ const markup = this._buildMarkup();
200
200
  this._disposeDropdowns();
201
201
  this._containers.forEach((container) => {
202
202
  container.className = `vg-table-pagination vg-table-pagination--${this._positionFor(container)}`;
@@ -286,10 +286,10 @@ class _pagination {
286
286
  return `<svg class="vg-table-page__ellipsis-chevron vg-table-page__ellipsis-chevron--${direction}" viewBox="0 0 20 20" focusable="false" aria-hidden="true">${paths}</svg>`;
287
287
  }
288
288
 
289
- _buildPages() {
290
- const total = this._totalPages();
291
- const maxButtons = this._options.maxButtons;
292
- if (Number.isInteger(maxButtons) && maxButtons >= 3) return this._buildLimitedPages(total, maxButtons);
289
+ _buildPages() {
290
+ const total = this._totalPages();
291
+ const maxButtons = this._options.maxButtons;
292
+ if (Number.isInteger(maxButtons) && maxButtons >= 3) return this._buildLimitedPages(total, maxButtons);
293
293
  const visible = Math.max(1, this._positiveInt(this._options.visible, 5));
294
294
  const threshold = Math.max(1, this._positiveInt(this._options.threshold, 5));
295
295
  if (this._options.ellipsis === false || total <= threshold || total <= visible + 2) {
@@ -304,30 +304,30 @@ class _pagination {
304
304
  for (let page = start; page <= end; page += 1) pages.push(page);
305
305
  if (end < total - 1) pages.push({direction: 'next'});
306
306
  pages.push(total);
307
- return pages;
308
- }
309
-
310
- _buildLimitedPages(total, maximum) {
311
- if (total <= maximum) return this._range(1, total);
312
- if (maximum < 5 || this._options.ellipsis === false) {
313
- const start = Math.max(1, Math.min(this._page - Math.floor(maximum / 2), total - maximum + 1));
314
- return this._range(start, start + maximum - 1);
315
- }
316
- // Резервируем края и подбираем наибольшее окно, учитывая оба многоточия в лимите.
317
- for (let count = maximum - 2; count >= 1; count -= 1) {
318
- const start = Math.max(2, Math.min(this._page - Math.floor(count / 2), total - count));
319
- const end = start + count - 1;
320
- const pages = [1];
321
- if (start === 3) pages.push(2);
322
- else if (start > 3) pages.push({direction: 'prev'});
323
- pages.push(...this._range(start, end));
324
- if (end === total - 2) pages.push(total - 1);
325
- else if (end < total - 2) pages.push({direction: 'next'});
326
- pages.push(total);
327
- if (pages.length <= maximum) return pages;
328
- }
329
- return [this._page];
330
- }
307
+ return pages;
308
+ }
309
+
310
+ _buildLimitedPages(total, maximum) {
311
+ if (total <= maximum) return this._range(1, total);
312
+ if (maximum < 5 || this._options.ellipsis === false) {
313
+ const start = Math.max(1, Math.min(this._page - Math.floor(maximum / 2), total - maximum + 1));
314
+ return this._range(start, start + maximum - 1);
315
+ }
316
+ // Резервируем края и подбираем наибольшее окно, учитывая оба многоточия в лимите.
317
+ for (let count = maximum - 2; count >= 1; count -= 1) {
318
+ const start = Math.max(2, Math.min(this._page - Math.floor(count / 2), total - count));
319
+ const end = start + count - 1;
320
+ const pages = [1];
321
+ if (start === 3) pages.push(2);
322
+ else if (start > 3) pages.push({direction: 'prev'});
323
+ pages.push(...this._range(start, end));
324
+ if (end === total - 2) pages.push(total - 1);
325
+ else if (end < total - 2) pages.push({direction: 'next'});
326
+ pages.push(total);
327
+ if (pages.length <= maximum) return pages;
328
+ }
329
+ return [this._page];
330
+ }
331
331
 
332
332
  _handleClick(event) {
333
333
  const sizeOption = event.target.closest('[data-pagination-per-page-option]');
@@ -386,8 +386,8 @@ class _pagination {
386
386
  if (input) input.value = String(this._perPage);
387
387
  }
388
388
 
389
- _handleFocusOut(event) {
390
- if (this._updatingPresentation) return;
389
+ _handleFocusOut(event) {
390
+ if (this._updatingPresentation) return;
391
391
  const input = event.target.closest('[data-pagination-per-page]');
392
392
  if (!input) return;
393
393
  const related = event.relatedTarget instanceof Element ? event.relatedTarget : null;
@@ -413,14 +413,14 @@ class _pagination {
413
413
  _resolveContainers() {
414
414
  if (!this._host) return [];
415
415
  const position = this._position();
416
- const existing = Array.from(this._host.querySelectorAll('[data-vg-table-pagination]'));
417
- if (existing.length) {
418
- const selected = position === 'both' ? existing : [existing.find((item) => item.getAttribute('data-position') === position) || existing[0]];
419
- if (this._manageExternalVisibility) existing.forEach((container) => {
420
- if (!this._externalVisibility.has(container)) this._externalVisibility.set(container, container.hidden);
421
- container.hidden = !selected.includes(container);
422
- });
423
- return selected;
416
+ const existing = Array.from(this._host.querySelectorAll('[data-vg-table-pagination]'));
417
+ if (existing.length) {
418
+ const selected = position === 'both' ? existing : [existing.find((item) => item.getAttribute('data-position') === position) || existing[0]];
419
+ if (this._manageExternalVisibility) existing.forEach((container) => {
420
+ if (!this._externalVisibility.has(container)) this._externalVisibility.set(container, container.hidden);
421
+ container.hidden = !selected.includes(container);
422
+ });
423
+ return selected;
424
424
  }
425
425
 
426
426
  const positions = position === 'both' ? ['top', 'bottom'] : [position];
@@ -1,79 +1,79 @@
1
- /**
2
- * Описание: адаптер общего Responsive для представления VGTable.
3
- * Возможности: отбор безопасных параметров пагинации и события таблицы; границы, наследование и подписки делегируются Responsive.
4
- */
5
- import EventHandler from "../../../utils/js/dom/event";
6
- import {Responsive} from "../../../utils/js/components/responsive";
7
-
8
- const object = (value) => value && typeof value === 'object' && !Array.isArray(value);
9
-
10
- // Только представление: page/per, callbacks, storage и параметры запросов не принимаются.
11
- const paginationProfile = (value) => {
12
- const result = {};
13
- if (!object(value)) return result;
14
- if (value.maxButtons === null || (Number.isInteger(value.maxButtons) && value.maxButtons >= 3)) result.maxButtons = value.maxButtons;
15
- if (['left', 'center', 'right', 'between'].includes(value.align)) result.align = value.align;
16
- if (['top', 'bottom', 'both'].includes(value.position)) result.position = value.position;
17
- if (object(value.size)) {
18
- result.size = {};
19
- if (typeof value.size.enabled === 'boolean') result.size.enabled = value.size.enabled;
20
- if (value.size.label === false || typeof value.size.label === 'string') result.size.label = value.size.label;
21
- }
22
- if (object(value.quick) && [true, false, 'auto'].includes(value.quick.enabled)) result.quick = {enabled: value.quick.enabled};
23
- return result;
24
- };
25
-
26
- class _responsive {
27
- constructor(table, options, onChange) {
28
- this._table = table;
29
- this._onChange = onChange;
30
- this._responsive = new Responsive({breakpoints: options.breakpoints, window: table.ownerDocument.defaultView});
31
- this._profiles = Object.fromEntries(Object.keys(this._responsive.breakpoints).map((name) => [name, paginationProfile(options[name]?.pagination)]));
32
- this._breakpoint = null;
33
- this._pagination = {};
34
- this._width = 0;
35
- this._valid = this._responsive.isValid();
36
- }
37
-
38
- init() {
39
- if (!this._valid) {
40
- console.warn('VGTable: responsive.breakpoints must start at xs: 0 and increase through xxl.');
41
- return this;
42
- }
43
- this.refresh();
44
- this._responsive.subscribe(() => this.refresh());
45
- return this;
46
- }
47
-
48
- refresh(force = false) {
49
- if (!this._valid || !this._responsive) return this.getState();
50
- this._width = this._responsive.viewport().width;
51
- const breakpoint = this._responsive.getBreakpointKey(this._width);
52
- if (!force && breakpoint === this._breakpoint) return this.getState();
53
- const previous = this._breakpoint;
54
- this._breakpoint = breakpoint;
55
- this._pagination = this._responsive.resolve(this._profiles, {}, this._width);
56
- this._onChange();
57
- if (previous !== null && previous !== breakpoint) {
58
- EventHandler.trigger(this._table, 'responsivechange.vg.table', {...this.getState(), previous});
59
- }
60
- return this.getState();
61
- }
62
-
63
- getState() {
64
- return {
65
- breakpoint: this._breakpoint,
66
- width: this._responsive?.viewport().width ?? this._width,
67
- reason: this._valid ? null : 'invalid-breakpoints',
68
- pagination: {...this._pagination, size: {...this._pagination.size}, quick: {...this._pagination.quick}},
69
- };
70
- }
71
-
72
- dispose() {
73
- this._width = this._responsive?.viewport().width ?? this._width;
74
- this._responsive?.dispose();
75
- this._responsive = null;
76
- }
77
- }
78
-
79
- export default _responsive;
1
+ /**
2
+ * Описание: адаптер общего Responsive для представления VGTable.
3
+ * Возможности: отбор безопасных параметров пагинации и события таблицы; границы, наследование и подписки делегируются Responsive.
4
+ */
5
+ import EventHandler from "../../../utils/js/dom/event";
6
+ import {Responsive} from "../../../utils/js/components/responsive";
7
+
8
+ const object = (value) => value && typeof value === 'object' && !Array.isArray(value);
9
+
10
+ // Только представление: page/per, callbacks, storage и параметры запросов не принимаются.
11
+ const paginationProfile = (value) => {
12
+ const result = {};
13
+ if (!object(value)) return result;
14
+ if (value.maxButtons === null || (Number.isInteger(value.maxButtons) && value.maxButtons >= 3)) result.maxButtons = value.maxButtons;
15
+ if (['left', 'center', 'right', 'between'].includes(value.align)) result.align = value.align;
16
+ if (['top', 'bottom', 'both'].includes(value.position)) result.position = value.position;
17
+ if (object(value.size)) {
18
+ result.size = {};
19
+ if (typeof value.size.enabled === 'boolean') result.size.enabled = value.size.enabled;
20
+ if (value.size.label === false || typeof value.size.label === 'string') result.size.label = value.size.label;
21
+ }
22
+ if (object(value.quick) && [true, false, 'auto'].includes(value.quick.enabled)) result.quick = {enabled: value.quick.enabled};
23
+ return result;
24
+ };
25
+
26
+ class _responsive {
27
+ constructor(table, options, onChange) {
28
+ this._table = table;
29
+ this._onChange = onChange;
30
+ this._responsive = new Responsive({breakpoints: options.breakpoints, window: table.ownerDocument.defaultView});
31
+ this._profiles = Object.fromEntries(Object.keys(this._responsive.breakpoints).map((name) => [name, paginationProfile(options[name]?.pagination)]));
32
+ this._breakpoint = null;
33
+ this._pagination = {};
34
+ this._width = 0;
35
+ this._valid = this._responsive.isValid();
36
+ }
37
+
38
+ init() {
39
+ if (!this._valid) {
40
+ console.warn('VGTable: responsive.breakpoints must start at xs: 0 and increase through xxl.');
41
+ return this;
42
+ }
43
+ this.refresh();
44
+ this._responsive.subscribe(() => this.refresh());
45
+ return this;
46
+ }
47
+
48
+ refresh(force = false) {
49
+ if (!this._valid || !this._responsive) return this.getState();
50
+ this._width = this._responsive.viewport().width;
51
+ const breakpoint = this._responsive.getBreakpointKey(this._width);
52
+ if (!force && breakpoint === this._breakpoint) return this.getState();
53
+ const previous = this._breakpoint;
54
+ this._breakpoint = breakpoint;
55
+ this._pagination = this._responsive.resolve(this._profiles, {}, this._width);
56
+ this._onChange();
57
+ if (previous !== null && previous !== breakpoint) {
58
+ EventHandler.trigger(this._table, 'responsivechange.vg.table', {...this.getState(), previous});
59
+ }
60
+ return this.getState();
61
+ }
62
+
63
+ getState() {
64
+ return {
65
+ breakpoint: this._breakpoint,
66
+ width: this._responsive?.viewport().width ?? this._width,
67
+ reason: this._valid ? null : 'invalid-breakpoints',
68
+ pagination: {...this._pagination, size: {...this._pagination.size}, quick: {...this._pagination.quick}},
69
+ };
70
+ }
71
+
72
+ dispose() {
73
+ this._width = this._responsive?.viewport().width ?? this._width;
74
+ this._responsive?.dispose();
75
+ this._responsive = null;
76
+ }
77
+ }
78
+
79
+ export default _responsive;