@fluentui-react-native/menu 0.13.0 → 0.14.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.
- package/CHANGELOG.json +58 -1
- package/CHANGELOG.md +28 -2
- package/jest.config.js +2 -0
- package/lib/Menu/Menu.types.d.ts +2 -0
- package/lib/Menu/Menu.types.d.ts.map +1 -1
- package/lib/Menu/useMenu.d.ts.map +1 -1
- package/lib/Menu/useMenu.js +8 -3
- package/lib/Menu/useMenu.js.map +1 -1
- package/lib/Menu/useMenuContextValue.d.ts.map +1 -1
- package/lib/Menu/useMenuContextValue.js +4 -1
- package/lib/Menu/useMenuContextValue.js.map +1 -1
- package/lib/MenuPopover/MenuPopover.d.ts.map +1 -1
- package/lib/MenuPopover/MenuPopover.js +7 -3
- package/lib/MenuPopover/MenuPopover.js.map +1 -1
- package/lib/MenuPopover/MenuPopover.types.d.ts +4 -10
- package/lib/MenuPopover/MenuPopover.types.d.ts.map +1 -1
- package/lib/MenuPopover/useMenuPopover.d.ts.map +1 -1
- package/lib/MenuPopover/useMenuPopover.js +35 -8
- package/lib/MenuPopover/useMenuPopover.js.map +1 -1
- package/lib/MenuTrigger/MenuTrigger.js +8 -8
- package/lib/MenuTrigger/MenuTrigger.js.map +1 -1
- package/lib/MenuTrigger/useMenuTrigger.d.ts.map +1 -1
- package/lib/MenuTrigger/useMenuTrigger.js +21 -20
- package/lib/MenuTrigger/useMenuTrigger.js.map +1 -1
- package/lib/__tests__/Menu.test.d.ts +2 -0
- package/lib/__tests__/Menu.test.d.ts.map +1 -0
- package/lib/__tests__/Menu.test.js +145 -0
- package/lib/__tests__/Menu.test.js.map +1 -0
- package/lib/consts.d.ts +3 -0
- package/lib/consts.d.ts.map +1 -0
- package/lib/consts.js +7 -0
- package/lib/consts.js.map +1 -0
- package/lib/context/menuContext.d.ts +10 -4
- package/lib/context/menuContext.d.ts.map +1 -1
- package/lib/context/menuContext.js.map +1 -1
- package/lib-commonjs/Menu/Menu.types.d.ts +2 -0
- package/lib-commonjs/Menu/Menu.types.d.ts.map +1 -1
- package/lib-commonjs/Menu/useMenu.d.ts.map +1 -1
- package/lib-commonjs/Menu/useMenu.js +8 -3
- package/lib-commonjs/Menu/useMenu.js.map +1 -1
- package/lib-commonjs/Menu/useMenuContextValue.d.ts.map +1 -1
- package/lib-commonjs/Menu/useMenuContextValue.js +4 -1
- package/lib-commonjs/Menu/useMenuContextValue.js.map +1 -1
- package/lib-commonjs/MenuPopover/MenuPopover.d.ts.map +1 -1
- package/lib-commonjs/MenuPopover/MenuPopover.js +5 -2
- package/lib-commonjs/MenuPopover/MenuPopover.js.map +1 -1
- package/lib-commonjs/MenuPopover/MenuPopover.types.d.ts +4 -10
- package/lib-commonjs/MenuPopover/MenuPopover.types.d.ts.map +1 -1
- package/lib-commonjs/MenuPopover/useMenuPopover.d.ts.map +1 -1
- package/lib-commonjs/MenuPopover/useMenuPopover.js +35 -8
- package/lib-commonjs/MenuPopover/useMenuPopover.js.map +1 -1
- package/lib-commonjs/MenuTrigger/MenuTrigger.js +8 -8
- package/lib-commonjs/MenuTrigger/MenuTrigger.js.map +1 -1
- package/lib-commonjs/MenuTrigger/useMenuTrigger.d.ts.map +1 -1
- package/lib-commonjs/MenuTrigger/useMenuTrigger.js +21 -20
- package/lib-commonjs/MenuTrigger/useMenuTrigger.js.map +1 -1
- package/lib-commonjs/__tests__/Menu.test.d.ts +2 -0
- package/lib-commonjs/__tests__/Menu.test.d.ts.map +1 -0
- package/lib-commonjs/__tests__/Menu.test.js +148 -0
- package/lib-commonjs/__tests__/Menu.test.js.map +1 -0
- package/lib-commonjs/consts.d.ts +3 -0
- package/lib-commonjs/consts.d.ts.map +1 -0
- package/lib-commonjs/consts.js +10 -0
- package/lib-commonjs/consts.js.map +1 -0
- package/lib-commonjs/context/menuContext.d.ts +10 -4
- package/lib-commonjs/context/menuContext.d.ts.map +1 -1
- package/lib-commonjs/context/menuContext.js.map +1 -1
- package/package.json +5 -3
- package/src/Menu/Menu.types.ts +1 -0
- package/src/Menu/useMenu.ts +9 -2
- package/src/Menu/useMenuContextValue.ts +4 -1
- package/src/MenuPopover/MenuPopover.tsx +7 -14
- package/src/MenuPopover/MenuPopover.types.ts +4 -9
- package/src/MenuPopover/useMenuPopover.ts +48 -8
- package/src/MenuTrigger/MenuTrigger.tsx +9 -9
- package/src/MenuTrigger/useMenuTrigger.ts +36 -26
- package/src/__tests__/Menu.test.tsx +235 -0
- package/src/__tests__/__snapshots__/Menu.test.tsx.snap +2098 -0
- package/src/consts.ts +8 -0
- package/src/context/menuContext.ts +6 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var tslib_1 = require("tslib");
|
|
4
|
+
var React = (0, tslib_1.__importStar)(require("react"));
|
|
5
|
+
var renderer = (0, tslib_1.__importStar)(require("react-test-renderer"));
|
|
6
|
+
var Menu_1 = require("../Menu/Menu");
|
|
7
|
+
var test_tools_1 = require("@fluentui-react-native/test-tools");
|
|
8
|
+
var MenuTrigger_1 = (0, tslib_1.__importDefault)(require("../MenuTrigger/MenuTrigger"));
|
|
9
|
+
var button_1 = require("@fluentui-react-native/button");
|
|
10
|
+
var MenuPopover_1 = (0, tslib_1.__importDefault)(require("../MenuPopover/MenuPopover"));
|
|
11
|
+
var MenuList_1 = require("../MenuList/MenuList");
|
|
12
|
+
var MenuItem_1 = require("../MenuItem/MenuItem");
|
|
13
|
+
var MenuItemCheckbox_1 = require("../MenuItemCheckbox/MenuItemCheckbox");
|
|
14
|
+
var MenuDivider_1 = require("../MenuDivider/MenuDivider");
|
|
15
|
+
var MenuItemRadio_1 = require("../MenuItemRadio/MenuItemRadio");
|
|
16
|
+
describe('Checkbox component tests', function () {
|
|
17
|
+
it('Menu default', function () {
|
|
18
|
+
var tree = renderer
|
|
19
|
+
.create(React.createElement(Menu_1.Menu, null,
|
|
20
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
21
|
+
React.createElement(button_1.ButtonV1, null, "Default")),
|
|
22
|
+
React.createElement(MenuPopover_1.default, null,
|
|
23
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
24
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" })))))
|
|
25
|
+
.toJSON();
|
|
26
|
+
expect(tree).toMatchSnapshot();
|
|
27
|
+
});
|
|
28
|
+
it('Menu open', function () {
|
|
29
|
+
var tree = renderer
|
|
30
|
+
.create(React.createElement(Menu_1.Menu, { open: true },
|
|
31
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
32
|
+
React.createElement(button_1.ButtonV1, null, "Open")),
|
|
33
|
+
React.createElement(MenuPopover_1.default, null,
|
|
34
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
35
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" })))))
|
|
36
|
+
.toJSON();
|
|
37
|
+
expect(tree).toMatchSnapshot();
|
|
38
|
+
});
|
|
39
|
+
it('Menu defaultOpen', function () {
|
|
40
|
+
var tree = renderer
|
|
41
|
+
.create(React.createElement(Menu_1.Menu, { defaultOpen: true },
|
|
42
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
43
|
+
React.createElement(button_1.ButtonV1, null, "Open")),
|
|
44
|
+
React.createElement(MenuPopover_1.default, null,
|
|
45
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
46
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" }),
|
|
47
|
+
React.createElement(MenuItem_1.MenuItem, { disabled: true, content: "Option 2" })))))
|
|
48
|
+
.toJSON();
|
|
49
|
+
expect(tree).toMatchSnapshot();
|
|
50
|
+
});
|
|
51
|
+
it('Menu open checkbox and divider', function () {
|
|
52
|
+
var tree = renderer
|
|
53
|
+
.create(React.createElement(Menu_1.Menu, { open: true },
|
|
54
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
55
|
+
React.createElement(button_1.ButtonV1, null, "Open")),
|
|
56
|
+
React.createElement(MenuPopover_1.default, null,
|
|
57
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
58
|
+
React.createElement(MenuItemCheckbox_1.MenuItemCheckbox, { content: "Option 1", name: "Option 1" }),
|
|
59
|
+
React.createElement(MenuDivider_1.MenuDivider, null),
|
|
60
|
+
React.createElement(MenuItemCheckbox_1.MenuItemCheckbox, { disabled: true, content: "Option 2", name: "Option 2" })))))
|
|
61
|
+
.toJSON();
|
|
62
|
+
expect(tree).toMatchSnapshot();
|
|
63
|
+
});
|
|
64
|
+
it('Menu open radio', function () {
|
|
65
|
+
var tree = renderer
|
|
66
|
+
.create(React.createElement(Menu_1.Menu, { open: true },
|
|
67
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
68
|
+
React.createElement(button_1.ButtonV1, null, "Open")),
|
|
69
|
+
React.createElement(MenuPopover_1.default, null,
|
|
70
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
71
|
+
React.createElement(MenuItemRadio_1.MenuItemRadio, { content: "Option 1", name: "Option 1" }),
|
|
72
|
+
React.createElement(MenuItemRadio_1.MenuItemRadio, { content: "Option 2", name: "Option 2" })))))
|
|
73
|
+
.toJSON();
|
|
74
|
+
expect(tree).toMatchSnapshot();
|
|
75
|
+
});
|
|
76
|
+
it('Menu open checkbox defaultChecked', function () {
|
|
77
|
+
var tree = renderer
|
|
78
|
+
.create(React.createElement(Menu_1.Menu, { open: true, defaultChecked: { 'Option 1': true } },
|
|
79
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
80
|
+
React.createElement(button_1.ButtonV1, null, "Open")),
|
|
81
|
+
React.createElement(MenuPopover_1.default, null,
|
|
82
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
83
|
+
React.createElement(MenuItemCheckbox_1.MenuItemCheckbox, { content: "Option 1", name: "Option 1" }),
|
|
84
|
+
React.createElement(MenuDivider_1.MenuDivider, null),
|
|
85
|
+
React.createElement(MenuItemCheckbox_1.MenuItemCheckbox, { content: "Option 2", name: "Option 2" })))))
|
|
86
|
+
.toJSON();
|
|
87
|
+
expect(tree).toMatchSnapshot();
|
|
88
|
+
});
|
|
89
|
+
it('Menu open checkbox checked', function () {
|
|
90
|
+
var tree = renderer
|
|
91
|
+
.create(React.createElement(Menu_1.Menu, { open: true, checked: { 'Option 1': true } },
|
|
92
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
93
|
+
React.createElement(button_1.ButtonV1, null, "Open")),
|
|
94
|
+
React.createElement(MenuPopover_1.default, null,
|
|
95
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
96
|
+
React.createElement(MenuItemCheckbox_1.MenuItemCheckbox, { content: "Option 1", name: "Option 1" }),
|
|
97
|
+
React.createElement(MenuDivider_1.MenuDivider, null),
|
|
98
|
+
React.createElement(MenuItemCheckbox_1.MenuItemCheckbox, { content: "Option 2", name: "Option 2" })))))
|
|
99
|
+
.toJSON();
|
|
100
|
+
expect(tree).toMatchSnapshot();
|
|
101
|
+
});
|
|
102
|
+
it('Menu submenu', function () {
|
|
103
|
+
var tree = renderer
|
|
104
|
+
.create(React.createElement(Menu_1.Menu, { open: true },
|
|
105
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
106
|
+
React.createElement(button_1.ButtonV1, null, "Default")),
|
|
107
|
+
React.createElement(MenuPopover_1.default, null,
|
|
108
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
109
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" }),
|
|
110
|
+
React.createElement(Menu_1.Menu, null,
|
|
111
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
112
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 2" })),
|
|
113
|
+
React.createElement(MenuPopover_1.default, null,
|
|
114
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
115
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" }))))))))
|
|
116
|
+
.toJSON();
|
|
117
|
+
expect(tree).toMatchSnapshot();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe('Menu rerender tests', function () {
|
|
121
|
+
it('Menu re-renders correctly', function () {
|
|
122
|
+
(0, test_tools_1.checkReRender)(function () { return (React.createElement(Menu_1.Menu, { open: true },
|
|
123
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
124
|
+
React.createElement(button_1.ButtonV1, null, "Rerender twice")),
|
|
125
|
+
React.createElement(MenuPopover_1.default, null,
|
|
126
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
127
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" }))))); }, 3);
|
|
128
|
+
});
|
|
129
|
+
it('Menu re-renders correctly with style', function () {
|
|
130
|
+
var style = { backgroundColor: 'black' };
|
|
131
|
+
(0, test_tools_1.checkReRender)(function () { return (React.createElement(Menu_1.Menu, null,
|
|
132
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
133
|
+
React.createElement(button_1.ButtonV1, { style: style }, "Rerender twice")),
|
|
134
|
+
React.createElement(MenuPopover_1.default, null,
|
|
135
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
136
|
+
React.createElement(MenuItem_1.MenuItem, { content: "Option 1" }))))); }, 3);
|
|
137
|
+
});
|
|
138
|
+
it('Menu re-renders correctly with accessibilityAction', function () {
|
|
139
|
+
var action = [{ name: 'Expand' }];
|
|
140
|
+
(0, test_tools_1.checkReRender)(function () { return (React.createElement(Menu_1.Menu, null,
|
|
141
|
+
React.createElement(MenuTrigger_1.default, null,
|
|
142
|
+
React.createElement(button_1.ButtonV1, null, "Rerender twice")),
|
|
143
|
+
React.createElement(MenuPopover_1.default, null,
|
|
144
|
+
React.createElement(MenuList_1.MenuList, null,
|
|
145
|
+
React.createElement(MenuItem_1.MenuItem, { accessibilityActions: action, content: "Option 1" }))))); }, 3);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=Menu.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Menu.test.js","sourceRoot":"","sources":["../../src/__tests__/Menu.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -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
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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,
|
|
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;
|
|
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.
|
|
3
|
+
"version": "0.14.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,10 +23,10 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@fluentui-react-native/adapters": ">=0.8.5 <1.0.0",
|
|
26
|
-
"@fluentui-react-native/callout": ">=0.20.
|
|
26
|
+
"@fluentui-react-native/callout": ">=0.20.6 <1.0.0",
|
|
27
27
|
"@fluentui-react-native/experimental-text": ">=0.9.0 <1.0.0",
|
|
28
28
|
"@fluentui-react-native/framework": "0.7.30",
|
|
29
|
-
"@fluentui-react-native/interactive-hooks": ">=0.16.
|
|
29
|
+
"@fluentui-react-native/interactive-hooks": ">=0.16.2 <1.0.0",
|
|
30
30
|
"@fluentui-react-native/theme-tokens": ">=0.18.0 <1.0.0",
|
|
31
31
|
"@fluentui-react-native/tokens": ">=0.14.0 <1.0.0",
|
|
32
32
|
"@fluentui-react-native/use-styling": ">=0.8.3 <1.0.0",
|
|
@@ -34,8 +34,10 @@
|
|
|
34
34
|
"tslib": "^2.3.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@fluentui-react-native/button": ">=0.22.27 <1.0.0",
|
|
37
38
|
"@fluentui-react-native/eslint-config-rules": "^0.1.1",
|
|
38
39
|
"@fluentui-react-native/scripts": "^0.1.1",
|
|
40
|
+
"@fluentui-react-native/test-tools": ">=0.1.1 <1.0.0",
|
|
39
41
|
"@types/react-native": "^0.64.0",
|
|
40
42
|
"react-native": "^0.64.3"
|
|
41
43
|
},
|
package/src/Menu/Menu.types.ts
CHANGED
|
@@ -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
|
}
|
package/src/Menu/useMenu.ts
CHANGED
|
@@ -4,17 +4,23 @@ import { useMenuContext } from '../context/menuContext';
|
|
|
4
4
|
import { MenuProps, MenuState } from './Menu.types';
|
|
5
5
|
|
|
6
6
|
export const useMenu = (props: MenuProps): MenuState => {
|
|
7
|
-
const triggerRef = React.useRef(
|
|
7
|
+
const triggerRef = React.useRef();
|
|
8
8
|
const context = useMenuContext();
|
|
9
9
|
const isSubmenu = context.triggerRef !== null;
|
|
10
10
|
const isControlled = typeof props.open !== 'undefined';
|
|
11
11
|
const [open, setOpen] = useMenuOpenState(isControlled, props);
|
|
12
12
|
|
|
13
|
-
// Default
|
|
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
|
-
|
|
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
|
};
|
|
@@ -1,27 +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 (
|
|
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
|
-
|
|
15
|
-
borderWidth={1}
|
|
16
|
-
borderColor={theme.colors.neutralStrokeAccessible}
|
|
17
|
-
target={state.triggerRef}
|
|
18
|
-
onDismiss={state.onDismiss}
|
|
19
|
-
dismissBehaviors={state.dismissBehaviors}
|
|
20
|
-
setInitialFocus={state.setInitialFocus}
|
|
21
|
-
directionalHint={state.directionalHint}
|
|
22
|
-
doNotTakePointerCapture={state.doNotTakePointerCapture}
|
|
23
|
-
>
|
|
24
|
-
{children}
|
|
16
|
+
<Callout borderWidth={1} borderColor={theme.colors.neutralStrokeAccessible} {...mergedProps}>
|
|
17
|
+
{content}
|
|
25
18
|
</Callout>
|
|
26
19
|
);
|
|
27
20
|
};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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
6
|
export type MenuPopoverProps = ICalloutProps;
|
|
7
7
|
|
|
8
8
|
export interface MenuPopoverState {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
dismissBehaviors: DismissBehaviors[];
|
|
12
|
-
doNotTakePointerCapture: boolean;
|
|
13
|
-
onDismiss: () => void;
|
|
14
|
-
setInitialFocus: boolean;
|
|
15
|
-
triggerRef: React.RefObject<React.Component>;
|
|
9
|
+
props: ICalloutProps;
|
|
10
|
+
innerView: IViewProps;
|
|
16
11
|
}
|
|
@@ -3,25 +3,65 @@ 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';
|
|
7
|
+
|
|
8
|
+
const controlledDismissBehaviors = ['preventDismissOnKeyDown', 'preventDismissOnClickOutside'] as DismissBehaviors[];
|
|
6
9
|
|
|
7
10
|
export const useMenuPopover = (_props: MenuPopoverProps): MenuPopoverState => {
|
|
8
11
|
const context = useMenuContext();
|
|
9
|
-
const
|
|
12
|
+
const {
|
|
13
|
+
setOpen,
|
|
14
|
+
triggerRef,
|
|
15
|
+
isControlled,
|
|
16
|
+
isSubmenu,
|
|
17
|
+
openOnHover,
|
|
18
|
+
parentPopoverHoverOutTimer,
|
|
19
|
+
popoverHoverOutTimer,
|
|
20
|
+
setPopoverHoverOutTimer,
|
|
21
|
+
triggerHoverOutTimer,
|
|
22
|
+
} = context;
|
|
10
23
|
|
|
11
|
-
const triggerRef = context.triggerRef;
|
|
12
24
|
const onDismiss = React.useCallback(() => setOpen(undefined, false /* isOpen */), [setOpen]);
|
|
13
|
-
const dismissBehaviors =
|
|
14
|
-
|
|
15
|
-
: undefined;
|
|
16
|
-
const directionalHint = getDirectionalHint(context.isSubmenu, I18nManager.isRTL);
|
|
25
|
+
const dismissBehaviors = isControlled ? controlledDismissBehaviors : undefined;
|
|
26
|
+
const directionalHint = getDirectionalHint(isSubmenu, I18nManager.isRTL);
|
|
17
27
|
|
|
18
28
|
// Initial focus behavior differs per platform, Windows platforms move focus
|
|
19
29
|
// automatically onto first element of Callout
|
|
20
30
|
const setInitialFocus = Platform.OS === ('win32' as any) || Platform.OS === 'windows';
|
|
21
|
-
const doNotTakePointerCapture =
|
|
31
|
+
const doNotTakePointerCapture = openOnHover;
|
|
22
32
|
const accessibilityRole = 'menu';
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
const onMouseEnter = React.useCallback(() => {
|
|
35
|
+
clearTimeout(triggerHoverOutTimer);
|
|
36
|
+
clearTimeout(popoverHoverOutTimer);
|
|
37
|
+
clearTimeout(parentPopoverHoverOutTimer);
|
|
38
|
+
}, [parentPopoverHoverOutTimer, popoverHoverOutTimer, triggerHoverOutTimer]);
|
|
39
|
+
const onMouseLeave = React.useCallback(() => {
|
|
40
|
+
if (!openOnHover) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const timer = setTimeout(() => {
|
|
45
|
+
setOpen(undefined, false /* isOpen */);
|
|
46
|
+
}, 500);
|
|
47
|
+
setPopoverHoverOutTimer(timer);
|
|
48
|
+
}, [openOnHover, setOpen, setPopoverHoverOutTimer]);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
props: {
|
|
52
|
+
accessibilityRole,
|
|
53
|
+
target: triggerRef,
|
|
54
|
+
onDismiss,
|
|
55
|
+
directionalHint,
|
|
56
|
+
dismissBehaviors,
|
|
57
|
+
doNotTakePointerCapture,
|
|
58
|
+
setInitialFocus,
|
|
59
|
+
},
|
|
60
|
+
innerView: {
|
|
61
|
+
onMouseEnter,
|
|
62
|
+
onMouseLeave: isCloseOnHoverOutEnabled && onMouseLeave,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
25
65
|
};
|
|
26
66
|
|
|
27
67
|
const getDirectionalHint = (isSubmenu: boolean, isRtl: boolean): DirectionalHint | undefined => {
|
|
@@ -21,8 +21,8 @@ export const MenuTrigger = stagedComponent((props: MenuTriggerProps) => {
|
|
|
21
21
|
// child component which may affect accessibility, we need to modify the
|
|
22
22
|
// state in the inner render so we can access the child component and its props.
|
|
23
23
|
const child = childrenArray[0];
|
|
24
|
-
const
|
|
25
|
-
const revised = React.cloneElement(child,
|
|
24
|
+
const revisedProps = getRevisedState(menuTrigger, child.props);
|
|
25
|
+
const revised = React.cloneElement(child, revisedProps);
|
|
26
26
|
|
|
27
27
|
return <MenuTriggerProvider value={menuTrigger.hasSubmenu}>{revised}</MenuTriggerProvider>;
|
|
28
28
|
};
|
|
@@ -30,24 +30,24 @@ export const MenuTrigger = stagedComponent((props: MenuTriggerProps) => {
|
|
|
30
30
|
MenuTrigger.displayName = menuTriggerName;
|
|
31
31
|
|
|
32
32
|
const getRevisedState = memoize(getRevisedStateWorker);
|
|
33
|
-
function getRevisedStateWorker(state: MenuTriggerState, props: any):
|
|
34
|
-
const
|
|
33
|
+
function getRevisedStateWorker(state: MenuTriggerState, props: any): MenuTriggerProps {
|
|
34
|
+
const revisedProps = state.props;
|
|
35
35
|
if (props.accessibilityState) {
|
|
36
|
-
|
|
36
|
+
revisedProps.accessibilityState = { ...revisedProps.accessibilityState, ...props.accessibilityState };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
if (props.accessibilityActions) {
|
|
40
|
-
|
|
40
|
+
revisedProps.accessibilityActions = { ...revisedProps.accessibilityActions, ...props.accessibilityActions };
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
if (props.onAccessibilityAction) {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
revisedProps.onAccessibilityAction = (e: AccessibilityActionEvent) => {
|
|
45
|
+
revisedProps.onAccessibilityAction(e);
|
|
46
46
|
props.onAccessibilityAction(e);
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
return
|
|
50
|
+
return revisedProps;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export default MenuTrigger;
|
|
@@ -3,18 +3,19 @@ import { InteractionEvent } from '@fluentui-react-native/interactive-hooks';
|
|
|
3
3
|
import { MenuTriggerProps, MenuTriggerState } from './MenuTrigger.types';
|
|
4
4
|
import { AccessibilityActionEvent, AccessibilityActionName, Platform } from 'react-native';
|
|
5
5
|
import React from 'react';
|
|
6
|
+
import { delayHover, isCloseOnHoverOutEnabled } from '../consts';
|
|
6
7
|
|
|
7
8
|
const accessibilityActions =
|
|
8
9
|
Platform.OS === ('win32' as any) ? [{ name: 'Expand' as AccessibilityActionName }, { name: 'Collapse' as AccessibilityActionName }] : [];
|
|
10
|
+
const expandedState = { expanded: true };
|
|
11
|
+
const collapsedState = { expanded: false };
|
|
9
12
|
|
|
10
13
|
export const useMenuTrigger = (_props: MenuTriggerProps): MenuTriggerState => {
|
|
11
14
|
const context = useMenuContext();
|
|
15
|
+
const { open, openOnHover, popoverHoverOutTimer, setOpen, setTriggerHoverOutTimer, triggerHoverOutTimer, triggerRef } = context;
|
|
16
|
+
|
|
17
|
+
const accessibilityState = open ? expandedState : collapsedState;
|
|
12
18
|
|
|
13
|
-
const setOpen = context.setOpen;
|
|
14
|
-
const open = context.open;
|
|
15
|
-
const openOnHover = context.openOnHover;
|
|
16
|
-
const triggerRef = context.triggerRef;
|
|
17
|
-
const accessibilityState = context.open ? { expanded: true } : { expanded: false };
|
|
18
19
|
const onAccessibilityAction = React.useCallback(
|
|
19
20
|
(e: AccessibilityActionEvent) => {
|
|
20
21
|
if (Platform.OS === ('win32' as any)) {
|
|
@@ -32,35 +33,44 @@ export const useMenuTrigger = (_props: MenuTriggerProps): MenuTriggerState => {
|
|
|
32
33
|
[setOpen],
|
|
33
34
|
);
|
|
34
35
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
const onHoverIn = React.useCallback(
|
|
37
|
+
(e: InteractionEvent) => {
|
|
38
|
+
if (openOnHover) {
|
|
39
|
+
clearTimeout(popoverHoverOutTimer);
|
|
40
|
+
clearTimeout(triggerHoverOutTimer);
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
setOpen(e, true /* isOpen */);
|
|
43
|
+
}, delayHover);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
[openOnHover, setOpen, triggerHoverOutTimer, popoverHoverOutTimer],
|
|
47
|
+
);
|
|
45
48
|
|
|
46
|
-
const onHoverOut = (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
const onHoverOut = React.useCallback(
|
|
50
|
+
(e: InteractionEvent) => {
|
|
51
|
+
if (openOnHover) {
|
|
52
|
+
const timer = setTimeout(() => {
|
|
53
|
+
setOpen(e, false /* isOpen */);
|
|
54
|
+
}, delayHover);
|
|
55
|
+
setTriggerHoverOutTimer(timer);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
[openOnHover, setOpen, setTriggerHoverOutTimer],
|
|
59
|
+
);
|
|
51
60
|
|
|
52
|
-
const onClick = (
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
const onClick = React.useCallback(
|
|
62
|
+
(e: InteractionEvent) => {
|
|
63
|
+
setOpen(e, !open);
|
|
64
|
+
},
|
|
65
|
+
[open, setOpen],
|
|
66
|
+
);
|
|
55
67
|
|
|
56
68
|
return {
|
|
57
69
|
props: {
|
|
58
70
|
onClick,
|
|
59
71
|
onHoverIn,
|
|
60
|
-
onHoverOut:
|
|
72
|
+
onHoverOut: isCloseOnHoverOutEnabled && onHoverOut,
|
|
61
73
|
componentRef: triggerRef,
|
|
62
|
-
delayHoverIn: delayHover,
|
|
63
|
-
delayHoverOut: Platform.OS === ('win32' as any) && delayHover,
|
|
64
74
|
accessibilityState,
|
|
65
75
|
accessibilityActions,
|
|
66
76
|
onAccessibilityAction,
|