vgapp 1.5.7 → 1.5.8

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 (109) 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 +7 -7
  6. package/app/modules/vgalert/scss/_variables.scss +16 -16
  7. package/app/modules/vgcollapse/scss/_variables.scss +7 -7
  8. package/app/modules/vgcollapse/scss/vgcollapse.scss +5 -5
  9. package/app/modules/vgdropdown/scss/_variables.scss +14 -14
  10. package/app/modules/vgdropdown/scss/vgdropdown.scss +5 -5
  11. package/app/modules/vgfilepreview/js/i18n.js +56 -56
  12. package/app/modules/vgfilepreview/js/renderers/image-modal.js +145 -145
  13. package/app/modules/vgfilepreview/js/renderers/image.js +92 -92
  14. package/app/modules/vgfilepreview/js/renderers/index.js +19 -19
  15. package/app/modules/vgfilepreview/js/renderers/office-modal.js +168 -168
  16. package/app/modules/vgfilepreview/js/renderers/office.js +79 -79
  17. package/app/modules/vgfilepreview/js/renderers/pdf-modal.js +260 -260
  18. package/app/modules/vgfilepreview/js/renderers/pdf.js +76 -76
  19. package/app/modules/vgfilepreview/js/renderers/playlist.js +71 -71
  20. package/app/modules/vgfilepreview/js/renderers/text-modal.js +343 -343
  21. package/app/modules/vgfilepreview/js/renderers/text.js +83 -83
  22. package/app/modules/vgfilepreview/js/renderers/zip-modal.js +522 -522
  23. package/app/modules/vgfilepreview/js/renderers/zip.js +89 -89
  24. package/app/modules/vgfilepreview/readme.md +68 -68
  25. package/app/modules/vgfiles/js/base.js +198 -198
  26. package/app/modules/vgfiles/js/droppable.js +17 -17
  27. package/app/modules/vgfiles/js/render.js +153 -153
  28. package/app/modules/vgfiles/js/sortable.js +52 -52
  29. package/app/modules/vgfiles/js/vgfiles.js +43 -43
  30. package/app/modules/vgfiles/readme.md +123 -123
  31. package/app/modules/vgfiles/scss/_mixins.scss +13 -13
  32. package/app/modules/vgfiles/scss/_variables.scss +10 -10
  33. package/app/modules/vgfiles/scss/vgfiles.scss +28 -28
  34. package/app/modules/vgformsender/js/hideshowpass.js +22 -22
  35. package/app/modules/vgformsender/readme.md +1 -1
  36. package/app/modules/vgformsender/scss/_variables.scss +5 -5
  37. package/app/modules/vgformsender/scss/vgformsender.scss +42 -42
  38. package/app/modules/vglawcookie/js/vglawcookie.js +19 -19
  39. package/app/modules/vglawcookie/scss/_variables.scss +13 -13
  40. package/app/modules/vglawcookie/scss/vglawcookie.scss +5 -5
  41. package/app/modules/vgmodal/js/vgmodal.interaction.js +216 -216
  42. package/app/modules/vgmodal/js/vgmodal.js +9 -9
  43. package/app/modules/vgmodal/js/vgmodal.minimized.js +227 -227
  44. package/app/modules/vgmodal/scss/_variables.scss +17 -17
  45. package/app/modules/vgmodal/scss/vgmodal.scss +77 -77
  46. package/app/modules/vgnav/js/vgnav.js +62 -62
  47. package/app/modules/vgnav/scss/_breakpoints.scss +36 -36
  48. package/app/modules/vgnav/scss/_hamburger.scss +5 -5
  49. package/app/modules/vgnav/scss/_placement.scss +5 -5
  50. package/app/modules/vgnav/scss/_toggle.scss +5 -5
  51. package/app/modules/vgnav/scss/_variables.scss +26 -26
  52. package/app/modules/vgnav/scss/vgnav.scss +41 -41
  53. package/app/modules/vgnestable/README.md +39 -39
  54. package/app/modules/vgrangeslider/js/skins.js +8 -8
  55. package/app/modules/vgrangeslider/js/vgrangeslider.js +29 -29
  56. package/app/modules/vgrangeslider/scss/_variables.scss +55 -55
  57. package/app/modules/vgrangeslider/scss/vgrangeslider.scss +239 -239
  58. package/app/modules/vgrollup/js/vgrollup.js +15 -15
  59. package/app/modules/vgrollup/scss/_variables.scss +15 -15
  60. package/app/modules/vgrollup/scss/vgrollup.scss +6 -6
  61. package/app/modules/vgselect/js/handlers.js +6 -6
  62. package/app/modules/vgselect/js/vgselect.js +167 -123
  63. package/app/modules/vgselect/readme.md +11 -11
  64. package/app/modules/vgselect/scss/_variables.scss +51 -51
  65. package/app/modules/vgselect/scss/vgselect.scss +1 -1
  66. package/app/modules/vgsidebar/js/vgsidebar.js +21 -21
  67. package/app/modules/vgsidebar/scss/_variables.scss +10 -10
  68. package/app/modules/vgsidebar/scss/vgsidebar.scss +5 -5
  69. package/app/modules/vgspy/js/vgspy.js +43 -43
  70. package/app/modules/vgtable/js/_filters.js +10 -6
  71. package/app/modules/vgtable/js/_options.js +16 -16
  72. package/app/modules/vgtable/js/_pagination.js +118 -118
  73. package/app/modules/vgtable/js/_responsive.js +79 -79
  74. package/app/modules/vgtable/js/_sticky-header.js +349 -280
  75. package/app/modules/vgtable/js/vgtable.js +98 -98
  76. package/app/modules/vgtable/scss/_sorting.scss +6 -6
  77. package/app/modules/vgtable/scss/_sticky-header.scss +31 -31
  78. package/app/modules/vgtable/scss/_variables.scss +6 -4
  79. package/app/modules/vgtable/scss/vgtable.scss +8 -4
  80. package/app/modules/vgtabs/js/vgtabs.js +91 -91
  81. package/app/modules/vgtabs/scss/_variables.scss +23 -23
  82. package/app/modules/vgtabs/scss/vgtabs.scss +5 -5
  83. package/app/modules/vgtoast/js/vgtoast.js +4 -4
  84. package/app/modules/vgtoast/scss/_variables.scss +13 -13
  85. package/app/modules/vgtoast/scss/vgtoast.scss +5 -5
  86. package/app/modules/vgtooltip/js/vgtooltip.js +127 -127
  87. package/app/modules/vgtooltip/scss/_variables.scss +10 -10
  88. package/app/modules/vgtooltip/scss/vgtooltip.scss +5 -5
  89. package/app/utils/js/components/audio-metadata.js +240 -240
  90. package/app/utils/js/components/backdrop.js +116 -116
  91. package/app/utils/js/components/file-icon.js +7 -7
  92. package/app/utils/js/components/file-preview.js +304 -304
  93. package/app/utils/js/components/responsive.js +165 -165
  94. package/app/utils/js/components/sanitize.js +150 -150
  95. package/app/utils/js/components/video-metadata.js +140 -140
  96. package/app/utils/scss/_backdrop.scss +5 -5
  97. package/app/utils/scss/_theme-default.scss +12 -12
  98. package/app/utils/scss/_theme.scss +7 -7
  99. package/app/utils/scss/default.scss +9 -9
  100. package/app/utils/scss/functions.scss +21 -21
  101. package/app/utils/scss/index.scss +4 -4
  102. package/app/utils/scss/mixin.scss +16 -16
  103. package/app/utils/scss/variables.scss +147 -147
  104. package/build/vgapp.css +1 -1
  105. package/build/vgapp.css.map +1 -1
  106. package/build/vgapp.js +1 -1
  107. package/build/vgapp.js.map +1 -1
  108. package/index.js +7 -7
  109. 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;