@hexdspace/react 0.1.48 → 0.1.49

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.
package/dist/index.d.ts CHANGED
@@ -906,15 +906,32 @@ declare class VimHandleKeyUseCase {
906
906
  private resolveInterRegionFallback;
907
907
  }
908
908
 
909
+ type VimMovementModifier = 'ctrl' | 'shift' | 'ctrlShift';
910
+ type VimModifierMovementActionArgs = {
911
+ scopeId: ScopeId;
912
+ key: RegionKey;
913
+ itemId: ItemId | null;
914
+ direction: VimDirection;
915
+ event: KeyboardEvent;
916
+ };
917
+ type VimModifierMovementAction = (args: VimModifierMovementActionArgs) => void;
918
+ type VimModifierMovementActions = {
919
+ ctrl?: Partial<Record<VimDirection, VimModifierMovementAction>>;
920
+ shift?: Partial<Record<VimDirection, VimModifierMovementAction>>;
921
+ ctrlShift?: Partial<Record<VimDirection, VimModifierMovementAction>>;
922
+ };
909
923
  declare class VimController {
910
924
  private readonly regions;
911
925
  private readonly handleKey;
912
926
  private readonly selection;
927
+ private readonly modifierMovementActionsByScope;
913
928
  constructor(selection: SelectionController, regions?: VimRegionRegistry, handleKey?: VimHandleKeyUseCase);
914
929
  handleRegisterRegionMeta(meta: VimRegionMeta): void;
915
930
  handleUnregisterRegionMeta(key: RegionKey): void;
916
931
  handleCharKey(char: string, e: KeyboardEvent): void;
917
932
  handleEscape(e: KeyboardEvent): void;
933
+ setModifierMovementActions(scopeId: ScopeId, actions: VimModifierMovementActions | null): void;
934
+ handleModifiedMovement(dir: VimDirection, modifier: VimMovementModifier, e: KeyboardEvent): void;
918
935
  resetActiveScope(): void;
919
936
  getSelection(): SelectionController;
920
937
  }
@@ -935,6 +952,7 @@ declare function useVimController(): VimController;
935
952
  type VimBindingOptions = {
936
953
  enabled?: boolean;
937
954
  allowArrowKeys?: boolean;
955
+ modifierMovementActions?: VimModifierMovementActions;
938
956
  };
939
957
  declare function useVimBindings(keyboardScopeId: string, options?: VimBindingOptions): void;
940
958
 
@@ -952,6 +970,7 @@ type UseVimRegionArgs = {
952
970
  keyboardScopeId?: string;
953
971
  bindKeys?: boolean;
954
972
  allowArrowKeys?: boolean;
973
+ modifierMovementActions?: VimModifierMovementActions;
955
974
  refreshDeps?: React__default.DependencyList;
956
975
  };
957
976
  type UseVimRegionResult = {
@@ -1139,4 +1158,4 @@ declare const Kbd: React.ForwardRefExoticComponent<KbdProps & React.RefAttribute
1139
1158
 
1140
1159
  declare function useMotionDuration(varName: string, fallbackSeconds: number): number;
1141
1160
 
1142
- export { AuthController, AuthControllerCtx, type AuthControllerDeps, AuthControllerProvider, AuthDispatchCtx, AuthProvider, type AuthState, AuthStateCtx, Button, type ButtonProps, type CacheInstruction, type ClearSelectionArgs, type ClearTarget, type CombineMode, ConfirmDialog, type ConfirmDialogProps, type ConfirmPayload, type CursorFallback, CustomDialog, type CustomDialogPayload, type CustomDialogProps, type CustomInstruction, DEFAULT_NOTIFICATION_CHANNEL, type DefaultDialogPayloads, type DefaultDialogTemplateKey, DefaultDialogTemplateKeys, Dialog, DialogContent, DialogController, DialogHost, type DialogInstance, type DialogOptions, type DialogProps, type DialogTemplate, type DisableScope, DisableScopeUseCase, DropdownMenu, DropdownMenuItem, type DropdownMenuItemProps, type DropdownMenuProps, DropdownMenuSeparator, type EnableScope, EnableScopeUseCase, type ErrorResponse, Field, type FieldProps, type GenericResponse, type GroupedShortcuts, type HandleSelection, type HttpClient, HttpError, type HttpMethod, type HttpResponse, InMemorySelectionStore, InfoDialog, type InfoDialogProps, type InfoPayload, Input, type InputProps, type Instruction, type InstructionContext, type ItemId, Kbd, type KbdProps, KeyboardController, KeyboardProvider, type ListShortcuts, ListShortcutsUseCase, type ListedShortcut, MockAuthHttpClient, MockHttpClient, type Mode, type MutationFn, type Notification, type NotificationAction, NotificationHost, type NotificationInstruction, type NotificationVariant, NotifierController, type OnSuccessFn, type OptimisticSnapshot, type OptimisticUpdateFn, Popover, type PopoverProps, type QuerySelection, RedirectIfAuthed, type RedirectIfAuthedProps, type RegionId, type RegionKey, type RegionSelection, type RegisterRegionArgs, type RegisterShortcut, RegisterShortcutUseCase, type RequestConfig, RequireAuth, type RequireAuthProps, type ResolvedToastTheme, type ResponsiveMutation, type ScopeId, ScopeManager, type ScopeState, SelectionController, type SelectionControllerDeps, SelectionControllerProvider, type SelectionState, type SelectionStore, type ShortcutBinding, type ShortcutHandler, type ShortcutRegistration, type ShortcutScope, Skeleton, type SkeletonProps, Textarea, type TextareaProps, type ToastActionTheme, type ToastTheme, type ToastTransition, type ToastifyCSSVars, Tooltip, type UIFail, type UIOk, type UIResult, type UnregisterShortcut, UnregisterShortcutUseCase, type UseVimRegionArgs, type UseVimRegionResult, type User, VimController, type VimControllerDeps, VimControllerProvider, type VimDirection, type VimInterDirection, type VimKeyState, type VimPending, type VimRegionMeta, VimRegionRegistry, authController, controllerFactory, createAuthController, createSelectionController, createVimController, dialogController, httpClient as fetchHttpClient, getDialogTemplate, keyboardController, notifierController, registerDefaultDialogs, registerDialogTemplate, resolveToastTheme, ui, unregisterDialogTemplate, useAuth, useAuthActions, useAuthController, useAuthDispatch, useAuthedUser, useDialog, useKeyboardController, useMotionDuration, useResponsiveMutation, useSelectionController, useShortcut, useShortcutScope, useVimBindings, useVimController, useVimRegion };
1161
+ export { AuthController, AuthControllerCtx, type AuthControllerDeps, AuthControllerProvider, AuthDispatchCtx, AuthProvider, type AuthState, AuthStateCtx, Button, type ButtonProps, type CacheInstruction, type ClearSelectionArgs, type ClearTarget, type CombineMode, ConfirmDialog, type ConfirmDialogProps, type ConfirmPayload, type CursorFallback, CustomDialog, type CustomDialogPayload, type CustomDialogProps, type CustomInstruction, DEFAULT_NOTIFICATION_CHANNEL, type DefaultDialogPayloads, type DefaultDialogTemplateKey, DefaultDialogTemplateKeys, Dialog, DialogContent, DialogController, DialogHost, type DialogInstance, type DialogOptions, type DialogProps, type DialogTemplate, type DisableScope, DisableScopeUseCase, DropdownMenu, DropdownMenuItem, type DropdownMenuItemProps, type DropdownMenuProps, DropdownMenuSeparator, type EnableScope, EnableScopeUseCase, type ErrorResponse, Field, type FieldProps, type GenericResponse, type GroupedShortcuts, type HandleSelection, type HttpClient, HttpError, type HttpMethod, type HttpResponse, InMemorySelectionStore, InfoDialog, type InfoDialogProps, type InfoPayload, Input, type InputProps, type Instruction, type InstructionContext, type ItemId, Kbd, type KbdProps, KeyboardController, KeyboardProvider, type ListShortcuts, ListShortcutsUseCase, type ListedShortcut, MockAuthHttpClient, MockHttpClient, type Mode, type MutationFn, type Notification, type NotificationAction, NotificationHost, type NotificationInstruction, type NotificationVariant, NotifierController, type OnSuccessFn, type OptimisticSnapshot, type OptimisticUpdateFn, Popover, type PopoverProps, type QuerySelection, RedirectIfAuthed, type RedirectIfAuthedProps, type RegionId, type RegionKey, type RegionSelection, type RegisterRegionArgs, type RegisterShortcut, RegisterShortcutUseCase, type RequestConfig, RequireAuth, type RequireAuthProps, type ResolvedToastTheme, type ResponsiveMutation, type ScopeId, ScopeManager, type ScopeState, SelectionController, type SelectionControllerDeps, SelectionControllerProvider, type SelectionState, type SelectionStore, type ShortcutBinding, type ShortcutHandler, type ShortcutRegistration, type ShortcutScope, Skeleton, type SkeletonProps, Textarea, type TextareaProps, type ToastActionTheme, type ToastTheme, type ToastTransition, type ToastifyCSSVars, Tooltip, type UIFail, type UIOk, type UIResult, type UnregisterShortcut, UnregisterShortcutUseCase, type UseVimRegionArgs, type UseVimRegionResult, type User, VimController, type VimControllerDeps, VimControllerProvider, type VimDirection, type VimInterDirection, type VimKeyState, type VimModifierMovementAction, type VimModifierMovementActionArgs, type VimModifierMovementActions, type VimMovementModifier, type VimPending, type VimRegionMeta, VimRegionRegistry, authController, controllerFactory, createAuthController, createSelectionController, createVimController, dialogController, httpClient as fetchHttpClient, getDialogTemplate, keyboardController, notifierController, registerDefaultDialogs, registerDialogTemplate, resolveToastTheme, ui, unregisterDialogTemplate, useAuth, useAuthActions, useAuthController, useAuthDispatch, useAuthedUser, useDialog, useKeyboardController, useMotionDuration, useResponsiveMutation, useSelectionController, useShortcut, useShortcutScope, useVimBindings, useVimController, useVimRegion };
package/dist/index.js CHANGED
@@ -3569,6 +3569,7 @@ var VimController = class {
3569
3569
  regions;
3570
3570
  handleKey;
3571
3571
  selection;
3572
+ modifierMovementActionsByScope = /* @__PURE__ */ new Map();
3572
3573
  constructor(selection, regions = new VimRegionRegistry(), handleKey = new VimHandleKeyUseCase(
3573
3574
  selection.getHandle(),
3574
3575
  selection.getQuery(),
@@ -3591,6 +3592,24 @@ var VimController = class {
3591
3592
  handleEscape(e) {
3592
3593
  this.handleKey.handleEscape(e);
3593
3594
  }
3595
+ setModifierMovementActions(scopeId, actions) {
3596
+ if (!actions) {
3597
+ this.modifierMovementActionsByScope.delete(scopeId);
3598
+ return;
3599
+ }
3600
+ this.modifierMovementActionsByScope.set(scopeId, actions);
3601
+ }
3602
+ handleModifiedMovement(dir, modifier, e) {
3603
+ const scopeId = this.selection.getActiveScope();
3604
+ if (!scopeId) return;
3605
+ const activeKey = this.selection.getActiveRegion(scopeId);
3606
+ if (!activeKey) return;
3607
+ const actions = this.modifierMovementActionsByScope.get(scopeId);
3608
+ const action = actions?.[modifier]?.[dir];
3609
+ if (!action) return;
3610
+ const itemId = this.selection.getActiveItem(activeKey);
3611
+ action({ scopeId, key: activeKey, itemId, direction: dir, event: e });
3612
+ }
3594
3613
  resetActiveScope() {
3595
3614
  const scopeId = this.selection.getActiveScope();
3596
3615
  if (!scopeId) return;
@@ -3647,6 +3666,7 @@ function useVimBindings(keyboardScopeId, options = {}) {
3647
3666
  const vim = useVimController();
3648
3667
  const enabled = options.enabled ?? true;
3649
3668
  const allowArrowKeys = options.allowArrowKeys ?? true;
3669
+ const modifierMovementActions = options.modifierMovementActions;
3650
3670
  const ownerIdRef = useRef3(Symbol("vim-binding-owner"));
3651
3671
  const [isOwner, setIsOwner] = useState5(false);
3652
3672
  const handleOwnerChange = useCallback5((ownerId) => {
@@ -3684,6 +3704,13 @@ function useVimBindings(keyboardScopeId, options = {}) {
3684
3704
  }
3685
3705
  };
3686
3706
  }, [enabled, handleOwnerChange, keyboardScopeId]);
3707
+ useEffect7(() => {
3708
+ if (!enabled || !isOwner) {
3709
+ return;
3710
+ }
3711
+ vim.setModifierMovementActions(keyboardScopeId, modifierMovementActions ?? null);
3712
+ return () => vim.setModifierMovementActions(keyboardScopeId, null);
3713
+ }, [enabled, isOwner, keyboardScopeId, modifierMovementActions, vim]);
3687
3714
  const bindings = useMemo6(() => {
3688
3715
  if (!enabled || !isOwner) {
3689
3716
  return [];
@@ -3706,6 +3733,36 @@ function useVimBindings(keyboardScopeId, options = {}) {
3706
3733
  up: "ArrowUp",
3707
3734
  right: "ArrowRight"
3708
3735
  } : { left: null, down: null, up: null, right: null };
3736
+ const movementEntries = [
3737
+ { dir: "left", char: "h", arrow: arrowCombos.left },
3738
+ { dir: "down", char: "j", arrow: arrowCombos.down },
3739
+ { dir: "up", char: "k", arrow: arrowCombos.up },
3740
+ { dir: "right", char: "l", arrow: arrowCombos.right }
3741
+ ];
3742
+ const modifierLabels = {
3743
+ ctrl: { label: "Ctrl", prefix: "Control" },
3744
+ shift: { label: "Shift", prefix: "Shift" },
3745
+ ctrlShift: { label: "Ctrl+Shift", prefix: "Control+Shift" }
3746
+ };
3747
+ const modifierBindings = (modifier, actions) => {
3748
+ if (!actions) return [];
3749
+ const { label, prefix } = modifierLabels[modifier];
3750
+ return movementEntries.flatMap((entry) => {
3751
+ if (!actions?.[entry.dir]) return [];
3752
+ const combos = [`${prefix}+${entry.char.toUpperCase()}`];
3753
+ if (entry.arrow) {
3754
+ combos.push(`${prefix}+${entry.arrow}`);
3755
+ }
3756
+ return [
3757
+ {
3758
+ combos,
3759
+ handler: (e) => vim.handleModifiedMovement(entry.dir, modifier, e),
3760
+ description: `vim: ${label.toLowerCase()}+${entry.dir}`,
3761
+ group: "vim"
3762
+ }
3763
+ ];
3764
+ });
3765
+ };
3709
3766
  return [
3710
3767
  ...digitBindings,
3711
3768
  {
@@ -3746,9 +3803,12 @@ function useVimBindings(keyboardScopeId, options = {}) {
3746
3803
  description: "vim: toggle item",
3747
3804
  group: "vim"
3748
3805
  },
3749
- { combos: ["Escape"], handler: (e) => vim.handleEscape(e), description: "vim: escape", group: "vim" }
3806
+ { combos: ["Escape"], handler: (e) => vim.handleEscape(e), description: "vim: escape", group: "vim" },
3807
+ ...modifierBindings("ctrl", modifierMovementActions?.ctrl),
3808
+ ...modifierBindings("shift", modifierMovementActions?.shift),
3809
+ ...modifierBindings("ctrlShift", modifierMovementActions?.ctrlShift)
3750
3810
  ];
3751
- }, [allowArrowKeys, enabled, isOwner, vim]);
3811
+ }, [allowArrowKeys, enabled, isOwner, modifierMovementActions, vim]);
3752
3812
  useShortcut(keyboardScopeId, bindings, { ignoreTyping: true, preventDefault: true });
3753
3813
  }
3754
3814
 
@@ -3831,7 +3891,11 @@ function useVimRegion(containerRef, args) {
3831
3891
  keyboard.handleEnableScope(keyboardScopeId);
3832
3892
  return () => keyboard.handleDisableScope(keyboardScopeId);
3833
3893
  }, [bindKeys, keyboard, keyboardScopeId]);
3834
- useVimBindings(keyboardScopeId, { enabled: bindKeys, allowArrowKeys: args.allowArrowKeys });
3894
+ useVimBindings(keyboardScopeId, {
3895
+ enabled: bindKeys,
3896
+ allowArrowKeys: args.allowArrowKeys,
3897
+ modifierMovementActions: args.modifierMovementActions
3898
+ });
3835
3899
  useSyncExternalStore(
3836
3900
  (listener) => selection.subscribe(listener),
3837
3901
  () => selection.getVersion(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexdspace/react",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",