@lvce-editor/explorer-view 3.17.0 → 3.19.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.
@@ -1137,13 +1137,13 @@ const Remove = 5;
1137
1137
 
1138
1138
  const Text = 12;
1139
1139
 
1140
- const TargetValue = 'event.target.value';
1140
+ const Button$3 = 'event.button';
1141
1141
  const ClientX = 'event.clientX';
1142
1142
  const ClientY = 'event.clientY';
1143
- const Button$3 = 'event.button';
1143
+ const CtrlKey = 'event.ctrlKey';
1144
1144
  const DeltaMode = 'event.deltaMode';
1145
1145
  const DeltaY = 'event.deltaY';
1146
- const CtrlKey = 'event.ctrlKey';
1146
+ const TargetValue = 'event.target.value';
1147
1147
 
1148
1148
  const Enter = 3;
1149
1149
  const Escape = 8;
@@ -1172,6 +1172,7 @@ const RendererWorker$1 = 1;
1172
1172
 
1173
1173
  const FocusElementByName = 'Viewlet.focusElementByName';
1174
1174
  const FocusSelector = 'Viewlet.focusSelector';
1175
+ const SetCss = 'Viewlet.setCss';
1175
1176
  const SetFocusContext = 'Viewlet.setFocusContext';
1176
1177
 
1177
1178
  const FocusExplorer = 13;
@@ -2640,6 +2641,183 @@ const copyRelativePath = async state => {
2640
2641
  return state;
2641
2642
  };
2642
2643
 
2644
+ const None$4 = 0;
2645
+ const Right = 1;
2646
+ const Down = 2;
2647
+
2648
+ const getChevronType = (type, useChevrons) => {
2649
+ if (!useChevrons) {
2650
+ return None$4;
2651
+ }
2652
+ switch (type) {
2653
+ case Directory:
2654
+ return Right;
2655
+ case DirectoryExpanded:
2656
+ case DirectoryExpanding:
2657
+ return Down;
2658
+ default:
2659
+ return None$4;
2660
+ }
2661
+ };
2662
+
2663
+ const None$3 = 0;
2664
+ const Expanded = 1;
2665
+ const Collapsed = 2;
2666
+
2667
+ const getExpandedType = type => {
2668
+ switch (type) {
2669
+ case Directory:
2670
+ return Collapsed;
2671
+ case DirectoryExpanding:
2672
+ case DirectoryExpanded:
2673
+ return Expanded;
2674
+ default:
2675
+ return None$3;
2676
+ }
2677
+ };
2678
+
2679
+ // 0 = 'Button'
2680
+ // 1 = 'IconButton'
2681
+ // 2 = 'Button IconButton'
2682
+ // it could make dom diffing faster, since for classname,
2683
+ // once at start, send all classnames to renderer process
2684
+ // only numbers are compared. it could also make rendering faster,
2685
+ // representing the concatenated strings for example
2686
+ // since less data is transferred to renderer process
2687
+ // then, components uses numeric classname
2688
+ // TODO add option to make classnames numeric
2689
+ // when a component uses multiple classnames, it is a new number
2690
+ const Actions = 'Actions';
2691
+ const Button$2 = 'Button';
2692
+ const ButtonNarrow = 'ButtonNarrow';
2693
+ const ButtonPrimary = 'ButtonPrimary';
2694
+ const ButtonWide = 'ButtonWide';
2695
+ const Chevron = 'Chevron';
2696
+ const Empty = '';
2697
+ const Explorer$1 = 'Explorer';
2698
+ const ExplorerDropTarget = 'DropTarget';
2699
+ const ExplorerErrorMessage = 'ExplorerErrorMessage';
2700
+ const ExplorerInputBox = 'ExplorerInputBox';
2701
+ const FileIcon = 'FileIcon';
2702
+ const FocusOutline = 'FocusOutline';
2703
+ const IconButton = 'IconButton';
2704
+ const InputValidationError = 'InputValidationError';
2705
+ const Label = 'Label';
2706
+ const LabelCut = 'LabelCut';
2707
+ const ListItems = 'ListItems';
2708
+ const MaskIconChevronDown = 'MaskIconChevronDown';
2709
+ const MaskIconChevronRight = 'MaskIconChevronRight';
2710
+ const ScrollBar = 'ScrollBar';
2711
+ const ScrollBarSmall = 'ScrollBarSmall';
2712
+ const ScrollBarThumb = 'ScrollBarThumb';
2713
+ const TreeItem$1 = 'TreeItem';
2714
+ const TreeItemActive = 'TreeItemActive';
2715
+ const Viewlet = 'Viewlet';
2716
+ const Welcome = 'Welcome';
2717
+ const WelcomeMessage = 'WelcomeMessage';
2718
+
2719
+ const mergeClassNames = (...classNames) => {
2720
+ return classNames.filter(Boolean).join(' ');
2721
+ };
2722
+
2723
+ const px = value => {
2724
+ return `${value}px`;
2725
+ };
2726
+ const position = (x, y) => {
2727
+ return `${x}px ${y}px`;
2728
+ };
2729
+
2730
+ const text = data => {
2731
+ return {
2732
+ type: Text,
2733
+ text: data,
2734
+ childCount: 0
2735
+ };
2736
+ };
2737
+
2738
+ const getTreeItemClassName = (isSelected, isFocused, isDropping, useChevrons, depth) => {
2739
+ let className = TreeItem$1;
2740
+ className = mergeClassNames(className, `Indent-${depth}`);
2741
+ if (isSelected || isFocused) {
2742
+ className = mergeClassNames(className, TreeItemActive);
2743
+ }
2744
+ if (isDropping) {
2745
+ className = mergeClassNames(className, 'DropTarget');
2746
+ }
2747
+ return className;
2748
+ };
2749
+
2750
+ const defaultIndent$1 = 1;
2751
+ const getTreeItemIndent = depth => {
2752
+ return `${depth * defaultIndent$1}rem`;
2753
+ };
2754
+
2755
+ // TODO make all of these variable configurable
2756
+ const defaultPaddingLeft = 4;
2757
+ const defaultIndent = 8;
2758
+
2759
+ // TODO make chevron size configurable
2760
+ const chevronSize = 22;
2761
+ const getTreeItemIndentWithChevron = (depth, chevron) => {
2762
+ // TODO use numeric value here, convert to string value in renderer process
2763
+ const extraSpace = chevron ? 0 : chevronSize;
2764
+ return `${depth * defaultIndent + extraSpace + defaultPaddingLeft}px`;
2765
+ };
2766
+
2767
+ const ariaExpandedValues = [undefined, 'true', 'false'];
2768
+ const getEditingChevron = direntType => {
2769
+ switch (direntType) {
2770
+ case EditingDirectoryExpanded:
2771
+ return Down;
2772
+ case EditingFolder:
2773
+ return Right;
2774
+ default:
2775
+ return None$4;
2776
+ }
2777
+ };
2778
+ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris = []) => {
2779
+ const visible = [];
2780
+ const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
2781
+ let iconIndex = 0;
2782
+ for (let i = minLineY; i < Math.min(maxLineY, items.length); i++) {
2783
+ const item = items[i];
2784
+ let chevron = getChevronType(item.type, useChevrons);
2785
+ const isFocused = i === focusedIndex;
2786
+ const id = isFocused ? 'TreeItemActive' : undefined;
2787
+ const isSelected = item.selected;
2788
+ const isCut = cutItems.includes(item.path);
2789
+ const isDropping = dropTargets.includes(i);
2790
+ const isIgnored = sourceControlIgnoredUris.includes(item.path);
2791
+ const className = getTreeItemClassName(isSelected, isFocused, isDropping, useChevrons, item.depth); // TODO compute classname in dom function
2792
+ const expanded = getExpandedType(item.type);
2793
+ const ariaExpanded = ariaExpandedValues[expanded];
2794
+ const isEditing = i === editingIndex;
2795
+ let icon = icons[iconIndex++];
2796
+ if (isEditing) {
2797
+ icon = editingIcon;
2798
+ chevron = getEditingChevron(item.type);
2799
+ }
2800
+ const indent = indentFn(item.depth, chevron);
2801
+ visible.push({
2802
+ ...item,
2803
+ posInSet: item.posInSet ?? i + 1,
2804
+ setSize: item.setSize ?? items.length,
2805
+ isEditing: isEditing,
2806
+ hasEditingError: isEditing && Boolean(editingErrorMessage),
2807
+ icon,
2808
+ indent,
2809
+ ariaExpanded,
2810
+ chevron,
2811
+ id,
2812
+ className,
2813
+ isCut,
2814
+ isIgnored,
2815
+ index: i
2816
+ });
2817
+ }
2818
+ return visible;
2819
+ };
2820
+
2643
2821
  const {
2644
2822
  get,
2645
2823
  set,
@@ -2700,7 +2878,11 @@ const create2 = (uid, uri, x, y, width, height, args, parentUid, platform = 0) =
2700
2878
  cutItems: [],
2701
2879
  isPointerDown: false,
2702
2880
  pointerDownIndex: -1,
2703
- sourceControlIgnoredUris: []
2881
+ sourceControlIgnoredUris: [],
2882
+ maxIndent: 0,
2883
+ errorMessageLeft: 0,
2884
+ errorMessageTop: 0,
2885
+ visibleExplorerItems: []
2704
2886
  };
2705
2887
  set(uid, state, state);
2706
2888
  };
@@ -2752,12 +2934,20 @@ const create = (id, uri, x, y, width, height, args, parentUid, platform = 0) =>
2752
2934
  cutItems: [],
2753
2935
  isPointerDown: false,
2754
2936
  pointerDownIndex: -1,
2755
- sourceControlIgnoredUris: []
2937
+ sourceControlIgnoredUris: [],
2938
+ maxIndent: 0,
2939
+ errorMessageLeft: 0,
2940
+ errorMessageTop: 0,
2941
+ visibleExplorerItems: []
2756
2942
  };
2757
2943
  set(state.uid, state, state);
2758
2944
  return state;
2759
2945
  };
2760
2946
 
2947
+ const isEqual$6 = (oldState, newState) => {
2948
+ return oldState.scrollBarHeight === newState.scrollBarHeight && oldState.scrollBarActive === newState.scrollBarActive && oldState.maxIndent === newState.maxIndent;
2949
+ };
2950
+
2761
2951
  const isEqual$5 = (oldState, newState) => {
2762
2952
  return oldState.isPointerDown || !newState.isPointerDown;
2763
2953
  };
@@ -2767,7 +2957,7 @@ const isEqual$4 = (oldState, newState) => {
2767
2957
  };
2768
2958
 
2769
2959
  const isEqual$3 = (oldState, newState) => {
2770
- 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 && oldState.icons === newState.icons && oldState.cutItems === newState.cutItems;
2960
+ 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 && oldState.icons === newState.icons && oldState.cutItems === newState.cutItems && oldState.visibleExplorerItems === newState.visibleExplorerItems;
2771
2961
  };
2772
2962
 
2773
2963
  const isEqual$2 = (oldState, newState) => {
@@ -2780,6 +2970,7 @@ const RenderFocusContext = 7;
2780
2970
  const RenderValue = 8;
2781
2971
  const RenderSelection = 9;
2782
2972
  const RenderDragData = 10;
2973
+ const RenderCss = 11;
2783
2974
 
2784
2975
  const isEqual$1 = (oldState, newState) => {
2785
2976
  if (newState.focus !== Input$1) {
@@ -2788,8 +2979,8 @@ const isEqual$1 = (oldState, newState) => {
2788
2979
  return oldState.focus === Input$1 && newState.focus === Input$1 && oldState.editingValue === newState.editingValue;
2789
2980
  };
2790
2981
 
2791
- const modules = [isEqual$3, isEqual$4, isEqual$4, isEqual$1, isEqual$2, isEqual$5];
2792
- const numbers = [RenderItems, RenderFocus, RenderFocusContext, RenderValue, RenderSelection, RenderDragData];
2982
+ const modules = [isEqual$3, isEqual$4, isEqual$4, isEqual$1, isEqual$2, isEqual$5, isEqual$6];
2983
+ const numbers = [RenderItems, RenderFocus, RenderFocusContext, RenderValue, RenderSelection, RenderDragData, RenderCss];
2793
2984
 
2794
2985
  const diff = (oldState, newState) => {
2795
2986
  const diffResult = [];
@@ -3091,25 +3282,6 @@ const focusPrevious = state => {
3091
3282
  }
3092
3283
  };
3093
3284
 
3094
- const mergeClassNames = (...classNames) => {
3095
- return classNames.filter(Boolean).join(' ');
3096
- };
3097
-
3098
- const px = value => {
3099
- return `${value}px`;
3100
- };
3101
- const position = (x, y) => {
3102
- return `${x}px ${y}px`;
3103
- };
3104
-
3105
- const text = data => {
3106
- return {
3107
- type: Text,
3108
- text: data,
3109
- childCount: 0
3110
- };
3111
- };
3112
-
3113
3285
  const getKeyBindings = () => {
3114
3286
  return [{
3115
3287
  key: Shift | UpArrow,
@@ -3207,7 +3379,7 @@ const getKeyBindings = () => {
3207
3379
  };
3208
3380
 
3209
3381
  const Separator = 1;
3210
- const None$4 = 0;
3382
+ const None$2 = 0;
3211
3383
  const RestoreFocus = 6;
3212
3384
 
3213
3385
  const menuEntrySeparator = {
@@ -3220,13 +3392,13 @@ const menuEntrySeparator = {
3220
3392
  const menuEntryNewFile = {
3221
3393
  id: 'newFile',
3222
3394
  label: newFile$1(),
3223
- flags: None$4,
3395
+ flags: None$2,
3224
3396
  command: 'Explorer.newFile'
3225
3397
  };
3226
3398
  const menuEntryNewFolder = {
3227
3399
  id: 'newFolder',
3228
3400
  label: newFolder$1(),
3229
- flags: None$4,
3401
+ flags: None$2,
3230
3402
  command: 'Explorer.newFolder'
3231
3403
  };
3232
3404
  const menuEntryOpenContainingFolder = {
@@ -3238,7 +3410,7 @@ const menuEntryOpenContainingFolder = {
3238
3410
  const menuEntryOpenInIntegratedTerminal = {
3239
3411
  id: 'openInIntegratedTerminal',
3240
3412
  label: openInIntegratedTerminal(),
3241
- flags: None$4,
3413
+ flags: None$2,
3242
3414
  command: /* TODO */'-1'
3243
3415
  };
3244
3416
  const menuEntryCut = {
@@ -3256,7 +3428,7 @@ const menuEntryCopy = {
3256
3428
  const menuEntryPaste = {
3257
3429
  id: 'paste',
3258
3430
  label: paste(),
3259
- flags: None$4,
3431
+ flags: None$2,
3260
3432
  command: 'Explorer.handlePaste'
3261
3433
  };
3262
3434
  const menuEntryCopyPath = {
@@ -3274,13 +3446,13 @@ const menuEntryCopyRelativePath = {
3274
3446
  const menuEntryRename = {
3275
3447
  id: 'rename',
3276
3448
  label: rename(),
3277
- flags: None$4,
3449
+ flags: None$2,
3278
3450
  command: 'Explorer.renameDirent'
3279
3451
  };
3280
3452
  const menuEntryDelete = {
3281
3453
  id: 'delete',
3282
3454
  label: deleteItem(),
3283
- flags: None$4,
3455
+ flags: None$2,
3284
3456
  command: 'Explorer.removeDirent'
3285
3457
  };
3286
3458
  const ALL_ENTRIES = [menuEntryNewFile, menuEntryNewFolder, menuEntryOpenContainingFolder, menuEntryOpenInIntegratedTerminal, menuEntrySeparator, menuEntryCut, menuEntryCopy, menuEntryPaste, menuEntrySeparator, menuEntryCopyPath, menuEntryCopyRelativePath, menuEntrySeparator, menuEntryRename, menuEntryDelete];
@@ -3379,16 +3551,27 @@ const handleClickDirectoryExpanded = async (state, dirent, index, keepFocus) =>
3379
3551
  minLineY,
3380
3552
  maxLineY,
3381
3553
  itemHeight,
3382
- fileIconCache
3554
+ fileIconCache,
3555
+ cutItems,
3556
+ sourceControlIgnoredUris,
3557
+ dropTargets,
3558
+ editingErrorMessage,
3559
+ editingIcon,
3560
+ editingIndex,
3561
+ editingType,
3562
+ editingValue,
3563
+ focusedIndex,
3564
+ useChevrons,
3565
+ items
3383
3566
  } = state;
3384
3567
  // @ts-ignore
3385
3568
  dirent.type = Directory;
3386
3569
  // @ts-ignore
3387
3570
  dirent.icon = '';
3388
- const endIndex = getParentEndIndex(state.items, index);
3571
+ const endIndex = getParentEndIndex(items, index);
3389
3572
  const removeCount = endIndex - index - 1;
3390
3573
  // TODO race conditions and side effects are everywhere
3391
- const newDirents = [...state.items];
3574
+ const newDirents = [...items];
3392
3575
  newDirents.splice(index + 1, removeCount);
3393
3576
  const newTotal = newDirents.length;
3394
3577
  if (newTotal < maxLineY) {
@@ -3401,30 +3584,34 @@ const handleClickDirectoryExpanded = async (state, dirent, index, keepFocus) =>
3401
3584
  icons,
3402
3585
  newFileIconCache
3403
3586
  } = await getFileIcons(parts, fileIconCache);
3587
+ const visibleExplorerItems = getVisibleExplorerItems(newDirents, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
3404
3588
  return {
3405
3589
  ...state,
3406
- items: newDirents,
3407
- icons,
3590
+ deltaY,
3408
3591
  fileIconCache: newFileIconCache,
3409
- focusedIndex: index,
3410
3592
  focused: keepFocus,
3411
- minLineY: newMinLineY,
3593
+ focusedIndex: index,
3594
+ icons,
3595
+ items: newDirents,
3412
3596
  maxLineY: newMaxLineY,
3413
- deltaY
3597
+ minLineY: newMinLineY,
3598
+ visibleExplorerItems
3414
3599
  };
3415
3600
  }
3416
- const parts = newDirents.slice(state.minLineY, state.maxLineY);
3601
+ const parts = newDirents.slice(minLineY, maxLineY);
3417
3602
  const {
3418
3603
  icons,
3419
3604
  newFileIconCache
3420
3605
  } = await getFileIcons(parts, fileIconCache);
3606
+ const visibleExplorerItems = getVisibleExplorerItems(newDirents, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
3421
3607
  return {
3422
3608
  ...state,
3423
- items: newDirents,
3424
- icons,
3425
3609
  fileIconCache: newFileIconCache,
3610
+ focused: keepFocus,
3426
3611
  focusedIndex: index,
3427
- focused: keepFocus
3612
+ icons,
3613
+ items: newDirents,
3614
+ visibleExplorerItems
3428
3615
  };
3429
3616
  };
3430
3617
 
@@ -3470,6 +3657,18 @@ const setFocus = key => {
3470
3657
  };
3471
3658
 
3472
3659
  const handleClickDirectory = async (state, dirent, index, keepFocus) => {
3660
+ const {
3661
+ cutItems,
3662
+ sourceControlIgnoredUris,
3663
+ dropTargets,
3664
+ editingErrorMessage,
3665
+ editingIcon,
3666
+ editingIndex,
3667
+ editingType,
3668
+ editingValue,
3669
+ focusedIndex,
3670
+ useChevrons
3671
+ } = state;
3473
3672
  // @ts-ignore
3474
3673
  dirent.type = DirectoryExpanding;
3475
3674
  // TODO handle error
@@ -3502,15 +3701,19 @@ const handleClickDirectory = async (state, dirent, index, keepFocus) => {
3502
3701
  icons,
3503
3702
  newFileIconCache
3504
3703
  } = await getFileIcons(parts, state.fileIconCache);
3704
+ const visibleExplorerItems = getVisibleExplorerItems(newDirents, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
3705
+
3706
+ // TODO use functional focus rendering
3505
3707
  await setFocus(FocusExplorer);
3506
3708
  return {
3507
3709
  ...state,
3508
- items: newDirents,
3509
- icons,
3510
3710
  fileIconCache: newFileIconCache,
3511
- focusedIndex: newIndex,
3512
3711
  focused: keepFocus,
3513
- maxLineY
3712
+ focusedIndex: newIndex,
3713
+ icons,
3714
+ items: newDirents,
3715
+ maxLineY,
3716
+ visibleExplorerItems
3514
3717
  };
3515
3718
  };
3516
3719
 
@@ -3820,7 +4023,7 @@ const show = async (x, y, id, ...args) => {
3820
4023
  return showContextMenu(x, y, id, ...args);
3821
4024
  };
3822
4025
 
3823
- const Explorer$1 = 4;
4026
+ const Explorer = 4;
3824
4027
 
3825
4028
  const handleContextMenuKeyboard = async state => {
3826
4029
  const {
@@ -3832,7 +4035,7 @@ const handleContextMenuKeyboard = async state => {
3832
4035
  } = state;
3833
4036
  const menuX = x;
3834
4037
  const menuY = y + (focusedIndex - minLineY + 1) * itemHeight;
3835
- await show(menuX, menuY, Explorer$1);
4038
+ await show(menuX, menuY, Explorer);
3836
4039
  return state;
3837
4040
  };
3838
4041
 
@@ -3846,7 +4049,7 @@ const handleContextMenuMouseAt = async (state, x, y) => {
3846
4049
  focused: false
3847
4050
  };
3848
4051
  set(state.uid, state, newState);
3849
- await show(x, y, Explorer$1);
4052
+ await show(x, y, Explorer);
3850
4053
  return state;
3851
4054
  };
3852
4055
 
@@ -4067,8 +4270,17 @@ const refresh = async state => {
4067
4270
  height,
4068
4271
  itemHeight,
4069
4272
  fileIconCache,
4273
+ cutItems,
4274
+ sourceControlIgnoredUris,
4275
+ dropTargets,
4276
+ editingErrorMessage,
4277
+ editingIcon,
4278
+ editingIndex,
4279
+ editingType,
4280
+ editingValue,
4281
+ focusedIndex,
4070
4282
  items,
4071
- focusedIndex
4283
+ useChevrons
4072
4284
  } = state;
4073
4285
  const expandedDirents = getExpandedDirents(items);
4074
4286
  const expandedPaths = getPaths(expandedDirents);
@@ -4086,13 +4298,15 @@ const refresh = async state => {
4086
4298
  if (focusedIndex >= newItems.length) {
4087
4299
  newFocusedIndex = newItems.length - 1;
4088
4300
  }
4301
+ const visibleExplorerItems = getVisibleExplorerItems(items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
4089
4302
  return {
4090
4303
  ...state,
4091
- items: newItems,
4092
4304
  fileIconCache: newFileIconCache,
4305
+ focusedIndex: newFocusedIndex,
4093
4306
  icons,
4307
+ items: newItems,
4094
4308
  maxLineY,
4095
- focusedIndex: newFocusedIndex
4309
+ visibleExplorerItems
4096
4310
  };
4097
4311
  };
4098
4312
 
@@ -4712,7 +4926,7 @@ const handlePasteCut = async (state, nativeFiles) => {
4712
4926
  };
4713
4927
  };
4714
4928
 
4715
- const None$3 = 'none';
4929
+ const None$1 = 'none';
4716
4930
 
4717
4931
  const handlePaste = async state => {
4718
4932
  const nativeFiles = await readNativeFiles();
@@ -4733,7 +4947,7 @@ const handlePaste = async state => {
4733
4947
  // TODO handle error gracefully when copy fails
4734
4948
 
4735
4949
  // If no files to paste, return original state unchanged
4736
- if (nativeFiles.type === None$3) {
4950
+ if (nativeFiles.type === None$1) {
4737
4951
  return state;
4738
4952
  }
4739
4953
 
@@ -4780,7 +4994,17 @@ const handleUpload = async (state, dirents) => {
4780
4994
  const setDeltaY = async (state, deltaY) => {
4781
4995
  const {
4782
4996
  itemHeight,
4997
+ useChevrons,
4783
4998
  height,
4999
+ cutItems,
5000
+ sourceControlIgnoredUris,
5001
+ dropTargets,
5002
+ editingErrorMessage,
5003
+ editingIcon,
5004
+ editingIndex,
5005
+ editingType,
5006
+ editingValue,
5007
+ focusedIndex,
4784
5008
  items
4785
5009
  } = state;
4786
5010
  if (deltaY < 0) {
@@ -4798,13 +5022,15 @@ const setDeltaY = async (state, deltaY) => {
4798
5022
  icons,
4799
5023
  newFileIconCache
4800
5024
  } = await getFileIcons(visible, state.fileIconCache);
5025
+ const visibleExplorerItems = getVisibleExplorerItems(items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
4801
5026
  return {
4802
5027
  ...state,
4803
5028
  deltaY,
4804
- minLineY,
4805
- maxLineY,
5029
+ fileIconCache: newFileIconCache,
4806
5030
  icons,
4807
- fileIconCache: newFileIconCache
5031
+ maxLineY,
5032
+ minLineY,
5033
+ visibleExplorerItems
4808
5034
  };
4809
5035
  };
4810
5036
 
@@ -4951,7 +5177,16 @@ const getSavedRoot = (savedState, workspacePath) => {
4951
5177
  };
4952
5178
  const loadContent = async (state, savedState) => {
4953
5179
  const {
4954
- fileIconCache
5180
+ fileIconCache,
5181
+ cutItems,
5182
+ sourceControlIgnoredUris,
5183
+ dropTargets,
5184
+ editingErrorMessage,
5185
+ editingIcon,
5186
+ editingIndex,
5187
+ editingType,
5188
+ editingValue,
5189
+ focusedIndex
4955
5190
  } = state;
4956
5191
  const {
4957
5192
  useChevrons,
@@ -4981,19 +5216,22 @@ const loadContent = async (state, savedState) => {
4981
5216
  icons,
4982
5217
  newFileIconCache
4983
5218
  } = await getFileIcons(visible, fileIconCache);
5219
+ const visibleExplorerItems = getVisibleExplorerItems(restoredDirents, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
4984
5220
  return {
4985
5221
  ...state,
4986
- root,
4987
- items: restoredDirents,
4988
- icons,
4989
- fileIconCache: newFileIconCache,
4990
- minLineY,
5222
+ confirmDelete,
4991
5223
  deltaY,
5224
+ excluded,
5225
+ fileIconCache: newFileIconCache,
5226
+ icons,
5227
+ items: restoredDirents,
5228
+ maxIndent: 10,
4992
5229
  maxLineY,
5230
+ minLineY,
4993
5231
  pathSeparator,
4994
- excluded,
5232
+ root,
4995
5233
  useChevrons,
4996
- confirmDelete
5234
+ visibleExplorerItems
4997
5235
  };
4998
5236
  };
4999
5237
 
@@ -5130,13 +5368,20 @@ const newDirent = async (state, editingType) => {
5130
5368
  await setFocus(ExplorerEditBox);
5131
5369
  // TODO do it like vscode, select position between folders and files
5132
5370
  const {
5133
- focusedIndex,
5134
- items,
5135
5371
  minLineY,
5136
5372
  height,
5137
5373
  itemHeight,
5374
+ root,
5138
5375
  fileIconCache,
5139
- root
5376
+ cutItems,
5377
+ sourceControlIgnoredUris,
5378
+ dropTargets,
5379
+ editingErrorMessage,
5380
+ editingIcon,
5381
+ editingValue,
5382
+ focusedIndex,
5383
+ items,
5384
+ useChevrons
5140
5385
  } = state;
5141
5386
  const index = getFittingIndex(items, focusedIndex);
5142
5387
  const direntType = getNewDirentType(editingType);
@@ -5148,17 +5393,19 @@ const newDirent = async (state, editingType) => {
5148
5393
  newFileIconCache
5149
5394
  } = await getFileIcons(visible, fileIconCache);
5150
5395
  const editingIndex = newDirents.findIndex(item => item.type === EditingFile || item.type === EditingFolder);
5396
+ const visibleExplorerItems = getVisibleExplorerItems(items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris);
5151
5397
  return {
5152
5398
  ...state,
5153
- items: newDirents,
5154
5399
  editingIndex,
5155
5400
  editingType,
5156
5401
  editingValue: '',
5157
- focusedIndex: editingIndex,
5402
+ fileIconCache: newFileIconCache,
5158
5403
  focus: Input$1,
5404
+ focusedIndex: editingIndex,
5159
5405
  icons,
5160
- fileIconCache: newFileIconCache,
5161
- maxLineY
5406
+ items: newDirents,
5407
+ maxLineY,
5408
+ visibleExplorerItems
5162
5409
  };
5163
5410
  };
5164
5411
 
@@ -5307,6 +5554,25 @@ const renameDirent = state => {
5307
5554
  };
5308
5555
  };
5309
5556
 
5557
+ const renderCss = (oldState, newState) => {
5558
+ const {
5559
+ scrollBarHeight,
5560
+ uid,
5561
+ maxIndent
5562
+ } = newState;
5563
+ const rules = [`.Explorer {
5564
+ --ScrollBarThumbHeight: ${scrollBarHeight}px;
5565
+ `];
5566
+ for (let i = 0; i < maxIndent; i++) {
5567
+ const indent = getTreeItemIndent(i);
5568
+ rules.push(`.Indent-${i} {
5569
+ padding-left: ${indent};
5570
+ }`);
5571
+ }
5572
+ const css = rules.join('\n');
5573
+ return [SetCss, uid, css];
5574
+ };
5575
+
5310
5576
  const getDragLabel = urls => {
5311
5577
  if (urls.length === 1) {
5312
5578
  return getBaseName('/', urls[0]);
@@ -5392,50 +5658,10 @@ const getErrorMessagePosition = (itemHeight, focusedIndex, minLineY, depth, inde
5392
5658
  };
5393
5659
  };
5394
5660
 
5395
- const None$2 = 'none';
5661
+ const None = 'none';
5396
5662
  const ToolBar = 'toolbar';
5397
5663
  const Tree = 'tree';
5398
- const TreeItem$1 = 'treeitem';
5399
-
5400
- // 0 = 'Button'
5401
- // 1 = 'IconButton'
5402
- // 2 = 'Button IconButton'
5403
- // it could make dom diffing faster, since for classname,
5404
- // once at start, send all classnames to renderer process
5405
- // only numbers are compared. it could also make rendering faster,
5406
- // representing the concatenated strings for example
5407
- // since less data is transferred to renderer process
5408
- // then, components uses numeric classname
5409
- // TODO add option to make classnames numeric
5410
- // when a component uses multiple classnames, it is a new number
5411
- const Actions = 'Actions';
5412
- const Button$2 = 'Button';
5413
- const ButtonNarrow = 'ButtonNarrow';
5414
- const ButtonPrimary = 'ButtonPrimary';
5415
- const ButtonWide = 'ButtonWide';
5416
- const Chevron = 'Chevron';
5417
- const Empty = '';
5418
- const Explorer = 'Explorer';
5419
- const ExplorerDropTarget = 'DropTarget';
5420
- const ExplorerErrorMessage = 'ExplorerErrorMessage';
5421
- const ExplorerInputBox = 'ExplorerInputBox';
5422
- const FileIcon = 'FileIcon';
5423
- const FocusOutline = 'FocusOutline';
5424
- const IconButton = 'IconButton';
5425
- const InputValidationError = 'InputValidationError';
5426
- const Label = 'Label';
5427
- const LabelCut = 'LabelCut';
5428
- const ListItems = 'ListItems';
5429
- const MaskIconChevronDown = 'MaskIconChevronDown';
5430
- const MaskIconChevronRight = 'MaskIconChevronRight';
5431
- const ScrollBar = 'ScrollBar';
5432
- const ScrollBarSmall = 'ScrollBarSmall';
5433
- const ScrollBarThumb = 'ScrollBarThumb';
5434
- const TreeItem = 'TreeItem';
5435
- const TreeItemActive = 'TreeItemActive';
5436
- const Viewlet = 'Viewlet';
5437
- const Welcome = 'Welcome';
5438
- const WelcomeMessage = 'WelcomeMessage';
5664
+ const TreeItem = 'treeitem';
5439
5665
 
5440
5666
  const Button$1 = 1;
5441
5667
  const Div = 4;
@@ -5474,7 +5700,7 @@ const HandleDragStart = 17;
5474
5700
  const getExplorerWelcomeVirtualDom = isWide => {
5475
5701
  return [{
5476
5702
  type: Div,
5477
- className: mergeClassNames(Viewlet, Explorer),
5703
+ className: mergeClassNames(Viewlet, Explorer$1),
5478
5704
  tabIndex: 0,
5479
5705
  childCount: 1
5480
5706
  }, {
@@ -5516,7 +5742,7 @@ const getFileIconVirtualDom = icon => {
5516
5742
  type: Img,
5517
5743
  className: FileIcon,
5518
5744
  src: icon,
5519
- role: None$2,
5745
+ role: None,
5520
5746
  childCount: 0
5521
5747
  };
5522
5748
  };
@@ -5528,7 +5754,10 @@ const getInputClassName = hasEditingError => {
5528
5754
  return ExplorerInputBox;
5529
5755
  };
5530
5756
 
5531
- const getInputDom = hasEditingError => {
5757
+ const getInputDom = (isEditing, hasEditingError) => {
5758
+ if (!isEditing) {
5759
+ return [];
5760
+ }
5532
5761
  const ariaLabel = typeAFileName();
5533
5762
  return [{
5534
5763
  type: Input,
@@ -5551,7 +5780,10 @@ const label = {
5551
5780
  className: Label,
5552
5781
  childCount: 1
5553
5782
  };
5554
- const getLabelDom = (name, isDimmed) => {
5783
+ const getLabelDom = (isEditing, name, isDimmed) => {
5784
+ if (isEditing) {
5785
+ return [];
5786
+ }
5555
5787
  if (isDimmed) {
5556
5788
  return [{
5557
5789
  type: Div,
@@ -5562,13 +5794,6 @@ const getLabelDom = (name, isDimmed) => {
5562
5794
  return [label, text(name)];
5563
5795
  };
5564
5796
 
5565
- const getInputOrLabelDom = (isEditing, hasEditingError, name, isCut, isIgnored) => {
5566
- if (isEditing) {
5567
- return getInputDom(hasEditingError);
5568
- }
5569
- return getLabelDom(name, isCut || isIgnored);
5570
- };
5571
-
5572
5797
  const getExplorerItemVirtualDom = item => {
5573
5798
  const {
5574
5799
  ariaExpanded,
@@ -5591,7 +5816,7 @@ const getExplorerItemVirtualDom = item => {
5591
5816
  const chevronDom = getChevronVirtualDom(chevron);
5592
5817
  return [{
5593
5818
  type: Div,
5594
- role: TreeItem$1,
5819
+ role: TreeItem,
5595
5820
  className,
5596
5821
  draggable: true,
5597
5822
  title: path,
@@ -5605,7 +5830,7 @@ const getExplorerItemVirtualDom = item => {
5605
5830
  ariaDescription: '',
5606
5831
  id,
5607
5832
  'data-index': index
5608
- }, ...chevronDom, getFileIconVirtualDom(icon), ...getInputOrLabelDom(isEditing, hasEditingError, name, isCut, isIgnored)];
5833
+ }, ...chevronDom, getFileIconVirtualDom(icon), ...getInputDom(isEditing, hasEditingError), ...getLabelDom(isEditing, name, isCut || isIgnored)];
5609
5834
  };
5610
5835
 
5611
5836
  const getActiveDescendant = focusedIndex => {
@@ -5698,130 +5923,13 @@ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused
5698
5923
  const parentNode = {
5699
5924
  type: Div,
5700
5925
  childCount,
5701
- className: mergeClassNames(Viewlet, Explorer),
5702
- role: None$2
5926
+ className: mergeClassNames(Viewlet, Explorer$1),
5927
+ role: None
5703
5928
  };
5704
5929
  const dom = [parentNode, ...getListItemsVirtualDom(visibleItems, focusedIndex, focused, dropTargets), ...scrollBarDom, ...errorDom];
5705
5930
  return dom;
5706
5931
  };
5707
5932
 
5708
- const None$1 = 0;
5709
- const Right = 1;
5710
- const Down = 2;
5711
-
5712
- const getChevronType = (type, useChevrons) => {
5713
- if (!useChevrons) {
5714
- return None$1;
5715
- }
5716
- switch (type) {
5717
- case Directory:
5718
- return Right;
5719
- case DirectoryExpanded:
5720
- case DirectoryExpanding:
5721
- return Down;
5722
- default:
5723
- return None$1;
5724
- }
5725
- };
5726
-
5727
- const None = 0;
5728
- const Expanded = 1;
5729
- const Collapsed = 2;
5730
-
5731
- const getExpandedType = type => {
5732
- switch (type) {
5733
- case Directory:
5734
- return Collapsed;
5735
- case DirectoryExpanding:
5736
- case DirectoryExpanded:
5737
- return Expanded;
5738
- default:
5739
- return None;
5740
- }
5741
- };
5742
-
5743
- const getTreeItemClassName = (isSelected, isFocused, isDropping) => {
5744
- let className = TreeItem;
5745
- if (isSelected || isFocused) {
5746
- className = mergeClassNames(className, TreeItemActive);
5747
- }
5748
- if (isDropping) {
5749
- className = mergeClassNames(className, 'DropTarget');
5750
- }
5751
- return className;
5752
- };
5753
-
5754
- const defaultIndent$1 = 1;
5755
- const getTreeItemIndent = depth => {
5756
- return `${depth * defaultIndent$1}rem`;
5757
- };
5758
-
5759
- // TODO make all of these variable configurable
5760
- const defaultPaddingLeft = 4;
5761
- const defaultIndent = 8;
5762
-
5763
- // TODO make chevron size configurable
5764
- const chevronSize = 22;
5765
- const getTreeItemIndentWithChevron = (depth, chevron) => {
5766
- // TODO use numeric value here, convert to string value in renderer process
5767
- const extraSpace = chevron ? 0 : chevronSize;
5768
- return `${depth * defaultIndent + extraSpace + defaultPaddingLeft}px`;
5769
- };
5770
-
5771
- const ariaExpandedValues = [undefined, 'true', 'false'];
5772
- const getEditingChevron = direntType => {
5773
- switch (direntType) {
5774
- case EditingDirectoryExpanded:
5775
- return Down;
5776
- case EditingFolder:
5777
- return Right;
5778
- default:
5779
- return None$1;
5780
- }
5781
- };
5782
- const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon, cutItems, sourceControlIgnoredUris = []) => {
5783
- const visible = [];
5784
- const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
5785
- let iconIndex = 0;
5786
- for (let i = minLineY; i < Math.min(maxLineY, items.length); i++) {
5787
- const item = items[i];
5788
- let chevron = getChevronType(item.type, useChevrons);
5789
- const isFocused = i === focusedIndex;
5790
- const id = isFocused ? 'TreeItemActive' : undefined;
5791
- const isSelected = item.selected;
5792
- const isCut = cutItems.includes(item.path);
5793
- const isDropping = dropTargets.includes(i);
5794
- const isIgnored = sourceControlIgnoredUris.includes(item.path);
5795
- const className = getTreeItemClassName(isSelected, isFocused, isDropping); // TODO compute classname in dom function
5796
- const expanded = getExpandedType(item.type);
5797
- const ariaExpanded = ariaExpandedValues[expanded];
5798
- const isEditing = i === editingIndex;
5799
- let icon = icons[iconIndex++];
5800
- if (isEditing) {
5801
- icon = editingIcon;
5802
- chevron = getEditingChevron(item.type);
5803
- }
5804
- const indent = indentFn(item.depth, chevron);
5805
- visible.push({
5806
- ...item,
5807
- posInSet: item.posInSet ?? i + 1,
5808
- setSize: item.setSize ?? items.length,
5809
- isEditing: isEditing,
5810
- hasEditingError: isEditing && Boolean(editingErrorMessage),
5811
- icon,
5812
- indent,
5813
- ariaExpanded,
5814
- chevron,
5815
- id,
5816
- className,
5817
- isCut,
5818
- isIgnored,
5819
- index: i
5820
- });
5821
- }
5822
- return visible;
5823
- };
5824
-
5825
5933
  const renderItems = (oldState, newState) => {
5826
5934
  const {
5827
5935
  cutItems,
@@ -5886,6 +5994,8 @@ const getRenderer = diffType => {
5886
5994
  return renderEditingSelection;
5887
5995
  case RenderDragData:
5888
5996
  return renderDragData;
5997
+ case RenderCss:
5998
+ return renderCss;
5889
5999
  default:
5890
6000
  throw new Error('unknown renderer');
5891
6001
  }
@@ -5951,7 +6061,7 @@ const getIconVirtualDom = (icon, type = Div) => {
5951
6061
  return {
5952
6062
  type,
5953
6063
  className: `MaskIcon MaskIcon${icon}`,
5954
- role: None$2,
6064
+ role: None,
5955
6065
  childCount: 0
5956
6066
  };
5957
6067
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "3.17.0",
3
+ "version": "3.19.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",