@lvce-editor/explorer-view 2.18.0 → 2.20.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.
@@ -1107,13 +1107,16 @@ const getNewDirentsAccept = async (state, newDirentType, createFn) => {
1107
1107
  const depth = parentDirent.depth + 1;
1108
1108
  const newDirent = {
1109
1109
  path: absolutePath,
1110
+ // @ts-ignore
1110
1111
  posInSet: -1,
1111
1112
  setSize: 1,
1112
1113
  depth,
1113
1114
  name: newFileName,
1114
1115
  type: newDirentType,
1115
- icon: ''
1116
+ icon: '',
1117
+ selected: false
1116
1118
  };
1119
+ // @ts-ignore
1117
1120
  newDirent.icon = '';
1118
1121
  let insertIndex = state.focusedIndex;
1119
1122
  let deltaPosInSet = 0;
@@ -1147,7 +1150,9 @@ const getNewDirentsAccept = async (state, newDirentType, createFn) => {
1147
1150
  // @ts-ignore
1148
1151
  dirent.posInSet += deltaPosInSet;
1149
1152
  }
1153
+ // @ts-ignore
1150
1154
  newDirent.setSize = setSize;
1155
+ // @ts-ignore
1151
1156
  newDirent.posInSet = posInSet;
1152
1157
  // @ts-ignore
1153
1158
  items.splice(insertIndex + 1, 0, newDirent);
@@ -1573,6 +1578,7 @@ const create = (id, uri, x, y, width, height, args, parentUid, platform = 0) =>
1573
1578
 
1574
1579
  const RenderItems = 4;
1575
1580
  const RenderFocus = 6;
1581
+ const RenderFocusContext = 7;
1576
1582
 
1577
1583
  const diffType$1 = RenderFocus;
1578
1584
  const isEqual$2 = (oldState, newState) => {
@@ -1584,8 +1590,8 @@ const isEqual$1 = (oldState, newState) => {
1584
1590
  return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex && oldState.editingIndex === newState.editingIndex && oldState.editingType === newState.editingType && oldState.editingValue === newState.editingValue && oldState.editingErrorMessage === newState.editingErrorMessage && oldState.width === newState.width && oldState.focused === newState.focused && oldState.dropTargets === newState.dropTargets;
1585
1591
  };
1586
1592
 
1587
- const modules = [isEqual$1, isEqual$2];
1588
- const numbers = [diffType, diffType$1];
1593
+ const modules = [isEqual$1, isEqual$2, isEqual$2];
1594
+ const numbers = [diffType, diffType$1, RenderFocusContext];
1589
1595
 
1590
1596
  const diff = (oldState, newState) => {
1591
1597
  const diffResult = [];
@@ -1872,12 +1878,18 @@ const expandRecursively = async state => {
1872
1878
  const focusIndex = (state, index) => {
1873
1879
  const {
1874
1880
  minLineY,
1875
- maxLineY
1881
+ maxLineY,
1882
+ items
1876
1883
  } = state;
1884
+ const newItems = items.map((item, i) => ({
1885
+ ...item,
1886
+ selected: i === index ? true : false
1887
+ }));
1877
1888
  if (index < minLineY) {
1878
1889
  if (index < 0) {
1879
1890
  return {
1880
1891
  ...state,
1892
+ items: newItems,
1881
1893
  focusedIndex: index,
1882
1894
  focused: true
1883
1895
  };
@@ -1885,6 +1897,7 @@ const focusIndex = (state, index) => {
1885
1897
  const diff = maxLineY - minLineY;
1886
1898
  return {
1887
1899
  ...state,
1900
+ items: newItems,
1888
1901
  focusedIndex: index,
1889
1902
  focused: true,
1890
1903
  minLineY: index,
@@ -1895,6 +1908,7 @@ const focusIndex = (state, index) => {
1895
1908
  const diff = maxLineY - minLineY;
1896
1909
  return {
1897
1910
  ...state,
1911
+ items: newItems,
1898
1912
  focusedIndex: index,
1899
1913
  focused: true,
1900
1914
  minLineY: index + 1 - diff,
@@ -1903,6 +1917,7 @@ const focusIndex = (state, index) => {
1903
1917
  }
1904
1918
  return {
1905
1919
  ...state,
1920
+ items: newItems,
1906
1921
  focusedIndex: index,
1907
1922
  focused: true
1908
1923
  };
@@ -1971,7 +1986,7 @@ const focusPrevious = state => {
1971
1986
  }
1972
1987
  };
1973
1988
 
1974
- const commandIds = ['acceptEdit', 'cancelEdit', 'collapseAll', 'copyPath', 'copyRelativePath', 'dispose', 'expandAll', 'expandRecursively', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'focusPrevious', 'getFocusedDirent', 'getMenuEntries2', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'setDeltaY', 'updateEditingValue', 'updateIcons'];
1989
+ const commandIds = ['acceptEdit', 'cancelEdit', 'collapseAll', 'copyPath', 'copyRelativePath', 'dispose', 'expandAll', 'expandRecursively', 'selectUp', 'selectDown', 'getMouseActions', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'focusPrevious', 'getFocusedDirent', 'getMenuEntries2', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'setDeltaY', 'updateEditingValue', 'updateIcons'];
1975
1990
 
1976
1991
  const getCommandIds = () => {
1977
1992
  return commandIds;
@@ -1993,6 +2008,7 @@ const F2 = 58;
1993
2008
  const Star = 131;
1994
2009
 
1995
2010
  const CtrlCmd = 1 << 11 >>> 0;
2011
+ const Shift = 1 << 10 >>> 0;
1996
2012
  const Alt = 1 << 9 >>> 0;
1997
2013
 
1998
2014
  const FocusExplorer = 13;
@@ -2000,6 +2016,14 @@ const FocusExplorerEditBox = 14;
2000
2016
 
2001
2017
  const getKeyBindings = () => {
2002
2018
  return [{
2019
+ key: Shift | UpArrow,
2020
+ command: 'Explorer.selectUp',
2021
+ when: FocusExplorer
2022
+ }, {
2023
+ key: Shift | DownArrow,
2024
+ command: 'Explorer.selectDown',
2025
+ when: FocusExplorer
2026
+ }, {
2003
2027
  key: RightArrow,
2004
2028
  command: 'Explorer.handleArrowRight',
2005
2029
  when: FocusExplorer
@@ -2196,6 +2220,46 @@ const getMenuEntries2 = uid => {
2196
2220
  return getMenuEntries(newState);
2197
2221
  };
2198
2222
 
2223
+ const Keyboard = -1;
2224
+ const LeftClick = 0;
2225
+
2226
+ const getMouseActions = () => {
2227
+ return [{
2228
+ id: 'explorer.openFile',
2229
+ description: 'Open file on click',
2230
+ button: LeftClick,
2231
+ modifiers: {},
2232
+ command: 'Explorer.openFile',
2233
+ when: FocusExplorer
2234
+ }, {
2235
+ id: 'explorer.toggleSelection',
2236
+ description: 'Toggle selection with Ctrl+Click',
2237
+ button: LeftClick,
2238
+ modifiers: {
2239
+ ctrl: true
2240
+ },
2241
+ command: 'Explorer.toggleSelection',
2242
+ when: FocusExplorer
2243
+ }, {
2244
+ id: 'explorer.rangeSelection',
2245
+ description: 'Select range with Shift+Click',
2246
+ button: LeftClick,
2247
+ modifiers: {
2248
+ shift: true
2249
+ },
2250
+ command: 'Explorer.rangeSelection',
2251
+ when: FocusExplorer
2252
+ }, {
2253
+ id: 'explorer.contextMenu',
2254
+ description: 'Show context menu on right click',
2255
+ button: 2,
2256
+ // Right click
2257
+ modifiers: {},
2258
+ command: 'Explorer.showContextMenu',
2259
+ when: FocusExplorer
2260
+ }];
2261
+ };
2262
+
2199
2263
  const getParentStartIndex = (dirents, index) => {
2200
2264
  const dirent = dirents[index];
2201
2265
  let startIndex = index - 1;
@@ -2535,14 +2599,44 @@ const getIndexFromPosition = (state, eventX, eventY) => {
2535
2599
  return index;
2536
2600
  };
2537
2601
 
2538
- const Keyboard = -1;
2539
- const LeftClick = 0;
2602
+ /**
2603
+ * Handles range selection in the explorer.
2604
+ * @param state The current explorer state
2605
+ * @param startIndex The starting index of the range (must be ≤ endIndex)
2606
+ * @param endIndex The ending index of the range (must be ≥ startIndex)
2607
+ * @throws Error if startIndex > endIndex
2608
+ */
2609
+ const handleRangeSelection = (state, startIndex, endIndex) => {
2610
+ if (startIndex > endIndex) {
2611
+ throw new Error('startIndex must be less than or equal to endIndex');
2612
+ }
2613
+ const {
2614
+ items
2615
+ } = state;
2616
+ const newItems = items.map((item, i) => ({
2617
+ ...item,
2618
+ selected: i >= startIndex && i <= endIndex ? true : item.selected
2619
+ }));
2620
+ return {
2621
+ ...state,
2622
+ items: newItems
2623
+ };
2624
+ };
2540
2625
 
2541
- const handleClickAt = (state, button, x, y) => {
2626
+ const handleClickAt = (state, button, ctrlKey, shiftKey, x, y) => {
2542
2627
  if (button !== LeftClick) {
2543
2628
  return state;
2544
2629
  }
2545
2630
  const index = getIndexFromPosition(state, x, y);
2631
+ if (shiftKey) {
2632
+ const firstSelectedIndex = state.items.findIndex(item => item.selected);
2633
+ if (firstSelectedIndex === -1) {
2634
+ return handleRangeSelection(state, index, index);
2635
+ }
2636
+ const min = Math.min(firstSelectedIndex, index);
2637
+ const max = Math.min(firstSelectedIndex, index);
2638
+ return handleRangeSelection(state, min, max);
2639
+ }
2546
2640
  return handleClick(state, index);
2547
2641
  };
2548
2642
 
@@ -3582,7 +3676,7 @@ const ExplorerInput = 'ExplorerInput';
3582
3676
 
3583
3677
  const User = 1;
3584
3678
 
3585
- const renderFocus = (oldState, newState) => {
3679
+ const renderFocus$1 = (oldState, newState) => {
3586
3680
  if (newState.inputSource === User) {
3587
3681
  return [];
3588
3682
  }
@@ -3598,6 +3692,16 @@ const renderFocus = (oldState, newState) => {
3598
3692
  return [];
3599
3693
  };
3600
3694
 
3695
+ const renderFocus = (oldState, newState) => {
3696
+ if (newState.focus === Input$1) {
3697
+ return ['Viewlet.setFocusContext', FocusExplorerEditBox];
3698
+ }
3699
+ if (newState.focus === List) {
3700
+ return ['Viewlet.setFocusContext', FocusExplorer];
3701
+ }
3702
+ return [];
3703
+ };
3704
+
3601
3705
  const None$2 = 'none';
3602
3706
  const ToolBar = 'toolbar';
3603
3707
  const Tree = 'tree';
@@ -3696,7 +3800,7 @@ const getFileIconVirtualDom = icon => {
3696
3800
  };
3697
3801
  };
3698
3802
 
3699
- const getClassName$1 = hasEditingError => {
3803
+ const getClassName$2 = hasEditingError => {
3700
3804
  if (hasEditingError) {
3701
3805
  return mergeClassNames(InputBox, InputValidationError);
3702
3806
  }
@@ -3705,7 +3809,7 @@ const getClassName$1 = hasEditingError => {
3705
3809
  const getInputDom = hasEditingError => {
3706
3810
  return [{
3707
3811
  type: Input,
3708
- className: getClassName$1(hasEditingError),
3812
+ className: getClassName$2(hasEditingError),
3709
3813
  id: 'ExplorerInput',
3710
3814
  onInput: HandleEditingInput,
3711
3815
  childCount: 0,
@@ -3789,7 +3893,7 @@ const getActiveDescendant = focusedIndex => {
3789
3893
  }
3790
3894
  return undefined;
3791
3895
  };
3792
- const getClassName = (focused, focusedIndex, dropTarget) => {
3896
+ const getClassName$1 = (focused, focusedIndex, dropTarget) => {
3793
3897
  const extraClass1 = focused && focusedIndex === -1 ? FocusOutline : Empty;
3794
3898
  const extraClass2 = dropTarget === dropTargetFull ? ExplorerDropTarget : Empty;
3795
3899
  const className = mergeClassNames(ListItems, extraClass1, extraClass2);
@@ -3807,7 +3911,7 @@ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused
3807
3911
  }
3808
3912
  const dom = [parentNode, {
3809
3913
  type: Div,
3810
- className: getClassName(focused, focusedIndex, dropTargets),
3914
+ className: getClassName$1(focused, focusedIndex, dropTargets),
3811
3915
  tabIndex: 0,
3812
3916
  role: Tree,
3813
3917
  ariaLabel: filesExplorer(),
@@ -3879,6 +3983,15 @@ const getTreeItemIndentWithChevron = (depth, chevron) => {
3879
3983
  };
3880
3984
 
3881
3985
  const ariaExpandedValues = [undefined, 'true', 'false'];
3986
+ const getClassName = (isSelected, isFocused) => {
3987
+ if (isFocused) {
3988
+ return mergeClassNames(TreeItem, TreeItemActive);
3989
+ }
3990
+ if (isSelected) {
3991
+ return mergeClassNames(TreeItem, TreeItemActive);
3992
+ }
3993
+ return TreeItem;
3994
+ };
3882
3995
  const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets) => {
3883
3996
  const visible = [];
3884
3997
  const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
@@ -3890,7 +4003,8 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
3890
4003
  const indent = indentFn(item.depth, chevron);
3891
4004
  const isFocused = i === focusedIndex;
3892
4005
  const id = isFocused ? 'TreeItemActive' : undefined;
3893
- const className = isFocused ? mergeClassNames(TreeItem, TreeItemActive) : TreeItem;
4006
+ const isSelected = item.selected;
4007
+ const className = getClassName(isSelected, isFocused);
3894
4008
  const expanded = getExpandedType(item.type);
3895
4009
  const ariaExpanded = ariaExpandedValues[expanded];
3896
4010
 
@@ -3921,7 +4035,8 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
3921
4035
  ariaExpanded: undefined,
3922
4036
  chevron: 0,
3923
4037
  id: undefined,
3924
- className: TreeItem
4038
+ className: TreeItem,
4039
+ selected: false
3925
4040
  });
3926
4041
  }
3927
4042
  return visible;
@@ -3939,6 +4054,8 @@ const getRenderer = diffType => {
3939
4054
  case RenderItems:
3940
4055
  return renderItems;
3941
4056
  case RenderFocus:
4057
+ return renderFocus$1;
4058
+ case RenderFocusContext:
3942
4059
  return renderFocus;
3943
4060
  default:
3944
4061
  throw new Error('unknown renderer');
@@ -4064,7 +4181,7 @@ const renderEventListeners = () => {
4064
4181
  params: ['handleBlur']
4065
4182
  }, {
4066
4183
  name: HandleClick,
4067
- params: ['handleClickAt', 'event.button', 'event.clientX', 'event.clientY'],
4184
+ params: ['handleClickAt', 'event.button', 'event.ctrlKey', 'event.shiftKey', 'event.clientX', 'event.clientY'],
4068
4185
  preventDefault: true
4069
4186
  }, {
4070
4187
  name: HandleClickOpenFolder,
@@ -4333,6 +4450,46 @@ const saveState = uid => {
4333
4450
  };
4334
4451
  };
4335
4452
 
4453
+ const selectDown = state => {
4454
+ const {
4455
+ items,
4456
+ focusedIndex
4457
+ } = state;
4458
+ const firstSelectedIndex = items.findIndex(item => item.selected);
4459
+ const targetIndex = firstSelectedIndex === -1 ? focusedIndex : firstSelectedIndex;
4460
+ if (targetIndex >= items.length - 1) {
4461
+ return state;
4462
+ }
4463
+ const newItems = items.map((item, i) => ({
4464
+ ...item,
4465
+ selected: i === targetIndex + 1 ? true : item.selected
4466
+ }));
4467
+ return {
4468
+ ...state,
4469
+ items: newItems
4470
+ };
4471
+ };
4472
+
4473
+ const selectUp = state => {
4474
+ const {
4475
+ items,
4476
+ focusedIndex
4477
+ } = state;
4478
+ const firstSelectedIndex = items.findIndex(item => item.selected);
4479
+ const targetIndex = firstSelectedIndex === -1 ? focusedIndex : firstSelectedIndex;
4480
+ if (targetIndex <= 0) {
4481
+ return state;
4482
+ }
4483
+ const newItems = items.map((item, i) => ({
4484
+ ...item,
4485
+ selected: i === targetIndex - 1 ? true : item.selected
4486
+ }));
4487
+ return {
4488
+ ...state,
4489
+ items: newItems
4490
+ };
4491
+ };
4492
+
4336
4493
  const terminate = () => {
4337
4494
  globalThis.close();
4338
4495
  };
@@ -4392,12 +4549,15 @@ const commandMap = {
4392
4549
  'Explorer.handleArrowLeft': wrapCommand(handleArrowLeft),
4393
4550
  'Explorer.handleArrowRight': wrapCommand(handleArrowRight),
4394
4551
  'Explorer.handleBlur': wrapCommand(handleBlur),
4552
+ 'Explorer.selectUp': wrapCommand(selectUp),
4553
+ 'Explorer.selectDown': wrapCommand(selectDown),
4395
4554
  'Explorer.handleClick': wrapCommand(handleClick),
4396
4555
  'Explorer.handleClickAt': wrapCommand(handleClickAt),
4397
4556
  'Explorer.handleClickCurrent': wrapCommand(handleClickCurrent),
4398
4557
  'Explorer.handleClickCurrentButKeepFocus': wrapCommand(handleClickCurrentButKeepFocus),
4399
4558
  'Explorer.handleClickOpenFolder': wrapCommand(handleClickOpenFolder),
4400
4559
  'Explorer.handleContextMenu': wrapCommand(handleContextMenu),
4560
+ 'Explorer.getMouseActions': getMouseActions,
4401
4561
  'Explorer.handleContextMenuKeyboard': wrapCommand(handleContextMenuKeyboard),
4402
4562
  'Explorer.handleCopy': wrapCommand(handleCopy),
4403
4563
  'Explorer.handleDragLeave': wrapCommand(handleDragLeave),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "2.18.0",
3
+ "version": "2.20.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",