@revolist/revogrid 4.8.1 → 4.8.2

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 (156) hide show
  1. package/dist/cjs/base.plugin-75fc9e81.js.map +1 -1
  2. package/dist/cjs/{column.service-b3b5a4ee.js → column.service-43f8c476.js} +2 -2
  3. package/dist/cjs/{column.service-b3b5a4ee.js.map → column.service-43f8c476.js.map} +1 -1
  4. package/dist/cjs/{filter.button-147884a8.js → filter.button-35f508a0.js} +3 -3
  5. package/dist/cjs/filter.button-35f508a0.js.map +1 -0
  6. package/dist/cjs/{header-cell-renderer-96a37624.js → header-cell-renderer-a3b43bca.js} +2 -2
  7. package/dist/cjs/{header-cell-renderer-96a37624.js.map → header-cell-renderer-a3b43bca.js.map} +1 -1
  8. package/dist/cjs/index.cjs.js +1 -1
  9. package/dist/cjs/{key.utils-be4d0b46.js → key.utils-4a384064.js} +17 -12
  10. package/dist/cjs/key.utils-4a384064.js.map +1 -0
  11. package/dist/cjs/revo-grid.cjs.entry.js +14 -9
  12. package/dist/cjs/revo-grid.cjs.entry.js.map +1 -1
  13. package/dist/cjs/revogr-attribution_6.cjs.entry.js +41 -12
  14. package/dist/cjs/revogr-attribution_6.cjs.entry.js.map +1 -1
  15. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +5 -3
  16. package/dist/cjs/revogr-clipboard_3.cjs.entry.js.map +1 -1
  17. package/dist/cjs/revogr-data_4.cjs.entry.js +10 -9
  18. package/dist/cjs/revogr-data_4.cjs.entry.js.map +1 -1
  19. package/dist/cjs/revogr-filter-panel.cjs.entry.js +13 -8
  20. package/dist/cjs/revogr-filter-panel.cjs.entry.js.map +1 -1
  21. package/dist/cjs/{selection.helpers-032d7192.js → selection.helpers-26d856ba.js} +67 -20
  22. package/dist/cjs/selection.helpers-26d856ba.js.map +1 -0
  23. package/dist/collection/components/clipboard/revogr-clipboard.js +1 -0
  24. package/dist/collection/components/clipboard/revogr-clipboard.js.map +1 -1
  25. package/dist/collection/components/data/revogr-data.js +1 -1
  26. package/dist/collection/components/data/revogr-data.js.map +1 -1
  27. package/dist/collection/components/editors/text-editor.js +4 -3
  28. package/dist/collection/components/editors/text-editor.js.map +1 -1
  29. package/dist/collection/components/header/header-renderer.js +2 -2
  30. package/dist/collection/components/header/header-renderer.js.map +1 -1
  31. package/dist/collection/components/overlay/keyboard.service.js +15 -5
  32. package/dist/collection/components/overlay/keyboard.service.js.map +1 -1
  33. package/dist/collection/components/overlay/revogr-overlay-selection.js +44 -5
  34. package/dist/collection/components/overlay/revogr-overlay-selection.js.map +1 -1
  35. package/dist/collection/components/revoGrid/revo-grid.js +3 -3
  36. package/dist/collection/components/revoGrid/revo-grid.js.map +1 -1
  37. package/dist/collection/plugins/base.plugin.js.map +1 -1
  38. package/dist/collection/plugins/column.auto-size.plugin.js.map +1 -1
  39. package/dist/collection/plugins/column.stretch.plugin.js.map +1 -1
  40. package/dist/collection/plugins/filter/filter.button.js +2 -2
  41. package/dist/collection/plugins/filter/filter.button.js.map +1 -1
  42. package/dist/collection/plugins/filter/filter.plugin.js +7 -2
  43. package/dist/collection/plugins/filter/filter.plugin.js.map +1 -1
  44. package/dist/collection/plugins/filter/filter.pop.js +13 -8
  45. package/dist/collection/plugins/filter/filter.pop.js.map +1 -1
  46. package/dist/collection/plugins/groupingRow/grouping.row.plugin.js.map +1 -1
  47. package/dist/collection/plugins/moveColumn/column.drag.plugin.js.map +1 -1
  48. package/dist/collection/plugins/sorting/sorting.plugin.js.map +1 -1
  49. package/dist/collection/plugins/sorting/sorting.sign.js +2 -1
  50. package/dist/collection/plugins/sorting/sorting.sign.js.map +1 -1
  51. package/dist/collection/services/selection.store.connector.js +62 -19
  52. package/dist/collection/services/selection.store.connector.js.map +1 -1
  53. package/dist/collection/store/selection/selection.store.js +4 -0
  54. package/dist/collection/store/selection/selection.store.js.map +1 -1
  55. package/dist/collection/types/interfaces.js.map +1 -1
  56. package/dist/collection/types/plugin.js.map +1 -1
  57. package/dist/collection/types/plugin.types.js.map +1 -1
  58. package/dist/collection/types/selection.js.map +1 -1
  59. package/dist/collection/utils/key.codes.js +6 -2
  60. package/dist/collection/utils/key.codes.js.map +1 -1
  61. package/dist/collection/utils/key.utils.js +25 -13
  62. package/dist/collection/utils/key.utils.js.map +1 -1
  63. package/dist/esm/base.plugin-e6e2bac2.js.map +1 -1
  64. package/dist/esm/{column.service-ffe99cfc.js → column.service-6aab6fac.js} +2 -2
  65. package/dist/esm/{column.service-ffe99cfc.js.map → column.service-6aab6fac.js.map} +1 -1
  66. package/dist/esm/{filter.button-f132c10a.js → filter.button-f9883a78.js} +3 -3
  67. package/dist/esm/filter.button-f9883a78.js.map +1 -0
  68. package/dist/esm/{header-cell-renderer-cac333a3.js → header-cell-renderer-b8663a21.js} +2 -2
  69. package/dist/esm/{header-cell-renderer-cac333a3.js.map → header-cell-renderer-b8663a21.js.map} +1 -1
  70. package/dist/esm/index.js +1 -1
  71. package/dist/esm/{key.utils-9120fde7.js → key.utils-c4a27968.js} +17 -12
  72. package/dist/esm/key.utils-c4a27968.js.map +1 -0
  73. package/dist/esm/revo-grid.entry.js +14 -9
  74. package/dist/esm/revo-grid.entry.js.map +1 -1
  75. package/dist/esm/revogr-attribution_6.entry.js +41 -12
  76. package/dist/esm/revogr-attribution_6.entry.js.map +1 -1
  77. package/dist/esm/revogr-clipboard_3.entry.js +5 -3
  78. package/dist/esm/revogr-clipboard_3.entry.js.map +1 -1
  79. package/dist/esm/revogr-data_4.entry.js +10 -9
  80. package/dist/esm/revogr-data_4.entry.js.map +1 -1
  81. package/dist/esm/revogr-filter-panel.entry.js +13 -8
  82. package/dist/esm/revogr-filter-panel.entry.js.map +1 -1
  83. package/dist/esm/{selection.helpers-0f3ed629.js → selection.helpers-dbf69cc1.js} +67 -20
  84. package/dist/esm/selection.helpers-dbf69cc1.js.map +1 -0
  85. package/dist/revo-grid/base.plugin-e6e2bac2.js.map +1 -1
  86. package/dist/revo-grid/{column.service-ffe99cfc.js → column.service-6aab6fac.js} +2 -2
  87. package/dist/revo-grid/{filter.button-f132c10a.js → filter.button-f9883a78.js} +2 -2
  88. package/dist/revo-grid/filter.button-f9883a78.js.map +1 -0
  89. package/dist/revo-grid/{header-cell-renderer-cac333a3.js → header-cell-renderer-b8663a21.js} +2 -2
  90. package/dist/revo-grid/index.esm.js +1 -1
  91. package/dist/revo-grid/{key.utils-9120fde7.js → key.utils-c4a27968.js} +2 -2
  92. package/dist/revo-grid/key.utils-c4a27968.js.map +1 -0
  93. package/dist/revo-grid/revo-grid.entry.js +1 -1
  94. package/dist/revo-grid/revo-grid.entry.js.map +1 -1
  95. package/dist/revo-grid/revogr-attribution_6.entry.js +1 -1
  96. package/dist/revo-grid/revogr-attribution_6.entry.js.map +1 -1
  97. package/dist/revo-grid/revogr-clipboard_3.entry.js +1 -1
  98. package/dist/revo-grid/revogr-clipboard_3.entry.js.map +1 -1
  99. package/dist/revo-grid/revogr-data_4.entry.js +1 -1
  100. package/dist/revo-grid/revogr-data_4.entry.js.map +1 -1
  101. package/dist/revo-grid/revogr-filter-panel.entry.js +1 -1
  102. package/dist/revo-grid/revogr-filter-panel.entry.js.map +1 -1
  103. package/dist/revo-grid/selection.helpers-dbf69cc1.js +5 -0
  104. package/dist/revo-grid/selection.helpers-dbf69cc1.js.map +1 -0
  105. package/dist/types/components/overlay/keyboard.service.d.ts +1 -1
  106. package/dist/types/components/overlay/revogr-overlay-selection.d.ts +9 -1
  107. package/dist/types/components.d.ts +5 -0
  108. package/dist/types/plugins/base.plugin.d.ts +8 -8
  109. package/dist/types/plugins/column.auto-size.plugin.d.ts +26 -16
  110. package/dist/types/plugins/column.stretch.plugin.d.ts +1 -1
  111. package/dist/types/plugins/filter/filter.button.d.ts +1 -1
  112. package/dist/types/plugins/filter/filter.plugin.d.ts +24 -16
  113. package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +2 -2
  114. package/dist/types/plugins/moveColumn/column.drag.plugin.d.ts +3 -3
  115. package/dist/types/plugins/sorting/sorting.plugin.d.ts +8 -8
  116. package/dist/types/services/selection.store.connector.d.ts +20 -0
  117. package/dist/types/store/selection/selection.store.d.ts +1 -0
  118. package/dist/types/types/interfaces.d.ts +2 -2
  119. package/dist/types/types/plugin.d.ts +23 -0
  120. package/dist/types/types/plugin.types.d.ts +20 -0
  121. package/dist/types/types/selection.d.ts +24 -0
  122. package/dist/types/utils/key.codes.d.ts +5 -2
  123. package/dist/types/utils/key.utils.d.ts +2 -1
  124. package/hydrate/index.js +153 -59
  125. package/hydrate/index.mjs +153 -59
  126. package/package.json +1 -1
  127. package/standalone/column.service.js +66 -19
  128. package/standalone/column.service.js.map +1 -1
  129. package/standalone/filter.button.js +2 -2
  130. package/standalone/filter.button.js.map +1 -1
  131. package/standalone/revo-grid.js +10 -5
  132. package/standalone/revo-grid.js.map +1 -1
  133. package/standalone/revogr-clipboard2.js +1 -0
  134. package/standalone/revogr-clipboard2.js.map +1 -1
  135. package/standalone/revogr-data2.js +1 -1
  136. package/standalone/revogr-data2.js.map +1 -1
  137. package/standalone/revogr-edit2.js +19 -13
  138. package/standalone/revogr-edit2.js.map +1 -1
  139. package/standalone/revogr-filter-panel.js +12 -7
  140. package/standalone/revogr-filter-panel.js.map +1 -1
  141. package/standalone/revogr-header2.js +5 -4
  142. package/standalone/revogr-header2.js.map +1 -1
  143. package/standalone/revogr-overlay-selection2.js +39 -10
  144. package/standalone/revogr-overlay-selection2.js.map +1 -1
  145. package/dist/cjs/filter.button-147884a8.js.map +0 -1
  146. package/dist/cjs/key.utils-be4d0b46.js.map +0 -1
  147. package/dist/cjs/selection.helpers-032d7192.js.map +0 -1
  148. package/dist/esm/filter.button-f132c10a.js.map +0 -1
  149. package/dist/esm/key.utils-9120fde7.js.map +0 -1
  150. package/dist/esm/selection.helpers-0f3ed629.js.map +0 -1
  151. package/dist/revo-grid/filter.button-f132c10a.js.map +0 -1
  152. package/dist/revo-grid/key.utils-9120fde7.js.map +0 -1
  153. package/dist/revo-grid/selection.helpers-0f3ed629.js +0 -5
  154. package/dist/revo-grid/selection.helpers-0f3ed629.js.map +0 -1
  155. /package/dist/revo-grid/{column.service-ffe99cfc.js.map → column.service-6aab6fac.js.map} +0 -0
  156. /package/dist/revo-grid/{header-cell-renderer-cac333a3.js.map → header-cell-renderer-b8663a21.js.map} +0 -0
@@ -3,10 +3,30 @@ import { DataProvider } from '../services/data.provider';
3
3
  import DimensionProvider from '../services/dimension.provider';
4
4
  import SelectionStoreConnector from '../services/selection.store.connector';
5
5
  import ViewportProvider from '../services/viewport.provider';
6
+ /**
7
+ * Services that are provided by the various plugins for use by the grid. Each plugin
8
+ * is responsible for providing a specific service, and the `PluginProviders` type collects all the services provided
9
+ * by the plugins.
10
+ */
6
11
  export type PluginProviders = {
12
+ /**
13
+ * The data service provides access to the grid data.
14
+ */
7
15
  data: DataProvider;
16
+ /**
17
+ * The dimension service provides access to the grid's dimensions and settings.
18
+ */
8
19
  dimension: DimensionProvider;
20
+ /**
21
+ * The selection service provides access to the grid's selection state.
22
+ */
9
23
  selection: SelectionStoreConnector;
24
+ /**
25
+ * The column service provides access to the grid's column data.
26
+ */
10
27
  column: ColumnDataProvider;
28
+ /**
29
+ * The viewport service provides access to the grid's viewport state.
30
+ */
11
31
  viewport: ViewportProvider;
12
32
  };
@@ -3,13 +3,37 @@ import { DimensionRows, DimensionCols } from './dimension';
3
3
  import { ColumnProp, DataType, DataLookup, HyperFunc, ColumnDataSchemaModel } from './interfaces';
4
4
  export type RowIndex = number;
5
5
  export type ColIndex = number;
6
+ /**
7
+ * Represents the state of the selection store.
8
+ * It contains information about the selection range, temporary range,
9
+ * focused cell, editing cell, last focused cell, and next cell to focus.
10
+ */
6
11
  export type SelectionStoreState = {
7
12
  range: RangeArea | null;
13
+ /**
14
+ * Temporary range selection area
15
+ */
8
16
  tempRange: RangeArea | null;
17
+ /**
18
+ * Type of the temporary range selection
19
+ */
9
20
  tempRangeType: string | null;
21
+ /**
22
+ * Focused cell coordinate
23
+ */
10
24
  focus: Cell | null;
25
+ /**
26
+ * Editing cell store
27
+ */
11
28
  edit: EditCellStore | null;
29
+ /**
30
+ * Last cell which was focused
31
+ */
12
32
  lastCell: Cell | null;
33
+ /**
34
+ * Next cell to focus
35
+ */
36
+ nextFocus: Cell | null;
13
37
  };
14
38
  export type RangeArea = {
15
39
  x: ColIndex;
@@ -49,7 +49,7 @@ declare enum codes {
49
49
  V = 86,
50
50
  X = 88
51
51
  }
52
- declare enum codesLetter {
52
+ export declare enum codesLetter {
53
53
  ENTER = "Enter",
54
54
  ENTER_NUM = "NumpadEnter",
55
55
  A = "KeyA",
@@ -66,5 +66,8 @@ declare enum codesLetter {
66
66
  ARROW_DOWN = "ArrowDown",
67
67
  SHIFT = "Shift"
68
68
  }
69
+ export declare enum keyValues {
70
+ ENTER = "Enter",// Enter + NumpadEnter
71
+ TAB = "Tab"
72
+ }
69
73
  export default codes;
70
- export { codesLetter };
@@ -5,7 +5,8 @@ export declare function isCtrlKey(code: number, platform: string): boolean;
5
5
  export declare function isCtrlMetaKey(code: KeyCodesEnum): boolean;
6
6
  export declare function isClear(code: string): boolean;
7
7
  export declare function isTab(code: string): boolean;
8
- export declare function isEnterKey(code: string): boolean;
8
+ export declare function isTabKeyValue(key: string): boolean;
9
+ export declare function isEnterKeyValue(key: string): boolean;
9
10
  export declare function isCut(event: KeyboardEvent): boolean;
10
11
  export declare function isCopy(event: KeyboardEvent): boolean;
11
12
  export declare function isPaste(event: KeyboardEvent): boolean;
package/hydrate/index.js CHANGED
@@ -2295,6 +2295,7 @@ class Clipboard {
2295
2295
  // if html, then search for table if no table fallback to regular text parsing
2296
2296
  if (beforePaste.detail.isHTML) {
2297
2297
  const table = this.htmlParse(beforePaste.detail.raw);
2298
+ // fallback to text if not possible to parse as html
2298
2299
  parsedData = table || this.textParse(dataText);
2299
2300
  }
2300
2301
  else {
@@ -2424,8 +2425,8 @@ const TrashButton = () => {
2424
2425
  hAsync("svg", { class: "trash-img", viewBox: "0 0 24 24" },
2425
2426
  hAsync("path", { fill: "currentColor", d: "M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M7,6H17V19H7V6M9,8V17H11V8H9M13,8V17H15V8H13Z" }))));
2426
2427
  };
2427
- const AndOrButton = ({ isAnd }) => {
2428
- return hAsync("button", { class: { [AND_OR_BUTTON]: true, 'light revo-button': true } }, isAnd ? 'and' : 'or');
2428
+ const AndOrButton = ({ text }) => {
2429
+ return hAsync("button", { class: { [AND_OR_BUTTON]: true, 'light revo-button': true } }, text);
2429
2430
  };
2430
2431
  function isFilterBtn(e) {
2431
2432
  if (e.classList.contains(FILTER_BUTTON_CLASS)) {
@@ -3016,6 +3017,10 @@ class FilterPanel {
3016
3017
  // drops the filter
3017
3018
  reset: 'Cancel',
3018
3019
  cancel: 'Close',
3020
+ add: 'Add more condition...',
3021
+ placeholder: 'Enter value...',
3022
+ and: 'and',
3023
+ or: 'or',
3019
3024
  };
3020
3025
  this.debouncedApplyFilter = debounce_1(() => {
3021
3026
  this.filterChange.emit(this.filterItems);
@@ -3065,7 +3070,8 @@ class FilterPanel {
3065
3070
  const options = [];
3066
3071
  const prop = (_a = this.changes) === null || _a === void 0 ? void 0 : _a.prop;
3067
3072
  if (!isDefaultTypeRemoved) {
3068
- options.push(hAsync("option", { selected: this.currentFilterType === defaultType, value: defaultType }, prop && this.filterItems[prop] && this.filterItems[prop].length > 0 ? 'Add more condition...' : this.filterNames[defaultType]));
3073
+ const capts = Object.assign(this.filterCaptionsInternal, this.filterCaptions);
3074
+ options.push(hAsync("option", { selected: this.currentFilterType === defaultType, value: defaultType }, prop && this.filterItems[prop] && this.filterItems[prop].length > 0 ? capts.add : this.filterNames[defaultType]));
3069
3075
  }
3070
3076
  for (let gIndex in this.filterTypes) {
3071
3077
  options.push(...this.filterTypes[gIndex].map(k => (hAsync("option", { value: k, selected: type === k }, this.filterNames[k]))));
@@ -3079,7 +3085,8 @@ class FilterPanel {
3079
3085
  return '';
3080
3086
  if (this.filterEntities[currentFilter[index].type].extra !== 'input')
3081
3087
  return '';
3082
- return (hAsync("input", { id: `filter-input-${currentFilter[index].id}`, placeholder: "Enter value...", type: "text", value: currentFilter[index].value, onInput: this.onUserInput.bind(this, index, prop), onKeyDown: e => this.onKeyDown(e) }));
3088
+ const capts = Object.assign(this.filterCaptionsInternal, this.filterCaptions);
3089
+ return (hAsync("input", { id: `filter-input-${currentFilter[index].id}`, placeholder: capts.placeholder, type: "text", value: currentFilter[index].value, onInput: this.onUserInput.bind(this, index, prop), onKeyDown: e => this.onKeyDown(e) }));
3083
3090
  }
3084
3091
  getFilterItemsList() {
3085
3092
  var _a;
@@ -3087,11 +3094,12 @@ class FilterPanel {
3087
3094
  if (!(prop || prop === 0))
3088
3095
  return '';
3089
3096
  const propFilters = this.filterItems[prop] || [];
3097
+ const capts = Object.assign(this.filterCaptionsInternal, this.filterCaptions);
3090
3098
  return (hAsync("div", { key: this.filterId }, propFilters.map((d, index) => {
3091
3099
  let andOrButton;
3092
3100
  // hide toggle button if there is only one filter and the last one
3093
3101
  if (index !== this.filterItems[prop].length - 1) {
3094
- andOrButton = (hAsync("div", { onClick: () => this.toggleFilterAndOr(d.id) }, hAsync(AndOrButton, { isAnd: d.relation === 'and' })));
3102
+ andOrButton = (hAsync("div", { onClick: () => this.toggleFilterAndOr(d.id) }, hAsync(AndOrButton, { text: d.relation === 'and' ? capts.and : capts.or })));
3095
3103
  }
3096
3104
  return (hAsync("div", { key: d.id, class: FILTER_LIST_CLASS }, hAsync("div", { class: { 'select-input': true } }, hAsync("select", { class: "select-css select-filter", onChange: e => this.onFilterTypeChange(e, prop, index) }, this.renderSelectOptions(this.filterItems[prop][index].type, true)), hAsync("div", { class: FILTER_LIST_CLASS_ACTION }, andOrButton), hAsync("div", { onClick: () => this.onRemoveFilter(d.id) }, hAsync(TrashButton, null))), hAsync("div", null, this.renderExtra(prop, index))));
3097
3105
  }), propFilters.length > 0 ? hAsync("div", { class: "add-filter-divider" }) : ''));
@@ -3111,8 +3119,7 @@ class FilterPanel {
3111
3119
  }
3112
3120
  onFilterTypeChange(e, prop, index) {
3113
3121
  const el = e.target;
3114
- const type = el.value;
3115
- this.filterItems[prop][index].type = type;
3122
+ this.filterItems[prop][index].type = el.value;
3116
3123
  // this re-renders the input to know if we need extra input
3117
3124
  this.filterId++;
3118
3125
  // adding setTimeout will wait for the next tick DOM update then focus on input
@@ -3126,8 +3133,7 @@ class FilterPanel {
3126
3133
  }
3127
3134
  onAddNewFilter(e) {
3128
3135
  const el = e.target;
3129
- const type = el.value;
3130
- this.currentFilterType = type;
3136
+ this.currentFilterType = el.value;
3131
3137
  this.addNewFilterToProp();
3132
3138
  // reset value after adding new filter
3133
3139
  const select = document.getElementById('add-filter');
@@ -7551,6 +7557,7 @@ function defaultState() {
7551
7557
  focus: null,
7552
7558
  edit: null,
7553
7559
  lastCell: null,
7560
+ nextFocus: null,
7554
7561
  };
7555
7562
  }
7556
7563
  class SelectionStore {
@@ -7582,6 +7589,9 @@ class SelectionStore {
7582
7589
  });
7583
7590
  }
7584
7591
  }
7592
+ setNextFocus(focus) {
7593
+ setStore(this.store, { nextFocus: focus });
7594
+ }
7585
7595
  setTempArea(range) {
7586
7596
  setStore(this.store, { tempRange: range === null || range === void 0 ? void 0 : range.area, tempRangeType: range === null || range === void 0 ? void 0 : range.type, edit: null });
7587
7597
  }
@@ -7767,42 +7777,91 @@ class SelectionStoreConnector {
7767
7777
  this.focusByCell(storePos, editCell, editCell);
7768
7778
  this.setEdit('');
7769
7779
  }
7780
+ /**
7781
+ * Sets the next focus cell before the current one.
7782
+ *
7783
+ * @param focus - The cell to set as the next focus.
7784
+ */
7785
+ beforeNextFocusCell(focus) {
7786
+ var _a;
7787
+ // If there is no focused store, return early.
7788
+ if (!this.focusedStore) {
7789
+ return;
7790
+ }
7791
+ // Get the next store based on the current focus and the last cell.
7792
+ const next = this.getNextStore(focus, this.focusedStore.position, this.focusedStore.entity.store.get('lastCell'));
7793
+ // Set the next focus cell in the store.
7794
+ (_a = next.store) === null || _a === void 0 ? void 0 : _a.setNextFocus(Object.assign(Object.assign({}, focus), next.item));
7795
+ }
7770
7796
  focusByCell(storePos, start, end) {
7771
7797
  const store = this.stores[storePos.y][storePos.x];
7772
7798
  this.focus(store, { focus: start, end });
7773
7799
  }
7774
7800
  focus(store, { focus, end }) {
7801
+ const currentStorePointer = this.getCurrentStorePointer(store);
7802
+ if (!currentStorePointer) {
7803
+ return null;
7804
+ }
7805
+ // check for the focus in nearby store/viewport
7806
+ const lastCell = store.store.get('lastCell');
7807
+ const next = this.getNextStore(focus, currentStorePointer, lastCell);
7808
+ // if next store present - update
7809
+ if (next === null || next === void 0 ? void 0 : next.store) {
7810
+ const item = Object.assign(Object.assign({}, focus), next.item);
7811
+ this.focus(next.store, { focus: item, end: item });
7812
+ return null;
7813
+ }
7814
+ focus = cropCellToMax(focus, lastCell);
7815
+ end = cropCellToMax(end, lastCell);
7816
+ store.setFocus(focus, end);
7817
+ return focus;
7818
+ }
7819
+ /**
7820
+ * Retrieves the current store pointer based on the active store.
7821
+ * Clears focus from all stores except the active one.
7822
+ */
7823
+ getCurrentStorePointer(store) {
7775
7824
  let currentStorePointer;
7776
- // clear all stores focus leave only active one
7825
+ // Iterate through all stores
7777
7826
  for (let y in this.stores) {
7778
7827
  for (let x in this.stores[y]) {
7779
7828
  const s = this.stores[y][x];
7780
- // clear other stores, only one area can be selected
7829
+ // Clear focus from stores other than the active one
7781
7830
  if (s !== store) {
7782
7831
  s.clearFocus();
7783
7832
  }
7784
7833
  else {
7785
- currentStorePointer = { x: parseInt(x, 10), y: parseInt(y, 10) };
7834
+ // Update the current store pointer with the active store coordinates
7835
+ currentStorePointer = {
7836
+ x: parseInt(x, 10),
7837
+ y: parseInt(y, 10)
7838
+ };
7786
7839
  }
7787
7840
  }
7788
7841
  }
7789
- if (!currentStorePointer) {
7790
- return null;
7791
- }
7792
- // check is focus in next store
7793
- const lastCell = store.store.get('lastCell');
7842
+ return currentStorePointer;
7843
+ }
7844
+ /**
7845
+ * Retrieves the next store based on the focus cell and current store pointer.
7846
+ * If the next store exists, returns an object with the next store and the item in the new store.
7847
+ * If the next store does not exist, returns null.
7848
+ */
7849
+ getNextStore(focus, currentStorePointer, lastCell) {
7794
7850
  // item in new store
7795
7851
  const nextItem = nextCell(focus, lastCell);
7796
- let nextStore;
7852
+ let nextStore = null;
7797
7853
  if (nextItem) {
7798
7854
  for (let i in nextItem) {
7799
7855
  let type = i;
7800
7856
  let stores;
7801
7857
  switch (type) {
7802
7858
  case 'x':
7859
+ // Get the X stores for the current Y coordinate of the current store pointer
7803
7860
  stores = this.getXStores(currentStorePointer.y);
7804
7861
  break;
7805
7862
  case 'y':
7863
+ // Get the Y stores for the current X coordinate of the current store pointer
7864
+ stores = this.getYStores(currentStorePointer.x);
7806
7865
  stores = this.getYStores(currentStorePointer.x);
7807
7866
  break;
7808
7867
  }
@@ -7818,16 +7877,10 @@ class SelectionStoreConnector {
7818
7877
  }
7819
7878
  }
7820
7879
  }
7821
- // if next store present - update
7822
- if (nextStore) {
7823
- let item = Object.assign(Object.assign({}, focus), nextItem);
7824
- this.focus(nextStore, { focus: item, end: item });
7825
- return null;
7826
- }
7827
- focus = cropCellToMax(focus, lastCell);
7828
- end = cropCellToMax(end, lastCell);
7829
- store.setFocus(focus, end);
7830
- return focus;
7880
+ return {
7881
+ store: nextStore,
7882
+ item: nextItem,
7883
+ };
7831
7884
  }
7832
7885
  clearAll() {
7833
7886
  var _a;
@@ -9141,6 +9194,11 @@ var codesLetter;
9141
9194
  codesLetter["ARROW_DOWN"] = "ArrowDown";
9142
9195
  codesLetter["SHIFT"] = "Shift";
9143
9196
  })(codesLetter || (codesLetter = {}));
9197
+ var keyValues;
9198
+ (function (keyValues) {
9199
+ keyValues["ENTER"] = "Enter";
9200
+ keyValues["TAB"] = "Tab";
9201
+ })(keyValues || (keyValues = {}));
9144
9202
 
9145
9203
  function isTouch(e) {
9146
9204
  return !!e.touches;
@@ -9365,24 +9423,24 @@ function isClear(code) {
9365
9423
  function isTab(code) {
9366
9424
  return codesLetter.TAB === code;
9367
9425
  }
9368
- function isEnterKey(code) {
9369
- return code === codesLetter.ENTER || code === codesLetter.ENTER_NUM;
9426
+ function isEnterKeyValue(key) {
9427
+ return keyValues.ENTER === key;
9370
9428
  }
9371
9429
  function isCut(event) {
9372
- return (event.ctrlKey && event.code === 'KeyX') || // Ctrl + X on Windows
9373
- (event.metaKey && event.code === 'KeyX'); // Cmd + X on Mac
9430
+ return ((event.ctrlKey && event.code === 'KeyX') || // Ctrl + X on Windows
9431
+ (event.metaKey && event.code === 'KeyX')); // Cmd + X on Mac
9374
9432
  }
9375
9433
  function isCopy(event) {
9376
- return (event.ctrlKey && event.code === 'KeyC') || // Ctrl + C on Windows
9377
- (event.metaKey && event.code === 'KeyC'); // Cmd + C on Mac
9434
+ return ((event.ctrlKey && event.code === 'KeyC') || // Ctrl + C on Windows
9435
+ (event.metaKey && event.code === 'KeyC')); // Cmd + C on Mac
9378
9436
  }
9379
9437
  function isPaste(event) {
9380
- return (event.ctrlKey && event.code === 'KeyV') || // Ctrl + V on Windows
9381
- (event.metaKey && event.code === 'KeyV'); // Cmd + V on Mac
9438
+ return ((event.ctrlKey && event.code === 'KeyV') || // Ctrl + V on Windows
9439
+ (event.metaKey && event.code === 'KeyV')); // Cmd + V on Mac
9382
9440
  }
9383
9441
  function isAll(event) {
9384
- return (event.ctrlKey && event.code === 'KeyA') || // Ctrl + A on Windows
9385
- (event.metaKey && event.code === 'KeyA'); // Cmd + A on Mac
9442
+ return ((event.ctrlKey && event.code === 'KeyA') || // Ctrl + A on Windows
9443
+ (event.metaKey && event.code === 'KeyA')); // Cmd + A on Mac
9386
9444
  }
9387
9445
 
9388
9446
  /* Generate range on size
@@ -9466,11 +9524,11 @@ class KeyboardService {
9466
9524
  }
9467
9525
  // tab key means same as arrow right
9468
9526
  if (codesLetter.TAB === e.code) {
9469
- this.keyChangeSelection(e, canRange);
9527
+ await this.keyChangeSelection(e, canRange);
9470
9528
  return;
9471
9529
  }
9472
9530
  // pressed enter
9473
- if (isEnterKey(e.code)) {
9531
+ if (isEnterKeyValue(e.key)) {
9474
9532
  this.sv.change();
9475
9533
  return;
9476
9534
  }
@@ -9535,15 +9593,19 @@ class KeyboardService {
9535
9593
  if (!data) {
9536
9594
  return false;
9537
9595
  }
9596
+ const eData = this.sv.getData();
9538
9597
  if (isMulti) {
9539
- const eData = this.sv.getData();
9540
9598
  if (isAfterLast(data.end, eData.lastCell) || isBeforeFirst(data.start)) {
9541
9599
  return false;
9542
9600
  }
9543
9601
  const range = getRange(data.start, data.end);
9544
9602
  return this.sv.range(range);
9545
9603
  }
9546
- return this.sv.focusNext(data.start, changes);
9604
+ return this.sv.focus(data.start, changes, isAfterLast(data.start, eData.lastCell)
9605
+ ? 1
9606
+ : isBeforeFirst(data.start)
9607
+ ? -1
9608
+ : 0);
9547
9609
  }
9548
9610
  /** Monitor key direction changes */
9549
9611
  changeDirectionKey(e, canRange) {
@@ -9551,6 +9613,12 @@ class KeyboardService {
9551
9613
  if (DIRECTION_CODES.includes(e.code)) {
9552
9614
  e.preventDefault();
9553
9615
  }
9616
+ if (e.shiftKey) {
9617
+ switch (e.code) {
9618
+ case codesLetter.TAB:
9619
+ return { changes: { x: -1 }, isMulti: false };
9620
+ }
9621
+ }
9554
9622
  switch (e.code) {
9555
9623
  case codesLetter.ARROW_UP:
9556
9624
  return { changes: { y: -1 }, isMulti };
@@ -9789,6 +9857,7 @@ class OverlaySelection {
9789
9857
  this.beforeRegionPaste = createEvent(this, "beforepasteregion", 7);
9790
9858
  this.cellEditApply = createEvent(this, "celleditapply", 7);
9791
9859
  this.beforeFocusCell = createEvent(this, "beforecellfocusinit", 7);
9860
+ this.beforeNextViewportFocus = createEvent(this, "beforenextvpfocus", 7);
9792
9861
  this.setEdit = createEvent(this, "setedit", 7);
9793
9862
  this.beforeApplyRange = createEvent(this, "beforeapplyrange", 7);
9794
9863
  this.beforeSetRange = createEvent(this, "beforesetrange", 7);
@@ -9811,6 +9880,7 @@ class OverlaySelection {
9811
9880
  this.keyboardService = null;
9812
9881
  this.autoFillService = null;
9813
9882
  this.revogrEdit = null;
9883
+ this.unsubscribeSelectionStore = [];
9814
9884
  this.readonly = undefined;
9815
9885
  this.range = undefined;
9816
9886
  this.canDrag = undefined;
@@ -9878,12 +9948,26 @@ class OverlaySelection {
9878
9948
  });
9879
9949
  }
9880
9950
  // #endregion
9881
- /** Selection & Keyboard */
9951
+ /**
9952
+ * Selection & Keyboard
9953
+ */
9882
9954
  selectionServiceSet(s) {
9955
+ // clear subscriptions
9956
+ this.unsubscribeSelectionStore.forEach(v => v());
9957
+ this.unsubscribeSelectionStore.length = 0;
9958
+ this.unsubscribeSelectionStore.push(s.onChange('nextFocus', (v) => this.doFocus(v, v)));
9883
9959
  this.keyboardService = new KeyboardService({
9884
9960
  selectionStore: s,
9885
9961
  range: r => this.triggerRangeEvent(r),
9886
- focusNext: (f, next) => this.doFocus(f, f, next),
9962
+ focus: (f, changes, focusNextViewport) => {
9963
+ if (focusNextViewport) {
9964
+ this.beforeNextViewportFocus.emit(f);
9965
+ return false;
9966
+ }
9967
+ else {
9968
+ return this.doFocus(f, f, changes);
9969
+ }
9970
+ },
9887
9971
  change: val => {
9888
9972
  if (this.readonly) {
9889
9973
  return;
@@ -9930,6 +10014,9 @@ class OverlaySelection {
9930
10014
  }
9931
10015
  disconnectedCallback() {
9932
10016
  var _a;
10017
+ // clear subscriptions
10018
+ this.unsubscribeSelectionStore.forEach(v => v());
10019
+ this.unsubscribeSelectionStore.length = 0;
9933
10020
  (_a = this.columnService) === null || _a === void 0 ? void 0 : _a.destroy();
9934
10021
  }
9935
10022
  async componentWillRender() {
@@ -9998,17 +10085,17 @@ class OverlaySelection {
9998
10085
  nodes.push(hAsync("revogr-order-editor", { ref: e => (this.orderEditor = e), dataStore: this.dataStore, dimensionRow: this.dimensionRow, dimensionCol: this.dimensionCol, parent: this.element, onRowdragstartinit: e => this.rowDragStart(e) }));
9999
10086
  }
10000
10087
  }
10001
- return (hAsync(Host, { key: '676c1ac41a3658f7c2cb93ada69fbf141a51c660', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true) }, nodes, hAsync("slot", { key: '42f4e051d6f531bd92e22106ca0eb1808068e8d0', name: "data" })));
10088
+ return (hAsync(Host, { key: '81dee4cfcce410cefb2bd9ff2661261472fc3a75', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true) }, nodes, hAsync("slot", { key: '6ac75c388ae3fbc5539a27c3acd58178dd53d1af', name: "data" })));
10002
10089
  }
10003
10090
  /**
10004
10091
  * Executes the focus operation on the specified range of cells.
10005
10092
  */
10006
- doFocus(focus, end, next) {
10093
+ doFocus(focus, end, changes) {
10007
10094
  const { defaultPrevented } = this.beforeFocusCell.emit(this.columnService.getSaveData(focus.y, focus.x));
10008
10095
  if (defaultPrevented) {
10009
10096
  return false;
10010
10097
  }
10011
- const evData = Object.assign({ range: Object.assign(Object.assign({}, focus), { x1: end.x, y1: end.y }), next }, this.types);
10098
+ const evData = Object.assign({ range: Object.assign(Object.assign({}, focus), { x1: end.x, y1: end.y }), next: changes }, this.types);
10012
10099
  const applyEvent = this.applyFocus.emit(evData);
10013
10100
  if (applyEvent.defaultPrevented) {
10014
10101
  return false;
@@ -10278,8 +10365,8 @@ class TextEditor {
10278
10365
  }
10279
10366
  }
10280
10367
  onKeyDown(e) {
10281
- const isEnter = isEnterKey(e.code);
10282
- const isKeyTab = isTab(e.code);
10368
+ const isEnter = isEnterKeyValue(e.key);
10369
+ const isKeyTab = isTab(e.key);
10283
10370
  if ((isKeyTab || isEnter) &&
10284
10371
  e.target &&
10285
10372
  this.saveCallback &&
@@ -10316,6 +10403,7 @@ class TextEditor {
10316
10403
  var _a;
10317
10404
  return h('input', {
10318
10405
  type: 'text',
10406
+ enterKeyHint: 'enter',
10319
10407
  // set input value from cell data
10320
10408
  value: ((_a = this.editCell) === null || _a === void 0 ? void 0 : _a.val) || '',
10321
10409
  // save input element as ref for further usage
@@ -11717,7 +11805,12 @@ class FilterPlugin extends BasePlugin {
11717
11805
  const buttonPos = el.getBoundingClientRect();
11718
11806
  const prop = e.detail.prop;
11719
11807
  this.pop.filterTypes = this.getColumnFilter(e.detail.filter);
11720
- this.pop.show(Object.assign(Object.assign({}, this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, prop }));
11808
+ this.pop.show(Object.assign(Object.assign({}, this.filterCollection[prop]), { x: -9999, y: buttonPos.y - gridPos.y + buttonPos.height, prop }));
11809
+ // fix filter dialog is out of view
11810
+ setTimeout(async () => {
11811
+ const { width } = this.pop.getBoundingClientRect();
11812
+ this.pop.style.left = Math.min(buttonPos.x - gridPos.x, gridPos.width - width - 20) + 'px';
11813
+ });
11721
11814
  }
11722
11815
  getColumnFilter(type) {
11723
11816
  let filterType = 'string';
@@ -11782,7 +11875,7 @@ class FilterPlugin extends BasePlugin {
11782
11875
  }
11783
11876
  // applies the hasFilter to the columns to show filter icon
11784
11877
  await this.revogrid.updateColumns(columnsToUpdate);
11785
- this.emit('afterFilterApply');
11878
+ this.emit('afterfilterapply');
11786
11879
  }
11787
11880
  async clearFiltering() {
11788
11881
  this.multiFilterItems = {};
@@ -14745,7 +14838,7 @@ class RevoGridComponent {
14745
14838
  // Render viewport data (vertical sections)
14746
14839
  view.dataPorts.forEach(data => {
14747
14840
  const key = `${data.type}_${view.type}`;
14748
- const dataView = (hAsync("revogr-overlay-selection", Object.assign({}, data, { isMobileDevice: isMobile, selectionStore: data.segmentSelectionStore, onSelectall: () => this.selectionStoreConnector.selectAll(), editors: this.editors, readonly: this.readonly, range: this.range, useClipboard: this.useClipboard, applyChangesOnClose: this.applyOnClose, additionalData: this.additionalData, slot: data.slot, onCanceledit: () => this.selectionStoreConnector.setEdit(false), onSetedit: ({ detail }) => {
14841
+ const dataView = (hAsync("revogr-overlay-selection", Object.assign({}, data, { isMobileDevice: isMobile, selectionStore: data.segmentSelectionStore, onSelectall: () => this.selectionStoreConnector.selectAll(), editors: this.editors, readonly: this.readonly, range: this.range, useClipboard: this.useClipboard, applyChangesOnClose: this.applyOnClose, additionalData: this.additionalData, slot: data.slot, onBeforenextvpfocus: (e) => this.selectionStoreConnector.beforeNextFocusCell(e.detail), onCanceledit: () => this.selectionStoreConnector.setEdit(false), onSetedit: ({ detail }) => {
14749
14842
  const event = this.beforeeditstart.emit(detail);
14750
14843
  if (!event.defaultPrevented) {
14751
14844
  this.selectionStoreConnector.setEdit(detail.val);
@@ -14762,11 +14855,11 @@ class RevoGridComponent {
14762
14855
  const typeCol = 'rgCol';
14763
14856
  const viewports = this.viewportProvider.stores;
14764
14857
  const dimensions = this.dimensionProvider.stores;
14765
- return (hAsync(Host, { key: '09af373e244a347c42e7f432ec8814ba3dbd9169', [`${UUID}`]: this.uuid }, this.hideAttribution ? null : (hAsync("revogr-attribution", { class: "attribution" })), hAsync("div", { key: '1ba5db255ea939bef4cef307abf5933d3727e828', class: "main-viewport", onClick: (e) => {
14858
+ return (hAsync(Host, { key: '9c290a3e6cff0f2e2375f98e020292646dc51ac6', [`${UUID}`]: this.uuid }, this.hideAttribution ? null : (hAsync("revogr-attribution", { class: "attribution" })), hAsync("div", { key: '48417bd11ec1eae854bcc0be942a7e4d27b630ac', class: "main-viewport", onClick: (e) => {
14766
14859
  if (e.currentTarget === e.target) {
14767
14860
  this.viewport.clearEdit();
14768
14861
  }
14769
- } }, hAsync("div", { key: 'e98b55cf7736922791256b9c2b04e8dc5a8ec06b', class: "viewports" }, hAsync("slot", { key: '079f088ea130397be68864c4beeba8be4552b58d', name: "viewport" }), viewportSections, hAsync("revogr-scroll-virtual", { key: 'a37ef654eac58654c71f0b9e772d3915f0793aa9', class: "vertical", dimension: typeRow, viewportStore: viewports[typeRow].store, dimensionStore: dimensions[typeRow].store, ref: el => this.scrollingService.registerElement(el, 'rowScroll'), onScrollvirtual: e => this.scrollingService.proxyScroll(e.detail) }), hAsync(OrderRenderer, { key: 'db366dd88f50f54f650aece77502ba415cb14e48', ref: e => (this.orderService = e) }))), hAsync("revogr-scroll-virtual", { key: '2030e23241ccfc74895e02d6bd2733244a909ff6', class: "horizontal", dimension: typeCol, viewportStore: viewports[typeCol].store, dimensionStore: dimensions[typeCol].store, ref: el => this.scrollingService.registerElement(el, 'colScroll'), onScrollvirtual: e => this.scrollingService.proxyScroll(e.detail) }), this.extraElements));
14862
+ } }, hAsync("div", { key: '870bb866b39ecdd7af06a0a265891adf76c0a736', class: "viewports" }, hAsync("slot", { key: '6a8b432762f85064e190ead625168913cd610d09', name: "viewport" }), viewportSections, hAsync("revogr-scroll-virtual", { key: '39d6c67a2910f411131bc433441219eb5ddaafa2', class: "vertical", dimension: typeRow, viewportStore: viewports[typeRow].store, dimensionStore: dimensions[typeRow].store, ref: el => this.scrollingService.registerElement(el, 'rowScroll'), onScrollvirtual: e => this.scrollingService.proxyScroll(e.detail) }), hAsync(OrderRenderer, { key: '5b0c5d2864da2b7fab55ca0709e5b1250e22db5f', ref: e => (this.orderService = e) }))), hAsync("revogr-scroll-virtual", { key: 'fde782c69924d2a4d1ba5e538da28ca64e8ac292', class: "horizontal", dimension: typeCol, viewportStore: viewports[typeCol].store, dimensionStore: dimensions[typeCol].store, ref: el => this.scrollingService.registerElement(el, 'colScroll'), onScrollvirtual: e => this.scrollingService.proxyScroll(e.detail) }), this.extraElements));
14770
14863
  }
14771
14864
  disconnectedCallback() {
14772
14865
  // Remove all plugins, to avoid memory leaks and unexpected behaviour when the component is removed
@@ -15150,7 +15243,7 @@ class RevogrData {
15150
15243
  this.beforerowrender.emit({
15151
15244
  node: row,
15152
15245
  item: rgRow,
15153
- dataItem,
15246
+ model: dataItem,
15154
15247
  colType: this.columnService.type,
15155
15248
  rowType: this.type,
15156
15249
  });
@@ -15587,11 +15680,12 @@ var keyBy = createAggregator(function(result, value, key) {
15587
15680
  var keyBy_1 = keyBy;
15588
15681
 
15589
15682
  const SortingSign = ({ column }) => {
15590
- return hAsync("i", { class: column.order });
15683
+ var _a;
15684
+ return hAsync("i", { class: (_a = column === null || column === void 0 ? void 0 : column.order) !== null && _a !== void 0 ? _a : 'sort-off' });
15591
15685
  };
15592
15686
 
15593
15687
  const HeaderRenderer = (p) => {
15594
- var _a, _b, _c, _d, _e, _f;
15688
+ var _a, _b, _c, _d, _e;
15595
15689
  const cellClass = {
15596
15690
  [HEADER_CLASS]: true,
15597
15691
  [HEADER_SORTABLE_CLASS]: !!((_a = p.data) === null || _a === void 0 ? void 0 : _a.sortable),
@@ -15626,8 +15720,8 @@ const HeaderRenderer = (p) => {
15626
15720
  }
15627
15721
  }
15628
15722
  return (hAsync(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData },
15629
- ((_e = p.data) === null || _e === void 0 ? void 0 : _e.order) ? hAsync(SortingSign, { column: p.data }) : '',
15630
- p.canFilter && ((_f = p.data) === null || _f === void 0 ? void 0 : _f.filter) !== false ? hAsync(FilterButton, { column: p.data }) : ''));
15723
+ hAsync(SortingSign, { column: p.data }),
15724
+ p.canFilter && ((_e = p.data) === null || _e === void 0 ? void 0 : _e.filter) !== false ? hAsync(FilterButton, { column: p.data }) : ''));
15631
15725
  };
15632
15726
 
15633
15727
  const GroupHeaderRenderer = (p) => {