@revolist/revogrid 4.0.10 → 4.0.12

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 (125) hide show
  1. package/dist/cjs/{column.service-e83d9809.js → column.service-bc269420.js} +23 -9
  2. package/dist/cjs/column.service-bc269420.js.map +1 -0
  3. package/dist/cjs/{events-7ccd6894.js → events-f8893bba.js} +15 -5
  4. package/dist/cjs/events-f8893bba.js.map +1 -0
  5. package/dist/cjs/{header-cell-renderer-8ba9b56d.js → header-cell-renderer-57acd2f7.js} +2 -2
  6. package/dist/cjs/{header-cell-renderer-8ba9b56d.js.map → header-cell-renderer-57acd2f7.js.map} +1 -1
  7. package/dist/cjs/{key.utils-dc4ac217.js → key.utils-59b9b528.js} +13 -1
  8. package/dist/cjs/key.utils-59b9b528.js.map +1 -0
  9. package/dist/cjs/revo-grid.cjs.entry.js +29 -13
  10. package/dist/cjs/revo-grid.cjs.entry.js.map +1 -1
  11. package/dist/cjs/revogr-attribution_6.cjs.entry.js +176 -131
  12. package/dist/cjs/revogr-attribution_6.cjs.entry.js.map +1 -1
  13. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +28 -11
  14. package/dist/cjs/revogr-clipboard_3.cjs.entry.js.map +1 -1
  15. package/dist/cjs/revogr-data_4.cjs.entry.js +2 -2
  16. package/dist/collection/components/data/column.service.js.map +1 -1
  17. package/dist/collection/components/data/revogr-data.js +1 -1
  18. package/dist/collection/components/editors/edit.utils.js +4 -0
  19. package/dist/collection/components/editors/edit.utils.js.map +1 -1
  20. package/dist/collection/components/editors/revogr-edit.js +30 -12
  21. package/dist/collection/components/editors/revogr-edit.js.map +1 -1
  22. package/dist/collection/components/order/revogr-order-editor.js +4 -1
  23. package/dist/collection/components/order/revogr-order-editor.js.map +1 -1
  24. package/dist/collection/components/overlay/autofill.service.js +36 -24
  25. package/dist/collection/components/overlay/autofill.service.js.map +1 -1
  26. package/dist/collection/components/overlay/keyboard.service.js +7 -7
  27. package/dist/collection/components/overlay/keyboard.service.js.map +1 -1
  28. package/dist/collection/components/overlay/revogr-overlay-selection.js +107 -59
  29. package/dist/collection/components/overlay/revogr-overlay-selection.js.map +1 -1
  30. package/dist/collection/components/overlay/selection.utils.js +37 -9
  31. package/dist/collection/components/overlay/selection.utils.js.map +1 -1
  32. package/dist/collection/components/revoGrid/revo-grid-style.css +8 -3
  33. package/dist/collection/components/revoGrid/revo-grid.js +26 -11
  34. package/dist/collection/components/revoGrid/revo-grid.js.map +1 -1
  35. package/dist/collection/components/revoGrid/viewport.helpers.js +22 -8
  36. package/dist/collection/components/revoGrid/viewport.helpers.js.map +1 -1
  37. package/dist/collection/components/revoGrid/viewport.service.js +1 -0
  38. package/dist/collection/components/revoGrid/viewport.service.js.map +1 -1
  39. package/dist/collection/serve/controller.js +86 -18
  40. package/dist/collection/store/selection/index.js +0 -1
  41. package/dist/collection/store/selection/index.js.map +1 -1
  42. package/dist/collection/types/interfaces.js +4 -0
  43. package/dist/collection/types/interfaces.js.map +1 -1
  44. package/dist/collection/types/selection.js.map +1 -1
  45. package/dist/collection/utils/events.js +11 -1
  46. package/dist/collection/utils/events.js.map +1 -1
  47. package/dist/collection/utils/row-header-utils.js +2 -2
  48. package/dist/collection/utils/row-header-utils.js.map +1 -1
  49. package/dist/esm/{column.service-f4922a8d.js → column.service-195345ab.js} +23 -9
  50. package/dist/esm/column.service-195345ab.js.map +1 -0
  51. package/dist/esm/{events-3dd8ee7c.js → events-3e39de50.js} +15 -5
  52. package/dist/esm/events-3e39de50.js.map +1 -0
  53. package/dist/esm/{header-cell-renderer-ac962570.js → header-cell-renderer-7c76465d.js} +2 -2
  54. package/dist/esm/{header-cell-renderer-ac962570.js.map → header-cell-renderer-7c76465d.js.map} +1 -1
  55. package/dist/esm/{key.utils-4586a3d6.js → key.utils-2836e8ae.js} +12 -2
  56. package/dist/esm/key.utils-2836e8ae.js.map +1 -0
  57. package/dist/esm/revo-grid.entry.js +29 -13
  58. package/dist/esm/revo-grid.entry.js.map +1 -1
  59. package/dist/esm/revogr-attribution_6.entry.js +177 -132
  60. package/dist/esm/revogr-attribution_6.entry.js.map +1 -1
  61. package/dist/esm/revogr-clipboard_3.entry.js +28 -11
  62. package/dist/esm/revogr-clipboard_3.entry.js.map +1 -1
  63. package/dist/esm/revogr-data_4.entry.js +2 -2
  64. package/dist/revo-grid/column.service-195345ab.js +5 -0
  65. package/dist/revo-grid/column.service-195345ab.js.map +1 -0
  66. package/dist/revo-grid/{events-3dd8ee7c.js → events-3e39de50.js} +2 -2
  67. package/dist/revo-grid/events-3e39de50.js.map +1 -0
  68. package/dist/revo-grid/{header-cell-renderer-ac962570.js → header-cell-renderer-7c76465d.js} +2 -2
  69. package/dist/revo-grid/key.utils-2836e8ae.js +5 -0
  70. package/dist/revo-grid/key.utils-2836e8ae.js.map +1 -0
  71. package/dist/revo-grid/revo-grid.entry.js +1 -1
  72. package/dist/revo-grid/revo-grid.entry.js.map +1 -1
  73. package/dist/revo-grid/revogr-attribution_6.entry.js +1 -1
  74. package/dist/revo-grid/revogr-attribution_6.entry.js.map +1 -1
  75. package/dist/revo-grid/revogr-clipboard_3.entry.js +1 -1
  76. package/dist/revo-grid/revogr-clipboard_3.entry.js.map +1 -1
  77. package/dist/revo-grid/revogr-data_4.entry.js +1 -1
  78. package/dist/types/components/data/column.service.d.ts +2 -2
  79. package/dist/types/components/editors/edit.utils.d.ts +2 -0
  80. package/dist/types/components/order/revogr-order-editor.d.ts +3 -0
  81. package/dist/types/components/overlay/autofill.service.d.ts +9 -6
  82. package/dist/types/components/overlay/keyboard.service.d.ts +2 -3
  83. package/dist/types/components/overlay/revogr-overlay-selection.d.ts +38 -15
  84. package/dist/types/components/overlay/selection.utils.d.ts +12 -4
  85. package/dist/types/components/revoGrid/revo-grid.d.ts +4 -1
  86. package/dist/types/components/revoGrid/viewport.helpers.d.ts +11 -2
  87. package/dist/types/components.d.ts +26 -2
  88. package/dist/types/store/selection/index.d.ts +0 -1
  89. package/dist/types/types/interfaces.d.ts +444 -23
  90. package/dist/types/types/selection.d.ts +1 -1
  91. package/dist/types/utils/events.d.ts +4 -1
  92. package/dist/types/utils/row-header-utils.d.ts +1 -1
  93. package/hydrate/index.js +296 -179
  94. package/package.json +5 -6
  95. package/standalone/column.service.js.map +1 -1
  96. package/standalone/revo-grid.js +28 -11
  97. package/standalone/revo-grid.js.map +1 -1
  98. package/standalone/revogr-edit2.js +37 -11
  99. package/standalone/revogr-edit2.js.map +1 -1
  100. package/standalone/revogr-focus2.js +1 -1
  101. package/standalone/revogr-order-editor2.js.map +1 -1
  102. package/standalone/revogr-overlay-selection2.js +142 -150
  103. package/standalone/revogr-overlay-selection2.js.map +1 -1
  104. package/standalone/revogr-row-headers2.js +2 -2
  105. package/standalone/revogr-row-headers2.js.map +1 -1
  106. package/standalone/revogr-temp-range2.js +1 -1
  107. package/standalone/revogr-viewport-scroll2.js +22 -8
  108. package/standalone/revogr-viewport-scroll2.js.map +1 -1
  109. package/standalone/selection.utils.js +72 -9
  110. package/standalone/selection.utils.js.map +1 -1
  111. package/dist/cjs/column.service-e83d9809.js.map +0 -1
  112. package/dist/cjs/events-7ccd6894.js.map +0 -1
  113. package/dist/cjs/key.utils-dc4ac217.js.map +0 -1
  114. package/dist/collection/store/selection/selection.store.service.js +0 -39
  115. package/dist/collection/store/selection/selection.store.service.js.map +0 -1
  116. package/dist/esm/column.service-f4922a8d.js.map +0 -1
  117. package/dist/esm/events-3dd8ee7c.js.map +0 -1
  118. package/dist/esm/key.utils-4586a3d6.js.map +0 -1
  119. package/dist/revo-grid/column.service-f4922a8d.js +0 -5
  120. package/dist/revo-grid/column.service-f4922a8d.js.map +0 -1
  121. package/dist/revo-grid/events-3dd8ee7c.js.map +0 -1
  122. package/dist/revo-grid/key.utils-4586a3d6.js +0 -5
  123. package/dist/revo-grid/key.utils-4586a3d6.js.map +0 -1
  124. package/dist/types/store/selection/selection.store.service.d.ts +0 -17
  125. /package/dist/revo-grid/{header-cell-renderer-ac962570.js.map → header-cell-renderer-7c76465d.js.map} +0 -0
@@ -2,52 +2,17 @@
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
4
  import { r as registerInstance, h, H as Host, c as createEvent, a as getElement } from './index-21436631.js';
5
- import { F as FOCUS_CLASS, E as EDIT_INPUT_WR, t as timeout, R as RESIZE_INTERVAL, a as CELL_HANDLER_CLASS, M as MOBILE_CLASS, S as SELECTION_BORDER_CLASS, b as ROW_HEADER_TYPE, g as getScrollbarSize, T as TMP_SELECTION_BG_CLASS } from './index-98fd0168.js';
5
+ import { F as FOCUS_CLASS, t as timeout, R as RESIZE_INTERVAL, a as CELL_HANDLER_CLASS, M as MOBILE_CLASS, S as SELECTION_BORDER_CLASS, b as ROW_HEADER_TYPE, g as getScrollbarSize, T as TMP_SELECTION_BG_CLASS } from './index-98fd0168.js';
6
6
  import { i as getItemByPosition, j as getItemByIndex, b as getSourceItem, D as DataStore } from './dimension.helpers-a3065cb1.js';
7
- import { n as ColumnService, H as HEADER_SLOT } from './column.service-f4922a8d.js';
7
+ import { g as getPropertyFromEvent, v as verifyTouchTarget, V as ViewportStore, c as calculateRowHeaderSize } from './events-3e39de50.js';
8
+ import { n as ColumnService, H as HEADER_SLOT } from './column.service-195345ab.js';
9
+ import { c as codesLetter, i as isClear, a as isEnterKey, b as isCopy, d as isCut, e as isPaste, f as isAll, g as isLetterKey, h as isEditInput } from './key.utils-2836e8ae.js';
8
10
  import { g as getRange, a as isRangeSingleCell } from './selection.store-2577ddf9.js';
9
- import { c as codesLetter, i as isClear, a as isEnterKey, b as isCopy, d as isCut, e as isPaste, f as isAll, g as isLetterKey } from './key.utils-4586a3d6.js';
10
11
  import { d as debounce_1 } from './debounce-7781346d.js';
11
- import { g as getFromEvent, v as verifyTouchTarget, V as ViewportStore, c as calculateRowHeaderSize } from './events-3dd8ee7c.js';
12
12
  import { L as LocalScrollTimer, a as LocalScrollService, g as getContentSize, t as throttle_1 } from './throttle-cfd527d6.js';
13
13
  import './toNumber-8de324a7.js';
14
14
  import './viewport.helpers-6591d423.js';
15
15
 
16
- class SelectionStoreService {
17
- constructor(store, config) {
18
- this.store = store;
19
- this.config = config;
20
- this.store = store;
21
- }
22
- get edited() {
23
- return this.store.get('edit');
24
- }
25
- get focused() {
26
- return this.store.get('focus');
27
- }
28
- get ranged() {
29
- return this.store.get('range');
30
- }
31
- changeRange(range) {
32
- return this.config.changeRange(range);
33
- }
34
- focus(cell, isMulti = false) {
35
- if (!cell) {
36
- return false;
37
- }
38
- let end = cell;
39
- // range edit
40
- if (isMulti) {
41
- let start = this.store.get('focus');
42
- if (start) {
43
- return this.config.changeRange(getRange(start, end));
44
- }
45
- }
46
- // single focus
47
- return this.config.focus(cell, end);
48
- }
49
- }
50
-
51
16
  const Attribution = class {
52
17
  constructor(hostRef) {
53
18
  registerInstance(this, hostRef);
@@ -57,26 +22,50 @@ const Attribution = class {
57
22
  }
58
23
  };
59
24
 
60
- /** Calculate cell based on x, y position */
25
+ function getFocusCellBasedOnEvent(e, data) {
26
+ // If event default is prevented, return
27
+ if (e.defaultPrevented) {
28
+ return null;
29
+ }
30
+ // Get coordinates from event object
31
+ const x = getPropertyFromEvent(e, 'clientX');
32
+ const y = getPropertyFromEvent(e, 'clientY');
33
+ // If coordinates are not available, return
34
+ if (x === null || y === null) {
35
+ return null;
36
+ }
37
+ // Get current cell based on coordinates and data
38
+ const focusCell = getCurrentCell({ x, y }, data);
39
+ // If current cell is not available, return
40
+ if (isAfterLast(focusCell, data.lastCell)) {
41
+ return null;
42
+ }
43
+ return focusCell;
44
+ }
45
+ /**
46
+ * Calculate cell based on x, y position
47
+ */
61
48
  function getCurrentCell({ x, y }, { el, rows, cols }) {
49
+ // Get the bounding rectangle of the element
62
50
  const { top, left, height, width } = el.getBoundingClientRect();
51
+ // Calculate the cell position relative to the element
63
52
  let cellY = y - top;
64
- // limit to element height
53
+ let cellX = x - left;
54
+ // Limit the cell position to the element height
65
55
  if (cellY >= height) {
66
56
  cellY = height - 1;
67
57
  }
68
- let cellX = x - left;
69
- // limit to element width
58
+ // Limit the cell position to the element width
70
59
  if (cellX >= width) {
71
60
  cellX = width - 1;
72
61
  }
62
+ // Get the row and column items based on the cell position
73
63
  const rgRow = getItemByPosition(rows, cellY);
74
64
  const rgCol = getItemByPosition(cols, cellX);
75
- // before first
65
+ // Set the row and column index to 0 if they are before the first item
76
66
  if (rgCol.itemIndex < 0) {
77
67
  rgCol.itemIndex = 0;
78
68
  }
79
- // before first
80
69
  if (rgRow.itemIndex < 0) {
81
70
  rgRow.itemIndex = 0;
82
71
  }
@@ -98,8 +87,11 @@ function getCoordinate(range, focus, changes, isMulti = false) {
98
87
  }
99
88
  return null;
100
89
  }
101
- /** check if out of range */
102
- function isAfterLast({ x, y }, { lastCell }) {
90
+ /**
91
+ * Check if the x coordinate of the cell position is after or equal to the x coordinate of the last cell position
92
+ * or if the y coordinate of the cell position is after or equal to the y coordinate of the last cell position
93
+ */
94
+ function isAfterLast({ x, y }, lastCell) {
103
95
  return x >= lastCell.x || y >= lastCell.y;
104
96
  }
105
97
  /** check if out of range */
@@ -229,11 +221,6 @@ const RevogrFocus$1 = class {
229
221
  };
230
222
  RevogrFocus$1.style = RevogrFocusStyle0;
231
223
 
232
- // is edit input
233
- function isEditInput(el) {
234
- return !!(el === null || el === void 0 ? void 0 : el.closest(`.${EDIT_INPUT_WR}`));
235
- }
236
-
237
224
  const DIRECTION_CODES = [
238
225
  codesLetter.TAB,
239
226
  codesLetter.ARROW_UP,
@@ -245,9 +232,9 @@ class KeyboardService {
245
232
  constructor(sv) {
246
233
  this.sv = sv;
247
234
  }
248
- async keyDown(e, canRange) {
235
+ async keyDown(e, canRange, isEditMode, { range, focus }) {
249
236
  // IF EDIT MODE
250
- if (this.sv.selectionStoreService.edited) {
237
+ if (isEditMode) {
251
238
  switch (e.code) {
252
239
  case codesLetter.ESCAPE:
253
240
  this.sv.cancel();
@@ -257,12 +244,12 @@ class KeyboardService {
257
244
  }
258
245
  // IF NOT EDIT MODE
259
246
  // pressed clear key
260
- if (this.sv.selectionStoreService.ranged && isClear(e.code)) {
247
+ if (range && isClear(e.code)) {
261
248
  this.sv.clearCell();
262
249
  return;
263
250
  }
264
251
  // below works with focus only
265
- if (!this.sv.selectionStoreService.focused) {
252
+ if (!focus) {
266
253
  return;
267
254
  }
268
255
  // tab key means same as arrow right
@@ -338,7 +325,7 @@ class KeyboardService {
338
325
  }
339
326
  if (isMulti) {
340
327
  const eData = this.sv.getData();
341
- if (isAfterLast(data.end, eData) || isBeforeFirst(data.start)) {
328
+ if (isAfterLast(data.end, eData.lastCell) || isBeforeFirst(data.start)) {
342
329
  return false;
343
330
  }
344
331
  const range = getRange(data.start, data.end);
@@ -390,7 +377,10 @@ class AutoFillService {
390
377
  return (h("div", { class: {
391
378
  [CELL_HANDLER_CLASS]: true,
392
379
  [MOBILE_CLASS]: true,
393
- }, style: { left: `${handlerStyle.right}px`, top: `${handlerStyle.bottom}px` }, onMouseDown: (e) => this.autoFillHandler(e), onTouchStart: (e) => this.autoFillHandler(e) }));
380
+ }, style: {
381
+ left: `${handlerStyle.right}px`,
382
+ top: `${handlerStyle.bottom}px`,
383
+ }, onMouseDown: (e) => this.autoFillHandler(e), onTouchStart: (e) => this.autoFillHandler(e) }));
394
384
  }
395
385
  autoFillHandler(e, type = "AutoFill" /* AutoFillType.autoFill */) {
396
386
  let target = null;
@@ -406,7 +396,9 @@ class AutoFillService {
406
396
  get isAutoFill() {
407
397
  return !!this.autoFillType;
408
398
  }
409
- /** Process mouse move events */
399
+ /**
400
+ * Process mouse move events
401
+ */
410
402
  selectionMouseMove(e) {
411
403
  // initiate mouse move debounce if not present
412
404
  if (!this.onMouseMoveAutofill) {
@@ -416,9 +408,7 @@ class AutoFillService {
416
408
  this.onMouseMoveAutofill(e, this.sv.getData());
417
409
  }
418
410
  }
419
- getFocus() {
420
- let focus = this.sv.selectionStoreService.focused;
421
- const range = this.sv.selectionStoreService.ranged;
411
+ getFocus(focus, range) {
422
412
  // there was an issue that it was taking last cell from range but focus was out
423
413
  if (!focus && range) {
424
414
  focus = { x: range.x, y: range.y };
@@ -434,8 +424,8 @@ class AutoFillService {
434
424
  if (!this.autoFillInitial) {
435
425
  return;
436
426
  }
437
- const x = getFromEvent(event, 'clientX', MOBILE_CLASS);
438
- const y = getFromEvent(event, 'clientY', MOBILE_CLASS);
427
+ const x = getPropertyFromEvent(event, 'clientX', MOBILE_CLASS);
428
+ const y = getPropertyFromEvent(event, 'clientY', MOBILE_CLASS);
439
429
  // skip touch
440
430
  if (x === null || y === null) {
441
431
  return;
@@ -448,11 +438,12 @@ class AutoFillService {
448
438
  }
449
439
  }
450
440
  // check if not the latest, if latest - do nothing
451
- if (isAfterLast(current, data)) {
441
+ if (isAfterLast(current, data.lastCell)) {
452
442
  return;
453
443
  }
454
444
  this.autoFillLast = current;
455
- const isSame = current.x === this.autoFillInitial.x && current.y === this.autoFillInitial.y;
445
+ const isSame = current.x === this.autoFillInitial.x &&
446
+ current.y === this.autoFillInitial.y;
456
447
  // if same as initial - clear
457
448
  if (isSame) {
458
449
  this.sv.setTempRange(null);
@@ -473,39 +464,48 @@ class AutoFillService {
473
464
  selectionStart(target, data, type = "Selection" /* AutoFillType.selection */) {
474
465
  /** Get cell by autofill element */
475
466
  const { top, left } = target.getBoundingClientRect();
476
- this.autoFillInitial = this.getFocus();
467
+ this.autoFillInitial = this.getFocus(data.focus, data.range);
477
468
  this.autoFillType = type;
478
469
  this.autoFillStart = getCurrentCell({ x: left, y: top }, data);
479
470
  }
480
471
  /**
481
- * Clear current range selection
482
- * on mouse up and mouse leave events
472
+ * Clear current range selection on mouse up and mouse leave events
483
473
  */
484
- clearAutoFillSelection() {
485
- // Apply autofill values on mouse up if present
474
+ clearAutoFillSelection(focus, oldRange) {
475
+ // If autofill was active, apply autofill values
486
476
  if (this.autoFillInitial) {
487
- // Get latest
488
- this.autoFillInitial = this.getFocus();
489
- // Apply range data if present
477
+ // Fetch latest focus
478
+ this.autoFillInitial = this.getFocus(focus, oldRange);
479
+ // Apply range data if autofill mode is active
490
480
  if (this.autoFillType === "AutoFill" /* AutoFillType.autoFill */) {
491
481
  const range = getRange(this.autoFillInitial, this.autoFillLast);
482
+ // If range is present, apply data
492
483
  if (range) {
493
- const { defaultPrevented: stopApply, detail: { range: newRange } } = this.sv.clearRangeDataApply({
484
+ const { defaultPrevented: stopApply, detail: { range: newRange }, } = this.sv.clearRangeDataApply({
494
485
  range,
495
486
  });
487
+ // If data apply was not prevented, apply new range
496
488
  if (!stopApply) {
497
- this.applyRangeWithData(newRange);
489
+ this.applyRangeWithData(newRange, oldRange);
498
490
  }
499
491
  else {
500
- // if prevented - clear temp range
492
+ // If data apply was prevented, clear temporary range
501
493
  this.sv.setTempRange(null);
502
494
  }
503
495
  }
504
496
  }
505
497
  else {
498
+ // If not autofill mode, apply range only
506
499
  this.applyRangeOnly(this.autoFillInitial, this.autoFillLast);
507
500
  }
508
501
  }
502
+ // Reset autofill state
503
+ this.resetAutoFillState();
504
+ }
505
+ /**
506
+ * Reset autofill state
507
+ */
508
+ resetAutoFillState() {
509
509
  this.autoFillType = null;
510
510
  this.autoFillInitial = null;
511
511
  this.autoFillLast = null;
@@ -525,8 +525,7 @@ class AutoFillService {
525
525
  this.sv.setRange(range);
526
526
  }
527
527
  /** Apply range and copy data during range application */
528
- applyRangeWithData(newRange) {
529
- const oldRange = this.sv.selectionStoreService.ranged;
528
+ applyRangeWithData(newRange, oldRange) {
530
529
  const rangeData = {
531
530
  type: this.sv.dataStore.get('type'),
532
531
  colType: this.sv.columnService.type,
@@ -615,44 +614,60 @@ const OverlaySelection = class {
615
614
  // #endregion
616
615
  // #region Listeners
617
616
  onMouseMove(e) {
618
- if (this.selectionStoreService.focused) {
617
+ if (this.selectionStore.get('focus')) {
619
618
  this.autoFillService.selectionMouseMove(e);
620
619
  }
621
620
  }
622
- /** Action finished inside of the document. */
623
- /** Pointer left document, clear any active operation. */
621
+ /**
622
+ * Action finished inside of the document.
623
+ * Pointer left document, clear any active operation.
624
+ */
624
625
  onMouseUp() {
625
- this.autoFillService.clearAutoFillSelection();
626
+ // Clear auto fill selection
627
+ // when pointer left document,
628
+ // clear any active operation.
629
+ this.autoFillService.clearAutoFillSelection(this.selectionStore.get('focus'), this.selectionStore.get('range'));
626
630
  }
627
- /** Row drag started. */
631
+ /**
632
+ * Row drag started.
633
+ * This event is fired when drag action started on cell.
634
+ */
628
635
  onCellDrag(e) {
629
636
  var _a;
637
+ // Invoke drag start on order editor.
630
638
  (_a = this.orderEditor) === null || _a === void 0 ? void 0 : _a.dragStart(e.detail);
631
639
  }
632
- /** Get keyboard down from element. */
640
+ /**
641
+ * Get keyboard down from element.
642
+ * This event is fired when keyboard key is released.
643
+ */
633
644
  onKeyUp(e) {
645
+ // Emit before key up event.
634
646
  this.beforeKeyUp.emit(e);
635
647
  }
636
- /** Get keyboard down from element. */
648
+ /**
649
+ * Get keyboard down from element.
650
+ * This event is fired when keyboard key is pressed.
651
+ */
637
652
  onKeyDown(e) {
638
653
  var _a;
654
+ // Emit before key down event and check if default prevention is set.
639
655
  const proxy = this.beforeKeyDown.emit(e);
640
656
  if (e.defaultPrevented || proxy.defaultPrevented) {
641
657
  return;
642
658
  }
643
- (_a = this.keyboardService) === null || _a === void 0 ? void 0 : _a.keyDown(e, this.range);
659
+ // Invoke key down on keyboard service.
660
+ (_a = this.keyboardService) === null || _a === void 0 ? void 0 : _a.keyDown(e, this.range, !!this.selectionStore.get('edit'), {
661
+ focus: this.selectionStore.get('focus'),
662
+ range: this.selectionStore.get('range'),
663
+ });
644
664
  }
645
665
  // #endregion
646
666
  /** Selection & Keyboard */
647
667
  selectionServiceSet(s) {
648
- this.selectionStoreService = new SelectionStoreService(s, {
649
- changeRange: range => this.triggerRangeEvent(range),
650
- focus: (focus, end) => this.doFocus(focus, end),
651
- });
652
668
  this.keyboardService = new KeyboardService({
653
- selectionStoreService: this.selectionStoreService,
654
669
  selectionStore: s,
655
- range: r => this.selectionStoreService.changeRange(r),
670
+ range: r => this.triggerRangeEvent(r),
656
671
  focusNext: (f, next) => this.doFocus(f, f, next),
657
672
  change: val => {
658
673
  if (this.readonly) {
@@ -674,7 +689,6 @@ const OverlaySelection = class {
674
689
  /** Autofill */
675
690
  createAutoFillService() {
676
691
  this.autoFillService = new AutoFillService({
677
- selectionStoreService: this.selectionStoreService,
678
692
  dimensionRow: this.dimensionRow,
679
693
  dimensionCol: this.dimensionCol,
680
694
  columnService: this.columnService,
@@ -750,10 +764,10 @@ const OverlaySelection = class {
750
764
  nodes.push(editCell);
751
765
  }
752
766
  else {
753
- const range = this.selectionStoreService.ranged;
754
- const selectionFocus = this.selectionStoreService.focused;
767
+ const range = this.selectionStore.get('range');
768
+ const focus = this.selectionStore.get('focus');
755
769
  // Clipboard
756
- if ((range || selectionFocus) && this.useClipboard) {
770
+ if ((range || focus) && this.useClipboard) {
757
771
  nodes.push(h("revogr-clipboard", { readonly: this.readonly, onCopyregion: e => this.onCopy(e.detail), onClearregion: () => !this.readonly && this.clearCell(), ref: e => (this.clipboard = e), onPasteregion: e => this.onPaste(e.detail) }));
758
772
  }
759
773
  // Range
@@ -761,23 +775,19 @@ const OverlaySelection = class {
761
775
  nodes.push(...this.renderRange(range));
762
776
  }
763
777
  // Autofill
764
- if (selectionFocus && !this.readonly && this.range) {
765
- nodes.push(this.autoFillService.renderAutofill(range, selectionFocus));
778
+ if (focus && !this.readonly && this.range) {
779
+ nodes.push(this.autoFillService.renderAutofill(range, focus));
766
780
  }
767
781
  // Order
768
782
  if (this.canDrag) {
769
783
  nodes.push(h("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) }));
770
784
  }
771
785
  }
772
- return (h(Host, { key: 'd20fcf63958e3d491f4fd881a4a5dd242cfdd9ac', class: { mobile: this.isMobileDevice },
773
- // Open Editor on DblClick
774
- onDblClick: (e) => {
775
- // DblClick prevented outside - Editor will not open
776
- if (!e.defaultPrevented) {
777
- this.doEdit();
778
- }
779
- }, onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true) }, nodes, h("slot", { key: '89b9bec7824739ea11fadeecbf3908ac74e85c96', name: "data" })));
786
+ return (h(Host, { key: '9dbb6247aebf4ad00c1c8c78852191671be33a11', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true) }, nodes, h("slot", { key: '7769092a5029c5a49da8c2d6f36eb9f17b461bc2', name: "data" })));
780
787
  }
788
+ /**
789
+ * Executes the focus operation on the specified range of cells.
790
+ */
781
791
  doFocus(focus, end, next) {
782
792
  const { defaultPrevented } = this.beforeFocusCell.emit(this.columnService.getSaveData(focus.y, focus.x));
783
793
  if (defaultPrevented) {
@@ -811,31 +821,48 @@ const OverlaySelection = class {
811
821
  }
812
822
  return !e.defaultPrevented;
813
823
  }
824
+ /**
825
+ * Open Editor on DblClick
826
+ */
827
+ onElementDblClick(e) {
828
+ // DblClick prevented outside - Editor will not open
829
+ // Get data from the component
830
+ const data = this.getData();
831
+ const focusCell = getFocusCellBasedOnEvent(e, data);
832
+ if (!focusCell) {
833
+ return;
834
+ }
835
+ this.doEdit();
836
+ }
837
+ /**
838
+ * Handle mouse down event on Host element
839
+ */
814
840
  onElementMouseDown(e, touch = false) {
841
+ // Get the target element from the event object
842
+ const targetElement = e.target;
815
843
  // Ignore focus if clicked input
816
- if (isEditInput(e.target)) {
844
+ if (isEditInput(targetElement)) {
817
845
  return;
818
846
  }
847
+ // Get data from the component
819
848
  const data = this.getData();
820
- if (e.defaultPrevented) {
821
- return;
822
- }
823
- const x = getFromEvent(e, 'clientX');
824
- const y = getFromEvent(e, 'clientY');
825
- // skip touch
826
- if (x === null || y === null) {
849
+ const focusCell = getFocusCellBasedOnEvent(e, data);
850
+ if (!focusCell) {
827
851
  return;
828
852
  }
829
- // Regular cell click
830
- const focusCell = getCurrentCell({ x, y }, data);
831
- this.selectionStoreService.focus(focusCell, this.range && e.shiftKey);
853
+ // Set focus on the current cell
854
+ this.focus(focusCell, this.range && e.shiftKey);
832
855
  // Initiate autofill selection
833
856
  if (this.range) {
834
- this.autoFillService.selectionStart(e.target, data);
857
+ this.autoFillService.selectionStart(targetElement, this.getData());
858
+ // Prevent default behavior for mouse events,
859
+ // but only if target element is not a mobile input
835
860
  if (!touch) {
836
861
  e.preventDefault();
837
862
  }
838
863
  else if (verifyTouchTarget(e.touches[0], MOBILE_CLASS)) {
864
+ // Prevent default behavior for touch events
865
+ // if target element is a mobile input
839
866
  e.preventDefault();
840
867
  }
841
868
  }
@@ -846,8 +873,8 @@ const OverlaySelection = class {
846
873
  doEdit(val = '') {
847
874
  var _a;
848
875
  if (this.canEdit()) {
849
- const editCell = this.selectionStore.get('focus');
850
- const data = this.columnService.getSaveData(editCell.y, editCell.x);
876
+ const focus = this.selectionStore.get('focus');
877
+ const data = this.columnService.getSaveData(focus.y, focus.x);
851
878
  (_a = this.setEdit) === null || _a === void 0 ? void 0 : _a.emit(Object.assign(Object.assign({}, data), { val }));
852
879
  }
853
880
  }
@@ -870,8 +897,8 @@ const OverlaySelection = class {
870
897
  this.cellEditApply.emit(dataToSave);
871
898
  }
872
899
  getRegion() {
873
- const focus = this.selectionStoreService.focused;
874
- let range = this.selectionStoreService.ranged;
900
+ const focus = this.selectionStore.get('focus');
901
+ let range = this.selectionStore.get('range');
875
902
  if (!range) {
876
903
  range = getRange(focus, focus);
877
904
  }
@@ -897,8 +924,8 @@ const OverlaySelection = class {
897
924
  return true;
898
925
  }
899
926
  onPaste(data) {
900
- const focus = this.selectionStoreService.focused;
901
- const isEditing = this.selectionStoreService.edited !== null;
927
+ const focus = this.selectionStore.get('focus');
928
+ const isEditing = this.selectionStore.get('edit') !== null;
902
929
  if (!focus || isEditing) {
903
930
  return;
904
931
  }
@@ -918,13 +945,13 @@ const OverlaySelection = class {
918
945
  }
919
946
  }
920
947
  clearCell() {
921
- if (this.selectionStoreService.ranged &&
922
- !isRangeSingleCell(this.selectionStoreService.ranged)) {
923
- const data = this.columnService.getRangeStaticData(this.selectionStoreService.ranged, '');
924
- this.autoFillService.onRangeApply(data, this.selectionStoreService.ranged);
948
+ if (this.selectionStore.get('range') &&
949
+ !isRangeSingleCell(this.selectionStore.get('range'))) {
950
+ const data = this.columnService.getRangeStaticData(this.selectionStore.get('range'), '');
951
+ this.autoFillService.onRangeApply(data, this.selectionStore.get('range'));
925
952
  }
926
953
  else if (this.canEdit()) {
927
- const focused = this.selectionStoreService.focused;
954
+ const focused = this.selectionStore.get('focus');
928
955
  const cell = this.columnService.getSaveData(focused.y, focused.x);
929
956
  this.cellEdit({
930
957
  rgRow: focused.y,
@@ -946,8 +973,24 @@ const OverlaySelection = class {
946
973
  if (this.readonly) {
947
974
  return false;
948
975
  }
949
- const editCell = this.selectionStoreService.focused;
950
- return editCell && !((_a = this.columnService) === null || _a === void 0 ? void 0 : _a.isReadOnly(editCell.y, editCell.x));
976
+ const focus = this.selectionStore.get('focus');
977
+ return focus && !((_a = this.columnService) === null || _a === void 0 ? void 0 : _a.isReadOnly(focus.y, focus.x));
978
+ }
979
+ get edited() {
980
+ return this.selectionStore.get('edit');
981
+ }
982
+ /**
983
+ * Sets the focus on a cell and optionally edits a range.
984
+ */
985
+ focus(cell, isRangeEdit = false) {
986
+ if (!cell)
987
+ return false;
988
+ const end = cell;
989
+ const start = this.selectionStore.get('focus');
990
+ if (isRangeEdit && start) {
991
+ return this.triggerRangeEvent(getRange(start, end));
992
+ }
993
+ return this.doFocus(cell, end);
951
994
  }
952
995
  get types() {
953
996
  return {
@@ -964,6 +1007,8 @@ const OverlaySelection = class {
964
1007
  rows: this.dimensionRow.state,
965
1008
  cols: this.dimensionCol.state,
966
1009
  lastCell: this.lastCell,
1010
+ focus: this.selectionStore.get('focus'),
1011
+ range: this.selectionStore.get('range'),
967
1012
  };
968
1013
  }
969
1014
  get element() { return getElement(this); }