@syncfusion/ej2-filemanager 33.1.44 → 33.1.47

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.
@@ -3935,6 +3935,9 @@ function triggerPopupOpen(parent, dlgModule, dialogName) {
3935
3935
  function triggerPopupClose(parent, dlgModule, dialogName) {
3936
3936
  const args = { popupModule: dlgModule, element: dlgModule.element, popupName: dialogName };
3937
3937
  parent.trigger('popupClose', args);
3938
+ if (dialogName !== 'Duplicate Items') {
3939
+ parent.restoreFocus();
3940
+ }
3938
3941
  }
3939
3942
  /**
3940
3943
  *
@@ -4815,6 +4818,7 @@ class LargeIconsView {
4815
4818
  this.isInteracted = true;
4816
4819
  this.imageEventArgsMap = new Map();
4817
4820
  this.imageUrlCache = new Map();
4821
+ this.nextFocusIndex = null;
4818
4822
  this.parent = parent;
4819
4823
  this.element = select('#' + this.parent.element.id + LARGEICON_ID, this.parent.element);
4820
4824
  addClass([this.element], LARGE_ICONS);
@@ -5221,6 +5225,13 @@ class LargeIconsView {
5221
5225
  }
5222
5226
  onDeleteInit() {
5223
5227
  if (this.parent.activeModule === 'largeiconsview') {
5228
+ const activeItem = this.getFocusedItem() || this.getActiveItem();
5229
+ if (activeItem) {
5230
+ const index = this.itemList.indexOf(activeItem);
5231
+ if (index !== -1) {
5232
+ this.nextFocusIndex = index;
5233
+ }
5234
+ }
5224
5235
  Delete(this.parent, this.parent.selectedItems, this.parent.path, 'delete');
5225
5236
  }
5226
5237
  }
@@ -5231,6 +5242,16 @@ class LargeIconsView {
5231
5242
  }
5232
5243
  this.onLayoutChange(args);
5233
5244
  this.parent.setProperties({ selectedItems: [] }, true);
5245
+ if (typeof this.nextFocusIndex === 'number') {
5246
+ const items = this.element.querySelectorAll('li.e-list-item');
5247
+ if (items.length > 0) {
5248
+ const focusIndex = this.nextFocusIndex >= items.length
5249
+ ? (this.nextFocusIndex === items.length ? items.length - 1 : 0) : this.nextFocusIndex;
5250
+ // eslint-disable-next-line security/detect-object-injection
5251
+ this.addFocus(items[focusIndex]);
5252
+ }
5253
+ this.nextFocusIndex = null;
5254
+ }
5234
5255
  this.clearSelect();
5235
5256
  }
5236
5257
  onRefreshEnd(args) {
@@ -5258,6 +5279,30 @@ class LargeIconsView {
5258
5279
  this.clearSelect();
5259
5280
  this.addSelection(this.parent.renamedItem);
5260
5281
  }
5282
+ let mappedItem = null;
5283
+ if (this.parent._lastFocused && this.parent.pathId && this.parent.pathId.length && this.items && this.itemList) {
5284
+ const key = this.parent.pathId[this.parent.pathId.length - 1];
5285
+ // eslint-disable-next-line security/detect-object-injection
5286
+ const mappedId = this.parent._lastFocused[key];
5287
+ if (mappedId) {
5288
+ let foundIndex = -1;
5289
+ for (let i = 0; i < this.items.length; i++) {
5290
+ // eslint-disable-next-line security/detect-object-injection
5291
+ if (getValue('_fm_id', this.items[i]) === mappedId || (this.parent.hasId && getValue('id', this.items[i]) === mappedId) || getValue('name', this.items[i]) === mappedId) {
5292
+ foundIndex = i;
5293
+ break;
5294
+ }
5295
+ }
5296
+ // eslint-disable-next-line security/detect-object-injection
5297
+ if (foundIndex > -1 && this.itemList[foundIndex]) {
5298
+ mappedItem = this.itemList[foundIndex];
5299
+ }
5300
+ }
5301
+ }
5302
+ const targetItem = this.getFocusedItem() || mappedItem || this.parent.visitedItem || this.getFirstItem();
5303
+ if (targetItem) {
5304
+ this.addFocus(targetItem);
5305
+ }
5261
5306
  }
5262
5307
  }
5263
5308
  onOpenInit(args) {
@@ -5715,6 +5760,9 @@ class LargeIconsView {
5715
5760
  if (!this.parent.isFile) {
5716
5761
  const val = this.parent.breadcrumbbarModule.searchObj.element.value;
5717
5762
  if (val === '' && !this.parent.isFiltered) {
5763
+ if (this.parent.pathId && this.parent.pathId.length) {
5764
+ this.parent._lastFocused = Object.assign(this.parent._lastFocused || {}, { [this.parent.pathId[this.parent.pathId.length - 1]]: getValue('_fm_id', details) || getValue('id', details) || text });
5765
+ }
5718
5766
  const id = getValue('id', details);
5719
5767
  this.parent.oldPath = this.parent.path;
5720
5768
  const newPath = this.parent.path + (isNullOrUndefined(id) ? text : id) + '/';
@@ -5954,12 +6002,26 @@ class LargeIconsView {
5954
6002
  const indexes = this.getIndexes([item], this.parent.hasId);
5955
6003
  return this.itemList[indexes[0]];
5956
6004
  }
6005
+ /**
6006
+ *
6007
+ * Gets the currently focused item element in the large icon view.
6008
+ *
6009
+ * @returns {Element} - The DOM element of the focused item, or null if none is focused.
6010
+ * @hidden
6011
+ */
5957
6012
  getFocusedItem() {
5958
6013
  return select('.' + LIST_ITEM + '.' + FOCUS, this.element);
5959
6014
  }
5960
6015
  getActiveItem() {
5961
6016
  return select('.' + LIST_ITEM + '.' + ACTIVE, this.element);
5962
6017
  }
6018
+ /**
6019
+ *
6020
+ * Gets the first item element in the large icon view.
6021
+ *
6022
+ * @returns {Element} - The DOM element representing the first item in the list.
6023
+ * @hidden
6024
+ */
5963
6025
  getFirstItem() {
5964
6026
  return this.itemList[0];
5965
6027
  }
@@ -6164,6 +6226,14 @@ class LargeIconsView {
6164
6226
  const data = this.getItemObject(item);
6165
6227
  return getItemName(this.parent, data);
6166
6228
  }
6229
+ /**
6230
+ *
6231
+ * Adds focus to the specified item element in the large icon view.
6232
+ *
6233
+ * @param {Element} item - The DOM element representing the item to focus.
6234
+ * @returns {void} - If null or invalid, no focus is applied.
6235
+ * @hidden
6236
+ */
6167
6237
  addFocus(item) {
6168
6238
  this.element.setAttribute('tabindex', '-1');
6169
6239
  const fItem = this.getFocusedItem();
@@ -6504,14 +6574,16 @@ class BreadCrumbBar {
6504
6574
  const icon = createElement('span', { className: ICONS });
6505
6575
  addressbarLI.appendChild(icon);
6506
6576
  }
6507
- if (pathNamesLen - i !== 1) {
6508
- addressATag = createElement('a', { className: LIST_TEXT });
6509
- addressbarLI.setAttribute('tabindex', '0');
6510
- }
6511
- else {
6512
- addressATag = createElement('span', { className: LIST_TEXT });
6577
+ addressbarLI.setAttribute('tabindex', '0');
6578
+ addressbarLI.setAttribute('role', 'link');
6579
+ const pathLabel = pathNames.slice(0, i + 1).join(' / ');
6580
+ addressbarLI.setAttribute('aria-label', pathLabel);
6581
+ if (pathNamesLen - i === 1) {
6582
+ addressbarLI.setAttribute('aria-current', 'page');
6513
6583
  }
6514
6584
  id = '';
6585
+ addressATag = createElement('a', { className: LIST_TEXT });
6586
+ addressATag.setAttribute('role', 'presentation');
6515
6587
  addressATag.innerText = pathNames[i];
6516
6588
  addressbarLI.appendChild(addressATag);
6517
6589
  addressbarUL.appendChild(addressbarLI);
@@ -6918,6 +6990,9 @@ class ContextMenu {
6918
6990
  return;
6919
6991
  }
6920
6992
  });
6993
+ if (!this.isMenuItemClicked && this.menuTarget) {
6994
+ this.parent.restoreFocus();
6995
+ }
6921
6996
  this.menuTarget = null;
6922
6997
  if (!this.isMenuItemClicked && this.parent.pathId.length > 1 && this.parent.activeModule === 'navigationpane') {
6923
6998
  this.parent.pathId.pop();
@@ -9017,6 +9092,20 @@ let FileManager = FileManager_1 = class FileManager extends Component {
9017
9092
  this.uploadObj.enableRtl = rtl;
9018
9093
  }
9019
9094
  }
9095
+ restoreFocus() {
9096
+ if (this.activeModule === 'detailsview') {
9097
+ if (this.detailsviewModule.gridObj) {
9098
+ this.detailsviewModule.addFocus(this.detailsviewModule.gridObj.selectedRowIndex > -1
9099
+ ? this.detailsviewModule.gridObj.selectedRowIndex : 0);
9100
+ }
9101
+ return;
9102
+ }
9103
+ const targetItem = this.largeiconsviewModule.getFocusedItem()
9104
+ || this.visitedItem || this.largeiconsviewModule.getFirstItem();
9105
+ if (targetItem && this.largeiconsviewModule) {
9106
+ this.largeiconsviewModule.addFocus(targetItem);
9107
+ }
9108
+ }
9020
9109
  };
9021
9110
  __decorate$8([
9022
9111
  Complex({}, AjaxSettings)
@@ -10993,6 +11082,7 @@ class DetailsView {
10993
11082
  this.isMultiSelect = false;
10994
11083
  this.pasteOperation = false;
10995
11084
  this.uploadOperation = false;
11085
+ this.nextFocusIndex = null;
10996
11086
  Grid.Inject(Resize, ContextMenu$2, Sort, VirtualScroll);
10997
11087
  this.parent = parent;
10998
11088
  this.element = select('#' + this.parent.element.id + GRID_ID, this.parent.element);
@@ -11443,6 +11533,13 @@ class DetailsView {
11443
11533
  sortIconElement.classList.remove('e-icon-ascending', 'e-ascending', 'e-icon-descending', 'e-descending');
11444
11534
  }
11445
11535
  }
11536
+ if (typeof this.nextFocusIndex === 'number') {
11537
+ const rowCount = this.gridObj.getRows().length;
11538
+ if (rowCount > 0) {
11539
+ this.addFocus(this.nextFocusIndex >= rowCount ? rowCount : this.nextFocusIndex);
11540
+ }
11541
+ this.nextFocusIndex = null;
11542
+ }
11446
11543
  }
11447
11544
  selectRecords(nodes) {
11448
11545
  const gridRecords = this.gridObj.getCurrentViewRecords();
@@ -11576,6 +11673,21 @@ class DetailsView {
11576
11673
  showSpinner(this.parent.element);
11577
11674
  this.parent.setProperties({ selectedItems: [] }, true);
11578
11675
  this.gridObj.dataSource = getSortedData(this.parent, args.files);
11676
+ if (this.parent._lastFocused && this.parent.pathId && this.parent.pathId.length) {
11677
+ const key = this.parent.pathId[this.parent.pathId.length - 1];
11678
+ // eslint-disable-next-line security/detect-object-injection
11679
+ const mappedId = this.parent._lastFocused[key];
11680
+ if (mappedId) {
11681
+ const gridItems = getSortedData(this.parent, args.files);
11682
+ for (let i = 0; i < gridItems.length; i++) {
11683
+ // eslint-disable-next-line security/detect-object-injection
11684
+ if (getValue('_fm_id', gridItems[i]) === mappedId || (this.parent.hasId && getValue('id', gridItems[i]) === mappedId) || getValue('name', gridItems[i]) === mappedId) {
11685
+ this.nextFocusIndex = i;
11686
+ break;
11687
+ }
11688
+ }
11689
+ }
11690
+ }
11579
11691
  this.gridObj.freezeRefresh();
11580
11692
  if (this.parent.isReact) {
11581
11693
  this.gridObj.on('reactTemplateRender', this.reactTemplateRender, this);
@@ -11646,6 +11758,9 @@ class DetailsView {
11646
11758
  else {
11647
11759
  const val = this.parent.breadcrumbbarModule.searchObj.element.value;
11648
11760
  if (val === '' && !this.parent.isFiltered) {
11761
+ if (this.parent.pathId && this.parent.pathId.length) {
11762
+ this.parent._lastFocused = Object.assign(this.parent._lastFocused || {}, { [this.parent.pathId[this.parent.pathId.length - 1]]: getValue('_fm_id', data) || getValue('id', data) || name });
11763
+ }
11649
11764
  const id = getValue('id', data);
11650
11765
  this.parent.oldPath = this.parent.path;
11651
11766
  const newPath = this.parent.path + (isNullOrUndefined(id) ? name : id) + '/';
@@ -11766,6 +11881,8 @@ class DetailsView {
11766
11881
  }
11767
11882
  onDeleteInit() {
11768
11883
  if (this.parent.activeModule === 'detailsview') {
11884
+ const selectedIndex = this.gridObj.selectedRowIndex;
11885
+ this.nextFocusIndex = selectedIndex >= 0 ? selectedIndex : this.nextFocusIndex;
11769
11886
  Delete(this.parent, this.parent.selectedItems, this.parent.path, 'delete');
11770
11887
  }
11771
11888
  }
@@ -12713,6 +12830,14 @@ class DetailsView {
12713
12830
  }
12714
12831
  this.startIndex = this.gridObj.selectedRowIndex;
12715
12832
  }
12833
+ /**
12834
+ * Adds focus to the specified grid row.
12835
+ *
12836
+ * @param {number | null} item - The row index of the item to focus.
12837
+ * If null or invalid, no focus is applied.
12838
+ * @returns {void}
12839
+ * @hidden
12840
+ */
12716
12841
  addFocus(item) {
12717
12842
  const fItem = this.getFocusedItem();
12718
12843
  const itemElement = this.gridObj.getRowByIndex(item);