@fluentui-react-native/menu 0.11.1 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.json +46 -1
  2. package/CHANGELOG.md +26 -2
  3. package/lib/Menu/Menu.types.d.ts +2 -0
  4. package/lib/Menu/Menu.types.d.ts.map +1 -1
  5. package/lib/Menu/useMenu.d.ts.map +1 -1
  6. package/lib/Menu/useMenu.js +7 -2
  7. package/lib/Menu/useMenu.js.map +1 -1
  8. package/lib/Menu/useMenuContextValue.d.ts.map +1 -1
  9. package/lib/Menu/useMenuContextValue.js +4 -1
  10. package/lib/Menu/useMenuContextValue.js.map +1 -1
  11. package/lib/MenuItem/MenuItem.js +1 -1
  12. package/lib/MenuItem/MenuItem.js.map +1 -1
  13. package/lib/MenuItem/useMenuItem.d.ts.map +1 -1
  14. package/lib/MenuItem/useMenuItem.js +34 -6
  15. package/lib/MenuItem/useMenuItem.js.map +1 -1
  16. package/lib/MenuItemCheckbox/MenuItemCheckbox.js +1 -1
  17. package/lib/MenuItemCheckbox/MenuItemCheckbox.js.map +1 -1
  18. package/lib/MenuItemCheckbox/useMenuItemCheckbox.d.ts.map +1 -1
  19. package/lib/MenuItemCheckbox/useMenuItemCheckbox.js +12 -8
  20. package/lib/MenuItemCheckbox/useMenuItemCheckbox.js.map +1 -1
  21. package/lib/MenuItemRadio/useMenuItemRadio.d.ts.map +1 -1
  22. package/lib/MenuItemRadio/useMenuItemRadio.js +5 -3
  23. package/lib/MenuItemRadio/useMenuItemRadio.js.map +1 -1
  24. package/lib/MenuPopover/MenuPopover.d.ts +1 -2
  25. package/lib/MenuPopover/MenuPopover.d.ts.map +1 -1
  26. package/lib/MenuPopover/MenuPopover.js +7 -3
  27. package/lib/MenuPopover/MenuPopover.js.map +1 -1
  28. package/lib/MenuPopover/MenuPopover.types.d.ts +5 -11
  29. package/lib/MenuPopover/MenuPopover.types.d.ts.map +1 -1
  30. package/lib/MenuPopover/useMenuPopover.d.ts.map +1 -1
  31. package/lib/MenuPopover/useMenuPopover.js +35 -8
  32. package/lib/MenuPopover/useMenuPopover.js.map +1 -1
  33. package/lib/MenuTrigger/MenuTrigger.d.ts.map +1 -1
  34. package/lib/MenuTrigger/MenuTrigger.js +24 -2
  35. package/lib/MenuTrigger/MenuTrigger.js.map +1 -1
  36. package/lib/MenuTrigger/MenuTrigger.types.d.ts +3 -0
  37. package/lib/MenuTrigger/MenuTrigger.types.d.ts.map +1 -1
  38. package/lib/MenuTrigger/useMenuTrigger.d.ts.map +1 -1
  39. package/lib/MenuTrigger/useMenuTrigger.js +41 -17
  40. package/lib/MenuTrigger/useMenuTrigger.js.map +1 -1
  41. package/lib/consts.d.ts +3 -0
  42. package/lib/consts.d.ts.map +1 -0
  43. package/lib/consts.js +7 -0
  44. package/lib/consts.js.map +1 -0
  45. package/lib/context/menuContext.d.ts +10 -4
  46. package/lib/context/menuContext.d.ts.map +1 -1
  47. package/lib/context/menuContext.js.map +1 -1
  48. package/lib-commonjs/Menu/Menu.types.d.ts +2 -0
  49. package/lib-commonjs/Menu/Menu.types.d.ts.map +1 -1
  50. package/lib-commonjs/Menu/useMenu.d.ts.map +1 -1
  51. package/lib-commonjs/Menu/useMenu.js +7 -2
  52. package/lib-commonjs/Menu/useMenu.js.map +1 -1
  53. package/lib-commonjs/Menu/useMenuContextValue.d.ts.map +1 -1
  54. package/lib-commonjs/Menu/useMenuContextValue.js +4 -1
  55. package/lib-commonjs/Menu/useMenuContextValue.js.map +1 -1
  56. package/lib-commonjs/MenuItem/MenuItem.js +1 -1
  57. package/lib-commonjs/MenuItem/MenuItem.js.map +1 -1
  58. package/lib-commonjs/MenuItem/useMenuItem.d.ts.map +1 -1
  59. package/lib-commonjs/MenuItem/useMenuItem.js +32 -4
  60. package/lib-commonjs/MenuItem/useMenuItem.js.map +1 -1
  61. package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.js +1 -1
  62. package/lib-commonjs/MenuItemCheckbox/MenuItemCheckbox.js.map +1 -1
  63. package/lib-commonjs/MenuItemCheckbox/useMenuItemCheckbox.d.ts.map +1 -1
  64. package/lib-commonjs/MenuItemCheckbox/useMenuItemCheckbox.js +12 -8
  65. package/lib-commonjs/MenuItemCheckbox/useMenuItemCheckbox.js.map +1 -1
  66. package/lib-commonjs/MenuItemRadio/useMenuItemRadio.d.ts.map +1 -1
  67. package/lib-commonjs/MenuItemRadio/useMenuItemRadio.js +5 -3
  68. package/lib-commonjs/MenuItemRadio/useMenuItemRadio.js.map +1 -1
  69. package/lib-commonjs/MenuPopover/MenuPopover.d.ts +1 -2
  70. package/lib-commonjs/MenuPopover/MenuPopover.d.ts.map +1 -1
  71. package/lib-commonjs/MenuPopover/MenuPopover.js +5 -2
  72. package/lib-commonjs/MenuPopover/MenuPopover.js.map +1 -1
  73. package/lib-commonjs/MenuPopover/MenuPopover.types.d.ts +5 -11
  74. package/lib-commonjs/MenuPopover/MenuPopover.types.d.ts.map +1 -1
  75. package/lib-commonjs/MenuPopover/useMenuPopover.d.ts.map +1 -1
  76. package/lib-commonjs/MenuPopover/useMenuPopover.js +35 -8
  77. package/lib-commonjs/MenuPopover/useMenuPopover.js.map +1 -1
  78. package/lib-commonjs/MenuTrigger/MenuTrigger.d.ts.map +1 -1
  79. package/lib-commonjs/MenuTrigger/MenuTrigger.js +22 -1
  80. package/lib-commonjs/MenuTrigger/MenuTrigger.js.map +1 -1
  81. package/lib-commonjs/MenuTrigger/MenuTrigger.types.d.ts +3 -0
  82. package/lib-commonjs/MenuTrigger/MenuTrigger.types.d.ts.map +1 -1
  83. package/lib-commonjs/MenuTrigger/useMenuTrigger.d.ts.map +1 -1
  84. package/lib-commonjs/MenuTrigger/useMenuTrigger.js +42 -17
  85. package/lib-commonjs/MenuTrigger/useMenuTrigger.js.map +1 -1
  86. package/lib-commonjs/consts.d.ts +3 -0
  87. package/lib-commonjs/consts.d.ts.map +1 -0
  88. package/lib-commonjs/consts.js +10 -0
  89. package/lib-commonjs/consts.js.map +1 -0
  90. package/lib-commonjs/context/menuContext.d.ts +10 -4
  91. package/lib-commonjs/context/menuContext.d.ts.map +1 -1
  92. package/lib-commonjs/context/menuContext.js.map +1 -1
  93. package/package.json +1 -1
  94. package/src/Menu/Menu.types.ts +1 -0
  95. package/src/Menu/useMenu.ts +8 -1
  96. package/src/Menu/useMenuContextValue.ts +4 -1
  97. package/src/MenuItem/MenuItem.tsx +1 -1
  98. package/src/MenuItem/useMenuItem.ts +49 -9
  99. package/src/MenuItemCheckbox/MenuItemCheckbox.tsx +1 -1
  100. package/src/MenuItemCheckbox/useMenuItemCheckbox.ts +13 -9
  101. package/src/MenuItemRadio/useMenuItemRadio.ts +5 -3
  102. package/src/MenuPopover/MenuPopover.tsx +7 -13
  103. package/src/MenuPopover/MenuPopover.types.ts +5 -9
  104. package/src/MenuPopover/useMenuPopover.ts +47 -8
  105. package/src/MenuTrigger/MenuTrigger.tsx +29 -3
  106. package/src/MenuTrigger/MenuTrigger.types.ts +3 -0
  107. package/src/MenuTrigger/useMenuTrigger.ts +62 -23
  108. package/src/consts.ts +8 -0
  109. package/src/context/menuContext.ts +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useMenuPopover.js","sourceRoot":"","sources":["../../src/MenuPopover/useMenuPopover.ts"],"names":[],"mappings":";;;;AAAA,6DAA0B;AAC1B,6CAAqD;AAErD,sDAAwD;AAGjD,IAAM,cAAc,GAAG,UAAC,MAAwB;IACrD,IAAM,OAAO,GAAG,IAAA,4BAAc,GAAE,CAAC;IACjC,IAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEhC,IAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,IAAM,SAAS,GAAG,eAAK,CAAC,WAAW,CAAC,cAAM,OAAA,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,EAAtC,CAAsC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7F,IAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY;QAC3C,CAAC,CAAE,CAAC,yBAAyB,EAAE,8BAA8B,CAAwB;QACrF,CAAC,CAAC,SAAS,CAAC;IACd,IAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,EAAE,0BAAW,CAAC,KAAK,CAAC,CAAC;IAEjF,4EAA4E;IAC5E,8CAA8C;IAC9C,IAAM,eAAe,GAAG,uBAAQ,CAAC,EAAE,KAAM,OAAe,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,CAAC;IACtF,IAAM,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC;IAEpD,OAAO,EAAE,UAAU,YAAA,EAAE,SAAS,WAAA,EAAE,eAAe,iBAAA,EAAE,gBAAgB,kBAAA,EAAE,uBAAuB,yBAAA,EAAE,eAAe,iBAAA,EAAE,CAAC;AAChH,CAAC,CAAC;AAjBW,QAAA,cAAc,kBAiBzB;AAEF,IAAM,kBAAkB,GAAG,UAAC,SAAkB,EAAE,KAAc;IAC5D,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,KAAK,EAAE;QACT,OAAO,aAAa,CAAC;KACtB;IAED,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC"}
1
+ {"version":3,"file":"useMenuPopover.js","sourceRoot":"","sources":["../../src/MenuPopover/useMenuPopover.ts"],"names":[],"mappings":";;;;AAAA,6DAA0B;AAC1B,6CAAqD;AAErD,sDAAwD;AAExD,oCAAqD;AAE9C,IAAM,cAAc,GAAG,UAAC,MAAwB;IACrD,IAAM,OAAO,GAAG,IAAA,4BAAc,GAAE,CAAC;IAE/B,IAAA,OAAO,GASL,OAAO,QATF,EACP,UAAU,GAQR,OAAO,WARC,EACV,YAAY,GAOV,OAAO,aAPG,EACZ,SAAS,GAMP,OAAO,UANA,EACT,WAAW,GAKT,OAAO,YALE,EACX,0BAA0B,GAIxB,OAAO,2BAJiB,EAC1B,oBAAoB,GAGlB,OAAO,qBAHW,EACpB,uBAAuB,GAErB,OAAO,wBAFc,EACvB,oBAAoB,GAClB,OAAO,qBADW,CACV;IAEZ,IAAM,SAAS,GAAG,eAAK,CAAC,WAAW,CAAC,cAAM,OAAA,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,EAAtC,CAAsC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7F,IAAM,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAE,CAAC,yBAAyB,EAAE,8BAA8B,CAAwB,CAAC,CAAC,CAAC,SAAS,CAAC;IACxI,IAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,EAAE,0BAAW,CAAC,KAAK,CAAC,CAAC;IAEzE,4EAA4E;IAC5E,8CAA8C;IAC9C,IAAM,eAAe,GAAG,uBAAQ,CAAC,EAAE,KAAM,OAAe,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,CAAC;IACtF,IAAM,uBAAuB,GAAG,WAAW,CAAC;IAC5C,IAAM,iBAAiB,GAAG,MAAM,CAAC;IAEjC,IAAM,YAAY,GAAG,eAAK,CAAC,WAAW,CAAC;QACrC,YAAY,CAAC,oBAAoB,CAAC,CAAC;QACnC,YAAY,CAAC,oBAAoB,CAAC,CAAC;QACnC,YAAY,CAAC,0BAA0B,CAAC,CAAC;IAC3C,CAAC,EAAE,CAAC,0BAA0B,EAAE,oBAAoB,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC7E,IAAM,YAAY,GAAG,eAAK,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,WAAW,EAAE;YAChB,OAAO;SACR;QAED,IAAM,KAAK,GAAG,UAAU,CAAC;YACvB,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC,EAAE,GAAG,CAAC,CAAC;QACR,uBAAuB,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAEpD,OAAO;QACL,KAAK,EAAE;YACL,iBAAiB,mBAAA;YACjB,MAAM,EAAE,UAAU;YAClB,SAAS,WAAA;YACT,eAAe,iBAAA;YACf,gBAAgB,kBAAA;YAChB,uBAAuB,yBAAA;YACvB,eAAe,iBAAA;SAChB;QACD,SAAS,EAAE;YACT,YAAY,cAAA;YACZ,YAAY,EAAE,iCAAwB,IAAI,YAAY;SACvD;KACF,CAAC;AACJ,CAAC,CAAC;AAvDW,QAAA,cAAc,kBAuDzB;AAEF,IAAM,kBAAkB,GAAG,UAAC,SAAkB,EAAE,KAAc;IAC5D,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,KAAK,EAAE;QACT,OAAO,aAAa,CAAC;KACtB;IAED,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MenuTrigger.d.ts","sourceRoot":"","sources":["../../src/MenuTrigger/MenuTrigger.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIxE,eAAO,MAAM,WAAW,iFAiBtB,CAAC;AAGH,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MenuTrigger.d.ts","sourceRoot":"","sources":["../../src/MenuTrigger/MenuTrigger.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,gBAAgB,EAAoB,MAAM,qBAAqB,CAAC;AAK1F,eAAO,MAAM,WAAW,iFAqBtB,CAAC;AAwBH,eAAe,WAAW,CAAC"}
@@ -16,11 +16,32 @@ exports.MenuTrigger = (0, framework_1.stagedComponent)(function (props) {
16
16
  console.log('Only expecting one child for MenuTrigger');
17
17
  }
18
18
  }
19
+ // In order to properly support accessibility without erasing props set on the
20
+ // child component which may affect accessibility, we need to modify the
21
+ // state in the inner render so we can access the child component and its props.
19
22
  var child = childrenArray[0];
20
- var revised = react_1.default.cloneElement(child, menuTrigger.props);
23
+ var revisedProps = getRevisedState(menuTrigger, child.props);
24
+ var revised = react_1.default.cloneElement(child, revisedProps);
21
25
  return react_1.default.createElement(menuTriggerContext_1.MenuTriggerProvider, { value: menuTrigger.hasSubmenu }, revised);
22
26
  };
23
27
  });
24
28
  exports.MenuTrigger.displayName = MenuTrigger_types_1.menuTriggerName;
29
+ var getRevisedState = (0, framework_1.memoize)(getRevisedStateWorker);
30
+ function getRevisedStateWorker(state, props) {
31
+ var revisedProps = (0, tslib_1.__assign)({}, state.props);
32
+ if (props.accessibilityState) {
33
+ revisedProps.accessibilityState = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, state.props.accessibilityState), props.accessibilityState);
34
+ }
35
+ if (props.accessibilityActions) {
36
+ revisedProps.accessibilityActions = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, state.props.accessibilityActions), props.accessibilityActions);
37
+ }
38
+ if (props.onAccessibilityAction) {
39
+ revisedProps.onAccessibilityAction = function (e) {
40
+ state.props.onAccessibilityAction(e);
41
+ props.onAccessibilityAction(e);
42
+ };
43
+ }
44
+ return revisedProps;
45
+ }
25
46
  exports.default = exports.MenuTrigger;
26
47
  //# sourceMappingURL=MenuTrigger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MenuTrigger.js","sourceRoot":"","sources":["../../src/MenuTrigger/MenuTrigger.tsx"],"names":[],"mappings":";;;;AAAA,6DAA0B;AAC1B,8DAAmE;AACnE,yDAAwE;AACxE,mDAAkD;AAClD,oEAAoE;AAEvD,QAAA,WAAW,GAAG,IAAA,2BAAe,EAAC,UAAC,KAAuB;IACjE,IAAM,WAAW,GAAG,IAAA,+BAAc,EAAC,KAAK,CAAC,CAAC;IAE1C,OAAO,UAAC,KAAuB,EAAE,QAAyB;QACxD,IAAM,aAAa,GAAG,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAyB,CAAC;QAE/E,IAAI,OAAO,EAAE;YACX,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC9B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;aACzD;SACF;QAED,IAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAM,OAAO,GAAG,eAAK,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;QAE7D,OAAO,8BAAC,wCAAmB,IAAC,KAAK,EAAE,WAAW,CAAC,UAAU,IAAG,OAAO,CAAuB,CAAC;IAC7F,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,mBAAW,CAAC,WAAW,GAAG,mCAAe,CAAC;AAE1C,kBAAe,mBAAW,CAAC"}
1
+ {"version":3,"file":"MenuTrigger.js","sourceRoot":"","sources":["../../src/MenuTrigger/MenuTrigger.tsx"],"names":[],"mappings":";;;;AAAA,6DAA0B;AAC1B,8DAA4E;AAC5E,yDAA0F;AAC1F,mDAAkD;AAElD,oEAAoE;AAEvD,QAAA,WAAW,GAAG,IAAA,2BAAe,EAAC,UAAC,KAAuB;IACjE,IAAM,WAAW,GAAG,IAAA,+BAAc,EAAC,KAAK,CAAC,CAAC;IAE1C,OAAO,UAAC,KAAuB,EAAE,QAAyB;QACxD,IAAM,aAAa,GAAG,eAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAyB,CAAC;QAE/E,IAAI,OAAO,EAAE;YACX,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC9B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;aACzD;SACF;QAED,8EAA8E;QAC9E,wEAAwE;QACxE,gFAAgF;QAChF,IAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAM,YAAY,GAAG,eAAe,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/D,IAAM,OAAO,GAAG,eAAK,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAExD,OAAO,8BAAC,wCAAmB,IAAC,KAAK,EAAE,WAAW,CAAC,UAAU,IAAG,OAAO,CAAuB,CAAC;IAC7F,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,mBAAW,CAAC,WAAW,GAAG,mCAAe,CAAC;AAE1C,IAAM,eAAe,GAAG,IAAA,mBAAO,EAAC,qBAAqB,CAAC,CAAC;AACvD,SAAS,qBAAqB,CAAC,KAAuB,EAAE,KAAU;IAChE,IAAM,YAAY,6BAAQ,KAAK,CAAC,KAAK,CAAE,CAAC;IACxC,IAAI,KAAK,CAAC,kBAAkB,EAAE;QAC5B,YAAY,CAAC,kBAAkB,mDAAQ,KAAK,CAAC,KAAK,CAAC,kBAAkB,GAAK,KAAK,CAAC,kBAAkB,CAAE,CAAC;KACtG;IAED,IAAI,KAAK,CAAC,oBAAoB,EAAE;QAC9B,YAAY,CAAC,oBAAoB,mDAAQ,KAAK,CAAC,KAAK,CAAC,oBAAoB,GAAK,KAAK,CAAC,oBAAoB,CAAE,CAAC;KAC5G;IAED,IAAI,KAAK,CAAC,qBAAqB,EAAE;QAC/B,YAAY,CAAC,qBAAqB,GAAG,UAAC,CAA2B;YAC/D,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACrC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC;KACH;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,kBAAe,mBAAW,CAAC"}
@@ -7,6 +7,9 @@ export interface MenuTriggerProps extends Omit<IWithPressableOptions<ViewProps>,
7
7
  * A RefObject to refer to the trigger component.
8
8
  */
9
9
  componentRef?: React.RefObject<React.Component>;
10
+ /**
11
+ * A callback to call on button click event
12
+ */
10
13
  onClick?: (e: InteractionEvent) => void;
11
14
  }
12
15
  export interface MenuTriggerState {
@@ -1 +1 @@
1
- {"version":3,"file":"MenuTrigger.types.d.ts","sourceRoot":"","sources":["../../src/MenuTrigger/MenuTrigger.types.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACnG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IACzF;;OAEG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEhD,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;CACrB"}
1
+ {"version":3,"file":"MenuTrigger.types.d.ts","sourceRoot":"","sources":["../../src/MenuTrigger/MenuTrigger.types.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACnG,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IACzF;;OAEG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEhD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;CACrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMenuTrigger.d.ts","sourceRoot":"","sources":["../../src/MenuTrigger/useMenuTrigger.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGzE,eAAO,MAAM,cAAc,WAAY,gBAAgB,KAAG,gBAiCzD,CAAC"}
1
+ {"version":3,"file":"useMenuTrigger.d.ts","sourceRoot":"","sources":["../../src/MenuTrigger/useMenuTrigger.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAQzE,eAAO,MAAM,cAAc,WAAY,gBAAgB,KAAG,gBAmEzD,CAAC"}
@@ -1,33 +1,58 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useMenuTrigger = void 0;
4
+ var tslib_1 = require("tslib");
4
5
  var menuContext_1 = require("../context/menuContext");
5
6
  var react_native_1 = require("react-native");
7
+ var react_1 = (0, tslib_1.__importDefault)(require("react"));
8
+ var consts_1 = require("../consts");
9
+ var accessibilityActions = react_native_1.Platform.OS === 'win32' ? [{ name: 'Expand' }, { name: 'Collapse' }] : [];
6
10
  var useMenuTrigger = function (_props) {
7
11
  var context = (0, menuContext_1.useMenuContext)();
8
- var setOpen = context.setOpen;
9
- var open = context.open;
10
- var openOnHover = context.openOnHover;
11
- var triggerRef = context.triggerRef;
12
- var delayHover = react_native_1.Platform.select({
13
- macos: 100,
14
- default: 500, // win32
15
- });
16
- var onHoverIn = function (e) {
12
+ var open = context.open, openOnHover = context.openOnHover, popoverHoverOutTimer = context.popoverHoverOutTimer, setOpen = context.setOpen, setTriggerHoverOutTimer = context.setTriggerHoverOutTimer, triggerHoverOutTimer = context.triggerHoverOutTimer, triggerRef = context.triggerRef;
13
+ var accessibilityState = open ? { expanded: true } : { expanded: false };
14
+ var onAccessibilityAction = react_1.default.useCallback(function (e) {
15
+ if (react_native_1.Platform.OS === 'win32') {
16
+ switch (e.nativeEvent.actionName) {
17
+ case 'Expand':
18
+ setOpen(e, true /* isOpen */);
19
+ break;
20
+ case 'Collapse':
21
+ setOpen(e, false /* isOpen */);
22
+ break;
23
+ }
24
+ }
25
+ }, [setOpen]);
26
+ var onHoverIn = react_1.default.useCallback(function (e) {
17
27
  if (openOnHover) {
18
- setOpen(e, true /* isOpen */);
28
+ clearTimeout(popoverHoverOutTimer);
29
+ clearTimeout(triggerHoverOutTimer);
30
+ setTimeout(function () {
31
+ setOpen(e, true /* isOpen */);
32
+ }, consts_1.delayHover);
19
33
  }
20
- };
21
- var onHoverOut = function (e) {
34
+ }, [openOnHover, setOpen, triggerHoverOutTimer, popoverHoverOutTimer]);
35
+ var onHoverOut = react_1.default.useCallback(function (e) {
22
36
  if (openOnHover) {
23
- setOpen(e, false /* isOpen */);
37
+ var timer = setTimeout(function () {
38
+ setOpen(e, false /* isOpen */);
39
+ }, consts_1.delayHover);
40
+ setTriggerHoverOutTimer(timer);
24
41
  }
25
- };
26
- var onClick = function (e) {
42
+ }, [openOnHover, setOpen, setTriggerHoverOutTimer]);
43
+ var onClick = react_1.default.useCallback(function (e) {
27
44
  setOpen(e, !open);
28
- };
45
+ }, [open, setOpen]);
29
46
  return {
30
- props: { onClick: onClick, onHoverIn: onHoverIn, onHoverOut: onHoverOut, componentRef: triggerRef, delayHoverIn: delayHover, delayHoverOut: delayHover },
47
+ props: {
48
+ onClick: onClick,
49
+ onHoverIn: onHoverIn,
50
+ onHoverOut: consts_1.isCloseOnHoverOutEnabled && onHoverOut,
51
+ componentRef: triggerRef,
52
+ accessibilityState: accessibilityState,
53
+ accessibilityActions: accessibilityActions,
54
+ onAccessibilityAction: onAccessibilityAction,
55
+ },
31
56
  hasSubmenu: context.isSubmenu,
32
57
  };
33
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useMenuTrigger.js","sourceRoot":"","sources":["../../src/MenuTrigger/useMenuTrigger.ts"],"names":[],"mappings":";;;AAAA,sDAAwD;AAGxD,6CAAwC;AAEjC,IAAM,cAAc,GAAG,UAAC,MAAwB;IACrD,IAAM,OAAO,GAAG,IAAA,4BAAc,GAAE,CAAC;IAEjC,IAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,IAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,IAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACxC,IAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAEtC,IAAM,UAAU,GAAG,uBAAQ,CAAC,MAAM,CAAC;QACjC,KAAK,EAAE,GAAG;QACV,OAAO,EAAE,GAAG,EAAE,QAAQ;KACvB,CAAC,CAAC;IAEH,IAAM,SAAS,GAAG,UAAC,CAAmB;QACpC,IAAI,WAAW,EAAE;YACf,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;SAC/B;IACH,CAAC,CAAC;IAEF,IAAM,UAAU,GAAG,UAAC,CAAmB;QACrC,IAAI,WAAW,EAAE;YACf,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;SAChC;IACH,CAAC,CAAC;IAEF,IAAM,OAAO,GAAG,UAAC,CAAmB;QAClC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,EAAE,OAAO,SAAA,EAAE,SAAS,WAAA,EAAE,UAAU,YAAA,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE;QACxH,UAAU,EAAE,OAAO,CAAC,SAAS;KAC9B,CAAC;AACJ,CAAC,CAAC;AAjCW,QAAA,cAAc,kBAiCzB"}
1
+ {"version":3,"file":"useMenuTrigger.js","sourceRoot":"","sources":["../../src/MenuTrigger/useMenuTrigger.ts"],"names":[],"mappings":";;;;AAAA,sDAAwD;AAGxD,6CAA2F;AAC3F,6DAA0B;AAC1B,oCAAiE;AAEjE,IAAM,oBAAoB,GACxB,uBAAQ,CAAC,EAAE,KAAM,OAAe,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAmC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAqC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAEpI,IAAM,cAAc,GAAG,UAAC,MAAwB;IACrD,IAAM,OAAO,GAAG,IAAA,4BAAc,GAAE,CAAC;IACzB,IAAA,IAAI,GAA4G,OAAO,KAAnH,EAAE,WAAW,GAA+F,OAAO,YAAtG,EAAE,oBAAoB,GAAyE,OAAO,qBAAhF,EAAE,OAAO,GAAgE,OAAO,QAAvE,EAAE,uBAAuB,GAAuC,OAAO,wBAA9C,EAAE,oBAAoB,GAAiB,OAAO,qBAAxB,EAAE,UAAU,GAAK,OAAO,WAAZ,CAAa;IAEhI,IAAM,kBAAkB,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAE3E,IAAM,qBAAqB,GAAG,eAAK,CAAC,WAAW,CAC7C,UAAC,CAA2B;QAC1B,IAAI,uBAAQ,CAAC,EAAE,KAAM,OAAe,EAAE;YACpC,QAAQ,CAAC,CAAC,WAAW,CAAC,UAAU,EAAE;gBAChC,KAAK,QAAQ;oBACX,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;oBAC9B,MAAM;gBAER,KAAK,UAAU;oBACb,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;oBAC/B,MAAM;aACT;SACF;IACH,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,IAAM,SAAS,GAAG,eAAK,CAAC,WAAW,CACjC,UAAC,CAAmB;QAClB,IAAI,WAAW,EAAE;YACf,YAAY,CAAC,oBAAoB,CAAC,CAAC;YACnC,YAAY,CAAC,oBAAoB,CAAC,CAAC;YACnC,UAAU,CAAC;gBACT,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,CAAC,EAAE,mBAAU,CAAC,CAAC;SAChB;IACH,CAAC,EACD,CAAC,WAAW,EAAE,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,CAAC,CACnE,CAAC;IAEF,IAAM,UAAU,GAAG,eAAK,CAAC,WAAW,CAClC,UAAC,CAAmB;QAClB,IAAI,WAAW,EAAE;YACf,IAAM,KAAK,GAAG,UAAU,CAAC;gBACvB,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;YACjC,CAAC,EAAE,mBAAU,CAAC,CAAC;YACf,uBAAuB,CAAC,KAAK,CAAC,CAAC;SAChC;IACH,CAAC,EACD,CAAC,WAAW,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAChD,CAAC;IAEF,IAAM,OAAO,GAAG,eAAK,CAAC,WAAW,CAC/B,UAAC,CAAmB;QAClB,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,IAAI,EAAE,OAAO,CAAC,CAChB,CAAC;IAEF,OAAO;QACL,KAAK,EAAE;YACL,OAAO,SAAA;YACP,SAAS,WAAA;YACT,UAAU,EAAE,iCAAwB,IAAI,UAAU;YAClD,YAAY,EAAE,UAAU;YACxB,kBAAkB,oBAAA;YAClB,oBAAoB,sBAAA;YACpB,qBAAqB,uBAAA;SACtB;QACD,UAAU,EAAE,OAAO,CAAC,SAAS;KAC9B,CAAC;AACJ,CAAC,CAAC;AAnEW,QAAA,cAAc,kBAmEzB"}
@@ -0,0 +1,3 @@
1
+ export declare const delayHover: number;
2
+ export declare const isCloseOnHoverOutEnabled: boolean;
3
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,QAGrB,CAAC;AAEH,eAAO,MAAM,wBAAwB,SAAmC,CAAC"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCloseOnHoverOutEnabled = exports.delayHover = void 0;
4
+ var react_native_1 = require("react-native");
5
+ exports.delayHover = react_native_1.Platform.select({
6
+ macos: 100,
7
+ default: 500, // win32
8
+ });
9
+ exports.isCloseOnHoverOutEnabled = react_native_1.Platform.OS === 'win32';
10
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AAE3B,QAAA,UAAU,GAAG,uBAAQ,CAAC,MAAM,CAAC;IACxC,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG,EAAE,QAAQ;CACvB,CAAC,CAAC;AAEU,QAAA,wBAAwB,GAAG,uBAAQ,CAAC,EAAE,KAAM,OAAe,CAAC"}
@@ -1,10 +1,16 @@
1
+ /// <reference types="node" />
1
2
  import * as React from 'react';
2
3
  import type { MenuState } from '../Menu/Menu.types';
3
4
  /**
4
5
  * Context shared between Menu and its child components
5
6
  */
6
- export declare type MenuContextValue = MenuState;
7
- export declare const MenuContext: React.Context<MenuState>;
8
- export declare const MenuProvider: React.Provider<MenuState>;
9
- export declare const useMenuContext: () => MenuState;
7
+ export interface MenuContextValue extends MenuState {
8
+ popoverHoverOutTimer?: NodeJS.Timeout;
9
+ triggerHoverOutTimer?: NodeJS.Timeout;
10
+ setPopoverHoverOutTimer?: (timer: NodeJS.Timeout) => void;
11
+ setTriggerHoverOutTimer?: (timer: NodeJS.Timeout) => void;
12
+ }
13
+ export declare const MenuContext: React.Context<MenuContextValue>;
14
+ export declare const MenuProvider: React.Provider<MenuContextValue>;
15
+ export declare const useMenuContext: () => MenuContextValue;
10
16
  //# sourceMappingURL=menuContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"menuContext.d.ts","sourceRoot":"","sources":["../../src/context/menuContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;GAEG;AACH,oBAAY,gBAAgB,GAAG,SAAS,CAAC;AAEzC,eAAO,MAAM,WAAW,0BAUtB,CAAC;AAEH,eAAO,MAAM,YAAY,2BAAuB,CAAC;AACjD,eAAO,MAAM,cAAc,iBAAsC,CAAC"}
1
+ {"version":3,"file":"menuContext.d.ts","sourceRoot":"","sources":["../../src/context/menuContext.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,oBAAoB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IACtC,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IAC1D,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,WAAW,iCAUtB,CAAC;AAEH,eAAO,MAAM,YAAY,kCAAuB,CAAC;AACjD,eAAO,MAAM,cAAc,wBAAsC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"menuContext.js","sourceRoot":"","sources":["../../src/context/menuContext.ts"],"names":[],"mappings":";;;;AAAA,wDAA+B;AAQlB,QAAA,WAAW,GAAG,KAAK,CAAC,aAAa,CAAmB;IAC/D,YAAY,EAAE,KAAK;IACnB,OAAO,EAAE,EAAE;IACX,cAAc,EAAE,EAAE;IAClB,aAAa,EAAE,KAAK;IACpB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,KAAK;IACX,eAAe,EAAE,cAAM,OAAA,KAAK,EAAL,CAAK;IAC5B,OAAO,EAAE,cAAM,OAAA,KAAK,EAAL,CAAK;IACpB,UAAU,EAAE,IAAI;CACjB,CAAC,CAAC;AAEU,QAAA,YAAY,GAAG,mBAAW,CAAC,QAAQ,CAAC;AAC1C,IAAM,cAAc,GAAG,cAAM,OAAA,KAAK,CAAC,UAAU,CAAC,mBAAW,CAAC,EAA7B,CAA6B,CAAC;AAArD,QAAA,cAAc,kBAAuC"}
1
+ {"version":3,"file":"menuContext.js","sourceRoot":"","sources":["../../src/context/menuContext.ts"],"names":[],"mappings":";;;;AAAA,wDAA+B;AAalB,QAAA,WAAW,GAAG,KAAK,CAAC,aAAa,CAAmB;IAC/D,YAAY,EAAE,KAAK;IACnB,OAAO,EAAE,EAAE;IACX,cAAc,EAAE,EAAE;IAClB,aAAa,EAAE,KAAK;IACpB,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,KAAK;IACX,eAAe,EAAE,cAAM,OAAA,KAAK,EAAL,CAAK;IAC5B,OAAO,EAAE,cAAM,OAAA,KAAK,EAAL,CAAK;IACpB,UAAU,EAAE,IAAI;CACjB,CAAC,CAAC;AAEU,QAAA,YAAY,GAAG,mBAAW,CAAC,QAAQ,CAAC;AAC1C,IAAM,cAAc,GAAG,cAAM,OAAA,KAAK,CAAC,UAAU,CAAC,mBAAW,CAAC,EAA7B,CAA6B,CAAC;AAArD,QAAA,cAAc,kBAAuC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-react-native/menu",
3
- "version": "0.11.1",
3
+ "version": "0.13.1",
4
4
  "description": "A cross-platform Menu component using the Fluent Design System",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -14,6 +14,7 @@ export interface MenuProps extends MenuListProps {
14
14
  export interface MenuState extends MenuProps {
15
15
  isControlled: boolean;
16
16
  isSubmenu: boolean;
17
+ parentPopoverHoverOutTimer?: NodeJS.Timeout;
17
18
  setOpen: (e: InteractionEvent, isOpen: boolean) => void;
18
19
  triggerRef: React.RefObject<React.Component>;
19
20
  }
@@ -10,11 +10,17 @@ export const useMenu = (props: MenuProps): MenuState => {
10
10
  const isControlled = typeof props.open !== 'undefined';
11
11
  const [open, setOpen] = useMenuOpenState(isControlled, props);
12
12
 
13
- // Default behaviot for submenu is to open on hover
13
+ // Default behavior for submenu is to open on hover
14
14
  // the ...props line below will override this behavior for a submenu
15
15
  // or apply openOnHover if passed into a root Menu.
16
16
  const openOnHover = isSubmenu;
17
17
 
18
+ // We need to be able to cancel the timer that gets set on
19
+ // hover out of the parent popover if the parent popover
20
+ // is also set to open/close on hover out. Otherwise
21
+ // the parent menu will close when the timeout passes.
22
+ const parentPopoverHoverOutTimer = isSubmenu ? context.popoverHoverOutTimer : undefined;
23
+
18
24
  return {
19
25
  openOnHover,
20
26
  ...props,
@@ -23,6 +29,7 @@ export const useMenu = (props: MenuProps): MenuState => {
23
29
  triggerRef,
24
30
  isSubmenu,
25
31
  isControlled,
32
+ parentPopoverHoverOutTimer,
26
33
  };
27
34
  };
28
35
 
@@ -1,6 +1,9 @@
1
+ import React from 'react';
1
2
  import { MenuContextValue } from '../context/menuContext';
2
3
  import { MenuState } from './Menu.types';
3
4
 
4
5
  export const useMenuContextValue = (state: MenuState): MenuContextValue => {
5
- return { ...state };
6
+ const [triggerHoverOutTimer, setTriggerHoverOutTimer] = React.useState<NodeJS.Timeout | undefined>();
7
+ const [popoverHoverOutTimer, setPopoverHoverOutTimer] = React.useState<NodeJS.Timeout>();
8
+ return { ...state, popoverHoverOutTimer, triggerHoverOutTimer, setPopoverHoverOutTimer, setTriggerHoverOutTimer };
6
9
  };
@@ -18,7 +18,7 @@ export const MenuItem = compose<MenuItemType>({
18
18
  },
19
19
  useRender: (userProps: MenuItemProps, useSlots: UseSlots<MenuItemType>) => {
20
20
  const menuItem = useMenuItem(userProps);
21
- const Slots = useSlots(userProps, (layer): boolean => menuItem.state[layer]);
21
+ const Slots = useSlots(userProps, (layer): boolean => menuItem.state[layer] || userProps[layer]);
22
22
 
23
23
  return (final: MenuItemProps) => {
24
24
  const mergedProps = mergeProps(menuItem.props, final);
@@ -1,20 +1,60 @@
1
1
  import * as React from 'react';
2
- import { AccessibilityState } from 'react-native';
2
+ import { AccessibilityState, I18nManager } from 'react-native';
3
3
  import { MenuItemProps, MenuItemState } from './MenuItem.types';
4
4
  import { memoize } from '@fluentui-react-native/framework';
5
- import { useAsPressable, useKeyProps } from '@fluentui-react-native/interactive-hooks';
5
+ import { InteractionEvent, isKeyPressEvent, useAsPressable, useKeyDownProps } from '@fluentui-react-native/interactive-hooks';
6
6
  import { useMenuContext } from '../context/menuContext';
7
7
  import { useMenuListContext } from '../context/menuListContext';
8
8
  import { useMenuTriggerContext } from '../context/menuTriggerContext';
9
9
 
10
+ const triggerKeys = [' ', 'Enter'];
11
+ const submenuTriggerKeys = [...triggerKeys, 'ArrowLeft', 'ArrowRight'];
12
+
10
13
  export const useMenuItem = (props: MenuItemProps): MenuItemState => {
11
14
  // attach the pressable state handlers
12
15
  const defaultComponentRef = React.useRef(null);
13
16
  const { onClick, accessibilityState, componentRef = defaultComponentRef, disabled, ...rest } = props;
14
- const pressable = useAsPressable({ ...rest, disabled, onPress: onClick });
15
- const onKeyProps = useKeyProps(onClick, ' ', 'Enter');
16
17
  const isTrigger = useMenuTriggerContext();
17
- const hasSubmenu = useMenuContext().isSubmenu && isTrigger;
18
+ const isSubmenu = useMenuContext().isSubmenu;
19
+ const hasSubmenu = isSubmenu && isTrigger;
20
+ const isInSubmenu = isSubmenu && !isTrigger;
21
+
22
+ const setOpen = useMenuContext().setOpen;
23
+ const onInvoke = React.useCallback(
24
+ (e: InteractionEvent) => {
25
+ if (disabled) {
26
+ return;
27
+ }
28
+
29
+ const isRtl = I18nManager.isRTL;
30
+ if (
31
+ isKeyPressEvent(e) &&
32
+ hasSubmenu &&
33
+ ((isRtl && e.nativeEvent.key === 'ArrowRight') || (!isRtl && e.nativeEvent.key === 'ArrowLeft'))
34
+ ) {
35
+ return;
36
+ }
37
+ if (
38
+ isKeyPressEvent(e) &&
39
+ isInSubmenu &&
40
+ ((isRtl && e.nativeEvent.key === 'ArrowLeft') || (!isRtl && e.nativeEvent.key === 'ArrowRight'))
41
+ ) {
42
+ return;
43
+ }
44
+
45
+ onClick?.(e);
46
+ if (!hasSubmenu) {
47
+ setOpen(e, false /*isOpen*/);
48
+ }
49
+ },
50
+ [disabled, hasSubmenu, isInSubmenu, onClick, setOpen],
51
+ );
52
+
53
+ const pressable = useAsPressable({ ...rest, disabled, onPress: onInvoke });
54
+ const keys = isSubmenu ? submenuTriggerKeys : triggerKeys;
55
+
56
+ // Explicitly override onKeyDown to override the native behavior of moving focus with arrow keys.
57
+ const onKeyDownProps = useKeyDownProps(onInvoke, ...keys);
18
58
  const hasCheckmarks = useMenuListContext().hasCheckmarks;
19
59
 
20
60
  return {
@@ -22,13 +62,13 @@ export const useMenuItem = (props: MenuItemProps): MenuItemState => {
22
62
  ...pressable.props,
23
63
  accessible: true,
24
64
  accessibilityRole: 'menuitem',
25
- onAccessibilityTap: props.onAccessibilityTap || props.onClick,
26
- accessibilityLabel: props.accessibilityLabel,
65
+ onAccessibilityTap: props.onAccessibilityTap || onInvoke,
66
+ accessibilityLabel: props.accessibilityLabel || props.content,
27
67
  accessibilityState: getAccessibilityState(disabled, accessibilityState),
28
68
  enableFocusRing: true,
29
- focusable: !disabled,
69
+ focusable: true,
30
70
  ref: componentRef,
31
- ...onKeyProps,
71
+ ...onKeyDownProps,
32
72
  },
33
73
  state: pressable.state,
34
74
  hasSubmenu,
@@ -23,7 +23,7 @@ export const MenuItemCheckbox = compose<MenuItemCheckboxType>({
23
23
  },
24
24
  useRender: (userProps: MenuItemCheckboxProps, useSlots: UseSlots<MenuItemCheckboxType>) => {
25
25
  const menuItem = useMenuItemCheckbox(userProps);
26
- const Slots = useSlots(userProps, (layer): boolean => menuItem.state[layer]);
26
+ const Slots = useSlots(userProps, (layer): boolean => menuItem.state[layer] || userProps[layer]);
27
27
 
28
28
  return menuItemFinalRender(menuItem, Slots);
29
29
  },
@@ -14,16 +14,18 @@ import { useMenuListContext } from '../context/menuListContext';
14
14
  const defaultAccessibilityActions = [{ name: 'Toggle' }];
15
15
 
16
16
  export const useMenuItemCheckbox = (props: MenuItemCheckboxProps): MenuItemCheckboxState => {
17
- const { name } = props;
17
+ const { disabled, name } = props;
18
18
  const context = useMenuListContext();
19
19
  const checked = context.checked?.[name];
20
20
  const onCheckedChange = context.onCheckedChange;
21
21
 
22
22
  const toggleChecked = React.useCallback(
23
23
  (e: InteractionEvent) => {
24
- onCheckedChange(e, name, !checked);
24
+ if (!disabled) {
25
+ onCheckedChange(e, name, !checked);
26
+ }
25
27
  },
26
- [checked, name, onCheckedChange],
28
+ [checked, disabled, name, onCheckedChange],
27
29
  );
28
30
 
29
31
  return useMenuCheckboxInteraction(props, toggleChecked);
@@ -74,12 +76,14 @@ export const useMenuCheckboxInteraction = (
74
76
  : defaultAccessibilityActions;
75
77
  const onAccessibilityActionProp = React.useCallback(
76
78
  (event: AccessibilityActionEvent) => {
77
- if (event.nativeEvent.actionName === 'Toggle') {
78
- toggleCallback(event);
79
+ if (!disabled) {
80
+ if (event.nativeEvent.actionName === 'Toggle') {
81
+ toggleCallback(event);
82
+ }
83
+ onAccessibilityAction && onAccessibilityAction(event);
79
84
  }
80
- onAccessibilityAction && onAccessibilityAction(event);
81
85
  },
82
- [toggleCallback, onAccessibilityAction],
86
+ [disabled, toggleCallback, onAccessibilityAction],
83
87
  );
84
88
 
85
89
  const state = {
@@ -93,11 +97,11 @@ export const useMenuCheckboxInteraction = (
93
97
  ...pressable.props,
94
98
  accessible: true,
95
99
  accessibilityActions: accessibilityActionsProp,
96
- accessibilityLabel: props.accessibilityLabel,
100
+ accessibilityLabel: props.accessibilityLabel || props.content,
97
101
  accessibilityRole: 'menuitem',
98
102
  accessibilityState: getAccessibilityState(disabled, state.checked, accessibilityState),
99
103
  enableFocusRing: true,
100
- focusable: !disabled,
104
+ focusable: true,
101
105
  onAccessibilityAction: onAccessibilityActionProp,
102
106
  ref: buttonRef,
103
107
  ...onKeyProps,
@@ -5,16 +5,18 @@ import { MenuItemCheckboxProps, MenuItemCheckboxState } from '../MenuItemCheckbo
5
5
  import { useMenuCheckboxInteraction } from '../MenuItemCheckbox/useMenuItemCheckbox';
6
6
 
7
7
  export const useMenuItemRadio = (props: MenuItemCheckboxProps): MenuItemCheckboxState => {
8
- const { name } = props;
8
+ const { disabled, name } = props;
9
9
  const context = useMenuListContext();
10
10
  const checked = context.checked?.[name];
11
11
  const selectRadio = context.selectRadio;
12
12
 
13
13
  const toggleChecked = React.useCallback(
14
14
  (e: InteractionEvent) => {
15
- selectRadio(e, name, !checked);
15
+ if (!disabled) {
16
+ selectRadio(e, name, !checked);
17
+ }
16
18
  },
17
- [checked, name, selectRadio],
19
+ [checked, disabled, name, selectRadio],
18
20
  );
19
21
 
20
22
  return useMenuCheckboxInteraction(props, toggleChecked);
@@ -1,26 +1,20 @@
1
1
  import React from 'react';
2
- import { stagedComponent, useFluentTheme } from '@fluentui-react-native/framework';
2
+ import { mergeProps, stagedComponent, useFluentTheme } from '@fluentui-react-native/framework';
3
3
  import { Callout } from '@fluentui-react-native/callout';
4
4
  import { menuPopoverName, MenuPopoverProps } from './MenuPopover.types';
5
5
  import { useMenuPopover } from './useMenuPopover';
6
+ import { View } from 'react-native';
6
7
 
7
8
  export const MenuPopover = stagedComponent((props: MenuPopoverProps) => {
8
9
  const state = useMenuPopover(props);
9
10
  const theme = useFluentTheme();
10
11
 
11
- return (_rest: MenuPopoverProps, children: React.ReactNode) => {
12
+ return (final: MenuPopoverProps, children: React.ReactNode) => {
13
+ const mergedProps = mergeProps(state.props, final);
14
+ const content = React.createElement(View, state.innerView, children);
12
15
  return (
13
- <Callout
14
- borderWidth={1}
15
- borderColor={theme.colors.neutralStrokeAccessible}
16
- target={state.triggerRef}
17
- onDismiss={state.onDismiss}
18
- dismissBehaviors={state.dismissBehaviors}
19
- setInitialFocus={state.setInitialFocus}
20
- directionalHint={state.directionalHint}
21
- doNotTakePointerCapture={state.doNotTakePointerCapture}
22
- >
23
- {children}
16
+ <Callout borderWidth={1} borderColor={theme.colors.neutralStrokeAccessible} {...mergedProps}>
17
+ {content}
24
18
  </Callout>
25
19
  );
26
20
  };
@@ -1,15 +1,11 @@
1
- import type { IViewProps } from '@fluentui-react-native/adapters';
2
- import { DirectionalHint, DismissBehaviors } from '@fluentui-react-native/callout';
1
+ import { IViewProps } from '@fluentui-react-native/adapters';
2
+ import { ICalloutProps } from '@fluentui-react-native/callout';
3
3
 
4
4
  export const menuPopoverName = 'MenuPopover';
5
5
 
6
- export interface MenuPopoverProps extends Omit<IViewProps, 'onPress'> {}
6
+ export type MenuPopoverProps = ICalloutProps;
7
7
 
8
8
  export interface MenuPopoverState {
9
- directionalHint?: DirectionalHint;
10
- dismissBehaviors: DismissBehaviors[];
11
- doNotTakePointerCapture: boolean;
12
- onDismiss: () => void;
13
- setInitialFocus: boolean;
14
- triggerRef: React.RefObject<React.Component>;
9
+ props: ICalloutProps;
10
+ innerView: IViewProps;
15
11
  }
@@ -3,24 +3,63 @@ import { I18nManager, Platform } from 'react-native';
3
3
  import { DirectionalHint, DismissBehaviors } from '@fluentui-react-native/callout';
4
4
  import { useMenuContext } from '../context/menuContext';
5
5
  import { MenuPopoverProps, MenuPopoverState } from './MenuPopover.types';
6
+ import { isCloseOnHoverOutEnabled } from '../consts';
6
7
 
7
8
  export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
8
9
  const context = useMenuContext();
9
- const setOpen = context.setOpen;
10
+ const {
11
+ setOpen,
12
+ triggerRef,
13
+ isControlled,
14
+ isSubmenu,
15
+ openOnHover,
16
+ parentPopoverHoverOutTimer,
17
+ popoverHoverOutTimer,
18
+ setPopoverHoverOutTimer,
19
+ triggerHoverOutTimer,
20
+ } = context;
10
21
 
11
- const triggerRef = context.triggerRef;
12
22
  const onDismiss = React.useCallback(() => setOpen(undefined, false /* isOpen */), [setOpen]);
13
- const dismissBehaviors = context.isControlled
14
- ? (['preventDismissOnKeyDown', 'preventDismissOnClickOutside'] as DismissBehaviors[])
15
- : undefined;
16
- const directionalHint = getDirectionalHint(context.isSubmenu, I18nManager.isRTL);
23
+ const dismissBehaviors = isControlled ? (['preventDismissOnKeyDown', 'preventDismissOnClickOutside'] as DismissBehaviors[]) : undefined;
24
+ const directionalHint = getDirectionalHint(isSubmenu, I18nManager.isRTL);
17
25
 
18
26
  // Initial focus behavior differs per platform, Windows platforms move focus
19
27
  // automatically onto first element of Callout
20
28
  const setInitialFocus = Platform.OS === ('win32' as any) || Platform.OS === 'windows';
21
- const doNotTakePointerCapture = context.openOnHover;
29
+ const doNotTakePointerCapture = openOnHover;
30
+ const accessibilityRole = 'menu';
22
31
 
23
- return { triggerRef, onDismiss, directionalHint, dismissBehaviors, doNotTakePointerCapture, setInitialFocus };
32
+ const onMouseEnter = React.useCallback(() => {
33
+ clearTimeout(triggerHoverOutTimer);
34
+ clearTimeout(popoverHoverOutTimer);
35
+ clearTimeout(parentPopoverHoverOutTimer);
36
+ }, [parentPopoverHoverOutTimer, popoverHoverOutTimer, triggerHoverOutTimer]);
37
+ const onMouseLeave = React.useCallback(() => {
38
+ if (!openOnHover) {
39
+ return;
40
+ }
41
+
42
+ const timer = setTimeout(() => {
43
+ setOpen(undefined, false /* isOpen */);
44
+ }, 500);
45
+ setPopoverHoverOutTimer(timer);
46
+ }, [openOnHover, setOpen, setPopoverHoverOutTimer]);
47
+
48
+ return {
49
+ props: {
50
+ accessibilityRole,
51
+ target: triggerRef,
52
+ onDismiss,
53
+ directionalHint,
54
+ dismissBehaviors,
55
+ doNotTakePointerCapture,
56
+ setInitialFocus,
57
+ },
58
+ innerView: {
59
+ onMouseEnter,
60
+ onMouseLeave: isCloseOnHoverOutEnabled && onMouseLeave,
61
+ },
62
+ };
24
63
  };
25
64
 
26
65
  const getDirectionalHint = (isSubmenu: boolean, isRtl: boolean): DirectionalHint | undefined => {