@fluentui-react-native/menu 0.3.2 → 0.5.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 (142) hide show
  1. package/CHANGELOG.json +76 -1
  2. package/CHANGELOG.md +31 -2
  3. package/lib/Menu/Menu.types.d.ts +1 -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 +4 -0
  7. package/lib/Menu/useMenu.js.map +1 -1
  8. package/lib/Menu/useMenuContextValue.js +1 -1
  9. package/lib/Menu/useMenuContextValue.js.map +1 -1
  10. package/lib/MenuItem/MenuItem.d.ts +3 -0
  11. package/lib/MenuItem/MenuItem.d.ts.map +1 -0
  12. package/lib/MenuItem/MenuItem.js +25 -0
  13. package/lib/MenuItem/MenuItem.js.map +1 -0
  14. package/lib/MenuItem/MenuItem.styling.d.ts +5 -0
  15. package/lib/MenuItem/MenuItem.styling.d.ts.map +1 -0
  16. package/lib/MenuItem/MenuItem.styling.js +26 -0
  17. package/lib/MenuItem/MenuItem.styling.js.map +1 -0
  18. package/lib/MenuItem/MenuItem.types.d.ts +45 -0
  19. package/lib/MenuItem/MenuItem.types.d.ts.map +1 -0
  20. package/lib/MenuItem/MenuItem.types.js +2 -0
  21. package/lib/MenuItem/MenuItem.types.js.map +1 -0
  22. package/lib/MenuItem/MenuItemTokens.d.ts +5 -0
  23. package/lib/MenuItem/MenuItemTokens.d.ts.map +1 -0
  24. package/lib/MenuItem/MenuItemTokens.js +26 -0
  25. package/lib/MenuItem/MenuItemTokens.js.map +1 -0
  26. package/lib/MenuItem/MenuItemTokens.win32.d.ts +5 -0
  27. package/lib/MenuItem/MenuItemTokens.win32.d.ts.map +1 -0
  28. package/lib/MenuItem/MenuItemTokens.win32.js +27 -0
  29. package/lib/MenuItem/MenuItemTokens.win32.js.map +1 -0
  30. package/lib/MenuItem/useMenuItem.d.ts +3 -0
  31. package/lib/MenuItem/useMenuItem.d.ts.map +1 -0
  32. package/lib/MenuItem/useMenuItem.js +25 -0
  33. package/lib/MenuItem/useMenuItem.js.map +1 -0
  34. package/lib/MenuList/MenuList.d.ts +4 -0
  35. package/lib/MenuList/MenuList.d.ts.map +1 -0
  36. package/lib/MenuList/MenuList.js +15 -0
  37. package/lib/MenuList/MenuList.js.map +1 -0
  38. package/lib/MenuList/MenuList.styling.d.ts +4 -0
  39. package/lib/MenuList/MenuList.styling.d.ts.map +1 -0
  40. package/lib/MenuList/MenuList.styling.js +14 -0
  41. package/lib/MenuList/MenuList.styling.js.map +1 -0
  42. package/lib/MenuList/MenuList.types.d.ts +17 -0
  43. package/lib/MenuList/MenuList.types.d.ts.map +1 -0
  44. package/lib/MenuList/MenuList.types.js +2 -0
  45. package/lib/MenuList/MenuList.types.js.map +1 -0
  46. package/lib/MenuList/MenuListTokens.d.ts +5 -0
  47. package/lib/MenuList/MenuListTokens.d.ts.map +1 -0
  48. package/lib/MenuList/MenuListTokens.js +8 -0
  49. package/lib/MenuList/MenuListTokens.js.map +1 -0
  50. package/lib/MenuList/MenuListTokens.win32.d.ts +5 -0
  51. package/lib/MenuList/MenuListTokens.win32.d.ts.map +1 -0
  52. package/lib/MenuList/MenuListTokens.win32.js +8 -0
  53. package/lib/MenuList/MenuListTokens.win32.js.map +1 -0
  54. package/lib/MenuPopover/MenuPopover.d.ts.map +1 -1
  55. package/lib/MenuPopover/MenuPopover.js +3 -2
  56. package/lib/MenuPopover/MenuPopover.js.map +1 -1
  57. package/lib/context/menuContext.d.ts.map +1 -1
  58. package/lib/context/menuContext.js +1 -0
  59. package/lib/context/menuContext.js.map +1 -1
  60. package/lib/index.d.ts +2 -0
  61. package/lib/index.d.ts.map +1 -1
  62. package/lib/index.js +2 -0
  63. package/lib/index.js.map +1 -1
  64. package/lib-commonjs/Menu/Menu.types.d.ts +1 -0
  65. package/lib-commonjs/Menu/Menu.types.d.ts.map +1 -1
  66. package/lib-commonjs/Menu/useMenu.d.ts.map +1 -1
  67. package/lib-commonjs/Menu/useMenu.js +4 -0
  68. package/lib-commonjs/Menu/useMenu.js.map +1 -1
  69. package/lib-commonjs/Menu/useMenuContextValue.js +1 -1
  70. package/lib-commonjs/Menu/useMenuContextValue.js.map +1 -1
  71. package/lib-commonjs/MenuItem/MenuItem.d.ts +3 -0
  72. package/lib-commonjs/MenuItem/MenuItem.d.ts.map +1 -0
  73. package/lib-commonjs/MenuItem/MenuItem.js +28 -0
  74. package/lib-commonjs/MenuItem/MenuItem.js.map +1 -0
  75. package/lib-commonjs/MenuItem/MenuItem.styling.d.ts +5 -0
  76. package/lib-commonjs/MenuItem/MenuItem.styling.d.ts.map +1 -0
  77. package/lib-commonjs/MenuItem/MenuItem.styling.js +29 -0
  78. package/lib-commonjs/MenuItem/MenuItem.styling.js.map +1 -0
  79. package/lib-commonjs/MenuItem/MenuItem.types.d.ts +45 -0
  80. package/lib-commonjs/MenuItem/MenuItem.types.d.ts.map +1 -0
  81. package/lib-commonjs/MenuItem/MenuItem.types.js +5 -0
  82. package/lib-commonjs/MenuItem/MenuItem.types.js.map +1 -0
  83. package/lib-commonjs/MenuItem/MenuItemTokens.d.ts +5 -0
  84. package/lib-commonjs/MenuItem/MenuItemTokens.d.ts.map +1 -0
  85. package/lib-commonjs/MenuItem/MenuItemTokens.js +30 -0
  86. package/lib-commonjs/MenuItem/MenuItemTokens.js.map +1 -0
  87. package/lib-commonjs/MenuItem/MenuItemTokens.win32.d.ts +5 -0
  88. package/lib-commonjs/MenuItem/MenuItemTokens.win32.d.ts.map +1 -0
  89. package/lib-commonjs/MenuItem/MenuItemTokens.win32.js +31 -0
  90. package/lib-commonjs/MenuItem/MenuItemTokens.win32.js.map +1 -0
  91. package/lib-commonjs/MenuItem/useMenuItem.d.ts +3 -0
  92. package/lib-commonjs/MenuItem/useMenuItem.d.ts.map +1 -0
  93. package/lib-commonjs/MenuItem/useMenuItem.js +29 -0
  94. package/lib-commonjs/MenuItem/useMenuItem.js.map +1 -0
  95. package/lib-commonjs/MenuList/MenuList.d.ts +4 -0
  96. package/lib-commonjs/MenuList/MenuList.d.ts.map +1 -0
  97. package/lib-commonjs/MenuList/MenuList.js +18 -0
  98. package/lib-commonjs/MenuList/MenuList.js.map +1 -0
  99. package/lib-commonjs/MenuList/MenuList.styling.d.ts +4 -0
  100. package/lib-commonjs/MenuList/MenuList.styling.d.ts.map +1 -0
  101. package/lib-commonjs/MenuList/MenuList.styling.js +17 -0
  102. package/lib-commonjs/MenuList/MenuList.styling.js.map +1 -0
  103. package/lib-commonjs/MenuList/MenuList.types.d.ts +17 -0
  104. package/lib-commonjs/MenuList/MenuList.types.d.ts.map +1 -0
  105. package/lib-commonjs/MenuList/MenuList.types.js +5 -0
  106. package/lib-commonjs/MenuList/MenuList.types.js.map +1 -0
  107. package/lib-commonjs/MenuList/MenuListTokens.d.ts +5 -0
  108. package/lib-commonjs/MenuList/MenuListTokens.d.ts.map +1 -0
  109. package/lib-commonjs/MenuList/MenuListTokens.js +12 -0
  110. package/lib-commonjs/MenuList/MenuListTokens.js.map +1 -0
  111. package/lib-commonjs/MenuList/MenuListTokens.win32.d.ts +5 -0
  112. package/lib-commonjs/MenuList/MenuListTokens.win32.d.ts.map +1 -0
  113. package/lib-commonjs/MenuList/MenuListTokens.win32.js +12 -0
  114. package/lib-commonjs/MenuList/MenuListTokens.win32.js.map +1 -0
  115. package/lib-commonjs/MenuPopover/MenuPopover.d.ts.map +1 -1
  116. package/lib-commonjs/MenuPopover/MenuPopover.js +2 -1
  117. package/lib-commonjs/MenuPopover/MenuPopover.js.map +1 -1
  118. package/lib-commonjs/context/menuContext.d.ts.map +1 -1
  119. package/lib-commonjs/context/menuContext.js +1 -0
  120. package/lib-commonjs/context/menuContext.js.map +1 -1
  121. package/lib-commonjs/index.d.ts +2 -0
  122. package/lib-commonjs/index.d.ts.map +1 -1
  123. package/lib-commonjs/index.js +5 -1
  124. package/lib-commonjs/index.js.map +1 -1
  125. package/package.json +9 -4
  126. package/src/Menu/Menu.types.ts +1 -0
  127. package/src/Menu/useMenu.ts +4 -0
  128. package/src/Menu/useMenuContextValue.ts +1 -1
  129. package/src/MenuItem/MenuItem.styling.ts +45 -0
  130. package/src/MenuItem/MenuItem.tsx +37 -0
  131. package/src/MenuItem/MenuItem.types.ts +54 -0
  132. package/src/MenuItem/MenuItemTokens.ts +29 -0
  133. package/src/MenuItem/MenuItemTokens.win32.ts +30 -0
  134. package/src/MenuItem/useMenuItem.ts +40 -0
  135. package/src/MenuList/MenuList.styling.ts +20 -0
  136. package/src/MenuList/MenuList.tsx +23 -0
  137. package/src/MenuList/MenuList.types.ts +17 -0
  138. package/src/MenuList/MenuListTokens.ts +11 -0
  139. package/src/MenuList/MenuListTokens.win32.ts +11 -0
  140. package/src/MenuPopover/MenuPopover.tsx +7 -2
  141. package/src/context/menuContext.ts +1 -0
  142. package/src/index.ts +2 -0
@@ -9,8 +9,9 @@ var MenuPopover_types_1 = require("./MenuPopover.types");
9
9
  var useMenuPopover_1 = require("./useMenuPopover");
10
10
  exports.MenuPopover = (0, framework_1.stagedComponent)(function (props) {
11
11
  var state = (0, useMenuPopover_1.useMenuPopover)(props);
12
+ var theme = (0, framework_1.useFluentTheme)();
12
13
  return function (_rest, children) {
13
- return react_1.default.createElement(callout_1.Callout, { target: state.triggerRef }, children);
14
+ return (react_1.default.createElement(callout_1.Callout, { target: state.triggerRef, borderWidth: 1, borderColor: theme.colors.neutralStrokeAccessible }, children));
14
15
  };
15
16
  });
16
17
  exports.MenuPopover.displayName = MenuPopover_types_1.menuPopoverName;
@@ -1 +1 @@
1
- {"version":3,"file":"MenuPopover.js","sourceRoot":"","sources":["../../src/MenuPopover/MenuPopover.tsx"],"names":[],"mappings":";;;;AAAA,6DAA0B;AAC1B,8DAAmE;AACnE,0DAAyD;AACzD,yDAAwE;AACxE,mDAAkD;AAErC,QAAA,WAAW,GAAG,IAAA,2BAAe,EAAC,UAAC,KAAuB;IACjE,IAAM,KAAK,GAAG,IAAA,+BAAc,EAAC,KAAK,CAAC,CAAC;IAEpC,OAAO,UAAC,KAAuB,EAAE,QAAyB;QACxD,OAAO,8BAAC,iBAAO,IAAC,MAAM,EAAE,KAAK,CAAC,UAAU,IAAG,QAAQ,CAAW,CAAC;IACjE,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,mBAAW,CAAC,WAAW,GAAG,mCAAe,CAAC;AAE1C,kBAAe,mBAAW,CAAC"}
1
+ {"version":3,"file":"MenuPopover.js","sourceRoot":"","sources":["../../src/MenuPopover/MenuPopover.tsx"],"names":[],"mappings":";;;;AAAA,6DAA0B;AAC1B,8DAAmF;AACnF,0DAAyD;AACzD,yDAAwE;AACxE,mDAAkD;AAErC,QAAA,WAAW,GAAG,IAAA,2BAAe,EAAC,UAAC,KAAuB;IACjE,IAAM,KAAK,GAAG,IAAA,+BAAc,EAAC,KAAK,CAAC,CAAC;IACpC,IAAM,KAAK,GAAG,IAAA,0BAAc,GAAE,CAAC;IAE/B,OAAO,UAAC,KAAuB,EAAE,QAAyB;QACxD,OAAO,CACL,8BAAC,iBAAO,IAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,uBAAuB,IACjG,QAAQ,CACD,CACX,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,mBAAW,CAAC,WAAW,GAAG,mCAAe,CAAC;AAE1C,kBAAe,mBAAW,CAAC"}
@@ -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,0BAItB,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,oBAAY,gBAAgB,GAAG,SAAS,CAAC;AAEzC,eAAO,MAAM,WAAW,0BAKtB,CAAC;AAEH,eAAO,MAAM,YAAY,2BAAuB,CAAC;AACjD,eAAO,MAAM,cAAc,iBAAsC,CAAC"}
@@ -4,6 +4,7 @@ exports.useMenuContext = exports.MenuProvider = exports.MenuContext = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var React = (0, tslib_1.__importStar)(require("react"));
6
6
  exports.MenuContext = React.createContext({
7
+ isSubmenu: false,
7
8
  open: false,
8
9
  setOpen: function () { return false; },
9
10
  triggerRef: null,
@@ -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,IAAI,EAAE,KAAK;IACX,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;AAQlB,QAAA,WAAW,GAAG,KAAK,CAAC,aAAa,CAAmB;IAC/D,SAAS,EAAE,KAAK;IAChB,IAAI,EAAE,KAAK;IACX,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,4 +1,6 @@
1
1
  export { Menu } from './Menu/Menu';
2
2
  export { MenuTrigger } from './MenuTrigger/MenuTrigger';
3
3
  export { MenuPopover } from './MenuPopover/MenuPopover';
4
+ export { MenuItem } from './MenuItem/MenuItem';
5
+ export { MenuList } from './MenuList/MenuList';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,10 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MenuPopover = exports.MenuTrigger = exports.Menu = void 0;
3
+ exports.MenuList = exports.MenuItem = exports.MenuPopover = exports.MenuTrigger = exports.Menu = void 0;
4
4
  var Menu_1 = require("./Menu/Menu");
5
5
  Object.defineProperty(exports, "Menu", { enumerable: true, get: function () { return Menu_1.Menu; } });
6
6
  var MenuTrigger_1 = require("./MenuTrigger/MenuTrigger");
7
7
  Object.defineProperty(exports, "MenuTrigger", { enumerable: true, get: function () { return MenuTrigger_1.MenuTrigger; } });
8
8
  var MenuPopover_1 = require("./MenuPopover/MenuPopover");
9
9
  Object.defineProperty(exports, "MenuPopover", { enumerable: true, get: function () { return MenuPopover_1.MenuPopover; } });
10
+ var MenuItem_1 = require("./MenuItem/MenuItem");
11
+ Object.defineProperty(exports, "MenuItem", { enumerable: true, get: function () { return MenuItem_1.MenuItem; } });
12
+ var MenuList_1 = require("./MenuList/MenuList");
13
+ Object.defineProperty(exports, "MenuList", { enumerable: true, get: function () { return MenuList_1.MenuList; } });
10
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,oCAAmC;AAA1B,4FAAA,IAAI,OAAA;AACb,yDAAwD;AAA/C,0GAAA,WAAW,OAAA;AACpB,yDAAwD;AAA/C,0GAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,oCAAmC;AAA1B,4FAAA,IAAI,OAAA;AACb,yDAAwD;AAA/C,0GAAA,WAAW,OAAA;AACpB,yDAAwD;AAA/C,0GAAA,WAAW,OAAA;AACpB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA;AACjB,gDAA+C;AAAtC,oGAAA,QAAQ,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-react-native/menu",
3
- "version": "0.3.2",
3
+ "version": "0.5.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",
@@ -23,9 +23,14 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@fluentui-react-native/adapters": ">=0.8.5 <1.0.0",
26
- "@fluentui-react-native/callout": ">=0.19.45 <1.0.0",
27
- "@fluentui-react-native/framework": "0.7.25",
28
- "@fluentui-react-native/interactive-hooks": ">=0.15.5 <1.0.0",
26
+ "@fluentui-react-native/callout": ">=0.20.0 <1.0.0",
27
+ "@fluentui-react-native/experimental-text": ">=0.7.26 <1.0.0",
28
+ "@fluentui-react-native/framework": "0.7.26",
29
+ "@fluentui-react-native/interactive-hooks": ">=0.15.6 <1.0.0",
30
+ "@fluentui-react-native/theme-tokens": ">=0.16.2 <1.0.0",
31
+ "@fluentui-react-native/tokens": ">=0.12.0 <1.0.0",
32
+ "@fluentui-react-native/use-styling": ">=0.8.3 <1.0.0",
33
+ "react-native-svg": "^12.3.0",
29
34
  "tslib": "^2.3.1"
30
35
  },
31
36
  "devDependencies": {
@@ -8,6 +8,7 @@ export interface MenuProps extends Omit<IViewProps, 'onPress'> {
8
8
  }
9
9
 
10
10
  export interface MenuState extends MenuProps {
11
+ isSubmenu: boolean;
11
12
  setOpen: (isOpen: boolean) => void;
12
13
  triggerRef: React.RefObject<React.Component>;
13
14
  }
@@ -1,14 +1,18 @@
1
1
  import React from 'react';
2
+ import { useMenuContext } from '../context/menuContext';
2
3
  import { MenuProps, MenuState } from './Menu.types';
3
4
 
4
5
  export const useMenu = (props: MenuProps): MenuState => {
5
6
  const [open, setOpen] = useMenuOpenState(props);
6
7
  const triggerRef = React.useRef(null);
8
+ const context = useMenuContext();
9
+ const isSubmenu = context.triggerRef !== null;
7
10
 
8
11
  return {
9
12
  open,
10
13
  setOpen,
11
14
  triggerRef,
15
+ isSubmenu,
12
16
  };
13
17
  };
14
18
 
@@ -2,5 +2,5 @@ import { MenuContextValue } from '../context/menuContext';
2
2
  import { MenuState } from './Menu.types';
3
3
 
4
4
  export const useMenuContextValue = (state: MenuState): MenuContextValue => {
5
- return { open: state.open, setOpen: state.setOpen, triggerRef: state.triggerRef };
5
+ return { open: state.open, setOpen: state.setOpen, triggerRef: state.triggerRef, isSubmenu: state.isSubmenu };
6
6
  };
@@ -0,0 +1,45 @@
1
+ import { Theme, UseStylingOptions, buildProps } from '@fluentui-react-native/framework';
2
+ import { fontStyles, layoutStyles } from '@fluentui-react-native/tokens';
3
+ import { defaultMenuItemTokens } from './MenuItemTokens';
4
+ import { menuItemName, MenuItemProps, MenuItemTokens, MenuItemSlotProps } from './MenuItem.types';
5
+
6
+ export const menuItemStates: (keyof MenuItemTokens)[] = ['hovered', 'focused', 'pressed', 'disabled'];
7
+
8
+ export const stylingSettings: UseStylingOptions<MenuItemProps, MenuItemSlotProps, MenuItemTokens> = {
9
+ tokens: [defaultMenuItemTokens, menuItemName],
10
+ states: menuItemStates,
11
+ slotProps: {
12
+ root: buildProps(
13
+ (tokens: MenuItemTokens, theme: Theme) => ({
14
+ style: {
15
+ alignItems: 'center',
16
+ backgroundColor: tokens.backgroundColor,
17
+ display: 'flex',
18
+ flexDirection: 'row',
19
+ ...layoutStyles.from(tokens, theme),
20
+ },
21
+ }),
22
+ ['backgroundColor', ...layoutStyles.keys],
23
+ ),
24
+ content: buildProps(
25
+ (tokens: MenuItemTokens, theme: Theme) => {
26
+ return {
27
+ style: {
28
+ flexGrow: 1,
29
+ color: tokens.color,
30
+ ...fontStyles.from(tokens, theme),
31
+ },
32
+ };
33
+ },
34
+ ['color', ...fontStyles.keys],
35
+ ),
36
+ submenuIndicator: buildProps(
37
+ (tokens: MenuItemTokens) => {
38
+ return {
39
+ color: tokens.color,
40
+ };
41
+ },
42
+ ['color'],
43
+ ),
44
+ },
45
+ };
@@ -0,0 +1,37 @@
1
+ /** @jsx withSlots */
2
+ import { View } from 'react-native';
3
+ import { SvgXml } from 'react-native-svg';
4
+ import { compose, mergeProps, UseSlots, withSlots } from '@fluentui-react-native/framework';
5
+ import { Text } from '@fluentui-react-native/experimental-text';
6
+ import { menuItemName, MenuItemProps, MenuItemType } from './MenuItem.types';
7
+ import { useMenuItem } from './useMenuItem';
8
+ import { stylingSettings } from './MenuItem.styling';
9
+
10
+ export const MenuItem = compose<MenuItemType>({
11
+ displayName: menuItemName,
12
+ ...stylingSettings,
13
+ slots: {
14
+ root: View,
15
+ content: Text,
16
+ submenuIndicator: SvgXml,
17
+ },
18
+ useRender: (userProps: MenuItemProps, useSlots: UseSlots<MenuItemType>) => {
19
+ const menuItem = useMenuItem(userProps);
20
+ const Slots = useSlots(userProps, (layer): boolean => menuItem.state[layer]);
21
+
22
+ return (final: MenuItemProps) => {
23
+ const mergedProps = mergeProps(menuItem.props, final);
24
+ const chevronXml = `
25
+ <svg width="12" height="16" viewBox="0 0 11 6">
26
+ <path fill='currentColor' d='M0.646447 0.646447C0.841709 0.451184 1.15829 0.451184 1.35355 0.646447L5.5 4.79289L9.64645 0.646447C9.84171 0.451185 10.1583 0.451185 10.3536 0.646447C10.5488 0.841709 10.5488 1.15829 10.3536 1.35355L5.85355 5.85355C5.65829 6.04882 5.34171 6.04882 5.14645 5.85355L0.646447 1.35355C0.451184 1.15829 0.451184 0.841709 0.646447 0.646447Z' />
27
+ </svg>`;
28
+
29
+ return (
30
+ <Slots.root {...mergedProps}>
31
+ {mergedProps.content && <Slots.content>{mergedProps.content}</Slots.content>}
32
+ {mergedProps.hasSubmenu && <Slots.submenuIndicator xml={chevronXml} />}
33
+ </Slots.root>
34
+ );
35
+ };
36
+ },
37
+ });
@@ -0,0 +1,54 @@
1
+ import * as React from 'react';
2
+ import { ViewProps } from 'react-native';
3
+ import { SvgProps, XmlProps } from 'react-native-svg';
4
+ import type { IViewProps } from '@fluentui-react-native/adapters';
5
+ import { TextProps } from '@fluentui-react-native/experimental-text';
6
+ import { IFocusable, InteractionEvent, IPressableHooks, IWithPressableOptions } from '@fluentui-react-native/interactive-hooks';
7
+ import { FontTokens, IBorderTokens, IColorTokens, LayoutTokens } from '@fluentui-react-native/tokens';
8
+
9
+ export const menuItemName = 'MenuItem';
10
+
11
+ export interface MenuItemTokens extends LayoutTokens, FontTokens, IBorderTokens, IColorTokens {
12
+ disabled?: MenuItemTokens;
13
+ focused?: MenuItemTokens;
14
+ hovered?: MenuItemTokens;
15
+ pressed?: MenuItemTokens;
16
+ }
17
+
18
+ export interface MenuItemProps extends Omit<IWithPressableOptions<ViewProps>, 'onPress'> {
19
+ content: string;
20
+
21
+ /**
22
+ * Applies disabled styles to menu item but remains focusable
23
+ */
24
+ disabled?: boolean;
25
+
26
+ /**
27
+ * A RefObject to access the IButton interface. Use this to access the public methods and properties of the component.
28
+ */
29
+ componentRef?: React.RefObject<IFocusable>;
30
+
31
+ /**
32
+ * If the menu item is a trigger for a submenu
33
+ */
34
+ hasSubmenu?: boolean;
35
+
36
+ /**
37
+ * A callback to call on button click event
38
+ */
39
+ onClick?: (e: InteractionEvent) => void;
40
+ }
41
+
42
+ export type MenuItemState = IPressableHooks<MenuItemProps & React.ComponentPropsWithRef<any>>;
43
+
44
+ export interface MenuItemSlotProps {
45
+ root: React.PropsWithRef<IViewProps>;
46
+ content?: TextProps;
47
+ submenuIndicator?: SvgProps | XmlProps;
48
+ }
49
+
50
+ export interface MenuItemType {
51
+ props: MenuItemProps;
52
+ tokens: MenuItemTokens;
53
+ slotProps: MenuItemSlotProps;
54
+ }
@@ -0,0 +1,29 @@
1
+ import { FontWeightValue, Theme } from '@fluentui-react-native/framework';
2
+ import { globalTokens } from '@fluentui-react-native/theme-tokens';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+ import { MenuItemTokens } from './MenuItem.types';
5
+
6
+ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: Theme): MenuItemTokens => ({
7
+ backgroundColor: t.colors.neutralBackground1,
8
+ borderRadius: globalTokens.corner.radius.medium,
9
+ color: t.colors.neutralForeground2,
10
+ fontFamily: t.typography.families.primary,
11
+ fontSize: globalTokens.font.size[300],
12
+ fontWeight: globalTokens.font.weight.regular as FontWeightValue,
13
+ minHeight: 32,
14
+ minWidth: 160,
15
+ maxWidth: 300,
16
+ padding: globalTokens.spacing.sNudge,
17
+ hovered: {
18
+ backgroundColor: t.colors.neutralBackground1Hover,
19
+ color: t.colors.neutralForeground2Hover,
20
+ },
21
+ pressed: {
22
+ backgroundColor: t.colors.neutralBackground1Pressed,
23
+ color: t.colors.neutralForeground2Pressed,
24
+ },
25
+ disabled: {
26
+ backgroundColor: t.colors.neutralBackground1,
27
+ color: t.colors.neutralForegroundDisabled,
28
+ },
29
+ });
@@ -0,0 +1,30 @@
1
+ import { FontWeightValue, Theme } from '@fluentui-react-native/framework';
2
+ import { globalTokens } from '@fluentui-react-native/theme-tokens';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+ import { MenuItemTokens } from './MenuItem.types';
5
+
6
+ export const defaultMenuItemTokens: TokenSettings<MenuItemTokens, Theme> = (t: Theme): MenuItemTokens => ({
7
+ backgroundColor: t.colors.neutralBackground1,
8
+ borderRadius: globalTokens.corner.radius.none,
9
+ color: t.colors.neutralForeground1,
10
+ fontFamily: t.typography.families.primary,
11
+ fontSize: globalTokens.font.size[200],
12
+ fontWeight: globalTokens.font.weight.regular as FontWeightValue,
13
+ minHeight: 24,
14
+ minWidth: 160,
15
+ maxWidth: 300,
16
+ padding: globalTokens.spacing.xs,
17
+ paddingHorizontal: globalTokens.spacing.s,
18
+ hovered: {
19
+ backgroundColor: t.colors.neutralBackground1Hover,
20
+ color: t.colors.neutralForeground1Hover,
21
+ },
22
+ pressed: {
23
+ backgroundColor: t.colors.neutralBackground1Pressed,
24
+ color: t.colors.neutralForeground1Pressed,
25
+ },
26
+ disabled: {
27
+ backgroundColor: t.colors.neutralBackground1,
28
+ color: t.colors.neutralForegroundDisabled,
29
+ },
30
+ });
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { AccessibilityState } from 'react-native';
3
+ import { MenuItemProps, MenuItemState } from './MenuItem.types';
4
+ import { memoize } from '@fluentui-react-native/framework';
5
+ import { useAsPressable, useKeyProps } from '@fluentui-react-native/interactive-hooks';
6
+ import { useMenuContext } from '../context/menuContext';
7
+
8
+ export const useMenuItem = (props: MenuItemProps): MenuItemState => {
9
+ // attach the pressable state handlers
10
+ const defaultComponentRef = React.useRef(null);
11
+ const { onClick, accessibilityState, componentRef = defaultComponentRef, disabled, ...rest } = props;
12
+ const pressable = useAsPressable({ ...rest, disabled, onPress: onClick });
13
+ const onKeyProps = useKeyProps(onClick, ' ', 'Enter');
14
+ const hasSubmenu = useMenuContext().isSubmenu;
15
+
16
+ return {
17
+ props: {
18
+ ...pressable.props,
19
+ accessible: true,
20
+ accessibilityRole: 'button',
21
+ onAccessibilityTap: props.onAccessibilityTap || props.onClick,
22
+ accessibilityLabel: props.accessibilityLabel,
23
+ accessibilityState: getAccessibilityState(disabled, accessibilityState),
24
+ enableFocusRing: true,
25
+ focusable: !disabled,
26
+ hasSubmenu,
27
+ ref: componentRef,
28
+ ...onKeyProps,
29
+ },
30
+ state: pressable.state,
31
+ };
32
+ };
33
+
34
+ const getAccessibilityState = memoize(getAccessibilityStateWorker);
35
+ function getAccessibilityStateWorker(disabled: boolean, accessibilityState?: AccessibilityState) {
36
+ if (accessibilityState) {
37
+ return { disabled, ...accessibilityState };
38
+ }
39
+ return { disabled };
40
+ }
@@ -0,0 +1,20 @@
1
+ import { Theme, UseStylingOptions, buildProps } from '@fluentui-react-native/framework';
2
+ import { layoutStyles } from '@fluentui-react-native/tokens';
3
+ import { defaultMenuListTokens } from './MenuListTokens';
4
+ import { menuListName, MenuListProps, MenuListTokens, MenuListSlotProps } from './MenuList.types';
5
+
6
+ export const stylingSettings: UseStylingOptions<MenuListProps, MenuListSlotProps, MenuListTokens> = {
7
+ tokens: [defaultMenuListTokens, menuListName],
8
+ slotProps: {
9
+ root: buildProps(
10
+ (tokens: MenuListTokens, theme: Theme) => ({
11
+ style: {
12
+ backgroundColor: tokens.backgroundColor,
13
+ display: 'flex',
14
+ ...layoutStyles.from(tokens, theme),
15
+ },
16
+ }),
17
+ ['backgroundColor', ...layoutStyles.keys],
18
+ ),
19
+ },
20
+ };
@@ -0,0 +1,23 @@
1
+ /** @jsx withSlots */
2
+ import React from 'react';
3
+ import { View } from 'react-native';
4
+ import { compose, UseSlots, withSlots } from '@fluentui-react-native/framework';
5
+ import { menuListName, MenuListProps, MenuListType } from './MenuList.types';
6
+ import { stylingSettings } from './MenuList.styling';
7
+
8
+ export const MenuList = compose<MenuListType>({
9
+ displayName: menuListName,
10
+ ...stylingSettings,
11
+ slots: {
12
+ root: View,
13
+ },
14
+ useRender: (userProps: MenuListProps, useSlots: UseSlots<MenuListType>) => {
15
+ const Slots = useSlots(userProps);
16
+
17
+ return (_final: MenuListProps, children: React.ReactNode) => {
18
+ return <Slots.root>{children}</Slots.root>;
19
+ };
20
+ },
21
+ });
22
+
23
+ export default MenuList;
@@ -0,0 +1,17 @@
1
+ import type { IViewProps } from '@fluentui-react-native/adapters';
2
+ import { IBackgroundColorTokens, LayoutTokens } from '@fluentui-react-native/tokens';
3
+
4
+ export const menuListName = 'MenuList';
5
+
6
+ export interface MenuListTokens extends LayoutTokens, IBackgroundColorTokens {}
7
+
8
+ export interface MenuListProps extends Omit<IViewProps, 'onPress'> {}
9
+
10
+ export interface MenuListSlotProps {
11
+ root: React.PropsWithRef<IViewProps>;
12
+ }
13
+ export interface MenuListType {
14
+ props: MenuListProps;
15
+ tokens: MenuListTokens;
16
+ slotProps: MenuListSlotProps;
17
+ }
@@ -0,0 +1,11 @@
1
+ import { Theme } from '@fluentui-react-native/framework';
2
+ import { globalTokens } from '@fluentui-react-native/theme-tokens';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+ import { MenuListTokens } from './MenuList.types';
5
+
6
+ export const defaultMenuListTokens: TokenSettings<MenuListTokens, Theme> = (t: Theme): MenuListTokens => ({
7
+ padding: globalTokens.spacing.xs,
8
+ minWidth: 128,
9
+ maxWidth: 300,
10
+ backgroundColor: t.colors.neutralBackground1,
11
+ });
@@ -0,0 +1,11 @@
1
+ import { Theme } from '@fluentui-react-native/framework';
2
+ import { globalTokens } from '@fluentui-react-native/theme-tokens';
3
+ import { TokenSettings } from '@fluentui-react-native/use-styling';
4
+ import { MenuListTokens } from './MenuList.types';
5
+
6
+ export const defaultMenuListTokens: TokenSettings<MenuListTokens, Theme> = (t: Theme): MenuListTokens => ({
7
+ paddingVertical: globalTokens.spacing.xs,
8
+ minWidth: 128,
9
+ maxWidth: 300,
10
+ backgroundColor: t.colors.neutralBackground1,
11
+ });
@@ -1,14 +1,19 @@
1
1
  import React from 'react';
2
- import { stagedComponent } from '@fluentui-react-native/framework';
2
+ import { 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
6
 
7
7
  export const MenuPopover = stagedComponent((props: MenuPopoverProps) => {
8
8
  const state = useMenuPopover(props);
9
+ const theme = useFluentTheme();
9
10
 
10
11
  return (_rest: MenuPopoverProps, children: React.ReactNode) => {
11
- return <Callout target={state.triggerRef}>{children}</Callout>;
12
+ return (
13
+ <Callout target={state.triggerRef} borderWidth={1} borderColor={theme.colors.neutralStrokeAccessible}>
14
+ {children}
15
+ </Callout>
16
+ );
12
17
  };
13
18
  });
14
19
  MenuPopover.displayName = menuPopoverName;
@@ -7,6 +7,7 @@ import type { MenuState } from '../Menu/Menu.types';
7
7
  export type MenuContextValue = MenuState;
8
8
 
9
9
  export const MenuContext = React.createContext<MenuContextValue>({
10
+ isSubmenu: false,
10
11
  open: false,
11
12
  setOpen: () => false,
12
13
  triggerRef: null,
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { Menu } from './Menu/Menu';
2
2
  export { MenuTrigger } from './MenuTrigger/MenuTrigger';
3
3
  export { MenuPopover } from './MenuPopover/MenuPopover';
4
+ export { MenuItem } from './MenuItem/MenuItem';
5
+ export { MenuList } from './MenuList/MenuList';