@revolist/revogrid 4.27.10 → 4.28.0

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 (30) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/revo-grid.cjs.js +1 -1
  4. package/dist/cjs/revogr-attribution_7.cjs.entry.js +59 -10
  5. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +7 -1
  6. package/dist/cjs/{text-editor-CJyQaYei.js → text-editor-COQdD50G.js} +8 -0
  7. package/dist/collection/components/editors/revogr-edit.js +15 -0
  8. package/dist/collection/components/editors/text-editor.js +8 -0
  9. package/dist/collection/components/overlay/keyboard.service.js +48 -8
  10. package/dist/collection/components/overlay/revogr-overlay-selection.js +11 -2
  11. package/dist/esm/index.js +1 -1
  12. package/dist/esm/loader.js +1 -1
  13. package/dist/esm/revo-grid.js +1 -1
  14. package/dist/esm/revogr-attribution_7.entry.js +59 -10
  15. package/dist/esm/revogr-clipboard_3.entry.js +7 -1
  16. package/dist/esm/{text-editor-eHtrwvxH.js → text-editor-BVb0idxe.js} +8 -0
  17. package/dist/revo-grid/index.esm.js +1 -1
  18. package/dist/revo-grid/revo-grid.esm.js +1 -1
  19. package/dist/revo-grid/revogr-attribution_7.entry.js +59 -10
  20. package/dist/revo-grid/revogr-clipboard_3.entry.js +7 -1
  21. package/dist/revo-grid/{text-editor-eHtrwvxH.js → text-editor-BVb0idxe.js} +8 -0
  22. package/dist/types/components/editors/revogr-edit.d.ts +1 -0
  23. package/dist/types/components/editors/text-editor.d.ts +1 -0
  24. package/dist/types/components/overlay/keyboard.service.d.ts +12 -4
  25. package/dist/types/types/selection.d.ts +5 -0
  26. package/hydrate/index.js +74 -11
  27. package/hydrate/index.mjs +74 -11
  28. package/package.json +1 -1
  29. package/standalone/revogr-edit2.js +1 -1
  30. package/standalone/revogr-overlay-selection2.js +1 -1
@@ -271,13 +271,13 @@ const RevogrFocus$1 = class RevogrFocus {
271
271
  };
272
272
  RevogrFocus$1.style = revogrFocusStyleCss();
273
273
 
274
- const DIRECTION_CODES = [
275
- codesLetter.TAB,
274
+ const ARROW_CODES = [
276
275
  codesLetter.ARROW_UP,
277
276
  codesLetter.ARROW_DOWN,
278
277
  codesLetter.ARROW_LEFT,
279
278
  codesLetter.ARROW_RIGHT,
280
279
  ];
280
+ const DIRECTION_CODES = new Set([codesLetter.TAB, ...ARROW_CODES]);
281
281
  class KeyboardService {
282
282
  constructor(sv) {
283
283
  this.sv = sv;
@@ -295,6 +295,10 @@ class KeyboardService {
295
295
  /**
296
296
  * Appends printable key input that arrives after edit mode was requested
297
297
  * but before the editor input has mounted or received focus.
298
+ *
299
+ * Once the input is rendered the key goes straight into it: a store update
300
+ * would only reach the input on the next render, and that render would
301
+ * overwrite whatever was typed natively into the input in the meantime.
298
302
  */
299
303
  appendPendingEditValue(e) {
300
304
  if (isShortcutModifier(e) ||
@@ -307,6 +311,9 @@ class KeyboardService {
307
311
  return false;
308
312
  }
309
313
  e.preventDefault();
314
+ if (this.sv.appendEditValue(e.key)) {
315
+ return true;
316
+ }
310
317
  this.sv.selectionStore.set('edit', Object.assign(Object.assign({}, editCell), { val: `${editCell.val}${e.key}` }));
311
318
  return true;
312
319
  }
@@ -407,7 +414,9 @@ class KeyboardService {
407
414
  this.applyingKeyChange = true;
408
415
  let changed;
409
416
  try {
410
- changed = this.keyPositionChange(data.changes, range, focus, data.isMulti);
417
+ changed = data.edge
418
+ ? this.keyEdgeChange(data.changes, range, focus, !!data.isMulti)
419
+ : this.keyPositionChange(data.changes, range, focus, data.isMulti);
411
420
  }
412
421
  finally {
413
422
  this.applyingKeyChange = false;
@@ -444,10 +453,33 @@ class KeyboardService {
444
453
  ? -1
445
454
  : 0);
446
455
  }
456
+ keyEdgeChange(changes, range, focus, isMulti) {
457
+ if (!range || !focus) {
458
+ return false;
459
+ }
460
+ const { lastCell } = this.sv.getData();
461
+ const coordinate = changes.x ? 'x' : 'y';
462
+ const direction = changes[coordinate];
463
+ const target = direction > 0 ? lastCell[coordinate] - 1 : 0;
464
+ if (isMulti) {
465
+ const edgeCoordinate = coordinate === 'x' ? 'x1' : 'y1';
466
+ return this.sv.range(Object.assign(Object.assign({}, range), { [coordinate]: direction < 0 ? target : focus[coordinate], [edgeCoordinate]: direction > 0 ? target : focus[coordinate] }));
467
+ }
468
+ const edgeFocus = Object.assign(Object.assign({}, focus), { [coordinate]: target });
469
+ return this.sv.focus(edgeFocus, {
470
+ [coordinate]: target - focus[coordinate],
471
+ });
472
+ }
447
473
  /** Monitor key direction changes */
448
474
  changeDirectionKey(e, canRange) {
449
475
  const isMulti = canRange && e.shiftKey;
450
- if (DIRECTION_CODES.includes(e.code)) {
476
+ const hasPrimaryModifier = e.ctrlKey || e.metaKey;
477
+ const isArrow = ARROW_CODES.includes(e.code);
478
+ const isEdgeShortcut = hasPrimaryModifier && !e.altKey && isArrow;
479
+ if (hasPrimaryModifier && !isEdgeShortcut) {
480
+ return;
481
+ }
482
+ if (DIRECTION_CODES.has(e.code)) {
451
483
  e.preventDefault();
452
484
  }
453
485
  if (e.shiftKey) {
@@ -456,17 +488,25 @@ class KeyboardService {
456
488
  return { changes: { x: -1 }, isMulti: false };
457
489
  }
458
490
  }
491
+ let changes;
459
492
  switch (e.code) {
460
493
  case codesLetter.ARROW_UP:
461
- return { changes: { y: -1 }, isMulti };
494
+ changes = { y: -1 };
495
+ break;
462
496
  case codesLetter.ARROW_DOWN:
463
- return { changes: { y: 1 }, isMulti };
497
+ changes = { y: 1 };
498
+ break;
464
499
  case codesLetter.ARROW_LEFT:
465
- return { changes: { x: -1 }, isMulti };
500
+ changes = { x: -1 };
501
+ break;
466
502
  case codesLetter.TAB:
467
503
  case codesLetter.ARROW_RIGHT:
468
- return { changes: { x: 1 }, isMulti };
504
+ changes = { x: 1 };
505
+ break;
506
+ default:
507
+ return;
469
508
  }
509
+ return Object.assign({ changes, isMulti }, (isEdgeShortcut && { edge: true }));
470
510
  }
471
511
  }
472
512
 
@@ -827,6 +867,15 @@ const OverlaySelection = class {
827
867
  await ((_a = this.revogrEdit) === null || _a === void 0 ? void 0 : _a.cancelChanges());
828
868
  this.closeEdit();
829
869
  },
870
+ appendEditValue: value => {
871
+ if (!this.revogrEdit) {
872
+ return false;
873
+ }
874
+ return !this.revogrEdit.dispatchEvent(new CustomEvent('internalappendeditvalue', {
875
+ cancelable: true,
876
+ detail: value,
877
+ }));
878
+ },
830
879
  clearCell: () => !this.readonly && this.clearCell(),
831
880
  internalPaste: () => !this.readonly && this.beforeRegionPaste.emit(),
832
881
  getData: () => this.getData(),
@@ -950,9 +999,9 @@ const OverlaySelection = class {
950
999
  nodes.push(h("revogr-order-editor", { ref: e => (this.orderEditor = e), dataStore: this.dataStore, dimensionRow: this.dimensionRow, dimensionCol: this.dimensionCol, parent: this.element, rowType: this.types.rowType, onRowdragstartinit: e => this.rowDragStart(e) }));
951
1000
  }
952
1001
  }
953
- return (h(Host, { key: '230e2122c5c7065c072f02019d616a64949d54d0', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
1002
+ return (h(Host, { key: '84d904c108e39ebf82b215afc7052d634eba677e', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
954
1003
  // it's done to be able to throw events from different levels, not just from editor
955
- onCelledit: (e) => this.onEditCell(e) }, nodes, h("slot", { key: '47740a79c605258b4024384510358be927d000b7', name: "data" })));
1004
+ onCelledit: (e) => this.onEditCell(e) }, nodes, h("slot", { key: '7434c5fceb445de4510675b7627bb5f2efc1a365', name: "data" })));
956
1005
  }
957
1006
  /**
958
1007
  * Executes the focus operation on the specified range of cells.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, a as createEvent, h, d as Host, g as getElement } from './index-CtimkLsB.js';
5
5
  import { E as EDIT_INPUT_WR, k as getItemByPosition, b as getSourceItem, B as DRAGG_TEXT } from './dimension.helpers-Cln9sALu.js';
6
- import { T as TextEditor } from './text-editor-eHtrwvxH.js';
6
+ import { T as TextEditor } from './text-editor-BVb0idxe.js';
7
7
  import { n as isEditorCtrConstructible } from './edit.utils-3ZbhQCv_.js';
8
8
  import { d as debounce } from './debounce-PCRWZliA.js';
9
9
  import './index-BvMNbQyq.js';
@@ -175,6 +175,12 @@ const RevoEdit = class {
175
175
  var _a, _b;
176
176
  (_b = (_a = this.currentEditor) === null || _a === void 0 ? void 0 : _a.beforeDisconnect) === null || _b === void 0 ? void 0 : _b.call(_a);
177
177
  }
178
+ onInternalAppendEditValue(e) {
179
+ var _a, _b;
180
+ if ((_b = (_a = this.currentEditor) === null || _a === void 0 ? void 0 : _a.appendPendingInput) === null || _b === void 0 ? void 0 : _b.call(_a, e.detail)) {
181
+ e.preventDefault();
182
+ }
183
+ }
178
184
  onAutoSave() {
179
185
  var _a, _b, _c;
180
186
  this.preventSaveOnClose = true;
@@ -22,6 +22,14 @@ class TextEditor {
22
22
  (_a = this.editInput) === null || _a === void 0 ? void 0 : _a.focus();
23
23
  }
24
24
  }
25
+ appendPendingInput(value) {
26
+ if (!this.editInput) {
27
+ return false;
28
+ }
29
+ this.editInput.value += value;
30
+ this.editInput.focus();
31
+ return true;
32
+ }
25
33
  onKeyDown(e) {
26
34
  const isEnter = isEnterKeyValue(e.key);
27
35
  const isKeyTab = isTab(e.key);
@@ -7,7 +7,7 @@ export { B as BEFORE_GROUPING_APPLY_EVENT, o as GROUPING_ROW_TYPE, j as GROUP_CO
7
7
  export { d as dispatch, a as dispatchByEvent } from './header-cell-renderer-YCiVIQ2E.js';
8
8
  export { C as CellRenderer, G as GroupingRowRenderer, S as SortingSign, e as expandEvent, a as expandSvgIconVNode, r as renderGroupCells } from './cell-renderer-D9ze8OJw.js';
9
9
  export { a as applyMixins, f as findPositionInArray, g as getScrollbarSize, m as mergeSortedArray, p as pushSorted, r as range, s as scaleValue, t as timeout } from './index-BvMNbQyq.js';
10
- export { T as TextEditor } from './text-editor-eHtrwvxH.js';
10
+ export { T as TextEditor } from './text-editor-BVb0idxe.js';
11
11
  export { k as isAll, c as isClear, h as isCopy, a as isCtrlKey, b as isCtrlMetaKey, g as isCut, m as isEditInput, n as isEditorCtrConstructible, f as isEnterKeyValue, i as isMetaKey, j as isPaste, l as isShortcutModifier, d as isTab, e as isTabKeyValue } from './edit.utils-3ZbhQCv_.js';
12
12
  export { h } from './index-CtimkLsB.js';
13
13
  export { C as CELL_CLASS, A as CELL_HANDLER_CLASS, n as DATA_COL, o as DATA_ROW, q as DISABLED_CLASS, y as DRAGGABLE_CLASS, B as DRAGG_TEXT, x as DRAG_ICON_CLASS, D as DataStore, E as EDIT_INPUT_WR, F as FOCUS_CLASS, G as GRID_INTERNALS, w as HEADER_ACTUAL_ROW_CLASS, H as HEADER_CLASS, v as HEADER_ROW_CLASS, u as HEADER_SORTABLE_CLASS, M as MIN_COL_SIZE, z as MOBILE_CLASS, R as RESIZE_INTERVAL, I as ROW_FOCUSED_CLASS, r as ROW_HEADER_TYPE, S as SELECTION_BORDER_CLASS, T as TMP_SELECTION_BG_CLASS, j as calculateDimensionData, J as codesLetter, h as gatherTrimmedItems, l as getItemByIndex, k as getItemByPosition, g as getPhysical, b as getSourceItem, f as getSourceItemVirtualIndexByProp, c as getSourcePhysicalIndex, i as getVisibleItems, a as getVisibleSourceItem, K as keyValues, p as proxyPlugin, e as setItems, d as setSourceByPhysicalIndex, s as setSourceByVirtualIndex, m as setStore, t as trimmedPlugin } from './dimension.helpers-Cln9sALu.js';
@@ -47,5 +47,5 @@ var patchCloneNodeFix = (HTMLElementPrototype) => {
47
47
 
48
48
  patchBrowser().then(async (options) => {
49
49
  await globalScripts();
50
- return bootstrapLazy([["revo-grid",[[260,"revo-grid",{"rowHeaders":[4,"row-headers"],"frameSize":[2,"frame-size"],"rowSize":[2,"row-size"],"colSize":[2,"col-size"],"range":[4],"readonly":[4],"resize":[4],"resizeRow":[4,"resize-row"],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"canFocus":[4,"can-focus"],"useClipboard":[4,"use-clipboard"],"columns":[16],"source":[16],"pinnedTopSource":[16],"pinnedBottomSource":[16],"rowDefinitions":[16],"editors":[16],"applyOnClose":[4,"apply-on-close"],"plugins":[16],"columnTypes":[16],"theme":[1537],"themeDefinitions":[16],"rowClass":[513,"row-class"],"autoSizeColumn":[4,"auto-size-column"],"filter":[4],"sorting":[16],"focusTemplate":[16],"canMoveColumns":[4,"can-move-columns"],"trimmedRows":[16],"exporting":[4],"grouping":[16],"stretch":[8],"additionalData":[16],"disableVirtualX":[4,"disable-virtual-x"],"virtualX":[16],"disableVirtualY":[4,"disable-virtual-y"],"hideAttribution":[4,"hide-attribution"],"jobsBeforeRender":[16],"registerVNode":[16],"accessible":[4],"rtl":[4],"canDrag":[4,"can-drag"],"refresh":[64],"setDataAt":[64],"scrollToRow":[64],"scrollToColumnIndex":[64],"scrollToColumnProp":[64],"updateColumns":[64],"addTrimmed":[64],"scrollToCoordinate":[64],"setCellEdit":[64],"setCellsFocus":[64],"getSource":[64],"getVisibleSource":[64],"getSourceStore":[64],"getColumnStore":[64],"updateColumnSorting":[64],"clearSorting":[64],"getColumns":[64],"clearFocus":[64],"getPlugins":[64],"getFocused":[64],"getContentSize":[64],"getSelectedRange":[64],"refreshExtraElements":[64],"getProviders":[64]},[[5,"touchstart","mousedownHandle"],[5,"mousedown","mousedownHandle"],[5,"touchend","mouseupHandle"],[5,"mouseup","mouseupHandle"],[0,"rowdragstartinit","onRowDragStarted"],[0,"rowdragendinit","onRowDragEnd"],[0,"roworderchange","onRowOrderChange"],[0,"rowdragmoveinit","onRowDrag"],[0,"rowdragmousemove","onRowMouseMove"],[0,"celleditapply","onCellEdit"],[0,"rangeeditapply","onRangeEdit"],[0,"selectionchangeinit","onRangeChanged"],[0,"rowdropinit","onRowDropped"],[0,"beforeheaderclick","onHeaderClick"],[0,"beforecellfocusinit","onCellFocus"]],{"columnTypes":[{"columnTypesChanged":0}],"columns":[{"columnChanged":0}],"disableVirtualX":[{"disableVirtualXChanged":0}],"virtualX":[{"virtualXChanged":0}],"rowSize":[{"rowSizeChanged":0}],"colSize":[{"colSizeChanged":0}],"theme":[{"themeChanged":0}],"themeDefinitions":[{"themeDefinitionsChanged":0}],"source":[{"dataSourceChanged":0}],"pinnedBottomSource":[{"dataSourceChanged":0}],"pinnedTopSource":[{"dataSourceChanged":0}],"disableVirtualY":[{"disableVirtualYChanged":0}],"rowDefinitions":[{"rowDefChanged":0}],"trimmedRows":[{"trimmedRowsChanged":0}],"grouping":[{"groupingChanged":0}],"stretch":[{"applyStretch":0}],"filter":[{"applyFilter":0}],"sorting":[{"applySorting":0}],"rowHeaders":[{"rowHeadersChange":0}],"resizeRow":[{"resizeRowChanged":0}],"registerVNode":[{"registerOutsideVNodes":0}],"additionalData":[{"additionalDataChanged":0}],"rtl":[{"rtlChanged":0}],"plugins":[{"pluginsChanged":0}]}]]],["revogr-filter-panel",[[260,"revogr-filter-panel",{"filterNames":[16],"filterEntities":[16],"filterCaptions":[16],"disableDynamicFiltering":[4,"disable-dynamic-filtering"],"closeOnOutsideClick":[4,"close-on-outside-click"],"allowDuplicateOperators":[4,"allow-duplicate-operators"],"isFilterIdSet":[32],"filterId":[32],"currentFilterId":[32],"currentFilterType":[32],"changes":[32],"filterItems":[32],"draggedFilterId":[32],"dragOverFilterId":[32],"show":[64],"getChanges":[64]},[[5,"mousedown","onMouseDown"]]]]],["revogr-clipboard_3",[[0,"revogr-clipboard",{"readonly":[4],"doCopy":[64]},[[4,"paste","onPaste"],[4,"copy","copyStarted"],[4,"cut","cutStarted"]]],[0,"revogr-edit",{"editCell":[16],"column":[16],"editor":[16],"saveOnClose":[4,"save-on-close"],"additionalData":[8,"additional-data"],"cancelChanges":[64],"beforeDisconnect":[64]}],[0,"revogr-order-editor",{"parent":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"rowType":[1,"row-type"],"dragStart":[64],"endOrder":[64],"clearOrder":[64]}]]],["revogr-data_4",[[260,"revogr-data",{"readonly":[4],"range":[4],"rowClass":[1,"row-class"],"additionalData":[8,"additional-data"],"rowSelectionStore":[16],"viewportRow":[16],"viewportCol":[16],"dimensionRow":[16],"colData":[16],"dataStore":[16],"type":[513],"colType":[513,"col-type"],"jobsBeforeRender":[16],"providers":[32],"updateCell":[64]},null,{"dataStore":[{"onDataStoreChange":0}],"colData":[{"onColDataChange":0}]}],[0,"revogr-header",{"viewportCol":[16],"dimensionCol":[16],"selectionStore":[16],"groups":[16],"groupingDepth":[2,"grouping-depth"],"readonly":[4],"canResize":[4,"can-resize"],"resizeHandler":[16],"colData":[16],"columnFilter":[4,"column-filter"],"type":[1],"additionalData":[8,"additional-data"]}],[260,"revogr-viewport-scroll",{"rowHeader":[4,"row-header"],"contentWidth":[2,"content-width"],"contentHeight":[2,"content-height"],"colType":[1,"col-type"],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"setScroll":[64],"changeScroll":[64],"applyScroll":[64]},[[0,"mousewheel-vertical","mousewheelVertical"],[0,"mousewheel-horizontal","mousewheelHorizontal"],[0,"scroll-coordinate","scrollApply"]]],[0,"vnode-html",{"redraw":[16]}]]],["revogr-attribution_7",[[0,"revogr-row-headers",{"height":[2],"dataPorts":[16],"headerProp":[16],"rowClass":[1,"row-class"],"resize":[4],"rowHeaderColumn":[16],"additionalData":[8,"additional-data"],"jobsBeforeRender":[16]}],[260,"revogr-overlay-selection",{"readonly":[4],"range":[4],"canDrag":[4,"can-drag"],"useClipboard":[4,"use-clipboard"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"lastCell":[16],"editors":[16],"applyChangesOnClose":[4,"apply-changes-on-close"],"additionalData":[8,"additional-data"],"isMobileDevice":[4,"is-mobile-device"]},[[5,"touchmove","onMouseMove"],[5,"mousemove","onMouseMove"],[5,"touchend","onMouseUp"],[5,"mouseup","onMouseUp"],[5,"mouseleave","onMouseUp"],[0,"dragstartcell","onCellDrag"],[4,"keyup","onKeyUp"],[4,"keydown","onKeyDown"]],{"selectionStore":[{"selectionServiceSet":0}],"dimensionRow":[{"createAutoFillService":0}],"dimensionCol":[{"createAutoFillService":0}],"dataStore":[{"columnServiceSet":0}],"colData":[{"columnServiceSet":0}]}],[0,"revogr-attribution"],[260,"revogr-focus",{"colType":[1,"col-type"],"rowType":[1,"row-type"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"focusTemplate":[16]}],[0,"revogr-scroll-virtual",{"dimension":[1],"realSize":[2,"real-size"],"virtualSize":[2,"virtual-size"],"clientSize":[2,"client-size"],"setScroll":[64],"changeScroll":[64]}],[0,"revogr-temp-range",{"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16]}],[0,"revogr-extra",{"nodes":[16],"update":[32],"refresh":[64]}]]]], options);
50
+ return bootstrapLazy([["revo-grid",[[260,"revo-grid",{"rowHeaders":[4,"row-headers"],"frameSize":[2,"frame-size"],"rowSize":[2,"row-size"],"colSize":[2,"col-size"],"range":[4],"readonly":[4],"resize":[4],"resizeRow":[4,"resize-row"],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"canFocus":[4,"can-focus"],"useClipboard":[4,"use-clipboard"],"columns":[16],"source":[16],"pinnedTopSource":[16],"pinnedBottomSource":[16],"rowDefinitions":[16],"editors":[16],"applyOnClose":[4,"apply-on-close"],"plugins":[16],"columnTypes":[16],"theme":[1537],"themeDefinitions":[16],"rowClass":[513,"row-class"],"autoSizeColumn":[4,"auto-size-column"],"filter":[4],"sorting":[16],"focusTemplate":[16],"canMoveColumns":[4,"can-move-columns"],"trimmedRows":[16],"exporting":[4],"grouping":[16],"stretch":[8],"additionalData":[16],"disableVirtualX":[4,"disable-virtual-x"],"virtualX":[16],"disableVirtualY":[4,"disable-virtual-y"],"hideAttribution":[4,"hide-attribution"],"jobsBeforeRender":[16],"registerVNode":[16],"accessible":[4],"rtl":[4],"canDrag":[4,"can-drag"],"refresh":[64],"setDataAt":[64],"scrollToRow":[64],"scrollToColumnIndex":[64],"scrollToColumnProp":[64],"updateColumns":[64],"addTrimmed":[64],"scrollToCoordinate":[64],"setCellEdit":[64],"setCellsFocus":[64],"getSource":[64],"getVisibleSource":[64],"getSourceStore":[64],"getColumnStore":[64],"updateColumnSorting":[64],"clearSorting":[64],"getColumns":[64],"clearFocus":[64],"getPlugins":[64],"getFocused":[64],"getContentSize":[64],"getSelectedRange":[64],"refreshExtraElements":[64],"getProviders":[64]},[[5,"touchstart","mousedownHandle"],[5,"mousedown","mousedownHandle"],[5,"touchend","mouseupHandle"],[5,"mouseup","mouseupHandle"],[0,"rowdragstartinit","onRowDragStarted"],[0,"rowdragendinit","onRowDragEnd"],[0,"roworderchange","onRowOrderChange"],[0,"rowdragmoveinit","onRowDrag"],[0,"rowdragmousemove","onRowMouseMove"],[0,"celleditapply","onCellEdit"],[0,"rangeeditapply","onRangeEdit"],[0,"selectionchangeinit","onRangeChanged"],[0,"rowdropinit","onRowDropped"],[0,"beforeheaderclick","onHeaderClick"],[0,"beforecellfocusinit","onCellFocus"]],{"columnTypes":[{"columnTypesChanged":0}],"columns":[{"columnChanged":0}],"disableVirtualX":[{"disableVirtualXChanged":0}],"virtualX":[{"virtualXChanged":0}],"rowSize":[{"rowSizeChanged":0}],"colSize":[{"colSizeChanged":0}],"theme":[{"themeChanged":0}],"themeDefinitions":[{"themeDefinitionsChanged":0}],"source":[{"dataSourceChanged":0}],"pinnedBottomSource":[{"dataSourceChanged":0}],"pinnedTopSource":[{"dataSourceChanged":0}],"disableVirtualY":[{"disableVirtualYChanged":0}],"rowDefinitions":[{"rowDefChanged":0}],"trimmedRows":[{"trimmedRowsChanged":0}],"grouping":[{"groupingChanged":0}],"stretch":[{"applyStretch":0}],"filter":[{"applyFilter":0}],"sorting":[{"applySorting":0}],"rowHeaders":[{"rowHeadersChange":0}],"resizeRow":[{"resizeRowChanged":0}],"registerVNode":[{"registerOutsideVNodes":0}],"additionalData":[{"additionalDataChanged":0}],"rtl":[{"rtlChanged":0}],"plugins":[{"pluginsChanged":0}]}]]],["revogr-filter-panel",[[260,"revogr-filter-panel",{"filterNames":[16],"filterEntities":[16],"filterCaptions":[16],"disableDynamicFiltering":[4,"disable-dynamic-filtering"],"closeOnOutsideClick":[4,"close-on-outside-click"],"allowDuplicateOperators":[4,"allow-duplicate-operators"],"isFilterIdSet":[32],"filterId":[32],"currentFilterId":[32],"currentFilterType":[32],"changes":[32],"filterItems":[32],"draggedFilterId":[32],"dragOverFilterId":[32],"show":[64],"getChanges":[64]},[[5,"mousedown","onMouseDown"]]]]],["revogr-clipboard_3",[[0,"revogr-clipboard",{"readonly":[4],"doCopy":[64]},[[4,"paste","onPaste"],[4,"copy","copyStarted"],[4,"cut","cutStarted"]]],[0,"revogr-edit",{"editCell":[16],"column":[16],"editor":[16],"saveOnClose":[4,"save-on-close"],"additionalData":[8,"additional-data"],"cancelChanges":[64],"beforeDisconnect":[64]},[[0,"internalappendeditvalue","onInternalAppendEditValue"]]],[0,"revogr-order-editor",{"parent":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"rowType":[1,"row-type"],"dragStart":[64],"endOrder":[64],"clearOrder":[64]}]]],["revogr-data_4",[[260,"revogr-data",{"readonly":[4],"range":[4],"rowClass":[1,"row-class"],"additionalData":[8,"additional-data"],"rowSelectionStore":[16],"viewportRow":[16],"viewportCol":[16],"dimensionRow":[16],"colData":[16],"dataStore":[16],"type":[513],"colType":[513,"col-type"],"jobsBeforeRender":[16],"providers":[32],"updateCell":[64]},null,{"dataStore":[{"onDataStoreChange":0}],"colData":[{"onColDataChange":0}]}],[0,"revogr-header",{"viewportCol":[16],"dimensionCol":[16],"selectionStore":[16],"groups":[16],"groupingDepth":[2,"grouping-depth"],"readonly":[4],"canResize":[4,"can-resize"],"resizeHandler":[16],"colData":[16],"columnFilter":[4,"column-filter"],"type":[1],"additionalData":[8,"additional-data"]}],[260,"revogr-viewport-scroll",{"rowHeader":[4,"row-header"],"contentWidth":[2,"content-width"],"contentHeight":[2,"content-height"],"colType":[1,"col-type"],"noHorizontalScrollTransfer":[4,"no-horizontal-scroll-transfer"],"setScroll":[64],"changeScroll":[64],"applyScroll":[64]},[[0,"mousewheel-vertical","mousewheelVertical"],[0,"mousewheel-horizontal","mousewheelHorizontal"],[0,"scroll-coordinate","scrollApply"]]],[0,"vnode-html",{"redraw":[16]}]]],["revogr-attribution_7",[[0,"revogr-row-headers",{"height":[2],"dataPorts":[16],"headerProp":[16],"rowClass":[1,"row-class"],"resize":[4],"rowHeaderColumn":[16],"additionalData":[8,"additional-data"],"jobsBeforeRender":[16]}],[260,"revogr-overlay-selection",{"readonly":[4],"range":[4],"canDrag":[4,"can-drag"],"useClipboard":[4,"use-clipboard"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"lastCell":[16],"editors":[16],"applyChangesOnClose":[4,"apply-changes-on-close"],"additionalData":[8,"additional-data"],"isMobileDevice":[4,"is-mobile-device"]},[[5,"touchmove","onMouseMove"],[5,"mousemove","onMouseMove"],[5,"touchend","onMouseUp"],[5,"mouseup","onMouseUp"],[5,"mouseleave","onMouseUp"],[0,"dragstartcell","onCellDrag"],[4,"keyup","onKeyUp"],[4,"keydown","onKeyDown"]],{"selectionStore":[{"selectionServiceSet":0}],"dimensionRow":[{"createAutoFillService":0}],"dimensionCol":[{"createAutoFillService":0}],"dataStore":[{"columnServiceSet":0}],"colData":[{"columnServiceSet":0}]}],[0,"revogr-attribution"],[260,"revogr-focus",{"colType":[1,"col-type"],"rowType":[1,"row-type"],"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16],"dataStore":[16],"colData":[16],"focusTemplate":[16]}],[0,"revogr-scroll-virtual",{"dimension":[1],"realSize":[2,"real-size"],"virtualSize":[2,"virtual-size"],"clientSize":[2,"client-size"],"setScroll":[64],"changeScroll":[64]}],[0,"revogr-temp-range",{"selectionStore":[16],"dimensionRow":[16],"dimensionCol":[16]}],[0,"revogr-extra",{"nodes":[16],"update":[32],"refresh":[64]}]]]], options);
51
51
  });
@@ -271,13 +271,13 @@ const RevogrFocus$1 = class RevogrFocus {
271
271
  };
272
272
  RevogrFocus$1.style = revogrFocusStyleCss();
273
273
 
274
- const DIRECTION_CODES = [
275
- codesLetter.TAB,
274
+ const ARROW_CODES = [
276
275
  codesLetter.ARROW_UP,
277
276
  codesLetter.ARROW_DOWN,
278
277
  codesLetter.ARROW_LEFT,
279
278
  codesLetter.ARROW_RIGHT,
280
279
  ];
280
+ const DIRECTION_CODES = new Set([codesLetter.TAB, ...ARROW_CODES]);
281
281
  class KeyboardService {
282
282
  constructor(sv) {
283
283
  this.sv = sv;
@@ -295,6 +295,10 @@ class KeyboardService {
295
295
  /**
296
296
  * Appends printable key input that arrives after edit mode was requested
297
297
  * but before the editor input has mounted or received focus.
298
+ *
299
+ * Once the input is rendered the key goes straight into it: a store update
300
+ * would only reach the input on the next render, and that render would
301
+ * overwrite whatever was typed natively into the input in the meantime.
298
302
  */
299
303
  appendPendingEditValue(e) {
300
304
  if (isShortcutModifier(e) ||
@@ -307,6 +311,9 @@ class KeyboardService {
307
311
  return false;
308
312
  }
309
313
  e.preventDefault();
314
+ if (this.sv.appendEditValue(e.key)) {
315
+ return true;
316
+ }
310
317
  this.sv.selectionStore.set('edit', Object.assign(Object.assign({}, editCell), { val: `${editCell.val}${e.key}` }));
311
318
  return true;
312
319
  }
@@ -407,7 +414,9 @@ class KeyboardService {
407
414
  this.applyingKeyChange = true;
408
415
  let changed;
409
416
  try {
410
- changed = this.keyPositionChange(data.changes, range, focus, data.isMulti);
417
+ changed = data.edge
418
+ ? this.keyEdgeChange(data.changes, range, focus, !!data.isMulti)
419
+ : this.keyPositionChange(data.changes, range, focus, data.isMulti);
411
420
  }
412
421
  finally {
413
422
  this.applyingKeyChange = false;
@@ -444,10 +453,33 @@ class KeyboardService {
444
453
  ? -1
445
454
  : 0);
446
455
  }
456
+ keyEdgeChange(changes, range, focus, isMulti) {
457
+ if (!range || !focus) {
458
+ return false;
459
+ }
460
+ const { lastCell } = this.sv.getData();
461
+ const coordinate = changes.x ? 'x' : 'y';
462
+ const direction = changes[coordinate];
463
+ const target = direction > 0 ? lastCell[coordinate] - 1 : 0;
464
+ if (isMulti) {
465
+ const edgeCoordinate = coordinate === 'x' ? 'x1' : 'y1';
466
+ return this.sv.range(Object.assign(Object.assign({}, range), { [coordinate]: direction < 0 ? target : focus[coordinate], [edgeCoordinate]: direction > 0 ? target : focus[coordinate] }));
467
+ }
468
+ const edgeFocus = Object.assign(Object.assign({}, focus), { [coordinate]: target });
469
+ return this.sv.focus(edgeFocus, {
470
+ [coordinate]: target - focus[coordinate],
471
+ });
472
+ }
447
473
  /** Monitor key direction changes */
448
474
  changeDirectionKey(e, canRange) {
449
475
  const isMulti = canRange && e.shiftKey;
450
- if (DIRECTION_CODES.includes(e.code)) {
476
+ const hasPrimaryModifier = e.ctrlKey || e.metaKey;
477
+ const isArrow = ARROW_CODES.includes(e.code);
478
+ const isEdgeShortcut = hasPrimaryModifier && !e.altKey && isArrow;
479
+ if (hasPrimaryModifier && !isEdgeShortcut) {
480
+ return;
481
+ }
482
+ if (DIRECTION_CODES.has(e.code)) {
451
483
  e.preventDefault();
452
484
  }
453
485
  if (e.shiftKey) {
@@ -456,17 +488,25 @@ class KeyboardService {
456
488
  return { changes: { x: -1 }, isMulti: false };
457
489
  }
458
490
  }
491
+ let changes;
459
492
  switch (e.code) {
460
493
  case codesLetter.ARROW_UP:
461
- return { changes: { y: -1 }, isMulti };
494
+ changes = { y: -1 };
495
+ break;
462
496
  case codesLetter.ARROW_DOWN:
463
- return { changes: { y: 1 }, isMulti };
497
+ changes = { y: 1 };
498
+ break;
464
499
  case codesLetter.ARROW_LEFT:
465
- return { changes: { x: -1 }, isMulti };
500
+ changes = { x: -1 };
501
+ break;
466
502
  case codesLetter.TAB:
467
503
  case codesLetter.ARROW_RIGHT:
468
- return { changes: { x: 1 }, isMulti };
504
+ changes = { x: 1 };
505
+ break;
506
+ default:
507
+ return;
469
508
  }
509
+ return Object.assign({ changes, isMulti }, (isEdgeShortcut && { edge: true }));
470
510
  }
471
511
  }
472
512
 
@@ -827,6 +867,15 @@ const OverlaySelection = class {
827
867
  await ((_a = this.revogrEdit) === null || _a === void 0 ? void 0 : _a.cancelChanges());
828
868
  this.closeEdit();
829
869
  },
870
+ appendEditValue: value => {
871
+ if (!this.revogrEdit) {
872
+ return false;
873
+ }
874
+ return !this.revogrEdit.dispatchEvent(new CustomEvent('internalappendeditvalue', {
875
+ cancelable: true,
876
+ detail: value,
877
+ }));
878
+ },
830
879
  clearCell: () => !this.readonly && this.clearCell(),
831
880
  internalPaste: () => !this.readonly && this.beforeRegionPaste.emit(),
832
881
  getData: () => this.getData(),
@@ -950,9 +999,9 @@ const OverlaySelection = class {
950
999
  nodes.push(h("revogr-order-editor", { ref: e => (this.orderEditor = e), dataStore: this.dataStore, dimensionRow: this.dimensionRow, dimensionCol: this.dimensionCol, parent: this.element, rowType: this.types.rowType, onRowdragstartinit: e => this.rowDragStart(e) }));
951
1000
  }
952
1001
  }
953
- return (h(Host, { key: '230e2122c5c7065c072f02019d616a64949d54d0', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
1002
+ return (h(Host, { key: '84d904c108e39ebf82b215afc7052d634eba677e', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
954
1003
  // it's done to be able to throw events from different levels, not just from editor
955
- onCelledit: (e) => this.onEditCell(e) }, nodes, h("slot", { key: '47740a79c605258b4024384510358be927d000b7', name: "data" })));
1004
+ onCelledit: (e) => this.onEditCell(e) }, nodes, h("slot", { key: '7434c5fceb445de4510675b7627bb5f2efc1a365', name: "data" })));
956
1005
  }
957
1006
  /**
958
1007
  * Executes the focus operation on the specified range of cells.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, a as createEvent, h, d as Host, g as getElement } from './index-CtimkLsB.js';
5
5
  import { E as EDIT_INPUT_WR, k as getItemByPosition, b as getSourceItem, B as DRAGG_TEXT } from './dimension.helpers-Cln9sALu.js';
6
- import { T as TextEditor } from './text-editor-eHtrwvxH.js';
6
+ import { T as TextEditor } from './text-editor-BVb0idxe.js';
7
7
  import { n as isEditorCtrConstructible } from './edit.utils-3ZbhQCv_.js';
8
8
  import { d as debounce } from './debounce-PCRWZliA.js';
9
9
  import './index-BvMNbQyq.js';
@@ -175,6 +175,12 @@ const RevoEdit = class {
175
175
  var _a, _b;
176
176
  (_b = (_a = this.currentEditor) === null || _a === void 0 ? void 0 : _a.beforeDisconnect) === null || _b === void 0 ? void 0 : _b.call(_a);
177
177
  }
178
+ onInternalAppendEditValue(e) {
179
+ var _a, _b;
180
+ if ((_b = (_a = this.currentEditor) === null || _a === void 0 ? void 0 : _a.appendPendingInput) === null || _b === void 0 ? void 0 : _b.call(_a, e.detail)) {
181
+ e.preventDefault();
182
+ }
183
+ }
178
184
  onAutoSave() {
179
185
  var _a, _b, _c;
180
186
  this.preventSaveOnClose = true;
@@ -22,6 +22,14 @@ class TextEditor {
22
22
  (_a = this.editInput) === null || _a === void 0 ? void 0 : _a.focus();
23
23
  }
24
24
  }
25
+ appendPendingInput(value) {
26
+ if (!this.editInput) {
27
+ return false;
28
+ }
29
+ this.editInput.value += value;
30
+ this.editInput.focus();
31
+ return true;
32
+ }
25
33
  onKeyDown(e) {
26
34
  const isEnter = isEnterKeyValue(e.key);
27
35
  const isKeyTab = isTab(e.key);
@@ -49,6 +49,7 @@ export declare class RevoEdit {
49
49
  * Can be triggered multiple times before actual disconnect.
50
50
  */
51
51
  beforeDisconnect(): Promise<void>;
52
+ onInternalAppendEditValue(e: CustomEvent<string>): void;
52
53
  onAutoSave(): void;
53
54
  /**
54
55
  * Callback triggered when cell editor saved.
@@ -23,6 +23,7 @@ export declare class TextEditor implements EditorBase {
23
23
  * Callback triggered on cell editor render
24
24
  */
25
25
  componentDidRender(): Promise<void>;
26
+ appendPendingInput(value: string): boolean;
26
27
  onKeyDown(e: KeyboardEvent): void;
27
28
  /**
28
29
  * IMPORTANT: Prevent scroll glitches when editor is closed and focus is on current input element.
@@ -5,6 +5,7 @@ type Config = {
5
5
  selectionStore: Observable<SelectionStoreState>;
6
6
  change(val?: any): boolean;
7
7
  cancel(): void;
8
+ appendEditValue(value: string): boolean;
8
9
  clearCell(): void;
9
10
  focus(focus: Cell, changes: Partial<Cell>, focusNextViewport?: number): boolean;
10
11
  getData(): any;
@@ -12,6 +13,11 @@ type Config = {
12
13
  range(range: RangeArea | null): boolean;
13
14
  selectAll(): void;
14
15
  };
16
+ type DirectionKeyChange = {
17
+ changes: Partial<Cell>;
18
+ isMulti?: boolean;
19
+ edge?: boolean;
20
+ };
15
21
  export declare class KeyboardService {
16
22
  private readonly sv;
17
23
  /** Keep focus transitions in keydown order so rendering can scroll each cell into view. */
@@ -24,16 +30,18 @@ export declare class KeyboardService {
24
30
  /**
25
31
  * Appends printable key input that arrives after edit mode was requested
26
32
  * but before the editor input has mounted or received focus.
33
+ *
34
+ * Once the input is rendered the key goes straight into it: a store update
35
+ * would only reach the input on the next render, and that render would
36
+ * overwrite whatever was typed natively into the input in the meantime.
27
37
  */
28
38
  private appendPendingEditValue;
29
39
  keyDown(e: KeyboardEvent, canRange: boolean, isEditMode: boolean, { range, focus }: Nullable<Pick<EventData, 'range' | 'focus'>>): Promise<void>;
30
40
  private selectAll;
31
41
  keyChangeSelection(e: KeyboardEvent, canRange: boolean): Promise<boolean>;
32
42
  keyPositionChange(changes: Partial<Cell>, range: RangeArea | null, focus: Cell | null, isMulti?: boolean): boolean;
43
+ private keyEdgeChange;
33
44
  /** Monitor key direction changes */
34
- changeDirectionKey(e: KeyboardEvent, canRange: boolean): {
35
- changes: Partial<Cell>;
36
- isMulti?: boolean;
37
- } | void;
45
+ changeDirectionKey(e: KeyboardEvent, canRange: boolean): DirectionKeyChange | void;
38
46
  }
39
47
  export {};
@@ -172,6 +172,11 @@ export interface EditorCtrConstructible {
172
172
  export interface EditorBase {
173
173
  element?: Element | null;
174
174
  editCell?: EditCell;
175
+ /**
176
+ * Consume printable input that reached the grid while the editor mounted.
177
+ * Return true when the editor handled the value.
178
+ */
179
+ appendPendingInput?(value: string): boolean;
175
180
  /**
176
181
  * Autosave usage when you want to return value for models.
177
182
  */