@hexdspace/react 0.1.51 → 0.1.52

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 (2) hide show
  1. package/dist/index.js +79 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3671,9 +3671,21 @@ import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMem
3671
3671
  var scopeBindings = /* @__PURE__ */ new Map();
3672
3672
  function notify(entry) {
3673
3673
  for (const notifySub of entry.subscribers.values()) {
3674
- notifySub(entry.ownerId);
3674
+ notifySub(entry);
3675
3675
  }
3676
3676
  }
3677
+ function getScopeEntry(keyboardScopeId) {
3678
+ const existing = scopeBindings.get(keyboardScopeId);
3679
+ if (existing) return existing;
3680
+ const entry = {
3681
+ ownerId: null,
3682
+ subscribers: /* @__PURE__ */ new Map(),
3683
+ modifierActionsByOwner: /* @__PURE__ */ new Map(),
3684
+ modifierActionsVersion: 0
3685
+ };
3686
+ scopeBindings.set(keyboardScopeId, entry);
3687
+ return entry;
3688
+ }
3677
3689
  function useVimBindings(regionKey, keyboardScopeId, options = {}) {
3678
3690
  const vim = useVimController();
3679
3691
  const enabled = options.enabled ?? true;
@@ -3681,20 +3693,18 @@ function useVimBindings(regionKey, keyboardScopeId, options = {}) {
3681
3693
  const modifierMovementActions = options.modifierMovementActions;
3682
3694
  const ownerIdRef = useRef3(Symbol("vim-binding-owner"));
3683
3695
  const [isOwner, setIsOwner] = useState5(false);
3684
- const handleOwnerChange = useCallback5((ownerId) => {
3685
- setIsOwner(ownerId === ownerIdRef.current);
3696
+ const [modifierActionsVersion, setModifierActionsVersion] = useState5(0);
3697
+ const handleEntryChange = useCallback5((entry) => {
3698
+ setIsOwner(entry.ownerId === ownerIdRef.current);
3699
+ setModifierActionsVersion(entry.modifierActionsVersion);
3686
3700
  }, []);
3687
3701
  useEffect7(() => {
3688
3702
  if (!enabled) {
3689
3703
  setIsOwner(false);
3690
3704
  return;
3691
3705
  }
3692
- const entry = scopeBindings.get(keyboardScopeId) ?? {
3693
- ownerId: null,
3694
- subscribers: /* @__PURE__ */ new Map()
3695
- };
3696
- scopeBindings.set(keyboardScopeId, entry);
3697
- entry.subscribers.set(ownerIdRef.current, handleOwnerChange);
3706
+ const entry = getScopeEntry(keyboardScopeId);
3707
+ entry.subscribers.set(ownerIdRef.current, handleEntryChange);
3698
3708
  if (!entry.ownerId) {
3699
3709
  entry.ownerId = ownerIdRef.current;
3700
3710
  }
@@ -3704,18 +3714,38 @@ function useVimBindings(regionKey, keyboardScopeId, options = {}) {
3704
3714
  if (entry.ownerId === ownerIdRef.current) {
3705
3715
  const nextOwner = entry.subscribers.keys().next().value ?? null;
3706
3716
  entry.ownerId = nextOwner;
3707
- if (!nextOwner && entry.subscribers.size === 0) {
3717
+ if (!nextOwner && entry.subscribers.size === 0 && entry.modifierActionsByOwner.size === 0) {
3708
3718
  scopeBindings.delete(keyboardScopeId);
3709
3719
  return;
3710
3720
  }
3711
3721
  notify(entry);
3712
3722
  return;
3713
3723
  }
3714
- if (entry.subscribers.size === 0) {
3724
+ if (entry.subscribers.size === 0 && entry.modifierActionsByOwner.size === 0) {
3725
+ scopeBindings.delete(keyboardScopeId);
3726
+ }
3727
+ };
3728
+ }, [enabled, handleEntryChange, keyboardScopeId]);
3729
+ useEffect7(() => {
3730
+ if (!enabled) {
3731
+ return;
3732
+ }
3733
+ const entry = getScopeEntry(keyboardScopeId);
3734
+ entry.modifierActionsByOwner.set(ownerIdRef.current, modifierMovementActions ?? null);
3735
+ entry.modifierActionsVersion += 1;
3736
+ notify(entry);
3737
+ return () => {
3738
+ const existing = scopeBindings.get(keyboardScopeId);
3739
+ if (!existing) return;
3740
+ existing.modifierActionsByOwner.delete(ownerIdRef.current);
3741
+ existing.modifierActionsVersion += 1;
3742
+ if (!existing.ownerId && existing.subscribers.size === 0 && existing.modifierActionsByOwner.size === 0) {
3715
3743
  scopeBindings.delete(keyboardScopeId);
3744
+ return;
3716
3745
  }
3746
+ notify(existing);
3717
3747
  };
3718
- }, [enabled, handleOwnerChange, keyboardScopeId]);
3748
+ }, [enabled, keyboardScopeId, modifierMovementActions]);
3719
3749
  useEffect7(() => {
3720
3750
  if (!enabled) {
3721
3751
  vim.setModifierMovementActions(regionKey, null);
@@ -3757,11 +3787,12 @@ function useVimBindings(regionKey, keyboardScopeId, options = {}) {
3757
3787
  shift: { label: "Shift", prefix: "Shift" },
3758
3788
  ctrlShift: { label: "Ctrl+Shift", prefix: "Control+Shift" }
3759
3789
  };
3790
+ const modifierAvailability = getModifierAvailability(keyboardScopeId);
3760
3791
  const modifierBindings = (modifier, actions) => {
3761
3792
  if (!actions) return [];
3762
3793
  const { label, prefix } = modifierLabels[modifier];
3763
3794
  return movementEntries.flatMap((entry) => {
3764
- if (!actions?.[entry.dir]) return [];
3795
+ if (!actions[entry.dir]) return [];
3765
3796
  const combos = [`${prefix}+${entry.char.toUpperCase()}`];
3766
3797
  if (entry.arrow) {
3767
3798
  combos.push(`${prefix}+${entry.arrow}`);
@@ -3817,13 +3848,44 @@ function useVimBindings(regionKey, keyboardScopeId, options = {}) {
3817
3848
  group: "vim"
3818
3849
  },
3819
3850
  { combos: ["Escape"], handler: (e) => vim.handleEscape(e), description: "vim: escape", group: "vim" },
3820
- ...modifierBindings("ctrl", modifierMovementActions?.ctrl),
3821
- ...modifierBindings("shift", modifierMovementActions?.shift),
3822
- ...modifierBindings("ctrlShift", modifierMovementActions?.ctrlShift)
3851
+ ...modifierBindings("ctrl", modifierAvailability?.ctrl),
3852
+ ...modifierBindings("shift", modifierAvailability?.shift),
3853
+ ...modifierBindings("ctrlShift", modifierAvailability?.ctrlShift)
3823
3854
  ];
3824
- }, [allowArrowKeys, enabled, isOwner, modifierMovementActions, vim]);
3855
+ }, [allowArrowKeys, enabled, isOwner, keyboardScopeId, modifierActionsVersion, vim]);
3825
3856
  useShortcut(keyboardScopeId, bindings, { ignoreTyping: true, preventDefault: true });
3826
3857
  }
3858
+ function getModifierAvailability(keyboardScopeId) {
3859
+ const entry = scopeBindings.get(keyboardScopeId);
3860
+ if (!entry) return null;
3861
+ const result = {
3862
+ ctrl: {},
3863
+ shift: {},
3864
+ ctrlShift: {}
3865
+ };
3866
+ for (const actions of entry.modifierActionsByOwner.values()) {
3867
+ if (!actions) continue;
3868
+ const ctrl = actions.ctrl;
3869
+ if (ctrl) {
3870
+ for (const dir of Object.keys(ctrl)) {
3871
+ if (ctrl[dir]) result.ctrl[dir] = true;
3872
+ }
3873
+ }
3874
+ const shift = actions.shift;
3875
+ if (shift) {
3876
+ for (const dir of Object.keys(shift)) {
3877
+ if (shift[dir]) result.shift[dir] = true;
3878
+ }
3879
+ }
3880
+ const ctrlShift = actions.ctrlShift;
3881
+ if (ctrlShift) {
3882
+ for (const dir of Object.keys(ctrlShift)) {
3883
+ if (ctrlShift[dir]) result.ctrlShift[dir] = true;
3884
+ }
3885
+ }
3886
+ }
3887
+ return result;
3888
+ }
3827
3889
 
3828
3890
  // src/feature/vim-navigation/infra/web/react/hook/use-vim-region.tsx
3829
3891
  import { useEffect as useEffect9, useMemo as useMemo8, useRef as useRef4, useSyncExternalStore } from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexdspace/react",
3
- "version": "0.1.51",
3
+ "version": "0.1.52",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",