react-native-hold-menu-actions 0.1.8 → 0.1.10

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.
@@ -38,8 +38,10 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
38
38
  //#region dependencies
39
39
  //#endregion
40
40
  //#region utils & types
41
+ const defaultItems = [];
42
+
41
43
  const HoldItemComponent = ({
42
- items,
44
+ items = defaultItems,
43
45
  bottom,
44
46
  containerStyles,
45
47
  disableMove,
@@ -49,13 +51,15 @@ const HoldItemComponent = ({
49
51
  actionParams,
50
52
  closeOnTap,
51
53
  longPressMinDurationMs = 150,
52
- children
54
+ children,
55
+ renderContent
53
56
  }) => {
54
57
  //#region hooks
55
58
  const {
56
59
  state,
57
60
  menuProps,
58
- safeAreaInsets
61
+ safeAreaInsets,
62
+ contentRenderer
59
63
  } = (0, _hooks.useInternal)();
60
64
  const deviceOrientation = (0, _hooks.useDeviceOrientation)(); //#endregion
61
65
  //#region variables
@@ -167,15 +171,20 @@ const HoldItemComponent = ({
167
171
  });
168
172
  };
169
173
 
174
+ const setContentRenderer = () => {
175
+ contentRenderer.current = renderContent || null;
176
+ };
177
+
170
178
  const onCompletion = isFinised => {
171
179
  'worklet';
172
180
 
173
- const isListValid = items && items.length > 0;
181
+ const isListValid = true; // items && items.length > 0;
174
182
 
175
183
  if (isFinised && isListValid) {
176
184
  state.value = _constants.CONTEXT_MENU_STATE.ACTIVE;
177
185
  isActive.value = true;
178
186
  scaleBack();
187
+ (0, _reactNativeReanimated.runOnJS)(setContentRenderer)();
179
188
 
180
189
  if (hapticFeedback !== 'None') {
181
190
  (0, _reactNativeReanimated.runOnJS)(hapticResponse)();
@@ -1 +1 @@
1
- {"version":3,"sources":["HoldItem.tsx"],"names":["HoldItemComponent","items","bottom","containerStyles","disableMove","menuAnchorPosition","activateOn","hapticFeedback","actionParams","closeOnTap","longPressMinDurationMs","children","state","menuProps","safeAreaInsets","deviceOrientation","isActive","isAnimationStarted","itemRectY","itemRectX","itemRectWidth","itemRectHeight","itemScale","transformValue","transformOrigin","key","menuHeight","itemsWithSeparator","filter","item","withSeparator","length","isHold","containerRef","hapticResponse","style","Haptics","selectionAsync","impactAsync","ImpactFeedbackStyle","notificationAsync","NotificationFeedbackType","activateAnimation","ctx","didMeasureLayout","measured","value","pageY","pageX","height","width","position","WINDOW_WIDTH","WINDOW_HEIGHT","calculateTransformValue","isAnchorPointTop","tY","topTransform","styleGuide","spacing","bottomTransform","top","setMenuProps","itemHeight","itemWidth","itemY","itemX","anchorPosition","scaleBack","duration","HOLD_ITEM_TRANSFORM_DURATION","onCompletion","isFinised","isListValid","CONTEXT_MENU_STATE","ACTIVE","scaleHold","HOLD_ITEM_SCALE_DOWN_VALUE","HOLD_ITEM_SCALE_DOWN_DURATION","scaleTap","canCallActivateFunctions","willActivateWithTap","gestureEvent","onActive","_","context","onFinish","overlayGestureEvent","END","animatedContainerStyle","animateOpacity","opacity","transform","scale","containerStyle","React","useMemo","animatedPortalStyle","transformAnimation","SPRING_CONFIGURATION","zIndex","left","translateY","portalContainerStyle","styles","holdItem","animatedPortalProps","pointerEvents","_state","GestureHandler","handlerChildren","PortalOverlay","portalOverlay","HoldItem"],"mappings":";;;;;;;AAAA;;AAIA;;AAMA;;AAiBA;;AACA;;AACA;;AAIA;;AAKA;;AASA;;AACA;;AAGA;;;;;;;;AAhDA;AAqBA;AAEA;AAIA;AAEA;AAyBA,MAAMA,iBAA0C,GAAG,CAAC;AAClDC,EAAAA,KADkD;AAElDC,EAAAA,MAFkD;AAGlDC,EAAAA,eAHkD;AAIlDC,EAAAA,WAJkD;AAKlDC,EAAAA,kBALkD;AAMlDC,EAAAA,UANkD;AAOlDC,EAAAA,cAPkD;AAQlDC,EAAAA,YARkD;AASlDC,EAAAA,UATkD;AAUlDC,EAAAA,sBAAsB,GAAG,GAVyB;AAWlDC,EAAAA;AAXkD,CAAD,KAY7C;AACJ;AACA,QAAM;AAAEC,IAAAA,KAAF;AAASC,IAAAA,SAAT;AAAoBC,IAAAA;AAApB,MAAuC,yBAA7C;AACA,QAAMC,iBAAiB,GAAG,kCAA1B,CAHI,CAIJ;AAEA;;AACA,QAAMC,QAAQ,GAAG,2CAAe,KAAf,CAAjB;AACA,QAAMC,kBAAkB,GAAG,2CAAe,KAAf,CAA3B;AAEA,QAAMC,SAAS,GAAG,2CAAuB,CAAvB,CAAlB;AACA,QAAMC,SAAS,GAAG,2CAAuB,CAAvB,CAAlB;AACA,QAAMC,aAAa,GAAG,2CAAuB,CAAvB,CAAtB;AACA,QAAMC,cAAc,GAAG,2CAAuB,CAAvB,CAAvB;AACA,QAAMC,SAAS,GAAG,2CAAuB,CAAvB,CAAlB;AACA,QAAMC,cAAc,GAAG,2CAAuB,CAAvB,CAAvB;AAEA,QAAMC,eAAe,GAAG,2CACtBnB,kBAAkB,IAAI,WADA,CAAxB;AAIA,QAAMoB,GAAG,GAAG,oBAAQ,MAAO,aAAY,wBAAS,EAApC,EAAuC,EAAvC,CAAZ;AACA,QAAMC,UAAU,GAAG,oBAAQ,MAAM;AAC/B,UAAMC,kBAAkB,GAAG1B,KAAK,CAAC2B,MAAN,CAAaC,IAAI,IAAIA,IAAI,CAACC,aAA1B,CAA3B;AACA,WAAO,uCAAoB7B,KAAK,CAAC8B,MAA1B,EAAkCJ,kBAAkB,CAACI,MAArD,CAAP;AACD,GAHkB,EAGhB,CAAC9B,KAAD,CAHgB,CAAnB;AAKA,QAAM+B,MAAM,GAAG,CAAC1B,UAAD,IAAeA,UAAU,KAAK,MAA7C,CA3BI,CA4BJ;AAEA;;AACA,QAAM2B,YAAY,GAAG,4CAArB,CA/BI,CAgCJ;AAEA;;AACA,QAAMC,cAAc,GAAG,MAAM;AAC3B,UAAMC,KAAK,GAAG,CAAC5B,cAAD,GAAkB,QAAlB,GAA6BA,cAA3C;;AACA,YAAQ4B,KAAR;AACE,WAAM,WAAN;AACEC,QAAAA,OAAO,CAACC,cAAR;AACA;;AACF,WAAM,OAAN;AACA,WAAM,QAAN;AACA,WAAM,OAAN;AACED,QAAAA,OAAO,CAACE,WAAR,CAAoBF,OAAO,CAACG,mBAAR,CAA4BJ,KAA5B,CAApB;AACA;;AACF,WAAM,SAAN;AACA,WAAM,SAAN;AACA,WAAM,OAAN;AACEC,QAAAA,OAAO,CAACI,iBAAR,CAA0BJ,OAAO,CAACK,wBAAR,CAAiCN,KAAjC,CAA1B;AACA;;AACF;AAdF;AAgBD,GAlBD,CAnCI,CAsDJ;AAEA;;;AACA,QAAMO,iBAAiB,GAAIC,GAAD,IAAc;AACtC;;AACA,QAAI,CAACA,GAAG,CAACC,gBAAT,EAA2B;AACzB,YAAMC,QAAQ,GAAG,oCAAQZ,YAAR,CAAjB;AAEAf,MAAAA,SAAS,CAAC4B,KAAV,GAAkBD,QAAQ,CAACE,KAA3B;AACA5B,MAAAA,SAAS,CAAC2B,KAAV,GAAkBD,QAAQ,CAACG,KAA3B;AACA3B,MAAAA,cAAc,CAACyB,KAAf,GAAuBD,QAAQ,CAACI,MAAhC;AACA7B,MAAAA,aAAa,CAAC0B,KAAd,GAAsBD,QAAQ,CAACK,KAA/B;;AAEA,UAAI,CAAC7C,kBAAL,EAAyB;AACvB,cAAM8C,QAAQ,GAAG,sCACfN,QAAQ,CAACG,KADM,EAEf5B,aAAa,CAAC0B,KAFC,EAGf/B,iBAAiB,KAAK,UAAtB,GAAmCqC,uBAAnC,GAAkDC,wBAHnC,EAIfnD,MAJe,CAAjB;AAMAsB,QAAAA,eAAe,CAACsB,KAAhB,GAAwBK,QAAxB;AACD;AACF;AACF,GApBD;;AAsBA,QAAMG,uBAAuB,GAAG,MAAM;AACpC;;AAEA,UAAML,MAAM,GACVlC,iBAAiB,KAAK,UAAtB,GAAmCsC,wBAAnC,GAAmDD,uBADrD;AAGA,UAAMG,gBAAgB,GAAGrC,SAAS,CAAC4B,KAAV,GAAkBO,2BAAgB,CAA3D;AAEA,QAAIG,EAAE,GAAG,CAAT;;AACA,QAAI,CAACpD,WAAL,EAAkB;AAChB,UAAImD,gBAAJ,EAAsB;AACpB,cAAME,YAAY,GAChBvC,SAAS,CAAC4B,KAAV,GACAzB,cAAc,CAACyB,KADf,GAEApB,UAFA,GAGAgC,oBAAWC,OAHX,IAIC,CAAA7C,cAAc,SAAd,IAAAA,cAAc,WAAd,YAAAA,cAAc,CAAEZ,MAAhB,KAA0B,CAJ3B,CADF;AAOAsD,QAAAA,EAAE,GAAGC,YAAY,GAAGR,MAAf,GAAwBA,MAAM,GAAGQ,YAAjC,GAAgD,CAArD;AACD,OATD,MASO;AACL,cAAMG,eAAe,GACnB1C,SAAS,CAAC4B,KAAV,GAAkBpB,UAAlB,IAAgC,CAAAZ,cAAc,SAAd,IAAAA,cAAc,WAAd,YAAAA,cAAc,CAAE+C,GAAhB,KAAuB,CAAvD,CADF;AAEAL,QAAAA,EAAE,GACAI,eAAe,GAAG,CAAlB,GAAsB,CAACA,eAAD,GAAmBF,oBAAWC,OAAX,GAAqB,CAA9D,GAAkE,CADpE;AAED;AACF;;AACD,WAAOH,EAAP;AACD,GA3BD;;AA6BA,QAAMM,YAAY,GAAG,MAAM;AACzB;;AAEAjD,IAAAA,SAAS,CAACiC,KAAV,GAAkB;AAChBiB,MAAAA,UAAU,EAAE1C,cAAc,CAACyB,KADX;AAEhBkB,MAAAA,SAAS,EAAE5C,aAAa,CAAC0B,KAFT;AAGhBmB,MAAAA,KAAK,EAAE/C,SAAS,CAAC4B,KAHD;AAIhBoB,MAAAA,KAAK,EAAE/C,SAAS,CAAC2B,KAJD;AAKhBqB,MAAAA,cAAc,EAAE3C,eAAe,CAACsB,KALhB;AAMhBpB,MAAAA,UAAU,EAAEA,UANI;AAOhBzB,MAAAA,KAPgB;AAQhBsB,MAAAA,cAAc,EAAEA,cAAc,CAACuB,KARf;AAShBtC,MAAAA,YAAY,EAAEA,YAAY,IAAI;AATd,KAAlB;AAWD,GAdD;;AAgBA,QAAM4D,SAAS,GAAG,MAAM;AACtB;;AACA9C,IAAAA,SAAS,CAACwB,KAAV,GAAkB,uCAAW,CAAX,EAAc;AAC9BuB,MAAAA,QAAQ,EAAEC,0CAA+B;AADX,KAAd,CAAlB;AAGD,GALD;;AAOA,QAAMC,YAAY,GAAIC,SAAD,IAAyB;AAC5C;;AACA,UAAMC,WAAW,GAAGxE,KAAK,IAAIA,KAAK,CAAC8B,MAAN,GAAe,CAA5C;;AACA,QAAIyC,SAAS,IAAIC,WAAjB,EAA8B;AAC5B7D,MAAAA,KAAK,CAACkC,KAAN,GAAc4B,8BAAmBC,MAAjC;AACA3D,MAAAA,QAAQ,CAAC8B,KAAT,GAAiB,IAAjB;AACAsB,MAAAA,SAAS;;AACT,UAAI7D,cAAc,KAAK,MAAvB,EAA+B;AAC7B,4CAAQ2B,cAAR;AACD;AACF;;AAEDjB,IAAAA,kBAAkB,CAAC6B,KAAnB,GAA2B,KAA3B,CAZ4C,CAc5C;AACD,GAfD;;AAiBA,QAAM8B,SAAS,GAAG,MAAM;AACtB;;AACAtD,IAAAA,SAAS,CAACwB,KAAV,GAAkB,uCAChB+B,qCADgB,EAEhB;AAAER,MAAAA,QAAQ,EAAES;AAAZ,KAFgB,EAGhBP,YAHgB,CAAlB;AAKD,GAPD;;AASA,QAAMQ,QAAQ,GAAG,MAAM;AACrB;;AACA9D,IAAAA,kBAAkB,CAAC6B,KAAnB,GAA2B,IAA3B;AAEAxB,IAAAA,SAAS,CAACwB,KAAV,GAAkB,yCAChB,uCAAW+B,qCAAX,EAAuC;AACrCR,MAAAA,QAAQ,EAAES;AAD2B,KAAvC,CADgB,EAIhB,uCACE,CADF,EAEE;AACET,MAAAA,QAAQ,EAAEC,0CAA+B;AAD3C,KAFF,EAKEC,YALF,CAJgB,CAAlB;AAYD,GAhBD;AAkBA;AACF;AACA;AACA;AACA;;;AACE,QAAMS,wBAAwB,GAAG,MAAM;AACrC;;AACA,UAAMC,mBAAmB,GACvB3E,UAAU,KAAK,YAAf,IAA+BA,UAAU,KAAK,KADhD;AAGA,WACG2E,mBAAmB,IAAI,CAAChE,kBAAkB,CAAC6B,KAA5C,IAAsD,CAACmC,mBADzD;AAGD,GARD,CApLI,CA6LJ;AAEA;;;AACA,QAAMC,YAAY,GAAG,sDAGnB;AACAC,IAAAA,QAAQ,EAAE,CAACC,CAAD,EAAIC,OAAJ,KAAgB;AACxB,UAAIL,wBAAwB,EAA5B,EAAgC;AAC9B,YAAI,CAACK,OAAO,CAACzC,gBAAb,EAA+B;AAC7BF,UAAAA,iBAAiB,CAAC2C,OAAD,CAAjB;AACA9D,UAAAA,cAAc,CAACuB,KAAf,GAAuBQ,uBAAuB,EAA9C;AACAQ,UAAAA,YAAY;AACZuB,UAAAA,OAAO,CAACzC,gBAAR,GAA2B,IAA3B;AACD;;AAED,YAAI,CAAC5B,QAAQ,CAAC8B,KAAd,EAAqB;AACnB,cAAId,MAAJ,EAAY;AACV4C,YAAAA,SAAS;AACV,WAFD,MAEO;AACLG,YAAAA,QAAQ;AACT;AACF;AACF;AACF,KAlBD;AAmBAO,IAAAA,QAAQ,EAAE,CAACF,CAAD,EAAIC,OAAJ,KAAgB;AACxBA,MAAAA,OAAO,CAACzC,gBAAR,GAA2B,KAA3B;;AACA,UAAIZ,MAAJ,EAAY;AACVoC,QAAAA,SAAS;AACV;AACF;AAxBD,GAHmB,CAArB;AA8BA,QAAMmB,mBAAmB,GAAG,sDAG1B;AACAJ,IAAAA,QAAQ,EAAEC,CAAC,IAAI;AACb,UAAI3E,UAAJ,EAAgBG,KAAK,CAACkC,KAAN,GAAc4B,8BAAmBc,GAAjC;AACjB;AAHD,GAH0B,CAA5B,CA9NI,CAsOJ;AAEA;;AACA,QAAMC,sBAAsB,GAAG,6CAAiB,MAAM;AACpD,UAAMC,cAAc,GAAG,MACrB,sCAAUpB,uCAAV,EAAwC,uCAAW,CAAX,EAAc;AAAED,MAAAA,QAAQ,EAAE;AAAZ,KAAd,CAAxC,CADF;;AAGA,WAAO;AACLsB,MAAAA,OAAO,EAAE3E,QAAQ,CAAC8B,KAAT,GAAiB,CAAjB,GAAqB4C,cAAc,EADvC;AAELE,MAAAA,SAAS,EAAE,CACT;AACEC,QAAAA,KAAK,EAAE7E,QAAQ,CAAC8B,KAAT,GACH,uCAAW,CAAX,EAAc;AAAEuB,UAAAA,QAAQ,EAAEC;AAAZ,SAAd,CADG,GAEHhD,SAAS,CAACwB;AAHhB,OADS;AAFN,KAAP;AAUD,GAd8B,CAA/B;;AAeA,QAAMgD,cAAc,GAAGC,eAAMC,OAAN,CACrB,MAAM,CAAC7F,eAAD,EAAkBsF,sBAAlB,CADe,EAErB,CAACtF,eAAD,EAAkBsF,sBAAlB,CAFqB,CAAvB;;AAKA,QAAMQ,mBAAmB,GAAG,6CAAiB,MAAM;AACjD,UAAMP,cAAc,GAAG,MACrB,sCAAUpB,uCAAV,EAAwC,uCAAW,CAAX,EAAc;AAAED,MAAAA,QAAQ,EAAE;AAAZ,KAAd,CAAxC,CADF;;AAGA,QAAIb,EAAE,GAAGF,uBAAuB,EAAhC;;AACA,UAAM4C,kBAAkB,GAAG,MACzB9F,WAAW,GACP,CADO,GAEPY,QAAQ,CAAC8B,KAAT,GACA,uCAAWU,EAAX,EAAe2C,+BAAf,CADA,GAEA,uCAAW,CAAC,GAAZ,EAAiB;AAAE9B,MAAAA,QAAQ,EAAEC;AAAZ,KAAjB,CALN;;AAOA,WAAO;AACL8B,MAAAA,MAAM,EAAE,EADH;AAELjD,MAAAA,QAAQ,EAAE,UAFL;AAGLU,MAAAA,GAAG,EAAE3C,SAAS,CAAC4B,KAHV;AAILuD,MAAAA,IAAI,EAAElF,SAAS,CAAC2B,KAJX;AAKLI,MAAAA,KAAK,EAAE9B,aAAa,CAAC0B,KALhB;AAMLG,MAAAA,MAAM,EAAE5B,cAAc,CAACyB,KANlB;AAOL6C,MAAAA,OAAO,EAAE3E,QAAQ,CAAC8B,KAAT,GAAiB,CAAjB,GAAqB4C,cAAc,EAPvC;AAQLE,MAAAA,SAAS,EAAE,CACT;AACEU,QAAAA,UAAU,EAAEJ,kBAAkB;AADhC,OADS,EAIT;AACEL,QAAAA,KAAK,EAAE7E,QAAQ,CAAC8B,KAAT,GACH,uCAAW,CAAX,EAAc;AAAEuB,UAAAA,QAAQ,EAAEC;AAAZ,SAAd,CADG,GAEHhD,SAAS,CAACwB;AAHhB,OAJS;AARN,KAAP;AAmBD,GA/B2B,CAA5B;AAgCA,QAAMyD,oBAAoB,GAAG,oBAC3B,MAAM,CAACC,gBAAOC,QAAR,EAAkBR,mBAAlB,CADqB,EAE3B,CAACA,mBAAD,CAF2B,CAA7B;AAKA,QAAMS,mBAAmB,GAAG,6CAA4B,OAAO;AAC7DC,IAAAA,aAAa,EAAE3F,QAAQ,CAAC8B,KAAT,GAAiB,MAAjB,GAA0B;AADoB,GAAP,CAA5B,CAA5B,CAlSI,CAqSJ;AAEA;;AACA,kDACE,MAAMlC,KAAK,CAACkC,KADd,EAEE8D,MAAM,IAAI;AACR,QAAIA,MAAM,KAAKlC,8BAAmBc,GAAlC,EAAuC;AACrCxE,MAAAA,QAAQ,CAAC8B,KAAT,GAAiB,KAAjB;AACD;AACF,GANH,EAxSI,CAgTJ;AAEA;;AACA,QAAM+D,cAAc,GAAG,oBAAQ,MAAM;AACnC,YAAQvG,UAAR;AACE,WAAM,YAAN;AACE,eAAO,CAAC;AAAEK,UAAAA,QAAQ,EAAEmG;AAAZ,SAAD,kBACL,6BAAC,4CAAD;AACE,UAAA,YAAY,EAAE,CADhB;AAEE,UAAA,oBAAoB,EAAE5B;AAFxB,WAIG4B,eAJH,CADF;;AAQF,WAAM,KAAN;AACE,eAAO,CAAC;AAAEnG,UAAAA,QAAQ,EAAEmG;AAAZ,SAAD,kBACL,6BAAC,4CAAD;AACE,UAAA,YAAY,EAAE,CADhB;AAEE,UAAA,oBAAoB,EAAE5B;AAFxB,WAIG4B,eAJH,CADF;AAQF;;AACA;AACE,eAAO,CAAC;AAAEnG,UAAAA,QAAQ,EAAEmG;AAAZ,SAAD,kBACL,6BAAC,kDAAD;AACE,UAAA,aAAa,EAAEpG,sBADjB;AAEE,UAAA,oBAAoB,EAAEwE;AAFxB,WAIG4B,eAJH,CADF;AArBJ;AA8BD,GA/BsB,EA+BpB,CAACxG,UAAD,EAAa4E,YAAb,CA/BoB,CAAvB;AAiCA,QAAM6B,aAAa,GAAG,oBAAQ,MAAM;AAClC,WAAO,mBACL,6BAAC,4CAAD;AACE,MAAA,YAAY,EAAE,CADhB;AAEE,MAAA,oBAAoB,EAAExB;AAFxB,oBAIE,6BAAC,8BAAD,CAAU,IAAV;AAAe,MAAA,KAAK,EAAEiB,gBAAOQ;AAA7B,MAJF,CADF;AAQD,GATqB,EASnB,CAACzB,mBAAD,CATmB,CAAtB,CApVI,CA8VJ;AAEA;;AACA,sBACE,yEACE,6BAAC,cAAD,qBACE,6BAAC,8BAAD,CAAU,IAAV;AAAe,IAAA,GAAG,EAAEtD,YAApB;AAAkC,IAAA,KAAK,EAAE6D;AAAzC,KACGnF,QADH,CADF,CADF,eAOE,6BAAC,cAAD;AAAQ,IAAA,GAAG,EAAEc,GAAb;AAAkB,IAAA,IAAI,EAAEA;AAAxB,kBACE,6BAAC,8BAAD,CAAU,IAAV;AACE,IAAA,GAAG,EAAEA,GADP;AAEE,IAAA,KAAK,EAAE8E,oBAFT;AAGE,IAAA,aAAa,EAAEG;AAHjB,kBAKE,6BAAC,aAAD,OALF,EAMG/F,QANH,CADF,CAPF,CADF,CAjWI,CAqXJ;AACD,CAlYD;;AAoYA,MAAMsG,QAAQ,gBAAG,iBAAKjH,iBAAL,CAAjB;eAEeiH,Q","sourcesContent":["import React, { memo, useMemo } from 'react';\nimport { ViewProps } from 'react-native';\n\n//#region reanimated & gesture handler\nimport {\n TapGestureHandler,\n LongPressGestureHandler,\n TapGestureHandlerGestureEvent,\n LongPressGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n measure,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedProps,\n useAnimatedRef,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withTiming,\n withSequence,\n withSpring,\n useAnimatedReaction,\n} from 'react-native-reanimated';\n//#endregion\n\n//#region dependencies\nimport { Portal } from '@gorhom/portal';\nimport { nanoid } from 'nanoid/non-secure';\nimport * as Haptics from 'expo-haptics';\n//#endregion\n\n//#region utils & types\nimport {\n TransformOriginAnchorPosition,\n getTransformOrigin,\n calculateMenuHeight,\n} from '../../utils/calculations';\nimport {\n HOLD_ITEM_TRANSFORM_DURATION,\n HOLD_ITEM_SCALE_DOWN_DURATION,\n HOLD_ITEM_SCALE_DOWN_VALUE,\n SPRING_CONFIGURATION,\n WINDOW_HEIGHT,\n WINDOW_WIDTH,\n CONTEXT_MENU_STATE,\n} from '../../constants';\nimport { useDeviceOrientation } from '../../hooks';\nimport styles from './styles';\n\nimport type { HoldItemProps, GestureHandlerProps } from './types';\nimport styleGuide from '../../styleGuide';\nimport { useInternal } from '../../hooks';\n//#endregion\n\ntype Context = { didMeasureLayout: boolean };\n\nconst HoldItemComponent: React.FC<HoldItemProps> = ({\n items,\n bottom,\n containerStyles,\n disableMove,\n menuAnchorPosition,\n activateOn,\n hapticFeedback,\n actionParams,\n closeOnTap,\n longPressMinDurationMs = 150,\n children,\n}) => {\n //#region hooks\n const { state, menuProps, safeAreaInsets } = useInternal();\n const deviceOrientation = useDeviceOrientation();\n //#endregion\n\n //#region variables\n const isActive = useSharedValue(false);\n const isAnimationStarted = useSharedValue(false);\n\n const itemRectY = useSharedValue<number>(0);\n const itemRectX = useSharedValue<number>(0);\n const itemRectWidth = useSharedValue<number>(0);\n const itemRectHeight = useSharedValue<number>(0);\n const itemScale = useSharedValue<number>(1);\n const transformValue = useSharedValue<number>(0);\n\n const transformOrigin = useSharedValue<TransformOriginAnchorPosition>(\n menuAnchorPosition || 'top-right'\n );\n\n const key = useMemo(() => `hold-item-${nanoid()}`, []);\n const menuHeight = useMemo(() => {\n const itemsWithSeparator = items.filter(item => item.withSeparator);\n return calculateMenuHeight(items.length, itemsWithSeparator.length);\n }, [items]);\n\n const isHold = !activateOn || activateOn === 'hold';\n //#endregion\n\n //#region refs\n const containerRef = useAnimatedRef<Animated.View>();\n //#endregion\n\n //#region functions\n const hapticResponse = () => {\n const style = !hapticFeedback ? 'Medium' : hapticFeedback;\n switch (style) {\n case `Selection`:\n Haptics.selectionAsync();\n break;\n case `Light`:\n case `Medium`:\n case `Heavy`:\n Haptics.impactAsync(Haptics.ImpactFeedbackStyle[style]);\n break;\n case `Success`:\n case `Warning`:\n case `Error`:\n Haptics.notificationAsync(Haptics.NotificationFeedbackType[style]);\n break;\n default:\n }\n };\n //#endregion\n\n //#region worklet functions\n const activateAnimation = (ctx: any) => {\n 'worklet';\n if (!ctx.didMeasureLayout) {\n const measured = measure(containerRef);\n\n itemRectY.value = measured.pageY;\n itemRectX.value = measured.pageX;\n itemRectHeight.value = measured.height;\n itemRectWidth.value = measured.width;\n\n if (!menuAnchorPosition) {\n const position = getTransformOrigin(\n measured.pageX,\n itemRectWidth.value,\n deviceOrientation === 'portrait' ? WINDOW_WIDTH : WINDOW_HEIGHT,\n bottom\n );\n transformOrigin.value = position;\n }\n }\n };\n\n const calculateTransformValue = () => {\n 'worklet';\n\n const height =\n deviceOrientation === 'portrait' ? WINDOW_HEIGHT : WINDOW_WIDTH;\n\n const isAnchorPointTop = itemRectY.value > WINDOW_HEIGHT / 2;\n\n let tY = 0;\n if (!disableMove) {\n if (isAnchorPointTop) {\n const topTransform =\n itemRectY.value +\n itemRectHeight.value +\n menuHeight +\n styleGuide.spacing +\n (safeAreaInsets?.bottom || 0);\n\n tY = topTransform > height ? height - topTransform : 0;\n } else {\n const bottomTransform =\n itemRectY.value - menuHeight - (safeAreaInsets?.top || 0);\n tY =\n bottomTransform < 0 ? -bottomTransform + styleGuide.spacing * 2 : 0;\n }\n }\n return tY;\n };\n\n const setMenuProps = () => {\n 'worklet';\n\n menuProps.value = {\n itemHeight: itemRectHeight.value,\n itemWidth: itemRectWidth.value,\n itemY: itemRectY.value,\n itemX: itemRectX.value,\n anchorPosition: transformOrigin.value,\n menuHeight: menuHeight,\n items,\n transformValue: transformValue.value,\n actionParams: actionParams || {},\n };\n };\n\n const scaleBack = () => {\n 'worklet';\n itemScale.value = withTiming(1, {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n });\n };\n\n const onCompletion = (isFinised?: boolean) => {\n 'worklet';\n const isListValid = items && items.length > 0;\n if (isFinised && isListValid) {\n state.value = CONTEXT_MENU_STATE.ACTIVE;\n isActive.value = true;\n scaleBack();\n if (hapticFeedback !== 'None') {\n runOnJS(hapticResponse)();\n }\n }\n\n isAnimationStarted.value = false;\n\n // TODO: Warn user if item list is empty or not given\n };\n\n const scaleHold = () => {\n 'worklet';\n itemScale.value = withTiming(\n HOLD_ITEM_SCALE_DOWN_VALUE,\n { duration: HOLD_ITEM_SCALE_DOWN_DURATION },\n onCompletion\n );\n };\n\n const scaleTap = () => {\n 'worklet';\n isAnimationStarted.value = true;\n\n itemScale.value = withSequence(\n withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {\n duration: HOLD_ITEM_SCALE_DOWN_DURATION,\n }),\n withTiming(\n 1,\n {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n },\n onCompletion\n )\n );\n };\n\n /**\n * When use tap activation (\"tap\") and trying to tap multiple times,\n * scale animation is called again despite it is started. This causes a bug.\n * To prevent this, it is better to check is animation already started.\n */\n const canCallActivateFunctions = () => {\n 'worklet';\n const willActivateWithTap =\n activateOn === 'double-tap' || activateOn === 'tap';\n\n return (\n (willActivateWithTap && !isAnimationStarted.value) || !willActivateWithTap\n );\n };\n //#endregion\n\n //#region gesture events\n const gestureEvent = useAnimatedGestureHandler<\n LongPressGestureHandlerGestureEvent | TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: (_, context) => {\n if (canCallActivateFunctions()) {\n if (!context.didMeasureLayout) {\n activateAnimation(context);\n transformValue.value = calculateTransformValue();\n setMenuProps();\n context.didMeasureLayout = true;\n }\n\n if (!isActive.value) {\n if (isHold) {\n scaleHold();\n } else {\n scaleTap();\n }\n }\n }\n },\n onFinish: (_, context) => {\n context.didMeasureLayout = false;\n if (isHold) {\n scaleBack();\n }\n },\n });\n\n const overlayGestureEvent = useAnimatedGestureHandler<\n TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: _ => {\n if (closeOnTap) state.value = CONTEXT_MENU_STATE.END;\n },\n });\n //#endregion\n\n //#region animated styles & props\n const animatedContainerStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(1, { duration: 0 }));\n\n return {\n opacity: isActive.value ? 0 : animateOpacity(),\n transform: [\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const containerStyle = React.useMemo(\n () => [containerStyles, animatedContainerStyle],\n [containerStyles, animatedContainerStyle]\n );\n\n const animatedPortalStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(0, { duration: 0 }));\n\n let tY = calculateTransformValue();\n const transformAnimation = () =>\n disableMove\n ? 0\n : isActive.value\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(-0.1, { duration: HOLD_ITEM_TRANSFORM_DURATION });\n\n return {\n zIndex: 10,\n position: 'absolute',\n top: itemRectY.value,\n left: itemRectX.value,\n width: itemRectWidth.value,\n height: itemRectHeight.value,\n opacity: isActive.value ? 1 : animateOpacity(),\n transform: [\n {\n translateY: transformAnimation(),\n },\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const portalContainerStyle = useMemo(\n () => [styles.holdItem, animatedPortalStyle],\n [animatedPortalStyle]\n );\n\n const animatedPortalProps = useAnimatedProps<ViewProps>(() => ({\n pointerEvents: isActive.value ? 'auto' : 'none',\n }));\n //#endregion\n\n //#region animated effects\n useAnimatedReaction(\n () => state.value,\n _state => {\n if (_state === CONTEXT_MENU_STATE.END) {\n isActive.value = false;\n }\n }\n );\n //#endregion\n\n //#region components\n const GestureHandler = useMemo(() => {\n switch (activateOn) {\n case `double-tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={2}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n case `tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n // default is hold\n default:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <LongPressGestureHandler\n minDurationMs={longPressMinDurationMs}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </LongPressGestureHandler>\n );\n }\n }, [activateOn, gestureEvent]);\n\n const PortalOverlay = useMemo(() => {\n return () => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={overlayGestureEvent}\n >\n <Animated.View style={styles.portalOverlay} />\n </TapGestureHandler>\n );\n }, [overlayGestureEvent]);\n //#endregion\n\n //#region render\n return (\n <>\n <GestureHandler>\n <Animated.View ref={containerRef} style={containerStyle}>\n {children}\n </Animated.View>\n </GestureHandler>\n\n <Portal key={key} name={key}>\n <Animated.View\n key={key}\n style={portalContainerStyle}\n animatedProps={animatedPortalProps}\n >\n <PortalOverlay />\n {children}\n </Animated.View>\n </Portal>\n </>\n );\n //#endregion\n};\n\nconst HoldItem = memo(HoldItemComponent) as React.FC<HoldItemProps>;\n\nexport default HoldItem;\n"]}
1
+ {"version":3,"sources":["HoldItem.tsx"],"names":["defaultItems","HoldItemComponent","items","bottom","containerStyles","disableMove","menuAnchorPosition","activateOn","hapticFeedback","actionParams","closeOnTap","longPressMinDurationMs","children","renderContent","state","menuProps","safeAreaInsets","contentRenderer","deviceOrientation","isActive","isAnimationStarted","itemRectY","itemRectX","itemRectWidth","itemRectHeight","itemScale","transformValue","transformOrigin","key","menuHeight","itemsWithSeparator","filter","item","withSeparator","length","isHold","containerRef","hapticResponse","style","Haptics","selectionAsync","impactAsync","ImpactFeedbackStyle","notificationAsync","NotificationFeedbackType","activateAnimation","ctx","didMeasureLayout","measured","value","pageY","pageX","height","width","position","WINDOW_WIDTH","WINDOW_HEIGHT","calculateTransformValue","isAnchorPointTop","tY","topTransform","styleGuide","spacing","bottomTransform","top","setMenuProps","itemHeight","itemWidth","itemY","itemX","anchorPosition","scaleBack","duration","HOLD_ITEM_TRANSFORM_DURATION","setContentRenderer","current","onCompletion","isFinised","isListValid","CONTEXT_MENU_STATE","ACTIVE","scaleHold","HOLD_ITEM_SCALE_DOWN_VALUE","HOLD_ITEM_SCALE_DOWN_DURATION","scaleTap","canCallActivateFunctions","willActivateWithTap","gestureEvent","onActive","_","context","onFinish","overlayGestureEvent","END","animatedContainerStyle","animateOpacity","opacity","transform","scale","containerStyle","React","useMemo","animatedPortalStyle","transformAnimation","SPRING_CONFIGURATION","zIndex","left","translateY","portalContainerStyle","styles","holdItem","animatedPortalProps","pointerEvents","_state","GestureHandler","handlerChildren","PortalOverlay","portalOverlay","HoldItem"],"mappings":"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","sourcesContent":["import React, { memo, useMemo } from 'react';\nimport { ViewProps } from 'react-native';\n\n//#region reanimated & gesture handler\nimport {\n TapGestureHandler,\n LongPressGestureHandler,\n TapGestureHandlerGestureEvent,\n LongPressGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n measure,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedProps,\n useAnimatedRef,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withTiming,\n withSequence,\n withSpring,\n useAnimatedReaction,\n} from 'react-native-reanimated';\n//#endregion\n\n//#region dependencies\nimport { Portal } from '@gorhom/portal';\nimport { nanoid } from 'nanoid/non-secure';\nimport * as Haptics from 'expo-haptics';\n//#endregion\n\n//#region utils & types\nimport {\n TransformOriginAnchorPosition,\n getTransformOrigin,\n calculateMenuHeight,\n} from '../../utils/calculations';\nimport {\n HOLD_ITEM_TRANSFORM_DURATION,\n HOLD_ITEM_SCALE_DOWN_DURATION,\n HOLD_ITEM_SCALE_DOWN_VALUE,\n SPRING_CONFIGURATION,\n WINDOW_HEIGHT,\n WINDOW_WIDTH,\n CONTEXT_MENU_STATE,\n} from '../../constants';\nimport { useDeviceOrientation } from '../../hooks';\nimport styles from './styles';\n\nimport type { HoldItemProps, GestureHandlerProps } from './types';\nimport styleGuide from '../../styleGuide';\nimport { useInternal } from '../../hooks';\nimport { MenuItemProps } from '../menu/types';\n//#endregion\n\ntype Context = { didMeasureLayout: boolean };\nconst defaultItems = [] as MenuItemProps[];\nconst HoldItemComponent: React.FC<HoldItemProps> = ({\n items = defaultItems,\n bottom,\n containerStyles,\n disableMove,\n menuAnchorPosition,\n activateOn,\n hapticFeedback,\n actionParams,\n closeOnTap,\n longPressMinDurationMs = 150,\n children,\n renderContent,\n}) => {\n //#region hooks\n const { state, menuProps, safeAreaInsets, contentRenderer } = useInternal();\n const deviceOrientation = useDeviceOrientation();\n //#endregion\n\n //#region variables\n const isActive = useSharedValue(false);\n const isAnimationStarted = useSharedValue(false);\n\n const itemRectY = useSharedValue<number>(0);\n const itemRectX = useSharedValue<number>(0);\n const itemRectWidth = useSharedValue<number>(0);\n const itemRectHeight = useSharedValue<number>(0);\n const itemScale = useSharedValue<number>(1);\n const transformValue = useSharedValue<number>(0);\n\n const transformOrigin = useSharedValue<TransformOriginAnchorPosition>(\n menuAnchorPosition || 'top-right'\n );\n\n const key = useMemo(() => `hold-item-${nanoid()}`, []);\n const menuHeight = useMemo(() => {\n const itemsWithSeparator = items.filter(item => item.withSeparator);\n return calculateMenuHeight(items.length, itemsWithSeparator.length);\n }, [items]);\n\n const isHold = !activateOn || activateOn === 'hold';\n //#endregion\n\n //#region refs\n const containerRef = useAnimatedRef<Animated.View>();\n //#endregion\n\n //#region functions\n const hapticResponse = () => {\n const style = !hapticFeedback ? 'Medium' : hapticFeedback;\n switch (style) {\n case `Selection`:\n Haptics.selectionAsync();\n break;\n case `Light`:\n case `Medium`:\n case `Heavy`:\n Haptics.impactAsync(Haptics.ImpactFeedbackStyle[style]);\n break;\n case `Success`:\n case `Warning`:\n case `Error`:\n Haptics.notificationAsync(Haptics.NotificationFeedbackType[style]);\n break;\n default:\n }\n };\n //#endregion\n\n //#region worklet functions\n const activateAnimation = (ctx: any) => {\n 'worklet';\n if (!ctx.didMeasureLayout) {\n const measured = measure(containerRef);\n\n itemRectY.value = measured.pageY;\n itemRectX.value = measured.pageX;\n itemRectHeight.value = measured.height;\n itemRectWidth.value = measured.width;\n\n if (!menuAnchorPosition) {\n const position = getTransformOrigin(\n measured.pageX,\n itemRectWidth.value,\n deviceOrientation === 'portrait' ? WINDOW_WIDTH : WINDOW_HEIGHT,\n bottom\n );\n transformOrigin.value = position;\n }\n }\n };\n\n const calculateTransformValue = () => {\n 'worklet';\n\n const height =\n deviceOrientation === 'portrait' ? WINDOW_HEIGHT : WINDOW_WIDTH;\n\n const isAnchorPointTop = itemRectY.value > WINDOW_HEIGHT / 2;\n\n let tY = 0;\n if (!disableMove) {\n if (isAnchorPointTop) {\n const topTransform =\n itemRectY.value +\n itemRectHeight.value +\n menuHeight +\n styleGuide.spacing +\n (safeAreaInsets?.bottom || 0);\n\n tY = topTransform > height ? height - topTransform : 0;\n } else {\n const bottomTransform =\n itemRectY.value - menuHeight - (safeAreaInsets?.top || 0);\n tY =\n bottomTransform < 0 ? -bottomTransform + styleGuide.spacing * 2 : 0;\n }\n }\n return tY;\n };\n\n const setMenuProps = () => {\n 'worklet';\n\n menuProps.value = {\n itemHeight: itemRectHeight.value,\n itemWidth: itemRectWidth.value,\n itemY: itemRectY.value,\n itemX: itemRectX.value,\n anchorPosition: transformOrigin.value,\n menuHeight: menuHeight,\n items,\n transformValue: transformValue.value,\n actionParams: actionParams || {},\n };\n };\n\n const scaleBack = () => {\n 'worklet';\n itemScale.value = withTiming(1, {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n });\n };\n\n const setContentRenderer = () => {\n contentRenderer.current = renderContent || null;\n };\n\n const onCompletion = (isFinised?: boolean) => {\n 'worklet';\n const isListValid = true;\n // items && items.length > 0;\n if (isFinised && isListValid) {\n state.value = CONTEXT_MENU_STATE.ACTIVE;\n isActive.value = true;\n scaleBack();\n runOnJS(setContentRenderer)();\n if (hapticFeedback !== 'None') {\n runOnJS(hapticResponse)();\n }\n }\n\n isAnimationStarted.value = false;\n\n // TODO: Warn user if item list is empty or not given\n };\n\n const scaleHold = () => {\n 'worklet';\n itemScale.value = withTiming(\n HOLD_ITEM_SCALE_DOWN_VALUE,\n { duration: HOLD_ITEM_SCALE_DOWN_DURATION },\n onCompletion\n );\n };\n\n const scaleTap = () => {\n 'worklet';\n isAnimationStarted.value = true;\n\n itemScale.value = withSequence(\n withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {\n duration: HOLD_ITEM_SCALE_DOWN_DURATION,\n }),\n withTiming(\n 1,\n {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n },\n onCompletion\n )\n );\n };\n\n /**\n * When use tap activation (\"tap\") and trying to tap multiple times,\n * scale animation is called again despite it is started. This causes a bug.\n * To prevent this, it is better to check is animation already started.\n */\n const canCallActivateFunctions = () => {\n 'worklet';\n const willActivateWithTap =\n activateOn === 'double-tap' || activateOn === 'tap';\n\n return (\n (willActivateWithTap && !isAnimationStarted.value) || !willActivateWithTap\n );\n };\n //#endregion\n\n //#region gesture events\n const gestureEvent = useAnimatedGestureHandler<\n LongPressGestureHandlerGestureEvent | TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: (_, context) => {\n if (canCallActivateFunctions()) {\n if (!context.didMeasureLayout) {\n activateAnimation(context);\n transformValue.value = calculateTransformValue();\n setMenuProps();\n context.didMeasureLayout = true;\n }\n\n if (!isActive.value) {\n if (isHold) {\n scaleHold();\n } else {\n scaleTap();\n }\n }\n }\n },\n onFinish: (_, context) => {\n context.didMeasureLayout = false;\n if (isHold) {\n scaleBack();\n }\n },\n });\n\n const overlayGestureEvent = useAnimatedGestureHandler<\n TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: _ => {\n if (closeOnTap) state.value = CONTEXT_MENU_STATE.END;\n },\n });\n //#endregion\n\n //#region animated styles & props\n const animatedContainerStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(1, { duration: 0 }));\n\n return {\n opacity: isActive.value ? 0 : animateOpacity(),\n transform: [\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const containerStyle = React.useMemo(\n () => [containerStyles, animatedContainerStyle],\n [containerStyles, animatedContainerStyle]\n );\n\n const animatedPortalStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(0, { duration: 0 }));\n\n let tY = calculateTransformValue();\n const transformAnimation = () =>\n disableMove\n ? 0\n : isActive.value\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(-0.1, { duration: HOLD_ITEM_TRANSFORM_DURATION });\n\n return {\n zIndex: 10,\n position: 'absolute',\n top: itemRectY.value,\n left: itemRectX.value,\n width: itemRectWidth.value,\n height: itemRectHeight.value,\n opacity: isActive.value ? 1 : animateOpacity(),\n transform: [\n {\n translateY: transformAnimation(),\n },\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const portalContainerStyle = useMemo(\n () => [styles.holdItem, animatedPortalStyle],\n [animatedPortalStyle]\n );\n\n const animatedPortalProps = useAnimatedProps<ViewProps>(() => ({\n pointerEvents: isActive.value ? 'auto' : 'none',\n }));\n //#endregion\n\n //#region animated effects\n useAnimatedReaction(\n () => state.value,\n _state => {\n if (_state === CONTEXT_MENU_STATE.END) {\n isActive.value = false;\n }\n }\n );\n //#endregion\n\n //#region components\n const GestureHandler = useMemo(() => {\n switch (activateOn) {\n case `double-tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={2}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n case `tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n // default is hold\n default:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <LongPressGestureHandler\n minDurationMs={longPressMinDurationMs}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </LongPressGestureHandler>\n );\n }\n }, [activateOn, gestureEvent]);\n\n const PortalOverlay = useMemo(() => {\n return () => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={overlayGestureEvent}\n >\n <Animated.View style={styles.portalOverlay} />\n </TapGestureHandler>\n );\n }, [overlayGestureEvent]);\n //#endregion\n\n //#region render\n return (\n <>\n <GestureHandler>\n <Animated.View ref={containerRef} style={containerStyle}>\n {children}\n </Animated.View>\n </GestureHandler>\n\n <Portal key={key} name={key}>\n <Animated.View\n key={key}\n style={portalContainerStyle}\n animatedProps={animatedPortalProps}\n >\n <PortalOverlay />\n {children}\n </Animated.View>\n </Portal>\n </>\n );\n //#endregion\n};\n\nconst HoldItem = memo(HoldItemComponent) as React.FC<HoldItemProps>;\n\nexport default HoldItem;\n"]}
@@ -17,27 +17,34 @@ function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return
17
17
 
18
18
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
19
 
20
- const Content = ({
21
- renderContent
22
- }) => {
20
+ const Content = () => {
23
21
  const {
24
22
  state,
25
- menuProps
23
+ menuProps,
24
+ contentRenderer
26
25
  } = (0, _hooks.useInternal)();
27
- const [isActive, setIsActive] = (0, _react.useState)(false); // синхронизируем Reanimated state → React state
26
+ const [isActive, setIsActive] = (0, _react.useState)(false);
27
+ const contentHeight = (0, _reactNativeReanimated.useSharedValue)(0);
28
+ const handleLayout = (0, _react.useCallback)(event => {
29
+ contentHeight.value = event.nativeEvent.layout.height;
30
+ }, [contentHeight]); // синхронизируем Reanimated state → React state
28
31
 
29
32
  (0, _reactNativeReanimated.useAnimatedReaction)(() => state.value, val => {
30
33
  (0, _reactNativeReanimated.runOnJS)(setIsActive)(val === _constants.CONTEXT_MENU_STATE.ACTIVE);
31
34
  });
35
+ const renderContent = contentRenderer.current;
32
36
  const wrapperStyles = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
33
37
  const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
34
- const top = anchorPositionVertical === 'top' ? menuProps.value.itemY - 24 : menuProps.value.itemY + menuProps.value.itemHeight + 8;
35
- const left = menuProps.value.itemX;
38
+ const anchorPositionHorizontal = menuProps.value.anchorPosition.split('-')[1];
39
+ const top = anchorPositionVertical === 'top' ? menuProps.value.itemY - contentHeight.value - 8 : menuProps.value.itemY + menuProps.value.itemHeight + 8;
40
+ const left = anchorPositionHorizontal === 'center' ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3 : anchorPositionHorizontal === 'right' ? undefined : menuProps.value.itemX;
41
+ const right = anchorPositionHorizontal === 'right' ? 0 : undefined;
36
42
  const tY = menuProps.value.transformValue;
37
43
  return {
38
44
  opacity: state.value === _constants.CONTEXT_MENU_STATE.ACTIVE ? (0, _reactNativeReanimated.withTiming)(1) : (0, _reactNativeReanimated.withTiming)(0),
39
45
  top,
40
46
  left,
47
+ right,
41
48
  transform: [{
42
49
  translateY: state.value === _constants.CONTEXT_MENU_STATE.ACTIVE ? (0, _reactNativeReanimated.withSpring)(tY, _constants.SPRING_CONFIGURATION) : (0, _reactNativeReanimated.withTiming)(0, {
43
50
  duration: _constants.HOLD_ITEM_TRANSFORM_DURATION
@@ -51,6 +58,7 @@ const Content = ({
51
58
  }
52
59
 
53
60
  return /*#__PURE__*/_react.default.createElement(_reactNativeReanimated.default.View, {
61
+ onLayout: handleLayout,
54
62
  style: [{
55
63
  position: 'absolute',
56
64
  left: 0,
@@ -1 +1 @@
1
- {"version":3,"sources":["Content.tsx"],"names":["Content","renderContent","state","menuProps","isActive","setIsActive","value","val","CONTEXT_MENU_STATE","ACTIVE","wrapperStyles","anchorPositionVertical","anchorPosition","split","top","itemY","itemHeight","left","itemX","tY","transformValue","opacity","transform","translateY","SPRING_CONFIGURATION","duration","HOLD_ITEM_TRANSFORM_DURATION","position","zIndex"],"mappings":";;;;;;;AAAA;;AACA;;AAOA;;AACA;;;;;;AAMA,MAAMA,OAAO,GAAG,CAAC;AACfC,EAAAA;AADe,CAAD,KAIV;AACJ,QAAM;AAAEC,IAAAA,KAAF;AAASC,IAAAA;AAAT,MAAuB,yBAA7B;AACA,QAAM,CAACC,QAAD,EAAWC,WAAX,IAA0B,qBAAS,KAAT,CAAhC,CAFI,CAIJ;;AACA,kDACE,MAAMH,KAAK,CAACI,KADd,EAEEC,GAAG,IAAI;AACL,wCAAQF,WAAR,EAAqBE,GAAG,KAAKC,8BAAmBC,MAAhD;AACD,GAJH;AAMA,QAAMC,aAAa,GAAG,6CAAiB,MAAM;AAC3C,UAAMC,sBAAsB,GAAGR,SAAS,CAACG,KAAV,CAAgBM,cAAhB,CAA+BC,KAA/B,CAAqC,GAArC,EAA0C,CAA1C,CAA/B;AAEA,UAAMC,GAAG,GACPH,sBAAsB,KAAK,KAA3B,GACIR,SAAS,CAACG,KAAV,CAAgBS,KAAhB,GAAwB,EAD5B,GAEIZ,SAAS,CAACG,KAAV,CAAgBS,KAAhB,GAAwBZ,SAAS,CAACG,KAAV,CAAgBU,UAAxC,GAAqD,CAH3D;AAKA,UAAMC,IAAI,GAAGd,SAAS,CAACG,KAAV,CAAgBY,KAA7B;AACA,UAAMC,EAAE,GAAGhB,SAAS,CAACG,KAAV,CAAgBc,cAA3B;AACA,WAAO;AACLC,MAAAA,OAAO,EACLnB,KAAK,CAACI,KAAN,KAAgBE,8BAAmBC,MAAnC,GACI,uCAAW,CAAX,CADJ,GAEI,uCAAW,CAAX,CAJD;AAKLK,MAAAA,GALK;AAMLG,MAAAA,IANK;AAOLK,MAAAA,SAAS,EAAE,CACT;AACEC,QAAAA,UAAU,EACRrB,KAAK,CAACI,KAAN,KAAgBE,8BAAmBC,MAAnC,GACI,uCAAWU,EAAX,EAAeK,+BAAf,CADJ,GAEI,uCAAW,CAAX,EAAc;AAAEC,UAAAA,QAAQ,EAAEC;AAAZ,SAAd;AAJR,OADS;AAPN,KAAP;AAgBD,GA1BqB,EA0BnB,CAACvB,SAAD,CA1BmB,CAAtB;;AA2BA,MAAI,CAACF,aAAL,EAAoB;AAClB,WAAO,IAAP;AACD;;AACD,sBACE,6BAAC,8BAAD,CAAU,IAAV;AACE,IAAA,KAAK,EAAE,CAAC;AAAE0B,MAAAA,QAAQ,EAAE,UAAZ;AAAwBV,MAAAA,IAAI,EAAE,CAA9B;AAAiCW,MAAAA,MAAM,EAAE;AAAzC,KAAD,EAAgDlB,aAAhD;AADT,KAGGN,QAAQ,IAAIH,aAAa,EAH5B,CADF;AAOD,CApDD;;eAsDeD,O","sourcesContent":["import React, { useState } from 'react';\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\nimport { useInternal } from '../../hooks';\nimport {\n CONTEXT_MENU_STATE,\n HOLD_ITEM_TRANSFORM_DURATION,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst Content = ({\n renderContent,\n}: {\n renderContent?: () => React.ReactNode;\n}) => {\n const { state, menuProps } = useInternal();\n const [isActive, setIsActive] = useState(false);\n\n // синхронизируем Reanimated state → React state\n useAnimatedReaction(\n () => state.value,\n val => {\n runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);\n }\n );\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemY - 24\n : menuProps.value.itemY + menuProps.value.itemHeight + 8;\n\n const left = menuProps.value.itemX;\n const tY = menuProps.value.transformValue;\n return {\n opacity:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withTiming(1)\n : withTiming(0),\n top,\n left,\n transform: [\n {\n translateY:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),\n },\n ],\n };\n }, [menuProps]);\n if (!renderContent) {\n return null;\n }\n return (\n <Animated.View\n style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}\n >\n {isActive && renderContent()}\n </Animated.View>\n );\n};\n\nexport default Content;\n"]}
1
+ {"version":3,"sources":["Content.tsx"],"names":["Content","state","menuProps","contentRenderer","isActive","setIsActive","contentHeight","handleLayout","event","value","nativeEvent","layout","height","val","CONTEXT_MENU_STATE","ACTIVE","renderContent","current","wrapperStyles","anchorPositionVertical","anchorPosition","split","anchorPositionHorizontal","top","itemY","itemHeight","left","itemX","itemWidth","undefined","right","tY","transformValue","opacity","transform","translateY","SPRING_CONFIGURATION","duration","HOLD_ITEM_TRANSFORM_DURATION","position","zIndex"],"mappings":"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","sourcesContent":["import React, { useCallback, useState } from 'react';\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n useSharedValue,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\nimport type { LayoutChangeEvent } from 'react-native';\nimport { useInternal } from '../../hooks';\nimport {\n CONTEXT_MENU_STATE,\n HOLD_ITEM_TRANSFORM_DURATION,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst Content = () => {\n const { state, menuProps, contentRenderer } = useInternal();\n const [isActive, setIsActive] = useState(false);\n const contentHeight = useSharedValue(0);\n\n const handleLayout = useCallback(\n (event: LayoutChangeEvent) => {\n contentHeight.value = event.nativeEvent.layout.height;\n },\n [contentHeight]\n );\n\n // синхронизируем Reanimated state → React state\n useAnimatedReaction(\n () => state.value,\n val => {\n runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);\n }\n );\n\n const renderContent = contentRenderer.current;\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n const anchorPositionHorizontal = menuProps.value.anchorPosition.split(\n '-'\n )[1];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemY - contentHeight.value - 8\n : menuProps.value.itemY + menuProps.value.itemHeight + 8;\n\n const left =\n anchorPositionHorizontal === 'center'\n ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3\n : anchorPositionHorizontal === 'right'\n ? undefined\n : menuProps.value.itemX;\n const right = anchorPositionHorizontal === 'right' ? 0 : undefined;\n\n const tY = menuProps.value.transformValue;\n return {\n opacity:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withTiming(1)\n : withTiming(0),\n top,\n left,\n right,\n transform: [\n {\n translateY:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),\n },\n ],\n };\n }, [menuProps]);\n if (!renderContent) {\n return null;\n }\n return (\n <Animated.View\n onLayout={handleLayout}\n style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}\n >\n {isActive && renderContent()}\n </Animated.View>\n );\n};\n\nexport default Content;\n"]}
@@ -40,8 +40,7 @@ const ProviderComponent = ({
40
40
  iconComponent,
41
41
  safeAreaInsets,
42
42
  onOpen,
43
- onClose,
44
- renderContent
43
+ onClose
45
44
  }) => {
46
45
  if (iconComponent) exports.AnimatedIcon = AnimatedIcon = _reactNativeReanimated.default.createAnimatedComponent(iconComponent);
47
46
  const state = (0, _reactNativeReanimated.useSharedValue)(_constants.CONTEXT_MENU_STATE.UNDETERMINED);
@@ -57,6 +56,7 @@ const ProviderComponent = ({
57
56
  transformValue: 0,
58
57
  actionParams: {}
59
58
  });
59
+ const contentRenderer = (0, _react.useRef)(null);
60
60
  (0, _react.useEffect)(() => {
61
61
  theme.value = selectedTheme || 'light'; // eslint-disable-next-line react-hooks/exhaustive-deps
62
62
  }, [selectedTheme]);
@@ -79,6 +79,7 @@ const ProviderComponent = ({
79
79
  state,
80
80
  theme,
81
81
  menuProps,
82
+ contentRenderer,
82
83
  safeAreaInsets: safeAreaInsets || {
83
84
  top: 0,
84
85
  bottom: 0,
@@ -92,9 +93,7 @@ const ProviderComponent = ({
92
93
  }
93
94
  }, /*#__PURE__*/_react.default.createElement(_internal.InternalContext.Provider, {
94
95
  value: internalContextVariables
95
- }, /*#__PURE__*/_react.default.createElement(_portal.PortalProvider, null, children, /*#__PURE__*/_react.default.createElement(_backdrop.Backdrop, null), /*#__PURE__*/_react.default.createElement(_menu.default, null), /*#__PURE__*/_react.default.createElement(_Content.default, {
96
- renderContent: renderContent
97
- }))));
96
+ }, /*#__PURE__*/_react.default.createElement(_portal.PortalProvider, null, children, /*#__PURE__*/_react.default.createElement(_backdrop.Backdrop, null), /*#__PURE__*/_react.default.createElement(_menu.default, null), /*#__PURE__*/_react.default.createElement(_Content.default, null))));
98
97
  };
99
98
 
100
99
  const Provider = /*#__PURE__*/(0, _react.memo)(ProviderComponent);
@@ -1 +1 @@
1
- {"version":3,"sources":["Provider.tsx"],"names":["AnimatedIcon","ProviderComponent","children","theme","selectedTheme","iconComponent","safeAreaInsets","onOpen","onClose","renderContent","Animated","createAnimatedComponent","state","CONTEXT_MENU_STATE","UNDETERMINED","menuProps","itemHeight","itemWidth","itemX","itemY","items","anchorPosition","menuHeight","transformValue","actionParams","value","ACTIVE","END","internalContextVariables","top","bottom","left","right","flex","Provider"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AAKA;;AAGA;;AAGA;;AAGA;;AAEA;;AACA;;;;;;;;AAVA;AAGA;AAcO,IAAIA,YAAJ;;;AAEP,MAAMC,iBAAkD,GAAG,CAAC;AAC1DC,EAAAA,QAD0D;AAE1DC,EAAAA,KAAK,EAAEC,aAFmD;AAG1DC,EAAAA,aAH0D;AAI1DC,EAAAA,cAJ0D;AAK1DC,EAAAA,MAL0D;AAM1DC,EAAAA,OAN0D;AAO1DC,EAAAA;AAP0D,CAAD,KAQrD;AACJ,MAAIJ,aAAJ,EACE,uBAAAL,YAAY,GAAGU,+BAASC,uBAAT,CAAiCN,aAAjC,CAAf;AAEF,QAAMO,KAAK,GAAG,2CACZC,8BAAmBC,YADP,CAAd;AAGA,QAAMX,KAAK,GAAG,2CAAiCC,aAAa,IAAI,OAAlD,CAAd;AACA,QAAMW,SAAS,GAAG,2CAAkC;AAClDC,IAAAA,UAAU,EAAE,CADsC;AAElDC,IAAAA,SAAS,EAAE,CAFuC;AAGlDC,IAAAA,KAAK,EAAE,CAH2C;AAIlDC,IAAAA,KAAK,EAAE,CAJ2C;AAKlDC,IAAAA,KAAK,EAAE,EAL2C;AAMlDC,IAAAA,cAAc,EAAE,YANkC;AAOlDC,IAAAA,UAAU,EAAE,CAPsC;AAQlDC,IAAAA,cAAc,EAAE,CARkC;AASlDC,IAAAA,YAAY,EAAE;AAToC,GAAlC,CAAlB;AAYA,wBAAU,MAAM;AACdrB,IAAAA,KAAK,CAACsB,KAAN,GAAcrB,aAAa,IAAI,OAA/B,CADc,CAEd;AACD,GAHD,EAGG,CAACA,aAAD,CAHH;AAKA,kDACE,MAAMQ,KAAK,CAACa,KADd,EAEEb,KAAK,IAAI;AACP,YAAQA,KAAR;AACE,WAAKC,8BAAmBa,MAAxB;AAAgC;AAC9B,cAAInB,MAAJ,EAAY,oCAAQA,MAAR;AACZ;AACD;;AACD,WAAKM,8BAAmBc,GAAxB;AAA6B;AAC3B,cAAInB,OAAJ,EAAa,oCAAQA,OAAR;AACb;AACD;AARH;AAUD,GAbH,EAcE,CAACI,KAAD,CAdF;AAiBA,QAAMgB,wBAAwB,GAAG,oBAC/B,OAAO;AACLhB,IAAAA,KADK;AAELT,IAAAA,KAFK;AAGLY,IAAAA,SAHK;AAILT,IAAAA,cAAc,EAAEA,cAAc,IAAI;AAChCuB,MAAAA,GAAG,EAAE,CAD2B;AAEhCC,MAAAA,MAAM,EAAE,CAFwB;AAGhCC,MAAAA,IAAI,EAAE,CAH0B;AAIhCC,MAAAA,KAAK,EAAE;AAJyB;AAJ7B,GAAP,CAD+B,EAY/B,CAACpB,KAAD,EAAQT,KAAR,EAAeY,SAAf,EAA0BT,cAA1B,CAZ+B,CAAjC;AAeA,sBACE,6BAAC,iDAAD;AAAwB,IAAA,KAAK,EAAE;AAAE2B,MAAAA,IAAI,EAAE;AAAR;AAA/B,kBACE,6BAAC,yBAAD,CAAiB,QAAjB;AAA0B,IAAA,KAAK,EAAEL;AAAjC,kBACE,6BAAC,sBAAD,QACG1B,QADH,eAEE,6BAAC,kBAAD,OAFF,eAGE,6BAAC,aAAD,OAHF,eAIE,6BAAC,gBAAD;AAAS,IAAA,aAAa,EAAEO;AAAxB,IAJF,CADF,CADF,CADF;AAYD,CA7ED;;AA+EA,MAAMyB,QAAQ,gBAAG,iBAAKjC,iBAAL,CAAjB;eAEeiC,Q","sourcesContent":["import React, { memo, useEffect, useMemo } from 'react';\nimport { PortalProvider } from '@gorhom/portal';\nimport Animated, {\n useSharedValue,\n useAnimatedReaction,\n runOnJS,\n} from 'react-native-reanimated';\nimport { GestureHandlerRootView } from 'react-native-gesture-handler';\n\n// Components\nimport { Backdrop } from '../backdrop';\n\n// Utils\nimport { InternalContext } from '../../context/internal';\nimport { HoldMenuProviderProps } from './types';\nimport { StateProps, Action } from './reducer';\nimport { CONTEXT_MENU_STATE } from '../../constants';\nimport { MenuInternalProps } from '../menu/types';\nimport Menu from '../menu';\nimport Content from './Content';\n\nexport interface Store {\n state: StateProps;\n dispatch?: React.Dispatch<Action>;\n}\n\nexport let AnimatedIcon: any;\n\nconst ProviderComponent: React.FC<HoldMenuProviderProps> = ({\n children,\n theme: selectedTheme,\n iconComponent,\n safeAreaInsets,\n onOpen,\n onClose,\n renderContent,\n}) => {\n if (iconComponent)\n AnimatedIcon = Animated.createAnimatedComponent(iconComponent);\n\n const state = useSharedValue<CONTEXT_MENU_STATE>(\n CONTEXT_MENU_STATE.UNDETERMINED\n );\n const theme = useSharedValue<'light' | 'dark'>(selectedTheme || 'light');\n const menuProps = useSharedValue<MenuInternalProps>({\n itemHeight: 0,\n itemWidth: 0,\n itemX: 0,\n itemY: 0,\n items: [],\n anchorPosition: 'top-center',\n menuHeight: 0,\n transformValue: 0,\n actionParams: {},\n });\n\n useEffect(() => {\n theme.value = selectedTheme || 'light';\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedTheme]);\n\n useAnimatedReaction(\n () => state.value,\n state => {\n switch (state) {\n case CONTEXT_MENU_STATE.ACTIVE: {\n if (onOpen) runOnJS(onOpen)();\n break;\n }\n case CONTEXT_MENU_STATE.END: {\n if (onClose) runOnJS(onClose)();\n break;\n }\n }\n },\n [state]\n );\n\n const internalContextVariables = useMemo(\n () => ({\n state,\n theme,\n menuProps,\n safeAreaInsets: safeAreaInsets || {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n }),\n [state, theme, menuProps, safeAreaInsets]\n );\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <InternalContext.Provider value={internalContextVariables}>\n <PortalProvider>\n {children}\n <Backdrop />\n <Menu />\n <Content renderContent={renderContent} />\n </PortalProvider>\n </InternalContext.Provider>\n </GestureHandlerRootView>\n );\n};\n\nconst Provider = memo(ProviderComponent) as React.FC<HoldMenuProviderProps>;\n\nexport default Provider;\n"]}
1
+ {"version":3,"sources":["Provider.tsx"],"names":["AnimatedIcon","ProviderComponent","children","theme","selectedTheme","iconComponent","safeAreaInsets","onOpen","onClose","Animated","createAnimatedComponent","state","CONTEXT_MENU_STATE","UNDETERMINED","menuProps","itemHeight","itemWidth","itemX","itemY","items","anchorPosition","menuHeight","transformValue","actionParams","contentRenderer","value","ACTIVE","END","internalContextVariables","top","bottom","left","right","flex","Provider"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AAKA;;AAGA;;AAGA;;AAGA;;AAEA;;AACA;;;;;;;;AAVA;AAGA;AAcO,IAAIA,YAAJ;;;AAEP,MAAMC,iBAAkD,GAAG,CAAC;AAC1DC,EAAAA,QAD0D;AAE1DC,EAAAA,KAAK,EAAEC,aAFmD;AAG1DC,EAAAA,aAH0D;AAI1DC,EAAAA,cAJ0D;AAK1DC,EAAAA,MAL0D;AAM1DC,EAAAA;AAN0D,CAAD,KAOrD;AACJ,MAAIH,aAAJ,EACE,uBAAAL,YAAY,GAAGS,+BAASC,uBAAT,CAAiCL,aAAjC,CAAf;AAEF,QAAMM,KAAK,GAAG,2CACZC,8BAAmBC,YADP,CAAd;AAGA,QAAMV,KAAK,GAAG,2CAAiCC,aAAa,IAAI,OAAlD,CAAd;AACA,QAAMU,SAAS,GAAG,2CAAkC;AAClDC,IAAAA,UAAU,EAAE,CADsC;AAElDC,IAAAA,SAAS,EAAE,CAFuC;AAGlDC,IAAAA,KAAK,EAAE,CAH2C;AAIlDC,IAAAA,KAAK,EAAE,CAJ2C;AAKlDC,IAAAA,KAAK,EAAE,EAL2C;AAMlDC,IAAAA,cAAc,EAAE,YANkC;AAOlDC,IAAAA,UAAU,EAAE,CAPsC;AAQlDC,IAAAA,cAAc,EAAE,CARkC;AASlDC,IAAAA,YAAY,EAAE;AAToC,GAAlC,CAAlB;AAWA,QAAMC,eAAe,GAAG,mBAAuC,IAAvC,CAAxB;AAEA,wBAAU,MAAM;AACdrB,IAAAA,KAAK,CAACsB,KAAN,GAAcrB,aAAa,IAAI,OAA/B,CADc,CAEd;AACD,GAHD,EAGG,CAACA,aAAD,CAHH;AAKA,kDACE,MAAMO,KAAK,CAACc,KADd,EAEEd,KAAK,IAAI;AACP,YAAQA,KAAR;AACE,WAAKC,8BAAmBc,MAAxB;AAAgC;AAC9B,cAAInB,MAAJ,EAAY,oCAAQA,MAAR;AACZ;AACD;;AACD,WAAKK,8BAAmBe,GAAxB;AAA6B;AAC3B,cAAInB,OAAJ,EAAa,oCAAQA,OAAR;AACb;AACD;AARH;AAUD,GAbH,EAcE,CAACG,KAAD,CAdF;AAiBA,QAAMiB,wBAAwB,GAAG,oBAC/B,OAAO;AACLjB,IAAAA,KADK;AAELR,IAAAA,KAFK;AAGLW,IAAAA,SAHK;AAILU,IAAAA,eAJK;AAKLlB,IAAAA,cAAc,EAAEA,cAAc,IAAI;AAChCuB,MAAAA,GAAG,EAAE,CAD2B;AAEhCC,MAAAA,MAAM,EAAE,CAFwB;AAGhCC,MAAAA,IAAI,EAAE,CAH0B;AAIhCC,MAAAA,KAAK,EAAE;AAJyB;AAL7B,GAAP,CAD+B,EAa/B,CAACrB,KAAD,EAAQR,KAAR,EAAeW,SAAf,EAA0BR,cAA1B,CAb+B,CAAjC;AAgBA,sBACE,6BAAC,iDAAD;AAAwB,IAAA,KAAK,EAAE;AAAE2B,MAAAA,IAAI,EAAE;AAAR;AAA/B,kBACE,6BAAC,yBAAD,CAAiB,QAAjB;AAA0B,IAAA,KAAK,EAAEL;AAAjC,kBACE,6BAAC,sBAAD,QACG1B,QADH,eAEE,6BAAC,kBAAD,OAFF,eAGE,6BAAC,aAAD,OAHF,eAIE,6BAAC,gBAAD,OAJF,CADF,CADF,CADF;AAYD,CA9ED;;AAgFA,MAAMgC,QAAQ,gBAAG,iBAAKjC,iBAAL,CAAjB;eAEeiC,Q","sourcesContent":["import React, { memo, useEffect, useMemo, useRef } from 'react';\nimport { PortalProvider } from '@gorhom/portal';\nimport Animated, {\n useSharedValue,\n useAnimatedReaction,\n runOnJS,\n} from 'react-native-reanimated';\nimport { GestureHandlerRootView } from 'react-native-gesture-handler';\n\n// Components\nimport { Backdrop } from '../backdrop';\n\n// Utils\nimport { InternalContext } from '../../context/internal';\nimport { HoldMenuProviderProps } from './types';\nimport { StateProps, Action } from './reducer';\nimport { CONTEXT_MENU_STATE } from '../../constants';\nimport { MenuInternalProps } from '../menu/types';\nimport Menu from '../menu';\nimport Content from './Content';\n\nexport interface Store {\n state: StateProps;\n dispatch?: React.Dispatch<Action>;\n}\n\nexport let AnimatedIcon: any;\n\nconst ProviderComponent: React.FC<HoldMenuProviderProps> = ({\n children,\n theme: selectedTheme,\n iconComponent,\n safeAreaInsets,\n onOpen,\n onClose,\n}) => {\n if (iconComponent)\n AnimatedIcon = Animated.createAnimatedComponent(iconComponent);\n\n const state = useSharedValue<CONTEXT_MENU_STATE>(\n CONTEXT_MENU_STATE.UNDETERMINED\n );\n const theme = useSharedValue<'light' | 'dark'>(selectedTheme || 'light');\n const menuProps = useSharedValue<MenuInternalProps>({\n itemHeight: 0,\n itemWidth: 0,\n itemX: 0,\n itemY: 0,\n items: [],\n anchorPosition: 'top-center',\n menuHeight: 0,\n transformValue: 0,\n actionParams: {},\n });\n const contentRenderer = useRef<(() => React.ReactNode) | null>(null);\n\n useEffect(() => {\n theme.value = selectedTheme || 'light';\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedTheme]);\n\n useAnimatedReaction(\n () => state.value,\n state => {\n switch (state) {\n case CONTEXT_MENU_STATE.ACTIVE: {\n if (onOpen) runOnJS(onOpen)();\n break;\n }\n case CONTEXT_MENU_STATE.END: {\n if (onClose) runOnJS(onClose)();\n break;\n }\n }\n },\n [state]\n );\n\n const internalContextVariables = useMemo(\n () => ({\n state,\n theme,\n menuProps,\n contentRenderer,\n safeAreaInsets: safeAreaInsets || {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n }),\n [state, theme, menuProps, safeAreaInsets]\n );\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <InternalContext.Provider value={internalContextVariables}>\n <PortalProvider>\n {children}\n <Backdrop />\n <Menu />\n <Content />\n </PortalProvider>\n </InternalContext.Provider>\n </GestureHandlerRootView>\n );\n};\n\nconst Provider = memo(ProviderComponent) as React.FC<HoldMenuProviderProps>;\n\nexport default Provider;\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["internal.ts"],"names":["InternalContext"],"mappings":";;;;;;;AAAA;;AAiBA;AACO,MAAMA,eAAe,gBAAG,2BAAxB","sourcesContent":["import { createContext } from 'react';\nimport type Animated from 'react-native-reanimated';\nimport type { CONTEXT_MENU_STATE } from '../constants';\nimport { MenuInternalProps } from '../components/menu/types';\n\nexport type InternalContextType = {\n state: Animated.SharedValue<CONTEXT_MENU_STATE>;\n theme: Animated.SharedValue<'light' | 'dark'>;\n menuProps: Animated.SharedValue<MenuInternalProps>;\n safeAreaInsets?: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n};\n\n// @ts-ignore\nexport const InternalContext = createContext<InternalContextType>();\n"]}
1
+ {"version":3,"sources":["internal.ts"],"names":["InternalContext"],"mappings":";;;;;;;AAAA;;AAuBA;AACO,MAAMA,eAAe,gBAAG,2BAAxB","sourcesContent":["import { createContext } from 'react';\nimport type { MutableRefObject } from 'react';\nimport type Animated from 'react-native-reanimated';\nimport type { CONTEXT_MENU_STATE } from '../constants';\nimport { MenuInternalProps } from '../components/menu/types';\n\nexport type ContentRendererRef = MutableRefObject<\n (() => React.ReactNode) | null\n>;\n\nexport type InternalContextType = {\n state: Animated.SharedValue<CONTEXT_MENU_STATE>;\n theme: Animated.SharedValue<'light' | 'dark'>;\n menuProps: Animated.SharedValue<MenuInternalProps>;\n contentRenderer: ContentRendererRef;\n safeAreaInsets?: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n};\n\n// @ts-ignore\nexport const InternalContext = createContext<InternalContextType>();\n"]}
@@ -14,10 +14,11 @@ import { HOLD_ITEM_TRANSFORM_DURATION, HOLD_ITEM_SCALE_DOWN_DURATION, HOLD_ITEM_
14
14
  import { useDeviceOrientation } from '../../hooks';
15
15
  import styles from './styles';
16
16
  import styleGuide from '../../styleGuide';
17
- import { useInternal } from '../../hooks'; //#endregion
17
+ import { useInternal } from '../../hooks';
18
+ const defaultItems = [];
18
19
 
19
20
  const HoldItemComponent = ({
20
- items,
21
+ items = defaultItems,
21
22
  bottom,
22
23
  containerStyles,
23
24
  disableMove,
@@ -27,13 +28,15 @@ const HoldItemComponent = ({
27
28
  actionParams,
28
29
  closeOnTap,
29
30
  longPressMinDurationMs = 150,
30
- children
31
+ children,
32
+ renderContent
31
33
  }) => {
32
34
  //#region hooks
33
35
  const {
34
36
  state,
35
37
  menuProps,
36
- safeAreaInsets
38
+ safeAreaInsets,
39
+ contentRenderer
37
40
  } = useInternal();
38
41
  const deviceOrientation = useDeviceOrientation(); //#endregion
39
42
  //#region variables
@@ -145,15 +148,20 @@ const HoldItemComponent = ({
145
148
  });
146
149
  };
147
150
 
151
+ const setContentRenderer = () => {
152
+ contentRenderer.current = renderContent || null;
153
+ };
154
+
148
155
  const onCompletion = isFinised => {
149
156
  'worklet';
150
157
 
151
- const isListValid = items && items.length > 0;
158
+ const isListValid = true; // items && items.length > 0;
152
159
 
153
160
  if (isFinised && isListValid) {
154
161
  state.value = CONTEXT_MENU_STATE.ACTIVE;
155
162
  isActive.value = true;
156
163
  scaleBack();
164
+ runOnJS(setContentRenderer)();
157
165
 
158
166
  if (hapticFeedback !== 'None') {
159
167
  runOnJS(hapticResponse)();
@@ -1 +1 @@
1
- {"version":3,"sources":["HoldItem.tsx"],"names":["React","memo","useMemo","TapGestureHandler","LongPressGestureHandler","Animated","measure","runOnJS","useAnimatedGestureHandler","useAnimatedProps","useAnimatedRef","useAnimatedStyle","useSharedValue","withDelay","withTiming","withSequence","withSpring","useAnimatedReaction","Portal","nanoid","Haptics","getTransformOrigin","calculateMenuHeight","HOLD_ITEM_TRANSFORM_DURATION","HOLD_ITEM_SCALE_DOWN_DURATION","HOLD_ITEM_SCALE_DOWN_VALUE","SPRING_CONFIGURATION","WINDOW_HEIGHT","WINDOW_WIDTH","CONTEXT_MENU_STATE","useDeviceOrientation","styles","styleGuide","useInternal","HoldItemComponent","items","bottom","containerStyles","disableMove","menuAnchorPosition","activateOn","hapticFeedback","actionParams","closeOnTap","longPressMinDurationMs","children","state","menuProps","safeAreaInsets","deviceOrientation","isActive","isAnimationStarted","itemRectY","itemRectX","itemRectWidth","itemRectHeight","itemScale","transformValue","transformOrigin","key","menuHeight","itemsWithSeparator","filter","item","withSeparator","length","isHold","containerRef","hapticResponse","style","selectionAsync","impactAsync","ImpactFeedbackStyle","notificationAsync","NotificationFeedbackType","activateAnimation","ctx","didMeasureLayout","measured","value","pageY","pageX","height","width","position","calculateTransformValue","isAnchorPointTop","tY","topTransform","spacing","bottomTransform","top","setMenuProps","itemHeight","itemWidth","itemY","itemX","anchorPosition","scaleBack","duration","onCompletion","isFinised","isListValid","ACTIVE","scaleHold","scaleTap","canCallActivateFunctions","willActivateWithTap","gestureEvent","onActive","_","context","onFinish","overlayGestureEvent","END","animatedContainerStyle","animateOpacity","opacity","transform","scale","containerStyle","animatedPortalStyle","transformAnimation","zIndex","left","translateY","portalContainerStyle","holdItem","animatedPortalProps","pointerEvents","_state","GestureHandler","handlerChildren","PortalOverlay","portalOverlay","HoldItem"],"mappings":"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","sourcesContent":["import React, { memo, useMemo } from 'react';\nimport { ViewProps } from 'react-native';\n\n//#region reanimated & gesture handler\nimport {\n TapGestureHandler,\n LongPressGestureHandler,\n TapGestureHandlerGestureEvent,\n LongPressGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n measure,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedProps,\n useAnimatedRef,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withTiming,\n withSequence,\n withSpring,\n useAnimatedReaction,\n} from 'react-native-reanimated';\n//#endregion\n\n//#region dependencies\nimport { Portal } from '@gorhom/portal';\nimport { nanoid } from 'nanoid/non-secure';\nimport * as Haptics from 'expo-haptics';\n//#endregion\n\n//#region utils & types\nimport {\n TransformOriginAnchorPosition,\n getTransformOrigin,\n calculateMenuHeight,\n} from '../../utils/calculations';\nimport {\n HOLD_ITEM_TRANSFORM_DURATION,\n HOLD_ITEM_SCALE_DOWN_DURATION,\n HOLD_ITEM_SCALE_DOWN_VALUE,\n SPRING_CONFIGURATION,\n WINDOW_HEIGHT,\n WINDOW_WIDTH,\n CONTEXT_MENU_STATE,\n} from '../../constants';\nimport { useDeviceOrientation } from '../../hooks';\nimport styles from './styles';\n\nimport type { HoldItemProps, GestureHandlerProps } from './types';\nimport styleGuide from '../../styleGuide';\nimport { useInternal } from '../../hooks';\n//#endregion\n\ntype Context = { didMeasureLayout: boolean };\n\nconst HoldItemComponent: React.FC<HoldItemProps> = ({\n items,\n bottom,\n containerStyles,\n disableMove,\n menuAnchorPosition,\n activateOn,\n hapticFeedback,\n actionParams,\n closeOnTap,\n longPressMinDurationMs = 150,\n children,\n}) => {\n //#region hooks\n const { state, menuProps, safeAreaInsets } = useInternal();\n const deviceOrientation = useDeviceOrientation();\n //#endregion\n\n //#region variables\n const isActive = useSharedValue(false);\n const isAnimationStarted = useSharedValue(false);\n\n const itemRectY = useSharedValue<number>(0);\n const itemRectX = useSharedValue<number>(0);\n const itemRectWidth = useSharedValue<number>(0);\n const itemRectHeight = useSharedValue<number>(0);\n const itemScale = useSharedValue<number>(1);\n const transformValue = useSharedValue<number>(0);\n\n const transformOrigin = useSharedValue<TransformOriginAnchorPosition>(\n menuAnchorPosition || 'top-right'\n );\n\n const key = useMemo(() => `hold-item-${nanoid()}`, []);\n const menuHeight = useMemo(() => {\n const itemsWithSeparator = items.filter(item => item.withSeparator);\n return calculateMenuHeight(items.length, itemsWithSeparator.length);\n }, [items]);\n\n const isHold = !activateOn || activateOn === 'hold';\n //#endregion\n\n //#region refs\n const containerRef = useAnimatedRef<Animated.View>();\n //#endregion\n\n //#region functions\n const hapticResponse = () => {\n const style = !hapticFeedback ? 'Medium' : hapticFeedback;\n switch (style) {\n case `Selection`:\n Haptics.selectionAsync();\n break;\n case `Light`:\n case `Medium`:\n case `Heavy`:\n Haptics.impactAsync(Haptics.ImpactFeedbackStyle[style]);\n break;\n case `Success`:\n case `Warning`:\n case `Error`:\n Haptics.notificationAsync(Haptics.NotificationFeedbackType[style]);\n break;\n default:\n }\n };\n //#endregion\n\n //#region worklet functions\n const activateAnimation = (ctx: any) => {\n 'worklet';\n if (!ctx.didMeasureLayout) {\n const measured = measure(containerRef);\n\n itemRectY.value = measured.pageY;\n itemRectX.value = measured.pageX;\n itemRectHeight.value = measured.height;\n itemRectWidth.value = measured.width;\n\n if (!menuAnchorPosition) {\n const position = getTransformOrigin(\n measured.pageX,\n itemRectWidth.value,\n deviceOrientation === 'portrait' ? WINDOW_WIDTH : WINDOW_HEIGHT,\n bottom\n );\n transformOrigin.value = position;\n }\n }\n };\n\n const calculateTransformValue = () => {\n 'worklet';\n\n const height =\n deviceOrientation === 'portrait' ? WINDOW_HEIGHT : WINDOW_WIDTH;\n\n const isAnchorPointTop = itemRectY.value > WINDOW_HEIGHT / 2;\n\n let tY = 0;\n if (!disableMove) {\n if (isAnchorPointTop) {\n const topTransform =\n itemRectY.value +\n itemRectHeight.value +\n menuHeight +\n styleGuide.spacing +\n (safeAreaInsets?.bottom || 0);\n\n tY = topTransform > height ? height - topTransform : 0;\n } else {\n const bottomTransform =\n itemRectY.value - menuHeight - (safeAreaInsets?.top || 0);\n tY =\n bottomTransform < 0 ? -bottomTransform + styleGuide.spacing * 2 : 0;\n }\n }\n return tY;\n };\n\n const setMenuProps = () => {\n 'worklet';\n\n menuProps.value = {\n itemHeight: itemRectHeight.value,\n itemWidth: itemRectWidth.value,\n itemY: itemRectY.value,\n itemX: itemRectX.value,\n anchorPosition: transformOrigin.value,\n menuHeight: menuHeight,\n items,\n transformValue: transformValue.value,\n actionParams: actionParams || {},\n };\n };\n\n const scaleBack = () => {\n 'worklet';\n itemScale.value = withTiming(1, {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n });\n };\n\n const onCompletion = (isFinised?: boolean) => {\n 'worklet';\n const isListValid = items && items.length > 0;\n if (isFinised && isListValid) {\n state.value = CONTEXT_MENU_STATE.ACTIVE;\n isActive.value = true;\n scaleBack();\n if (hapticFeedback !== 'None') {\n runOnJS(hapticResponse)();\n }\n }\n\n isAnimationStarted.value = false;\n\n // TODO: Warn user if item list is empty or not given\n };\n\n const scaleHold = () => {\n 'worklet';\n itemScale.value = withTiming(\n HOLD_ITEM_SCALE_DOWN_VALUE,\n { duration: HOLD_ITEM_SCALE_DOWN_DURATION },\n onCompletion\n );\n };\n\n const scaleTap = () => {\n 'worklet';\n isAnimationStarted.value = true;\n\n itemScale.value = withSequence(\n withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {\n duration: HOLD_ITEM_SCALE_DOWN_DURATION,\n }),\n withTiming(\n 1,\n {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n },\n onCompletion\n )\n );\n };\n\n /**\n * When use tap activation (\"tap\") and trying to tap multiple times,\n * scale animation is called again despite it is started. This causes a bug.\n * To prevent this, it is better to check is animation already started.\n */\n const canCallActivateFunctions = () => {\n 'worklet';\n const willActivateWithTap =\n activateOn === 'double-tap' || activateOn === 'tap';\n\n return (\n (willActivateWithTap && !isAnimationStarted.value) || !willActivateWithTap\n );\n };\n //#endregion\n\n //#region gesture events\n const gestureEvent = useAnimatedGestureHandler<\n LongPressGestureHandlerGestureEvent | TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: (_, context) => {\n if (canCallActivateFunctions()) {\n if (!context.didMeasureLayout) {\n activateAnimation(context);\n transformValue.value = calculateTransformValue();\n setMenuProps();\n context.didMeasureLayout = true;\n }\n\n if (!isActive.value) {\n if (isHold) {\n scaleHold();\n } else {\n scaleTap();\n }\n }\n }\n },\n onFinish: (_, context) => {\n context.didMeasureLayout = false;\n if (isHold) {\n scaleBack();\n }\n },\n });\n\n const overlayGestureEvent = useAnimatedGestureHandler<\n TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: _ => {\n if (closeOnTap) state.value = CONTEXT_MENU_STATE.END;\n },\n });\n //#endregion\n\n //#region animated styles & props\n const animatedContainerStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(1, { duration: 0 }));\n\n return {\n opacity: isActive.value ? 0 : animateOpacity(),\n transform: [\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const containerStyle = React.useMemo(\n () => [containerStyles, animatedContainerStyle],\n [containerStyles, animatedContainerStyle]\n );\n\n const animatedPortalStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(0, { duration: 0 }));\n\n let tY = calculateTransformValue();\n const transformAnimation = () =>\n disableMove\n ? 0\n : isActive.value\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(-0.1, { duration: HOLD_ITEM_TRANSFORM_DURATION });\n\n return {\n zIndex: 10,\n position: 'absolute',\n top: itemRectY.value,\n left: itemRectX.value,\n width: itemRectWidth.value,\n height: itemRectHeight.value,\n opacity: isActive.value ? 1 : animateOpacity(),\n transform: [\n {\n translateY: transformAnimation(),\n },\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const portalContainerStyle = useMemo(\n () => [styles.holdItem, animatedPortalStyle],\n [animatedPortalStyle]\n );\n\n const animatedPortalProps = useAnimatedProps<ViewProps>(() => ({\n pointerEvents: isActive.value ? 'auto' : 'none',\n }));\n //#endregion\n\n //#region animated effects\n useAnimatedReaction(\n () => state.value,\n _state => {\n if (_state === CONTEXT_MENU_STATE.END) {\n isActive.value = false;\n }\n }\n );\n //#endregion\n\n //#region components\n const GestureHandler = useMemo(() => {\n switch (activateOn) {\n case `double-tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={2}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n case `tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n // default is hold\n default:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <LongPressGestureHandler\n minDurationMs={longPressMinDurationMs}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </LongPressGestureHandler>\n );\n }\n }, [activateOn, gestureEvent]);\n\n const PortalOverlay = useMemo(() => {\n return () => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={overlayGestureEvent}\n >\n <Animated.View style={styles.portalOverlay} />\n </TapGestureHandler>\n );\n }, [overlayGestureEvent]);\n //#endregion\n\n //#region render\n return (\n <>\n <GestureHandler>\n <Animated.View ref={containerRef} style={containerStyle}>\n {children}\n </Animated.View>\n </GestureHandler>\n\n <Portal key={key} name={key}>\n <Animated.View\n key={key}\n style={portalContainerStyle}\n animatedProps={animatedPortalProps}\n >\n <PortalOverlay />\n {children}\n </Animated.View>\n </Portal>\n </>\n );\n //#endregion\n};\n\nconst HoldItem = memo(HoldItemComponent) as React.FC<HoldItemProps>;\n\nexport default HoldItem;\n"]}
1
+ {"version":3,"sources":["HoldItem.tsx"],"names":["React","memo","useMemo","TapGestureHandler","LongPressGestureHandler","Animated","measure","runOnJS","useAnimatedGestureHandler","useAnimatedProps","useAnimatedRef","useAnimatedStyle","useSharedValue","withDelay","withTiming","withSequence","withSpring","useAnimatedReaction","Portal","nanoid","Haptics","getTransformOrigin","calculateMenuHeight","HOLD_ITEM_TRANSFORM_DURATION","HOLD_ITEM_SCALE_DOWN_DURATION","HOLD_ITEM_SCALE_DOWN_VALUE","SPRING_CONFIGURATION","WINDOW_HEIGHT","WINDOW_WIDTH","CONTEXT_MENU_STATE","useDeviceOrientation","styles","styleGuide","useInternal","defaultItems","HoldItemComponent","items","bottom","containerStyles","disableMove","menuAnchorPosition","activateOn","hapticFeedback","actionParams","closeOnTap","longPressMinDurationMs","children","renderContent","state","menuProps","safeAreaInsets","contentRenderer","deviceOrientation","isActive","isAnimationStarted","itemRectY","itemRectX","itemRectWidth","itemRectHeight","itemScale","transformValue","transformOrigin","key","menuHeight","itemsWithSeparator","filter","item","withSeparator","length","isHold","containerRef","hapticResponse","style","selectionAsync","impactAsync","ImpactFeedbackStyle","notificationAsync","NotificationFeedbackType","activateAnimation","ctx","didMeasureLayout","measured","value","pageY","pageX","height","width","position","calculateTransformValue","isAnchorPointTop","tY","topTransform","spacing","bottomTransform","top","setMenuProps","itemHeight","itemWidth","itemY","itemX","anchorPosition","scaleBack","duration","setContentRenderer","current","onCompletion","isFinised","isListValid","ACTIVE","scaleHold","scaleTap","canCallActivateFunctions","willActivateWithTap","gestureEvent","onActive","_","context","onFinish","overlayGestureEvent","END","animatedContainerStyle","animateOpacity","opacity","transform","scale","containerStyle","animatedPortalStyle","transformAnimation","zIndex","left","translateY","portalContainerStyle","holdItem","animatedPortalProps","pointerEvents","_state","GestureHandler","handlerChildren","PortalOverlay","portalOverlay","HoldItem"],"mappings":"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","sourcesContent":["import React, { memo, useMemo } from 'react';\nimport { ViewProps } from 'react-native';\n\n//#region reanimated & gesture handler\nimport {\n TapGestureHandler,\n LongPressGestureHandler,\n TapGestureHandlerGestureEvent,\n LongPressGestureHandlerGestureEvent,\n} from 'react-native-gesture-handler';\nimport Animated, {\n measure,\n runOnJS,\n useAnimatedGestureHandler,\n useAnimatedProps,\n useAnimatedRef,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withTiming,\n withSequence,\n withSpring,\n useAnimatedReaction,\n} from 'react-native-reanimated';\n//#endregion\n\n//#region dependencies\nimport { Portal } from '@gorhom/portal';\nimport { nanoid } from 'nanoid/non-secure';\nimport * as Haptics from 'expo-haptics';\n//#endregion\n\n//#region utils & types\nimport {\n TransformOriginAnchorPosition,\n getTransformOrigin,\n calculateMenuHeight,\n} from '../../utils/calculations';\nimport {\n HOLD_ITEM_TRANSFORM_DURATION,\n HOLD_ITEM_SCALE_DOWN_DURATION,\n HOLD_ITEM_SCALE_DOWN_VALUE,\n SPRING_CONFIGURATION,\n WINDOW_HEIGHT,\n WINDOW_WIDTH,\n CONTEXT_MENU_STATE,\n} from '../../constants';\nimport { useDeviceOrientation } from '../../hooks';\nimport styles from './styles';\n\nimport type { HoldItemProps, GestureHandlerProps } from './types';\nimport styleGuide from '../../styleGuide';\nimport { useInternal } from '../../hooks';\nimport { MenuItemProps } from '../menu/types';\n//#endregion\n\ntype Context = { didMeasureLayout: boolean };\nconst defaultItems = [] as MenuItemProps[];\nconst HoldItemComponent: React.FC<HoldItemProps> = ({\n items = defaultItems,\n bottom,\n containerStyles,\n disableMove,\n menuAnchorPosition,\n activateOn,\n hapticFeedback,\n actionParams,\n closeOnTap,\n longPressMinDurationMs = 150,\n children,\n renderContent,\n}) => {\n //#region hooks\n const { state, menuProps, safeAreaInsets, contentRenderer } = useInternal();\n const deviceOrientation = useDeviceOrientation();\n //#endregion\n\n //#region variables\n const isActive = useSharedValue(false);\n const isAnimationStarted = useSharedValue(false);\n\n const itemRectY = useSharedValue<number>(0);\n const itemRectX = useSharedValue<number>(0);\n const itemRectWidth = useSharedValue<number>(0);\n const itemRectHeight = useSharedValue<number>(0);\n const itemScale = useSharedValue<number>(1);\n const transformValue = useSharedValue<number>(0);\n\n const transformOrigin = useSharedValue<TransformOriginAnchorPosition>(\n menuAnchorPosition || 'top-right'\n );\n\n const key = useMemo(() => `hold-item-${nanoid()}`, []);\n const menuHeight = useMemo(() => {\n const itemsWithSeparator = items.filter(item => item.withSeparator);\n return calculateMenuHeight(items.length, itemsWithSeparator.length);\n }, [items]);\n\n const isHold = !activateOn || activateOn === 'hold';\n //#endregion\n\n //#region refs\n const containerRef = useAnimatedRef<Animated.View>();\n //#endregion\n\n //#region functions\n const hapticResponse = () => {\n const style = !hapticFeedback ? 'Medium' : hapticFeedback;\n switch (style) {\n case `Selection`:\n Haptics.selectionAsync();\n break;\n case `Light`:\n case `Medium`:\n case `Heavy`:\n Haptics.impactAsync(Haptics.ImpactFeedbackStyle[style]);\n break;\n case `Success`:\n case `Warning`:\n case `Error`:\n Haptics.notificationAsync(Haptics.NotificationFeedbackType[style]);\n break;\n default:\n }\n };\n //#endregion\n\n //#region worklet functions\n const activateAnimation = (ctx: any) => {\n 'worklet';\n if (!ctx.didMeasureLayout) {\n const measured = measure(containerRef);\n\n itemRectY.value = measured.pageY;\n itemRectX.value = measured.pageX;\n itemRectHeight.value = measured.height;\n itemRectWidth.value = measured.width;\n\n if (!menuAnchorPosition) {\n const position = getTransformOrigin(\n measured.pageX,\n itemRectWidth.value,\n deviceOrientation === 'portrait' ? WINDOW_WIDTH : WINDOW_HEIGHT,\n bottom\n );\n transformOrigin.value = position;\n }\n }\n };\n\n const calculateTransformValue = () => {\n 'worklet';\n\n const height =\n deviceOrientation === 'portrait' ? WINDOW_HEIGHT : WINDOW_WIDTH;\n\n const isAnchorPointTop = itemRectY.value > WINDOW_HEIGHT / 2;\n\n let tY = 0;\n if (!disableMove) {\n if (isAnchorPointTop) {\n const topTransform =\n itemRectY.value +\n itemRectHeight.value +\n menuHeight +\n styleGuide.spacing +\n (safeAreaInsets?.bottom || 0);\n\n tY = topTransform > height ? height - topTransform : 0;\n } else {\n const bottomTransform =\n itemRectY.value - menuHeight - (safeAreaInsets?.top || 0);\n tY =\n bottomTransform < 0 ? -bottomTransform + styleGuide.spacing * 2 : 0;\n }\n }\n return tY;\n };\n\n const setMenuProps = () => {\n 'worklet';\n\n menuProps.value = {\n itemHeight: itemRectHeight.value,\n itemWidth: itemRectWidth.value,\n itemY: itemRectY.value,\n itemX: itemRectX.value,\n anchorPosition: transformOrigin.value,\n menuHeight: menuHeight,\n items,\n transformValue: transformValue.value,\n actionParams: actionParams || {},\n };\n };\n\n const scaleBack = () => {\n 'worklet';\n itemScale.value = withTiming(1, {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n });\n };\n\n const setContentRenderer = () => {\n contentRenderer.current = renderContent || null;\n };\n\n const onCompletion = (isFinised?: boolean) => {\n 'worklet';\n const isListValid = true;\n // items && items.length > 0;\n if (isFinised && isListValid) {\n state.value = CONTEXT_MENU_STATE.ACTIVE;\n isActive.value = true;\n scaleBack();\n runOnJS(setContentRenderer)();\n if (hapticFeedback !== 'None') {\n runOnJS(hapticResponse)();\n }\n }\n\n isAnimationStarted.value = false;\n\n // TODO: Warn user if item list is empty or not given\n };\n\n const scaleHold = () => {\n 'worklet';\n itemScale.value = withTiming(\n HOLD_ITEM_SCALE_DOWN_VALUE,\n { duration: HOLD_ITEM_SCALE_DOWN_DURATION },\n onCompletion\n );\n };\n\n const scaleTap = () => {\n 'worklet';\n isAnimationStarted.value = true;\n\n itemScale.value = withSequence(\n withTiming(HOLD_ITEM_SCALE_DOWN_VALUE, {\n duration: HOLD_ITEM_SCALE_DOWN_DURATION,\n }),\n withTiming(\n 1,\n {\n duration: HOLD_ITEM_TRANSFORM_DURATION / 2,\n },\n onCompletion\n )\n );\n };\n\n /**\n * When use tap activation (\"tap\") and trying to tap multiple times,\n * scale animation is called again despite it is started. This causes a bug.\n * To prevent this, it is better to check is animation already started.\n */\n const canCallActivateFunctions = () => {\n 'worklet';\n const willActivateWithTap =\n activateOn === 'double-tap' || activateOn === 'tap';\n\n return (\n (willActivateWithTap && !isAnimationStarted.value) || !willActivateWithTap\n );\n };\n //#endregion\n\n //#region gesture events\n const gestureEvent = useAnimatedGestureHandler<\n LongPressGestureHandlerGestureEvent | TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: (_, context) => {\n if (canCallActivateFunctions()) {\n if (!context.didMeasureLayout) {\n activateAnimation(context);\n transformValue.value = calculateTransformValue();\n setMenuProps();\n context.didMeasureLayout = true;\n }\n\n if (!isActive.value) {\n if (isHold) {\n scaleHold();\n } else {\n scaleTap();\n }\n }\n }\n },\n onFinish: (_, context) => {\n context.didMeasureLayout = false;\n if (isHold) {\n scaleBack();\n }\n },\n });\n\n const overlayGestureEvent = useAnimatedGestureHandler<\n TapGestureHandlerGestureEvent,\n Context\n >({\n onActive: _ => {\n if (closeOnTap) state.value = CONTEXT_MENU_STATE.END;\n },\n });\n //#endregion\n\n //#region animated styles & props\n const animatedContainerStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(1, { duration: 0 }));\n\n return {\n opacity: isActive.value ? 0 : animateOpacity(),\n transform: [\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const containerStyle = React.useMemo(\n () => [containerStyles, animatedContainerStyle],\n [containerStyles, animatedContainerStyle]\n );\n\n const animatedPortalStyle = useAnimatedStyle(() => {\n const animateOpacity = () =>\n withDelay(HOLD_ITEM_TRANSFORM_DURATION, withTiming(0, { duration: 0 }));\n\n let tY = calculateTransformValue();\n const transformAnimation = () =>\n disableMove\n ? 0\n : isActive.value\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(-0.1, { duration: HOLD_ITEM_TRANSFORM_DURATION });\n\n return {\n zIndex: 10,\n position: 'absolute',\n top: itemRectY.value,\n left: itemRectX.value,\n width: itemRectWidth.value,\n height: itemRectHeight.value,\n opacity: isActive.value ? 1 : animateOpacity(),\n transform: [\n {\n translateY: transformAnimation(),\n },\n {\n scale: isActive.value\n ? withTiming(1, { duration: HOLD_ITEM_TRANSFORM_DURATION })\n : itemScale.value,\n },\n ],\n };\n });\n const portalContainerStyle = useMemo(\n () => [styles.holdItem, animatedPortalStyle],\n [animatedPortalStyle]\n );\n\n const animatedPortalProps = useAnimatedProps<ViewProps>(() => ({\n pointerEvents: isActive.value ? 'auto' : 'none',\n }));\n //#endregion\n\n //#region animated effects\n useAnimatedReaction(\n () => state.value,\n _state => {\n if (_state === CONTEXT_MENU_STATE.END) {\n isActive.value = false;\n }\n }\n );\n //#endregion\n\n //#region components\n const GestureHandler = useMemo(() => {\n switch (activateOn) {\n case `double-tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={2}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n case `tap`:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </TapGestureHandler>\n );\n // default is hold\n default:\n return ({ children: handlerChildren }: GestureHandlerProps) => (\n <LongPressGestureHandler\n minDurationMs={longPressMinDurationMs}\n onHandlerStateChange={gestureEvent}\n >\n {handlerChildren}\n </LongPressGestureHandler>\n );\n }\n }, [activateOn, gestureEvent]);\n\n const PortalOverlay = useMemo(() => {\n return () => (\n <TapGestureHandler\n numberOfTaps={1}\n onHandlerStateChange={overlayGestureEvent}\n >\n <Animated.View style={styles.portalOverlay} />\n </TapGestureHandler>\n );\n }, [overlayGestureEvent]);\n //#endregion\n\n //#region render\n return (\n <>\n <GestureHandler>\n <Animated.View ref={containerRef} style={containerStyle}>\n {children}\n </Animated.View>\n </GestureHandler>\n\n <Portal key={key} name={key}>\n <Animated.View\n key={key}\n style={portalContainerStyle}\n animatedProps={animatedPortalProps}\n >\n <PortalOverlay />\n {children}\n </Animated.View>\n </Portal>\n </>\n );\n //#endregion\n};\n\nconst HoldItem = memo(HoldItemComponent) as React.FC<HoldItemProps>;\n\nexport default HoldItem;\n"]}
@@ -1,29 +1,36 @@
1
- import React, { useState } from 'react';
2
- import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, withSpring, withTiming } from 'react-native-reanimated';
1
+ import React, { useCallback, useState } from 'react';
2
+ import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
3
3
  import { useInternal } from '../../hooks';
4
4
  import { CONTEXT_MENU_STATE, HOLD_ITEM_TRANSFORM_DURATION, SPRING_CONFIGURATION } from '../../constants';
5
5
 
6
- const Content = ({
7
- renderContent
8
- }) => {
6
+ const Content = () => {
9
7
  const {
10
8
  state,
11
- menuProps
9
+ menuProps,
10
+ contentRenderer
12
11
  } = useInternal();
13
- const [isActive, setIsActive] = useState(false); // синхронизируем Reanimated state → React state
12
+ const [isActive, setIsActive] = useState(false);
13
+ const contentHeight = useSharedValue(0);
14
+ const handleLayout = useCallback(event => {
15
+ contentHeight.value = event.nativeEvent.layout.height;
16
+ }, [contentHeight]); // синхронизируем Reanimated state → React state
14
17
 
15
18
  useAnimatedReaction(() => state.value, val => {
16
19
  runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);
17
20
  });
21
+ const renderContent = contentRenderer.current;
18
22
  const wrapperStyles = useAnimatedStyle(() => {
19
23
  const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
20
- const top = anchorPositionVertical === 'top' ? menuProps.value.itemY - 24 : menuProps.value.itemY + menuProps.value.itemHeight + 8;
21
- const left = menuProps.value.itemX;
24
+ const anchorPositionHorizontal = menuProps.value.anchorPosition.split('-')[1];
25
+ const top = anchorPositionVertical === 'top' ? menuProps.value.itemY - contentHeight.value - 8 : menuProps.value.itemY + menuProps.value.itemHeight + 8;
26
+ const left = anchorPositionHorizontal === 'center' ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3 : anchorPositionHorizontal === 'right' ? undefined : menuProps.value.itemX;
27
+ const right = anchorPositionHorizontal === 'right' ? 0 : undefined;
22
28
  const tY = menuProps.value.transformValue;
23
29
  return {
24
30
  opacity: state.value === CONTEXT_MENU_STATE.ACTIVE ? withTiming(1) : withTiming(0),
25
31
  top,
26
32
  left,
33
+ right,
27
34
  transform: [{
28
35
  translateY: state.value === CONTEXT_MENU_STATE.ACTIVE ? withSpring(tY, SPRING_CONFIGURATION) : withTiming(0, {
29
36
  duration: HOLD_ITEM_TRANSFORM_DURATION
@@ -37,6 +44,7 @@ const Content = ({
37
44
  }
38
45
 
39
46
  return /*#__PURE__*/React.createElement(Animated.View, {
47
+ onLayout: handleLayout,
40
48
  style: [{
41
49
  position: 'absolute',
42
50
  left: 0,
@@ -1 +1 @@
1
- {"version":3,"sources":["Content.tsx"],"names":["React","useState","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","withSpring","withTiming","useInternal","CONTEXT_MENU_STATE","HOLD_ITEM_TRANSFORM_DURATION","SPRING_CONFIGURATION","Content","renderContent","state","menuProps","isActive","setIsActive","value","val","ACTIVE","wrapperStyles","anchorPositionVertical","anchorPosition","split","top","itemY","itemHeight","left","itemX","tY","transformValue","opacity","transform","translateY","duration","position","zIndex"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,QAAhB,QAAgC,OAAhC;AACA,OAAOC,QAAP,IACEC,OADF,EAEEC,mBAFF,EAGEC,gBAHF,EAIEC,UAJF,EAKEC,UALF,QAMO,yBANP;AAOA,SAASC,WAAT,QAA4B,aAA5B;AACA,SACEC,kBADF,EAEEC,4BAFF,EAGEC,oBAHF,QAIO,iBAJP;;AAMA,MAAMC,OAAO,GAAG,CAAC;AACfC,EAAAA;AADe,CAAD,KAIV;AACJ,QAAM;AAAEC,IAAAA,KAAF;AAASC,IAAAA;AAAT,MAAuBP,WAAW,EAAxC;AACA,QAAM,CAACQ,QAAD,EAAWC,WAAX,IAA0BhB,QAAQ,CAAC,KAAD,CAAxC,CAFI,CAIJ;;AACAG,EAAAA,mBAAmB,CACjB,MAAMU,KAAK,CAACI,KADK,EAEjBC,GAAG,IAAI;AACLhB,IAAAA,OAAO,CAACc,WAAD,CAAP,CAAqBE,GAAG,KAAKV,kBAAkB,CAACW,MAAhD;AACD,GAJgB,CAAnB;AAMA,QAAMC,aAAa,GAAGhB,gBAAgB,CAAC,MAAM;AAC3C,UAAMiB,sBAAsB,GAAGP,SAAS,CAACG,KAAV,CAAgBK,cAAhB,CAA+BC,KAA/B,CAAqC,GAArC,EAA0C,CAA1C,CAA/B;AAEA,UAAMC,GAAG,GACPH,sBAAsB,KAAK,KAA3B,GACIP,SAAS,CAACG,KAAV,CAAgBQ,KAAhB,GAAwB,EAD5B,GAEIX,SAAS,CAACG,KAAV,CAAgBQ,KAAhB,GAAwBX,SAAS,CAACG,KAAV,CAAgBS,UAAxC,GAAqD,CAH3D;AAKA,UAAMC,IAAI,GAAGb,SAAS,CAACG,KAAV,CAAgBW,KAA7B;AACA,UAAMC,EAAE,GAAGf,SAAS,CAACG,KAAV,CAAgBa,cAA3B;AACA,WAAO;AACLC,MAAAA,OAAO,EACLlB,KAAK,CAACI,KAAN,KAAgBT,kBAAkB,CAACW,MAAnC,GACIb,UAAU,CAAC,CAAD,CADd,GAEIA,UAAU,CAAC,CAAD,CAJX;AAKLkB,MAAAA,GALK;AAMLG,MAAAA,IANK;AAOLK,MAAAA,SAAS,EAAE,CACT;AACEC,QAAAA,UAAU,EACRpB,KAAK,CAACI,KAAN,KAAgBT,kBAAkB,CAACW,MAAnC,GACId,UAAU,CAACwB,EAAD,EAAKnB,oBAAL,CADd,GAEIJ,UAAU,CAAC,CAAD,EAAI;AAAE4B,UAAAA,QAAQ,EAAEzB;AAAZ,SAAJ;AAJlB,OADS;AAPN,KAAP;AAgBD,GA1BqC,EA0BnC,CAACK,SAAD,CA1BmC,CAAtC;;AA2BA,MAAI,CAACF,aAAL,EAAoB;AAClB,WAAO,IAAP;AACD;;AACD,sBACE,oBAAC,QAAD,CAAU,IAAV;AACE,IAAA,KAAK,EAAE,CAAC;AAAEuB,MAAAA,QAAQ,EAAE,UAAZ;AAAwBR,MAAAA,IAAI,EAAE,CAA9B;AAAiCS,MAAAA,MAAM,EAAE;AAAzC,KAAD,EAAgDhB,aAAhD;AADT,KAGGL,QAAQ,IAAIH,aAAa,EAH5B,CADF;AAOD,CApDD;;AAsDA,eAAeD,OAAf","sourcesContent":["import React, { useState } from 'react';\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\nimport { useInternal } from '../../hooks';\nimport {\n CONTEXT_MENU_STATE,\n HOLD_ITEM_TRANSFORM_DURATION,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst Content = ({\n renderContent,\n}: {\n renderContent?: () => React.ReactNode;\n}) => {\n const { state, menuProps } = useInternal();\n const [isActive, setIsActive] = useState(false);\n\n // синхронизируем Reanimated state → React state\n useAnimatedReaction(\n () => state.value,\n val => {\n runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);\n }\n );\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemY - 24\n : menuProps.value.itemY + menuProps.value.itemHeight + 8;\n\n const left = menuProps.value.itemX;\n const tY = menuProps.value.transformValue;\n return {\n opacity:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withTiming(1)\n : withTiming(0),\n top,\n left,\n transform: [\n {\n translateY:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),\n },\n ],\n };\n }, [menuProps]);\n if (!renderContent) {\n return null;\n }\n return (\n <Animated.View\n style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}\n >\n {isActive && renderContent()}\n </Animated.View>\n );\n};\n\nexport default Content;\n"]}
1
+ {"version":3,"sources":["Content.tsx"],"names":["React","useCallback","useState","Animated","runOnJS","useAnimatedReaction","useAnimatedStyle","useSharedValue","withSpring","withTiming","useInternal","CONTEXT_MENU_STATE","HOLD_ITEM_TRANSFORM_DURATION","SPRING_CONFIGURATION","Content","state","menuProps","contentRenderer","isActive","setIsActive","contentHeight","handleLayout","event","value","nativeEvent","layout","height","val","ACTIVE","renderContent","current","wrapperStyles","anchorPositionVertical","anchorPosition","split","anchorPositionHorizontal","top","itemY","itemHeight","left","itemX","itemWidth","undefined","right","tY","transformValue","opacity","transform","translateY","duration","position","zIndex"],"mappings":"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","sourcesContent":["import React, { useCallback, useState } from 'react';\nimport Animated, {\n runOnJS,\n useAnimatedReaction,\n useAnimatedStyle,\n useSharedValue,\n withSpring,\n withTiming,\n} from 'react-native-reanimated';\nimport type { LayoutChangeEvent } from 'react-native';\nimport { useInternal } from '../../hooks';\nimport {\n CONTEXT_MENU_STATE,\n HOLD_ITEM_TRANSFORM_DURATION,\n SPRING_CONFIGURATION,\n} from '../../constants';\n\nconst Content = () => {\n const { state, menuProps, contentRenderer } = useInternal();\n const [isActive, setIsActive] = useState(false);\n const contentHeight = useSharedValue(0);\n\n const handleLayout = useCallback(\n (event: LayoutChangeEvent) => {\n contentHeight.value = event.nativeEvent.layout.height;\n },\n [contentHeight]\n );\n\n // синхронизируем Reanimated state → React state\n useAnimatedReaction(\n () => state.value,\n val => {\n runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);\n }\n );\n\n const renderContent = contentRenderer.current;\n const wrapperStyles = useAnimatedStyle(() => {\n const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];\n const anchorPositionHorizontal = menuProps.value.anchorPosition.split(\n '-'\n )[1];\n\n const top =\n anchorPositionVertical === 'top'\n ? menuProps.value.itemY - contentHeight.value - 8\n : menuProps.value.itemY + menuProps.value.itemHeight + 8;\n\n const left =\n anchorPositionHorizontal === 'center'\n ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3\n : anchorPositionHorizontal === 'right'\n ? undefined\n : menuProps.value.itemX;\n const right = anchorPositionHorizontal === 'right' ? 0 : undefined;\n\n const tY = menuProps.value.transformValue;\n return {\n opacity:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withTiming(1)\n : withTiming(0),\n top,\n left,\n right,\n transform: [\n {\n translateY:\n state.value === CONTEXT_MENU_STATE.ACTIVE\n ? withSpring(tY, SPRING_CONFIGURATION)\n : withTiming(0, { duration: HOLD_ITEM_TRANSFORM_DURATION }),\n },\n ],\n };\n }, [menuProps]);\n if (!renderContent) {\n return null;\n }\n return (\n <Animated.View\n onLayout={handleLayout}\n style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}\n >\n {isActive && renderContent()}\n </Animated.View>\n );\n};\n\nexport default Content;\n"]}
@@ -1,4 +1,4 @@
1
- import React, { memo, useEffect, useMemo } from 'react';
1
+ import React, { memo, useEffect, useMemo, useRef } from 'react';
2
2
  import { PortalProvider } from '@gorhom/portal';
3
3
  import Animated, { useSharedValue, useAnimatedReaction, runOnJS } from 'react-native-reanimated';
4
4
  import { GestureHandlerRootView } from 'react-native-gesture-handler'; // Components
@@ -17,8 +17,7 @@ const ProviderComponent = ({
17
17
  iconComponent,
18
18
  safeAreaInsets,
19
19
  onOpen,
20
- onClose,
21
- renderContent
20
+ onClose
22
21
  }) => {
23
22
  if (iconComponent) AnimatedIcon = Animated.createAnimatedComponent(iconComponent);
24
23
  const state = useSharedValue(CONTEXT_MENU_STATE.UNDETERMINED);
@@ -34,6 +33,7 @@ const ProviderComponent = ({
34
33
  transformValue: 0,
35
34
  actionParams: {}
36
35
  });
36
+ const contentRenderer = useRef(null);
37
37
  useEffect(() => {
38
38
  theme.value = selectedTheme || 'light'; // eslint-disable-next-line react-hooks/exhaustive-deps
39
39
  }, [selectedTheme]);
@@ -56,6 +56,7 @@ const ProviderComponent = ({
56
56
  state,
57
57
  theme,
58
58
  menuProps,
59
+ contentRenderer,
59
60
  safeAreaInsets: safeAreaInsets || {
60
61
  top: 0,
61
62
  bottom: 0,
@@ -69,9 +70,7 @@ const ProviderComponent = ({
69
70
  }
70
71
  }, /*#__PURE__*/React.createElement(InternalContext.Provider, {
71
72
  value: internalContextVariables
72
- }, /*#__PURE__*/React.createElement(PortalProvider, null, children, /*#__PURE__*/React.createElement(Backdrop, null), /*#__PURE__*/React.createElement(Menu, null), /*#__PURE__*/React.createElement(Content, {
73
- renderContent: renderContent
74
- }))));
73
+ }, /*#__PURE__*/React.createElement(PortalProvider, null, children, /*#__PURE__*/React.createElement(Backdrop, null), /*#__PURE__*/React.createElement(Menu, null), /*#__PURE__*/React.createElement(Content, null))));
75
74
  };
76
75
 
77
76
  const Provider = /*#__PURE__*/memo(ProviderComponent);
@@ -1 +1 @@
1
- {"version":3,"sources":["Provider.tsx"],"names":["React","memo","useEffect","useMemo","PortalProvider","Animated","useSharedValue","useAnimatedReaction","runOnJS","GestureHandlerRootView","Backdrop","InternalContext","CONTEXT_MENU_STATE","Menu","Content","AnimatedIcon","ProviderComponent","children","theme","selectedTheme","iconComponent","safeAreaInsets","onOpen","onClose","renderContent","createAnimatedComponent","state","UNDETERMINED","menuProps","itemHeight","itemWidth","itemX","itemY","items","anchorPosition","menuHeight","transformValue","actionParams","value","ACTIVE","END","internalContextVariables","top","bottom","left","right","flex","Provider"],"mappings":"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","sourcesContent":["import React, { memo, useEffect, useMemo } from 'react';\nimport { PortalProvider } from '@gorhom/portal';\nimport Animated, {\n useSharedValue,\n useAnimatedReaction,\n runOnJS,\n} from 'react-native-reanimated';\nimport { GestureHandlerRootView } from 'react-native-gesture-handler';\n\n// Components\nimport { Backdrop } from '../backdrop';\n\n// Utils\nimport { InternalContext } from '../../context/internal';\nimport { HoldMenuProviderProps } from './types';\nimport { StateProps, Action } from './reducer';\nimport { CONTEXT_MENU_STATE } from '../../constants';\nimport { MenuInternalProps } from '../menu/types';\nimport Menu from '../menu';\nimport Content from './Content';\n\nexport interface Store {\n state: StateProps;\n dispatch?: React.Dispatch<Action>;\n}\n\nexport let AnimatedIcon: any;\n\nconst ProviderComponent: React.FC<HoldMenuProviderProps> = ({\n children,\n theme: selectedTheme,\n iconComponent,\n safeAreaInsets,\n onOpen,\n onClose,\n renderContent,\n}) => {\n if (iconComponent)\n AnimatedIcon = Animated.createAnimatedComponent(iconComponent);\n\n const state = useSharedValue<CONTEXT_MENU_STATE>(\n CONTEXT_MENU_STATE.UNDETERMINED\n );\n const theme = useSharedValue<'light' | 'dark'>(selectedTheme || 'light');\n const menuProps = useSharedValue<MenuInternalProps>({\n itemHeight: 0,\n itemWidth: 0,\n itemX: 0,\n itemY: 0,\n items: [],\n anchorPosition: 'top-center',\n menuHeight: 0,\n transformValue: 0,\n actionParams: {},\n });\n\n useEffect(() => {\n theme.value = selectedTheme || 'light';\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedTheme]);\n\n useAnimatedReaction(\n () => state.value,\n state => {\n switch (state) {\n case CONTEXT_MENU_STATE.ACTIVE: {\n if (onOpen) runOnJS(onOpen)();\n break;\n }\n case CONTEXT_MENU_STATE.END: {\n if (onClose) runOnJS(onClose)();\n break;\n }\n }\n },\n [state]\n );\n\n const internalContextVariables = useMemo(\n () => ({\n state,\n theme,\n menuProps,\n safeAreaInsets: safeAreaInsets || {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n }),\n [state, theme, menuProps, safeAreaInsets]\n );\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <InternalContext.Provider value={internalContextVariables}>\n <PortalProvider>\n {children}\n <Backdrop />\n <Menu />\n <Content renderContent={renderContent} />\n </PortalProvider>\n </InternalContext.Provider>\n </GestureHandlerRootView>\n );\n};\n\nconst Provider = memo(ProviderComponent) as React.FC<HoldMenuProviderProps>;\n\nexport default Provider;\n"]}
1
+ {"version":3,"sources":["Provider.tsx"],"names":["React","memo","useEffect","useMemo","useRef","PortalProvider","Animated","useSharedValue","useAnimatedReaction","runOnJS","GestureHandlerRootView","Backdrop","InternalContext","CONTEXT_MENU_STATE","Menu","Content","AnimatedIcon","ProviderComponent","children","theme","selectedTheme","iconComponent","safeAreaInsets","onOpen","onClose","createAnimatedComponent","state","UNDETERMINED","menuProps","itemHeight","itemWidth","itemX","itemY","items","anchorPosition","menuHeight","transformValue","actionParams","contentRenderer","value","ACTIVE","END","internalContextVariables","top","bottom","left","right","flex","Provider"],"mappings":"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","sourcesContent":["import React, { memo, useEffect, useMemo, useRef } from 'react';\nimport { PortalProvider } from '@gorhom/portal';\nimport Animated, {\n useSharedValue,\n useAnimatedReaction,\n runOnJS,\n} from 'react-native-reanimated';\nimport { GestureHandlerRootView } from 'react-native-gesture-handler';\n\n// Components\nimport { Backdrop } from '../backdrop';\n\n// Utils\nimport { InternalContext } from '../../context/internal';\nimport { HoldMenuProviderProps } from './types';\nimport { StateProps, Action } from './reducer';\nimport { CONTEXT_MENU_STATE } from '../../constants';\nimport { MenuInternalProps } from '../menu/types';\nimport Menu from '../menu';\nimport Content from './Content';\n\nexport interface Store {\n state: StateProps;\n dispatch?: React.Dispatch<Action>;\n}\n\nexport let AnimatedIcon: any;\n\nconst ProviderComponent: React.FC<HoldMenuProviderProps> = ({\n children,\n theme: selectedTheme,\n iconComponent,\n safeAreaInsets,\n onOpen,\n onClose,\n}) => {\n if (iconComponent)\n AnimatedIcon = Animated.createAnimatedComponent(iconComponent);\n\n const state = useSharedValue<CONTEXT_MENU_STATE>(\n CONTEXT_MENU_STATE.UNDETERMINED\n );\n const theme = useSharedValue<'light' | 'dark'>(selectedTheme || 'light');\n const menuProps = useSharedValue<MenuInternalProps>({\n itemHeight: 0,\n itemWidth: 0,\n itemX: 0,\n itemY: 0,\n items: [],\n anchorPosition: 'top-center',\n menuHeight: 0,\n transformValue: 0,\n actionParams: {},\n });\n const contentRenderer = useRef<(() => React.ReactNode) | null>(null);\n\n useEffect(() => {\n theme.value = selectedTheme || 'light';\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedTheme]);\n\n useAnimatedReaction(\n () => state.value,\n state => {\n switch (state) {\n case CONTEXT_MENU_STATE.ACTIVE: {\n if (onOpen) runOnJS(onOpen)();\n break;\n }\n case CONTEXT_MENU_STATE.END: {\n if (onClose) runOnJS(onClose)();\n break;\n }\n }\n },\n [state]\n );\n\n const internalContextVariables = useMemo(\n () => ({\n state,\n theme,\n menuProps,\n contentRenderer,\n safeAreaInsets: safeAreaInsets || {\n top: 0,\n bottom: 0,\n left: 0,\n right: 0,\n },\n }),\n [state, theme, menuProps, safeAreaInsets]\n );\n\n return (\n <GestureHandlerRootView style={{ flex: 1 }}>\n <InternalContext.Provider value={internalContextVariables}>\n <PortalProvider>\n {children}\n <Backdrop />\n <Menu />\n <Content />\n </PortalProvider>\n </InternalContext.Provider>\n </GestureHandlerRootView>\n );\n};\n\nconst Provider = memo(ProviderComponent) as React.FC<HoldMenuProviderProps>;\n\nexport default Provider;\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["internal.ts"],"names":["createContext","InternalContext"],"mappings":"AAAA,SAASA,aAAT,QAA8B,OAA9B;AAiBA;AACA,OAAO,MAAMC,eAAe,gBAAGD,aAAa,EAArC","sourcesContent":["import { createContext } from 'react';\nimport type Animated from 'react-native-reanimated';\nimport type { CONTEXT_MENU_STATE } from '../constants';\nimport { MenuInternalProps } from '../components/menu/types';\n\nexport type InternalContextType = {\n state: Animated.SharedValue<CONTEXT_MENU_STATE>;\n theme: Animated.SharedValue<'light' | 'dark'>;\n menuProps: Animated.SharedValue<MenuInternalProps>;\n safeAreaInsets?: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n};\n\n// @ts-ignore\nexport const InternalContext = createContext<InternalContextType>();\n"]}
1
+ {"version":3,"sources":["internal.ts"],"names":["createContext","InternalContext"],"mappings":"AAAA,SAASA,aAAT,QAA8B,OAA9B;AAuBA;AACA,OAAO,MAAMC,eAAe,gBAAGD,aAAa,EAArC","sourcesContent":["import { createContext } from 'react';\nimport type { MutableRefObject } from 'react';\nimport type Animated from 'react-native-reanimated';\nimport type { CONTEXT_MENU_STATE } from '../constants';\nimport { MenuInternalProps } from '../components/menu/types';\n\nexport type ContentRendererRef = MutableRefObject<\n (() => React.ReactNode) | null\n>;\n\nexport type InternalContextType = {\n state: Animated.SharedValue<CONTEXT_MENU_STATE>;\n theme: Animated.SharedValue<'light' | 'dark'>;\n menuProps: Animated.SharedValue<MenuInternalProps>;\n contentRenderer: ContentRendererRef;\n safeAreaInsets?: {\n top: number;\n right: number;\n bottom: number;\n left: number;\n };\n};\n\n// @ts-ignore\nexport const InternalContext = createContext<InternalContextType>();\n"]}
@@ -8,7 +8,7 @@ export type HoldItemProps = {
8
8
  * @type MenuItemProps[]
9
9
  * @default []
10
10
  */
11
- items: MenuItemProps[];
11
+ items?: MenuItemProps[];
12
12
 
13
13
  /**
14
14
  * Object of keys that same name with items to match parameters to onPress actions.
@@ -124,6 +124,15 @@ export type HoldItemProps = {
124
124
  * longPressMinDurationMs={250}
125
125
  */
126
126
  longPressMinDurationMs?: number;
127
+
128
+ /**
129
+ * Custom content renderer for this HoldItem.
130
+ * Allows to render custom content (e.g. reactions) above/below the menu.
131
+ * @type () => React.ReactNode
132
+ * @examples
133
+ * renderContent={() => <MyReactions />}
134
+ */
135
+ renderContent?: () => React.ReactNode;
127
136
  };
128
137
 
129
138
  export type GestureHandlerProps = {
@@ -1,5 +1,2 @@
1
- import React from 'react';
2
- declare const Content: ({ renderContent, }: {
3
- renderContent?: (() => React.ReactNode) | undefined;
4
- }) => JSX.Element | null;
1
+ declare const Content: () => JSX.Element | null;
5
2
  export default Content;
@@ -30,6 +30,4 @@ export interface HoldMenuProviderProps {
30
30
 
31
31
  onOpen?: () => void;
32
32
  onClose?: () => void;
33
-
34
- renderContent?: () => React.ReactNode;
35
33
  }
@@ -1,11 +1,13 @@
1
- /// <reference types="react" />
1
+ import type { MutableRefObject } from 'react';
2
2
  import type Animated from 'react-native-reanimated';
3
3
  import type { CONTEXT_MENU_STATE } from '../constants';
4
4
  import { MenuInternalProps } from '../components/menu/types';
5
+ export declare type ContentRendererRef = MutableRefObject<(() => React.ReactNode) | null>;
5
6
  export declare type InternalContextType = {
6
7
  state: Animated.SharedValue<CONTEXT_MENU_STATE>;
7
8
  theme: Animated.SharedValue<'light' | 'dark'>;
8
9
  menuProps: Animated.SharedValue<MenuInternalProps>;
10
+ contentRenderer: ContentRendererRef;
9
11
  safeAreaInsets?: {
10
12
  top: number;
11
13
  right: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-hold-menu-actions",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "A performant, easy to use hold to open context menu for React Native powered by Reanimated.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -51,12 +51,13 @@ import styles from './styles';
51
51
  import type { HoldItemProps, GestureHandlerProps } from './types';
52
52
  import styleGuide from '../../styleGuide';
53
53
  import { useInternal } from '../../hooks';
54
+ import { MenuItemProps } from '../menu/types';
54
55
  //#endregion
55
56
 
56
57
  type Context = { didMeasureLayout: boolean };
57
-
58
+ const defaultItems = [] as MenuItemProps[];
58
59
  const HoldItemComponent: React.FC<HoldItemProps> = ({
59
- items,
60
+ items = defaultItems,
60
61
  bottom,
61
62
  containerStyles,
62
63
  disableMove,
@@ -67,9 +68,10 @@ const HoldItemComponent: React.FC<HoldItemProps> = ({
67
68
  closeOnTap,
68
69
  longPressMinDurationMs = 150,
69
70
  children,
71
+ renderContent,
70
72
  }) => {
71
73
  //#region hooks
72
- const { state, menuProps, safeAreaInsets } = useInternal();
74
+ const { state, menuProps, safeAreaInsets, contentRenderer } = useInternal();
73
75
  const deviceOrientation = useDeviceOrientation();
74
76
  //#endregion
75
77
 
@@ -198,13 +200,19 @@ const HoldItemComponent: React.FC<HoldItemProps> = ({
198
200
  });
199
201
  };
200
202
 
203
+ const setContentRenderer = () => {
204
+ contentRenderer.current = renderContent || null;
205
+ };
206
+
201
207
  const onCompletion = (isFinised?: boolean) => {
202
208
  'worklet';
203
- const isListValid = items && items.length > 0;
209
+ const isListValid = true;
210
+ // items && items.length > 0;
204
211
  if (isFinised && isListValid) {
205
212
  state.value = CONTEXT_MENU_STATE.ACTIVE;
206
213
  isActive.value = true;
207
214
  scaleBack();
215
+ runOnJS(setContentRenderer)();
208
216
  if (hapticFeedback !== 'None') {
209
217
  runOnJS(hapticResponse)();
210
218
  }
@@ -8,7 +8,7 @@ export type HoldItemProps = {
8
8
  * @type MenuItemProps[]
9
9
  * @default []
10
10
  */
11
- items: MenuItemProps[];
11
+ items?: MenuItemProps[];
12
12
 
13
13
  /**
14
14
  * Object of keys that same name with items to match parameters to onPress actions.
@@ -124,6 +124,15 @@ export type HoldItemProps = {
124
124
  * longPressMinDurationMs={250}
125
125
  */
126
126
  longPressMinDurationMs?: number;
127
+
128
+ /**
129
+ * Custom content renderer for this HoldItem.
130
+ * Allows to render custom content (e.g. reactions) above/below the menu.
131
+ * @type () => React.ReactNode
132
+ * @examples
133
+ * renderContent={() => <MyReactions />}
134
+ */
135
+ renderContent?: () => React.ReactNode;
127
136
  };
128
137
 
129
138
  export type GestureHandlerProps = {
@@ -1,11 +1,13 @@
1
- import React, { useState } from 'react';
1
+ import React, { useCallback, useState } from 'react';
2
2
  import Animated, {
3
3
  runOnJS,
4
4
  useAnimatedReaction,
5
5
  useAnimatedStyle,
6
+ useSharedValue,
6
7
  withSpring,
7
8
  withTiming,
8
9
  } from 'react-native-reanimated';
10
+ import type { LayoutChangeEvent } from 'react-native';
9
11
  import { useInternal } from '../../hooks';
10
12
  import {
11
13
  CONTEXT_MENU_STATE,
@@ -13,13 +15,17 @@ import {
13
15
  SPRING_CONFIGURATION,
14
16
  } from '../../constants';
15
17
 
16
- const Content = ({
17
- renderContent,
18
- }: {
19
- renderContent?: () => React.ReactNode;
20
- }) => {
21
- const { state, menuProps } = useInternal();
18
+ const Content = () => {
19
+ const { state, menuProps, contentRenderer } = useInternal();
22
20
  const [isActive, setIsActive] = useState(false);
21
+ const contentHeight = useSharedValue(0);
22
+
23
+ const handleLayout = useCallback(
24
+ (event: LayoutChangeEvent) => {
25
+ contentHeight.value = event.nativeEvent.layout.height;
26
+ },
27
+ [contentHeight]
28
+ );
23
29
 
24
30
  // синхронизируем Reanimated state → React state
25
31
  useAnimatedReaction(
@@ -28,15 +34,27 @@ const Content = ({
28
34
  runOnJS(setIsActive)(val === CONTEXT_MENU_STATE.ACTIVE);
29
35
  }
30
36
  );
37
+
38
+ const renderContent = contentRenderer.current;
31
39
  const wrapperStyles = useAnimatedStyle(() => {
32
40
  const anchorPositionVertical = menuProps.value.anchorPosition.split('-')[0];
41
+ const anchorPositionHorizontal = menuProps.value.anchorPosition.split(
42
+ '-'
43
+ )[1];
33
44
 
34
45
  const top =
35
46
  anchorPositionVertical === 'top'
36
- ? menuProps.value.itemY - 24
47
+ ? menuProps.value.itemY - contentHeight.value - 8
37
48
  : menuProps.value.itemY + menuProps.value.itemHeight + 8;
38
49
 
39
- const left = menuProps.value.itemX;
50
+ const left =
51
+ anchorPositionHorizontal === 'center'
52
+ ? menuProps.value.itemX / 2 - menuProps.value.itemWidth / 3
53
+ : anchorPositionHorizontal === 'right'
54
+ ? undefined
55
+ : menuProps.value.itemX;
56
+ const right = anchorPositionHorizontal === 'right' ? 0 : undefined;
57
+
40
58
  const tY = menuProps.value.transformValue;
41
59
  return {
42
60
  opacity:
@@ -45,6 +63,7 @@ const Content = ({
45
63
  : withTiming(0),
46
64
  top,
47
65
  left,
66
+ right,
48
67
  transform: [
49
68
  {
50
69
  translateY:
@@ -60,6 +79,7 @@ const Content = ({
60
79
  }
61
80
  return (
62
81
  <Animated.View
82
+ onLayout={handleLayout}
63
83
  style={[{ position: 'absolute', left: 0, zIndex: 12 }, wrapperStyles]}
64
84
  >
65
85
  {isActive && renderContent()}
@@ -1,4 +1,4 @@
1
- import React, { memo, useEffect, useMemo } from 'react';
1
+ import React, { memo, useEffect, useMemo, useRef } from 'react';
2
2
  import { PortalProvider } from '@gorhom/portal';
3
3
  import Animated, {
4
4
  useSharedValue,
@@ -33,7 +33,6 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
33
33
  safeAreaInsets,
34
34
  onOpen,
35
35
  onClose,
36
- renderContent,
37
36
  }) => {
38
37
  if (iconComponent)
39
38
  AnimatedIcon = Animated.createAnimatedComponent(iconComponent);
@@ -53,6 +52,7 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
53
52
  transformValue: 0,
54
53
  actionParams: {},
55
54
  });
55
+ const contentRenderer = useRef<(() => React.ReactNode) | null>(null);
56
56
 
57
57
  useEffect(() => {
58
58
  theme.value = selectedTheme || 'light';
@@ -81,6 +81,7 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
81
81
  state,
82
82
  theme,
83
83
  menuProps,
84
+ contentRenderer,
84
85
  safeAreaInsets: safeAreaInsets || {
85
86
  top: 0,
86
87
  bottom: 0,
@@ -98,7 +99,7 @@ const ProviderComponent: React.FC<HoldMenuProviderProps> = ({
98
99
  {children}
99
100
  <Backdrop />
100
101
  <Menu />
101
- <Content renderContent={renderContent} />
102
+ <Content />
102
103
  </PortalProvider>
103
104
  </InternalContext.Provider>
104
105
  </GestureHandlerRootView>
@@ -30,6 +30,4 @@ export interface HoldMenuProviderProps {
30
30
 
31
31
  onOpen?: () => void;
32
32
  onClose?: () => void;
33
-
34
- renderContent?: () => React.ReactNode;
35
33
  }
@@ -1,12 +1,18 @@
1
1
  import { createContext } from 'react';
2
+ import type { MutableRefObject } from 'react';
2
3
  import type Animated from 'react-native-reanimated';
3
4
  import type { CONTEXT_MENU_STATE } from '../constants';
4
5
  import { MenuInternalProps } from '../components/menu/types';
5
6
 
7
+ export type ContentRendererRef = MutableRefObject<
8
+ (() => React.ReactNode) | null
9
+ >;
10
+
6
11
  export type InternalContextType = {
7
12
  state: Animated.SharedValue<CONTEXT_MENU_STATE>;
8
13
  theme: Animated.SharedValue<'light' | 'dark'>;
9
14
  menuProps: Animated.SharedValue<MenuInternalProps>;
15
+ contentRenderer: ContentRendererRef;
10
16
  safeAreaInsets?: {
11
17
  top: number;
12
18
  right: number;