react-aria-menubutton 7.0.3 → 8.0.0

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 (43) hide show
  1. package/README.md +140 -122
  2. package/dist/index.d.ts +59 -0
  3. package/dist/react-aria-menubutton.cjs.js +1 -0
  4. package/dist/react-aria-menubutton.es.js +566 -0
  5. package/dist/react-aria-menubutton.umd.js +1 -0
  6. package/package.json +62 -57
  7. package/CHANGELOG.md +0 -176
  8. package/CODE_OF_CONDUCT.md +0 -22
  9. package/dist/Button.js +0 -140
  10. package/dist/ManagerContext.js +0 -7
  11. package/dist/Menu.js +0 -131
  12. package/dist/MenuItem.js +0 -96
  13. package/dist/Wrapper.js +0 -74
  14. package/dist/createManager.js +0 -163
  15. package/dist/externalStateControl.js +0 -32
  16. package/dist/index.js +0 -12
  17. package/dist/propTypes.js +0 -7
  18. package/dist/specialAssign.js +0 -11
  19. package/src/Button.js +0 -129
  20. package/src/ManagerContext.js +0 -5
  21. package/src/Menu.js +0 -118
  22. package/src/MenuItem.js +0 -84
  23. package/src/Wrapper.js +0 -62
  24. package/src/__tests__/Button.test.js +0 -169
  25. package/src/__tests__/Menu.test.js +0 -130
  26. package/src/__tests__/MenuItem.test.js +0 -106
  27. package/src/__tests__/__snapshots__/Button.test.js.snap +0 -41
  28. package/src/__tests__/__snapshots__/Menu.test.js.snap +0 -54
  29. package/src/__tests__/__snapshots__/MenuItem.test.js.snap +0 -37
  30. package/src/__tests__/createManager.test.js +0 -190
  31. package/src/__tests__/helpers/MockWrapper.js +0 -24
  32. package/src/__tests__/helpers/createMockKeyEvent.js +0 -7
  33. package/src/__tests__/helpers/createMockManager.js +0 -22
  34. package/src/__tests__/helpers/jest-setup.js +0 -5
  35. package/src/__tests__/helpers/raf.js +0 -3
  36. package/src/createManager.js +0 -173
  37. package/src/externalStateControl.js +0 -31
  38. package/src/index.js +0 -10
  39. package/src/propTypes.js +0 -8
  40. package/src/specialAssign.js +0 -9
  41. package/umd/ReactAriaMenuButton.js +0 -1
  42. package/webpack-demo.config.js +0 -14
  43. package/webpack-umd.config.js +0 -35
package/dist/MenuItem.js DELETED
@@ -1,96 +0,0 @@
1
- 'use strict';
2
-
3
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4
-
5
- function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6
-
7
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8
-
9
- var React = require('react');
10
- var PropTypes = require('prop-types');
11
- var ManagerContext = require('./ManagerContext');
12
-
13
- var _require = require("./propTypes"),
14
- refType = _require.refType;
15
-
16
- var specialAssign = require('./specialAssign');
17
-
18
- var checkedProps = {
19
- ambManager: PropTypes.object.isRequired,
20
- children: PropTypes.node.isRequired,
21
- forwardedRef: refType,
22
- tag: PropTypes.string,
23
- text: PropTypes.string,
24
- value: PropTypes.any
25
- };
26
-
27
- var AriaMenuButtonMenuItem = function (_React$Component) {
28
- _inherits(AriaMenuButtonMenuItem, _React$Component);
29
-
30
- function AriaMenuButtonMenuItem() {
31
- var _temp, _this, _ret;
32
-
33
- _classCallCheck(this, AriaMenuButtonMenuItem);
34
-
35
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
36
- args[_key] = arguments[_key];
37
- }
38
-
39
- return _ret = (_temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.ref = React.createRef(), _this.handleKeyDown = function (event) {
40
- if (event.key !== 'Enter' && event.key !== ' ') return;
41
- if (_this.props.tag === 'a' && _this.props.href) return;
42
- event.preventDefault();
43
- _this.selectItem(event);
44
- }, _this.selectItem = function (event) {
45
- // If there's no value, we'll send the child
46
- var value = typeof _this.props.value !== 'undefined' ? _this.props.value : _this.props.children;
47
- _this.props.ambManager.handleSelection(value, event);
48
- }, _this.setRef = function (instance) {
49
- _this.ref.current = instance;
50
- if (typeof _this.props.forwardedRef === "function") {
51
- _this.props.forwardedRef(instance);
52
- } else if (_this.props.forwardedRef) {
53
- _this.props.forwardedRef.current = instance;
54
- }
55
- }, _temp), _possibleConstructorReturn(_this, _ret);
56
- }
57
-
58
- AriaMenuButtonMenuItem.prototype.componentDidMount = function componentDidMount() {
59
- this.props.ambManager.addItem({
60
- node: this.ref.current,
61
- text: this.props.text
62
- });
63
- };
64
-
65
- AriaMenuButtonMenuItem.prototype.render = function render() {
66
- var menuItemProps = {
67
- onClick: this.selectItem,
68
- onKeyDown: this.handleKeyDown,
69
- role: 'menuitem',
70
- tabIndex: '-1',
71
- ref: this.setRef
72
- };
73
-
74
- specialAssign(menuItemProps, this.props, checkedProps);
75
-
76
- return React.createElement(this.props.tag, menuItemProps, this.props.children);
77
- };
78
-
79
- return AriaMenuButtonMenuItem;
80
- }(React.Component);
81
-
82
- AriaMenuButtonMenuItem.propTypes = checkedProps;
83
- AriaMenuButtonMenuItem.defaultProps = { tag: 'div' };
84
-
85
-
86
- module.exports = React.forwardRef(function (props, ref) {
87
- return React.createElement(ManagerContext.Consumer, null, function (ambManager) {
88
- var buttonProps = { ambManager: ambManager, forwardedRef: ref };
89
- specialAssign(buttonProps, props, {
90
- ambManager: checkedProps.ambManager,
91
- children: checkedProps.children,
92
- forwardedRef: checkedProps.forwardedRef
93
- });
94
- return React.createElement(AriaMenuButtonMenuItem, buttonProps, props.children);
95
- });
96
- });
package/dist/Wrapper.js DELETED
@@ -1,74 +0,0 @@
1
- 'use strict';
2
-
3
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
4
-
5
- function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
6
-
7
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
8
-
9
- var React = require('react');
10
- var PropTypes = require('prop-types');
11
- var createManager = require('./createManager');
12
- var ManagerContext = require('./ManagerContext');
13
-
14
- var _require = require("./propTypes"),
15
- refType = _require.refType;
16
-
17
- var specialAssign = require('./specialAssign');
18
-
19
- var checkedProps = {
20
- children: PropTypes.node.isRequired,
21
- forwardedRef: refType,
22
- onMenuToggle: PropTypes.func,
23
- onSelection: PropTypes.func,
24
- closeOnSelection: PropTypes.bool,
25
- closeOnBlur: PropTypes.bool,
26
- tag: PropTypes.string
27
- };
28
-
29
- var managerOptionsFromProps = function managerOptionsFromProps(props) {
30
- return {
31
- onMenuToggle: props.onMenuToggle,
32
- onSelection: props.onSelection,
33
- closeOnSelection: props.closeOnSelection,
34
- closeOnBlur: props.closeOnBlur,
35
- id: props.id
36
- };
37
- };
38
-
39
- var AriaMenuButtonWrapper = function (_React$Component) {
40
- _inherits(AriaMenuButtonWrapper, _React$Component);
41
-
42
- function AriaMenuButtonWrapper(props) {
43
- _classCallCheck(this, AriaMenuButtonWrapper);
44
-
45
- var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
46
-
47
- _this.manager = createManager(managerOptionsFromProps(props));
48
- return _this;
49
- }
50
-
51
- AriaMenuButtonWrapper.prototype.componentDidUpdate = function componentDidUpdate() {
52
- this.manager.updateOptions(managerOptionsFromProps(this.props));
53
- };
54
-
55
- AriaMenuButtonWrapper.prototype.render = function render() {
56
- var wrapperProps = {};
57
- specialAssign(wrapperProps, this.props, checkedProps);
58
-
59
- return React.createElement(ManagerContext.Provider, { value: this.manager }, React.createElement(this.props.tag, wrapperProps, this.props.children));
60
- };
61
-
62
- return AriaMenuButtonWrapper;
63
- }(React.Component);
64
-
65
- AriaMenuButtonWrapper.propTypes = checkedProps;
66
- AriaMenuButtonWrapper.defaultProps = { tag: 'div' };
67
-
68
-
69
- module.exports = React.forwardRef(function (props, ref) {
70
- var wrapperProps = { forwardedRef: ref };
71
- specialAssign(wrapperProps, props, { children: checkedProps.children, forwardedRef: checkedProps.forwardedRef });
72
- specialAssign(wrapperProps, { forwardedRef: ref });
73
- return React.createElement(AriaMenuButtonWrapper, wrapperProps, props.children);
74
- });
@@ -1,163 +0,0 @@
1
- 'use strict';
2
-
3
- var createFocusGroup = require('focus-group');
4
- var externalStateControl = require('./externalStateControl');
5
-
6
- var focusGroupOptions = {
7
- wrap: true,
8
- stringSearch: true
9
- };
10
-
11
- var protoManager = {
12
- init: function init(options) {
13
- this.updateOptions(options);
14
-
15
- this.handleBlur = handleBlur.bind(this);
16
- this.handleSelection = handleSelection.bind(this);
17
- this.handleMenuKey = handleMenuKey.bind(this);
18
-
19
- // "With focus on the drop-down menu, the Up and Down Arrow
20
- // keys move focus within the menu items, "wrapping" at the top and bottom."
21
- // "Typing a letter (printable character) key moves focus to the next
22
- // instance of a visible node whose title begins with that printable letter."
23
- //
24
- // All of the above is handled by focus-group.
25
- this.focusGroup = createFocusGroup(focusGroupOptions);
26
-
27
- // These component references are added when the relevant components mount
28
- this.button = null;
29
- this.menu = null;
30
-
31
- // State trackers
32
- this.isOpen = false;
33
- },
34
- updateOptions: function updateOptions(options) {
35
- var oldOptions = this.options;
36
-
37
- this.options = options || this.options || {};
38
-
39
- if (typeof this.options.closeOnSelection === 'undefined') {
40
- this.options.closeOnSelection = true;
41
- }
42
-
43
- if (typeof this.options.closeOnBlur === 'undefined') {
44
- this.options.closeOnBlur = true;
45
- }
46
-
47
- if (this.options.id) {
48
- externalStateControl.registerManager(this.options.id, this);
49
- }
50
-
51
- if (oldOptions && oldOptions.id && oldOptions.id !== this.options.id) {
52
- externalStateControl.unregisterManager(this.options.id, this);
53
- }
54
- },
55
- focusItem: function focusItem(index) {
56
- this.focusGroup.focusNodeAtIndex(index);
57
- },
58
- addItem: function addItem(item) {
59
- this.focusGroup.addMember(item);
60
- },
61
- clearItems: function clearItems() {
62
- this.focusGroup.clearMembers();
63
- },
64
- handleButtonNonArrowKey: function handleButtonNonArrowKey(event) {
65
- this.focusGroup._handleUnboundKey(event);
66
- },
67
- destroy: function destroy() {
68
- this.button = null;
69
- this.menu = null;
70
- this.focusGroup.deactivate();
71
- clearTimeout(this.blurTimer);
72
- clearTimeout(this.moveFocusTimer);
73
- },
74
- update: function update() {
75
- this.menu.setState({ isOpen: this.isOpen });
76
- this.button.setState({ menuOpen: this.isOpen });
77
- this.options.onMenuToggle && this.options.onMenuToggle({ isOpen: this.isOpen });
78
- },
79
- openMenu: function openMenu(openOptions) {
80
- if (this.isOpen) return;
81
- openOptions = openOptions || {};
82
- if (openOptions.focusMenu === undefined) {
83
- openOptions.focusMenu = true;
84
- }
85
- this.isOpen = true;
86
- this.update();
87
- this.focusGroup.activate();
88
- if (openOptions.focusMenu) {
89
- var self = this;
90
- this.moveFocusTimer = setTimeout(function () {
91
- self.focusItem(0);
92
- }, 0);
93
- }
94
- },
95
- closeMenu: function closeMenu(closeOptions) {
96
- if (!this.isOpen) return;
97
- closeOptions = closeOptions || {};
98
- this.isOpen = false;
99
- this.update();
100
- if (closeOptions.focusButton) {
101
- this.button.ref.current.focus();
102
- }
103
- },
104
- toggleMenu: function toggleMenu(closeOptions, openOptions) {
105
- closeOptions = closeOptions || {};
106
- openOptions = openOptions || {};
107
- if (this.isOpen) {
108
- this.closeMenu(closeOptions);
109
- } else {
110
- this.openMenu(openOptions);
111
- }
112
- }
113
- };
114
-
115
- function handleBlur() {
116
- var self = this;
117
- self.blurTimer = setTimeout(function () {
118
- if (!self.button) return;
119
- var buttonNode = self.button.ref.current;
120
- if (!buttonNode) return;
121
- var activeEl = buttonNode.ownerDocument.activeElement;
122
- if (buttonNode && activeEl === buttonNode) return;
123
- var menuNode = self.menu.ref.current;
124
- if (menuNode === activeEl) {
125
- self.focusItem(0);
126
- return;
127
- }
128
- if (menuNode && menuNode.contains(activeEl)) return;
129
- if (self.isOpen) self.closeMenu({ focusButton: false });
130
- }, 0);
131
- }
132
-
133
- function handleSelection(value, event) {
134
- if (this.options.closeOnSelection) this.closeMenu({ focusButton: true });
135
- if (this.options.onSelection) this.options.onSelection(value, event);
136
- }
137
-
138
- function handleMenuKey(event) {
139
- if (this.isOpen) {
140
- switch (event.key) {
141
- // With focus on the drop-down menu, pressing Escape closes
142
- // the menu and returns focus to the button.
143
- case 'Escape':
144
- event.preventDefault();
145
- this.closeMenu({ focusButton: true });
146
- break;
147
- case 'Home':
148
- event.preventDefault();
149
- this.focusGroup.moveFocusToFirst();
150
- break;
151
- case 'End':
152
- event.preventDefault();
153
- this.focusGroup.moveFocusToLast();
154
- break;
155
- }
156
- }
157
- }
158
-
159
- module.exports = function (options) {
160
- var newManager = Object.create(protoManager);
161
- newManager.init(options);
162
- return newManager;
163
- };
@@ -1,32 +0,0 @@
1
- 'use strict';
2
-
3
- var registeredManagers = {};
4
-
5
- var errorCommon = 'a menu outside a mounted Wrapper with an id, or a menu that does not exist';
6
-
7
- function registerManager(menuId, manager) {
8
- registeredManagers[menuId] = manager;
9
- }
10
-
11
- function unregisterManager(menuId) {
12
- delete registeredManagers[menuId];
13
- }
14
-
15
- function openMenu(menuId, openOptions) {
16
- var manager = registeredManagers[menuId];
17
- if (!manager) throw new Error('Cannot open ' + errorCommon);
18
- manager.openMenu(openOptions);
19
- }
20
-
21
- function closeMenu(menuId, closeOptions) {
22
- var manager = registeredManagers[menuId];
23
- if (!manager) throw new Error('Cannot close ' + errorCommon);
24
- manager.closeMenu(closeOptions);
25
- }
26
-
27
- module.exports = {
28
- registerManager: registerManager,
29
- unregisterManager: unregisterManager,
30
- openMenu: openMenu,
31
- closeMenu: closeMenu
32
- };
package/dist/index.js DELETED
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- var externalStateControl = require('./externalStateControl');
4
-
5
- module.exports = {
6
- Wrapper: require('./Wrapper'),
7
- Button: require('./Button'),
8
- Menu: require('./Menu'),
9
- MenuItem: require('./MenuItem'),
10
- openMenu: externalStateControl.openMenu,
11
- closeMenu: externalStateControl.closeMenu
12
- };
package/dist/propTypes.js DELETED
@@ -1,7 +0,0 @@
1
- "use strict";
2
-
3
- var PropTypes = require("prop-types");
4
-
5
- module.exports = {
6
- refType: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.elementType })])
7
- };
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = function (a, b, reserved) {
4
- reserved = reserved || {};
5
- // This will get id, className, style, etc.
6
- for (var x in b) {
7
- if (!b.hasOwnProperty(x)) continue;
8
- if (reserved[x]) continue;
9
- a[x] = b[x];
10
- }
11
- };
package/src/Button.js DELETED
@@ -1,129 +0,0 @@
1
- const React = require('react');
2
- const PropTypes = require('prop-types');
3
- const ManagerContext = require('./ManagerContext');
4
- const { refType } = require("./propTypes");
5
- const specialAssign = require('./specialAssign');
6
-
7
- const checkedProps = {
8
- ambManager: PropTypes.object.isRequired,
9
- children: PropTypes.node.isRequired,
10
- disabled: PropTypes.bool,
11
- forwardedRef: refType,
12
- tag: PropTypes.string
13
- };
14
-
15
- // List retrieved from https://www.w3schools.com/tags/att_disabled.asp
16
- const disabledSupportedTags = () => [
17
- 'button',
18
- 'fieldset',
19
- 'input',
20
- 'optgroup',
21
- 'option',
22
- 'select',
23
- 'textarea'
24
- ];
25
-
26
- class AriaMenuButtonButton extends React.Component {
27
- static propTypes = checkedProps;
28
-
29
- static defaultProps = { tag: 'span' };
30
-
31
- ref = React.createRef();
32
-
33
- componentDidMount() {
34
- this.props.ambManager.button = this;
35
- }
36
-
37
- componentWillUnmount() {
38
- this.props.ambManager.destroy();
39
- }
40
-
41
- handleKeyDown = event => {
42
- if (this.props.disabled) return;
43
-
44
- const ambManager = this.props.ambManager;
45
-
46
- switch (event.key) {
47
- case 'ArrowDown':
48
- event.preventDefault();
49
- if (!ambManager.isOpen) {
50
- ambManager.openMenu();
51
- } else {
52
- ambManager.focusItem(0);
53
- }
54
- break;
55
- case 'Enter':
56
- case ' ':
57
- event.preventDefault();
58
- ambManager.toggleMenu();
59
- break;
60
- case 'Escape':
61
- ambManager.handleMenuKey(event);
62
- break;
63
- default:
64
- // (Potential) letter keys
65
- ambManager.handleButtonNonArrowKey(event);
66
- }
67
- };
68
-
69
- handleClick = () => {
70
- if (this.props.disabled) return;
71
- this.props.ambManager.toggleMenu({}, { focusMenu: false });
72
- };
73
-
74
- setRef = instance => {
75
- this.ref.current = instance;
76
- if (typeof this.props.forwardedRef === "function") {
77
- this.props.forwardedRef(instance);
78
- } else if (this.props.forwardedRef) {
79
- this.props.forwardedRef.current = instance;
80
- }
81
- };
82
-
83
- render() {
84
- const props = this.props;
85
- const ambManager = this.props.ambManager;
86
-
87
- const buttonProps = {
88
- // "The menu button itself has a role of button."
89
- role: 'button',
90
- tabIndex: props.disabled ? '' : '0',
91
- // "The menu button has an aria-haspopup property, set to true."
92
- 'aria-haspopup': true,
93
- 'aria-expanded': ambManager.isOpen,
94
- 'aria-disabled': props.disabled,
95
- onKeyDown: this.handleKeyDown,
96
- onClick: this.handleClick
97
- };
98
-
99
- const reserved = {};
100
- specialAssign(reserved, checkedProps);
101
- // The disabled property should be passed down to the Button element
102
- // if the tag has support for disabled attribute. So it needs to be removed
103
- // from the reserved property object
104
- if (disabledSupportedTags().indexOf(props.tag) >= 0) {
105
- delete reserved.disabled;
106
- }
107
- if (ambManager.options.closeOnBlur) {
108
- buttonProps.onBlur = ambManager.handleBlur;
109
- }
110
- specialAssign(buttonProps, props, reserved);
111
- specialAssign(buttonProps, { ref: this.setRef });
112
-
113
- return React.createElement(props.tag, buttonProps, props.children);
114
- }
115
- }
116
-
117
- module.exports = React.forwardRef((props, ref) => React.createElement(
118
- ManagerContext.Consumer,
119
- null,
120
- (ambManager) => {
121
- const buttonProps = { ambManager, forwardedRef: ref };
122
- specialAssign(buttonProps, props, {
123
- ambManager: checkedProps.ambManager,
124
- children: checkedProps.children,
125
- forwardedRef: checkedProps.forwardedRef
126
- });
127
- return React.createElement(AriaMenuButtonButton, buttonProps, props.children);
128
- }
129
- ));
@@ -1,5 +0,0 @@
1
- const React = require('react');
2
-
3
- const AriaMenuButtonManagerContext = React.createContext();
4
-
5
- module.exports = AriaMenuButtonManagerContext;
package/src/Menu.js DELETED
@@ -1,118 +0,0 @@
1
- const React = require('react');
2
- const PropTypes = require('prop-types');
3
- const createTapListener = require('teeny-tap');
4
- const ManagerContext = require('./ManagerContext');
5
- const { refType } = require("./propTypes");
6
- const specialAssign = require('./specialAssign');
7
-
8
- const checkedProps = {
9
- ambManager: PropTypes.object.isRequired,
10
- children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,
11
- forwardedRef: refType,
12
- tag: PropTypes.string
13
- };
14
-
15
- class AriaMenuButtonMenu extends React.Component {
16
- static propTypes = checkedProps;
17
- static defaultProps = { tag: 'div' };
18
-
19
- ref = React.createRef();
20
-
21
- componentDidMount() {
22
- this.props.ambManager.menu = this;
23
- }
24
-
25
- componentDidUpdate() {
26
- const ambManager = this.props.ambManager;
27
- if (!ambManager.options.closeOnBlur) return;
28
- if (ambManager.isOpen && !this.tapListener) {
29
- this.addTapListener();
30
- } else if (!ambManager.isOpen && this.tapListener) {
31
- this.tapListener.remove();
32
- delete this.tapListener;
33
- }
34
-
35
- if (!ambManager.isOpen) {
36
- // Clear the ambManager's items, so they
37
- // can be reloaded next time this menu opens
38
- ambManager.clearItems();
39
- }
40
- }
41
-
42
- componentWillUnmount() {
43
- if (this.tapListener) this.tapListener.remove();
44
- this.props.ambManager.destroy();
45
- }
46
-
47
- addTapListener = () => {
48
- const el = this.ref.current;
49
- if (!el) return;
50
- const doc = el.ownerDocument;
51
- if (!doc) return;
52
- this.tapListener = createTapListener(doc.documentElement, this.handleTap);
53
- };
54
-
55
- handleTap = event => {
56
- if (this.ref.current.contains(event.target)) return;
57
- if (
58
- this.props.ambManager.button.ref.current.contains(
59
- event.target
60
- )
61
- )
62
- return;
63
- this.props.ambManager.closeMenu();
64
- };
65
-
66
- setRef = instance => {
67
- this.ref.current = instance;
68
- if (typeof this.props.forwardedRef === "function") {
69
- this.props.forwardedRef(instance);
70
- } else if (this.props.forwardedRef) {
71
- this.props.forwardedRef.current = instance;
72
- }
73
- };
74
-
75
- render() {
76
- const props = this.props;
77
- const ambManager = this.props.ambManager;
78
-
79
- const childrenToRender = (function() {
80
- if (typeof props.children === 'function') {
81
- return props.children({ isOpen: ambManager.isOpen });
82
- }
83
- if (ambManager.isOpen) return props.children;
84
- return false;
85
- })();
86
-
87
- if (!childrenToRender) return false;
88
-
89
- const menuProps = {
90
- onKeyDown: ambManager.handleMenuKey,
91
- role: 'menu',
92
- tabIndex: -1
93
- };
94
-
95
- if (ambManager.options.closeOnBlur) {
96
- menuProps.onBlur = ambManager.handleBlur;
97
- }
98
-
99
- specialAssign(menuProps, props, checkedProps);
100
- specialAssign(menuProps, { ref: this.setRef });
101
-
102
- return React.createElement(props.tag, menuProps, childrenToRender);
103
- }
104
- }
105
-
106
- module.exports = React.forwardRef((props, ref) => React.createElement(
107
- ManagerContext.Consumer,
108
- null,
109
- (ambManager) => {
110
- const buttonProps = { ambManager, forwardedRef: ref };
111
- specialAssign(buttonProps, props, {
112
- ambManager: checkedProps.ambManager,
113
- children: checkedProps.children,
114
- forwardedRef: checkedProps.forwardedRef
115
- });
116
- return React.createElement(AriaMenuButtonMenu, buttonProps, props.children);
117
- }
118
- ));