This commit is contained in:
129
node_modules/react-aria-menubutton/src/Button.js
generated
vendored
Normal file
129
node_modules/react-aria-menubutton/src/Button.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const ManagerContext = require('./ManagerContext');
|
||||
const { refType } = require("./propTypes");
|
||||
const specialAssign = require('./specialAssign');
|
||||
|
||||
const checkedProps = {
|
||||
ambManager: PropTypes.object.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
forwardedRef: refType,
|
||||
tag: PropTypes.string
|
||||
};
|
||||
|
||||
// List retrieved from https://www.w3schools.com/tags/att_disabled.asp
|
||||
const disabledSupportedTags = () => [
|
||||
'button',
|
||||
'fieldset',
|
||||
'input',
|
||||
'optgroup',
|
||||
'option',
|
||||
'select',
|
||||
'textarea'
|
||||
];
|
||||
|
||||
class AriaMenuButtonButton extends React.Component {
|
||||
static propTypes = checkedProps;
|
||||
|
||||
static defaultProps = { tag: 'span' };
|
||||
|
||||
ref = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
this.props.ambManager.button = this;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.ambManager.destroy();
|
||||
}
|
||||
|
||||
handleKeyDown = event => {
|
||||
if (this.props.disabled) return;
|
||||
|
||||
const ambManager = this.props.ambManager;
|
||||
|
||||
switch (event.key) {
|
||||
case 'ArrowDown':
|
||||
event.preventDefault();
|
||||
if (!ambManager.isOpen) {
|
||||
ambManager.openMenu();
|
||||
} else {
|
||||
ambManager.focusItem(0);
|
||||
}
|
||||
break;
|
||||
case 'Enter':
|
||||
case ' ':
|
||||
event.preventDefault();
|
||||
ambManager.toggleMenu();
|
||||
break;
|
||||
case 'Escape':
|
||||
ambManager.handleMenuKey(event);
|
||||
break;
|
||||
default:
|
||||
// (Potential) letter keys
|
||||
ambManager.handleButtonNonArrowKey(event);
|
||||
}
|
||||
};
|
||||
|
||||
handleClick = () => {
|
||||
if (this.props.disabled) return;
|
||||
this.props.ambManager.toggleMenu({}, { focusMenu: false });
|
||||
};
|
||||
|
||||
setRef = instance => {
|
||||
this.ref.current = instance;
|
||||
if (typeof this.props.forwardedRef === "function") {
|
||||
this.props.forwardedRef(instance);
|
||||
} else if (this.props.forwardedRef) {
|
||||
this.props.forwardedRef.current = instance;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const ambManager = this.props.ambManager;
|
||||
|
||||
const buttonProps = {
|
||||
// "The menu button itself has a role of button."
|
||||
role: 'button',
|
||||
tabIndex: props.disabled ? '' : '0',
|
||||
// "The menu button has an aria-haspopup property, set to true."
|
||||
'aria-haspopup': true,
|
||||
'aria-expanded': ambManager.isOpen,
|
||||
'aria-disabled': props.disabled,
|
||||
onKeyDown: this.handleKeyDown,
|
||||
onClick: this.handleClick
|
||||
};
|
||||
|
||||
const reserved = {};
|
||||
specialAssign(reserved, checkedProps);
|
||||
// The disabled property should be passed down to the Button element
|
||||
// if the tag has support for disabled attribute. So it needs to be removed
|
||||
// from the reserved property object
|
||||
if (disabledSupportedTags().indexOf(props.tag) >= 0) {
|
||||
delete reserved.disabled;
|
||||
}
|
||||
if (ambManager.options.closeOnBlur) {
|
||||
buttonProps.onBlur = ambManager.handleBlur;
|
||||
}
|
||||
specialAssign(buttonProps, props, reserved);
|
||||
specialAssign(buttonProps, { ref: this.setRef });
|
||||
|
||||
return React.createElement(props.tag, buttonProps, props.children);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = React.forwardRef((props, ref) => React.createElement(
|
||||
ManagerContext.Consumer,
|
||||
null,
|
||||
(ambManager) => {
|
||||
const buttonProps = { ambManager, forwardedRef: ref };
|
||||
specialAssign(buttonProps, props, {
|
||||
ambManager: checkedProps.ambManager,
|
||||
children: checkedProps.children,
|
||||
forwardedRef: checkedProps.forwardedRef
|
||||
});
|
||||
return React.createElement(AriaMenuButtonButton, buttonProps, props.children);
|
||||
}
|
||||
));
|
||||
5
node_modules/react-aria-menubutton/src/ManagerContext.js
generated
vendored
Normal file
5
node_modules/react-aria-menubutton/src/ManagerContext.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
const React = require('react');
|
||||
|
||||
const AriaMenuButtonManagerContext = React.createContext();
|
||||
|
||||
module.exports = AriaMenuButtonManagerContext;
|
||||
118
node_modules/react-aria-menubutton/src/Menu.js
generated
vendored
Normal file
118
node_modules/react-aria-menubutton/src/Menu.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const createTapListener = require('teeny-tap');
|
||||
const ManagerContext = require('./ManagerContext');
|
||||
const { refType } = require("./propTypes");
|
||||
const specialAssign = require('./specialAssign');
|
||||
|
||||
const checkedProps = {
|
||||
ambManager: PropTypes.object.isRequired,
|
||||
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,
|
||||
forwardedRef: refType,
|
||||
tag: PropTypes.string
|
||||
};
|
||||
|
||||
class AriaMenuButtonMenu extends React.Component {
|
||||
static propTypes = checkedProps;
|
||||
static defaultProps = { tag: 'div' };
|
||||
|
||||
ref = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
this.props.ambManager.menu = this;
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const ambManager = this.props.ambManager;
|
||||
if (!ambManager.options.closeOnBlur) return;
|
||||
if (ambManager.isOpen && !this.tapListener) {
|
||||
this.addTapListener();
|
||||
} else if (!ambManager.isOpen && this.tapListener) {
|
||||
this.tapListener.remove();
|
||||
delete this.tapListener;
|
||||
}
|
||||
|
||||
if (!ambManager.isOpen) {
|
||||
// Clear the ambManager's items, so they
|
||||
// can be reloaded next time this menu opens
|
||||
ambManager.clearItems();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.tapListener) this.tapListener.remove();
|
||||
this.props.ambManager.destroy();
|
||||
}
|
||||
|
||||
addTapListener = () => {
|
||||
const el = this.ref.current;
|
||||
if (!el) return;
|
||||
const doc = el.ownerDocument;
|
||||
if (!doc) return;
|
||||
this.tapListener = createTapListener(doc.documentElement, this.handleTap);
|
||||
};
|
||||
|
||||
handleTap = event => {
|
||||
if (this.ref.current.contains(event.target)) return;
|
||||
if (
|
||||
this.props.ambManager.button.ref.current.contains(
|
||||
event.target
|
||||
)
|
||||
)
|
||||
return;
|
||||
this.props.ambManager.closeMenu();
|
||||
};
|
||||
|
||||
setRef = instance => {
|
||||
this.ref.current = instance;
|
||||
if (typeof this.props.forwardedRef === "function") {
|
||||
this.props.forwardedRef(instance);
|
||||
} else if (this.props.forwardedRef) {
|
||||
this.props.forwardedRef.current = instance;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const ambManager = this.props.ambManager;
|
||||
|
||||
const childrenToRender = (function() {
|
||||
if (typeof props.children === 'function') {
|
||||
return props.children({ isOpen: ambManager.isOpen });
|
||||
}
|
||||
if (ambManager.isOpen) return props.children;
|
||||
return false;
|
||||
})();
|
||||
|
||||
if (!childrenToRender) return false;
|
||||
|
||||
const menuProps = {
|
||||
onKeyDown: ambManager.handleMenuKey,
|
||||
role: 'menu',
|
||||
tabIndex: -1
|
||||
};
|
||||
|
||||
if (ambManager.options.closeOnBlur) {
|
||||
menuProps.onBlur = ambManager.handleBlur;
|
||||
}
|
||||
|
||||
specialAssign(menuProps, props, checkedProps);
|
||||
specialAssign(menuProps, { ref: this.setRef });
|
||||
|
||||
return React.createElement(props.tag, menuProps, childrenToRender);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = React.forwardRef((props, ref) => React.createElement(
|
||||
ManagerContext.Consumer,
|
||||
null,
|
||||
(ambManager) => {
|
||||
const buttonProps = { ambManager, forwardedRef: ref };
|
||||
specialAssign(buttonProps, props, {
|
||||
ambManager: checkedProps.ambManager,
|
||||
children: checkedProps.children,
|
||||
forwardedRef: checkedProps.forwardedRef
|
||||
});
|
||||
return React.createElement(AriaMenuButtonMenu, buttonProps, props.children);
|
||||
}
|
||||
));
|
||||
84
node_modules/react-aria-menubutton/src/MenuItem.js
generated
vendored
Normal file
84
node_modules/react-aria-menubutton/src/MenuItem.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const ManagerContext = require('./ManagerContext');
|
||||
const { refType } = require("./propTypes");
|
||||
const specialAssign = require('./specialAssign');
|
||||
|
||||
const checkedProps = {
|
||||
ambManager: PropTypes.object.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
forwardedRef: refType,
|
||||
tag: PropTypes.string,
|
||||
text: PropTypes.string,
|
||||
value: PropTypes.any
|
||||
};
|
||||
|
||||
class AriaMenuButtonMenuItem extends React.Component {
|
||||
static propTypes = checkedProps;
|
||||
static defaultProps = { tag: 'div' };
|
||||
|
||||
ref = React.createRef();
|
||||
|
||||
componentDidMount() {
|
||||
this.props.ambManager.addItem({
|
||||
node: this.ref.current,
|
||||
text: this.props.text
|
||||
});
|
||||
}
|
||||
|
||||
handleKeyDown = event => {
|
||||
if (event.key !== 'Enter' && event.key !== ' ') return;
|
||||
if (this.props.tag === 'a' && this.props.href) return;
|
||||
event.preventDefault();
|
||||
this.selectItem(event);
|
||||
};
|
||||
|
||||
selectItem = event => {
|
||||
// If there's no value, we'll send the child
|
||||
const value = typeof this.props.value !== 'undefined'
|
||||
? this.props.value
|
||||
: this.props.children;
|
||||
this.props.ambManager.handleSelection(value, event);
|
||||
};
|
||||
|
||||
setRef = instance => {
|
||||
this.ref.current = instance;
|
||||
if (typeof this.props.forwardedRef === "function") {
|
||||
this.props.forwardedRef(instance);
|
||||
} else if (this.props.forwardedRef) {
|
||||
this.props.forwardedRef.current = instance;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const menuItemProps = {
|
||||
onClick: this.selectItem,
|
||||
onKeyDown: this.handleKeyDown,
|
||||
role: 'menuitem',
|
||||
tabIndex: '-1',
|
||||
ref: this.setRef
|
||||
};
|
||||
|
||||
specialAssign(menuItemProps, this.props, checkedProps);
|
||||
|
||||
return React.createElement(
|
||||
this.props.tag,
|
||||
menuItemProps,
|
||||
this.props.children
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = React.forwardRef((props, ref) => React.createElement(
|
||||
ManagerContext.Consumer,
|
||||
null,
|
||||
(ambManager) => {
|
||||
const buttonProps = { ambManager, forwardedRef: ref };
|
||||
specialAssign(buttonProps, props, {
|
||||
ambManager: checkedProps.ambManager,
|
||||
children: checkedProps.children,
|
||||
forwardedRef: checkedProps.forwardedRef
|
||||
});
|
||||
return React.createElement(AriaMenuButtonMenuItem, buttonProps, props.children);
|
||||
}
|
||||
));
|
||||
62
node_modules/react-aria-menubutton/src/Wrapper.js
generated
vendored
Normal file
62
node_modules/react-aria-menubutton/src/Wrapper.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const createManager = require('./createManager');
|
||||
const ManagerContext = require('./ManagerContext');
|
||||
const { refType } = require("./propTypes");
|
||||
const specialAssign = require('./specialAssign');
|
||||
|
||||
const checkedProps = {
|
||||
children: PropTypes.node.isRequired,
|
||||
forwardedRef: refType,
|
||||
onMenuToggle: PropTypes.func,
|
||||
onSelection: PropTypes.func,
|
||||
closeOnSelection: PropTypes.bool,
|
||||
closeOnBlur: PropTypes.bool,
|
||||
tag: PropTypes.string
|
||||
};
|
||||
|
||||
const managerOptionsFromProps = (props) => {
|
||||
return {
|
||||
onMenuToggle: props.onMenuToggle,
|
||||
onSelection: props.onSelection,
|
||||
closeOnSelection: props.closeOnSelection,
|
||||
closeOnBlur: props.closeOnBlur,
|
||||
id: props.id
|
||||
}
|
||||
}
|
||||
|
||||
class AriaMenuButtonWrapper extends React.Component {
|
||||
static propTypes = checkedProps;
|
||||
static defaultProps = { tag: 'div' };
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.manager = createManager(managerOptionsFromProps(props));
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.manager.updateOptions(managerOptionsFromProps(this.props))
|
||||
}
|
||||
|
||||
render() {
|
||||
const wrapperProps = {};
|
||||
specialAssign(wrapperProps, this.props, checkedProps);
|
||||
|
||||
return React.createElement(
|
||||
ManagerContext.Provider,
|
||||
{ value: this.manager },
|
||||
React.createElement(
|
||||
this.props.tag,
|
||||
wrapperProps,
|
||||
this.props.children,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = React.forwardRef((props, ref) => {
|
||||
const wrapperProps = { forwardedRef: ref };
|
||||
specialAssign(wrapperProps, props, { children: checkedProps.children, forwardedRef: checkedProps.forwardedRef });
|
||||
specialAssign(wrapperProps, { forwardedRef: ref });
|
||||
return React.createElement(AriaMenuButtonWrapper, wrapperProps, props.children);
|
||||
});
|
||||
169
node_modules/react-aria-menubutton/src/__tests__/Button.test.js
generated
vendored
Normal file
169
node_modules/react-aria-menubutton/src/__tests__/Button.test.js
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
const React = require('react');
|
||||
const ReactDOMServer = require('react-dom/server');
|
||||
const shallow = require('enzyme').shallow;
|
||||
const shallowToJson = require('enzyme-to-json').shallowToJson;
|
||||
const Button = require('../Button');
|
||||
const ManagerContext = require('../ManagerContext');
|
||||
const MockWrapper = require('./helpers/MockWrapper');
|
||||
const createMockKeyEvent = require('./helpers/createMockKeyEvent');
|
||||
const createMockManager = require('./helpers/createMockManager');
|
||||
const createManager = require('../createManager');
|
||||
|
||||
const el = React.createElement;
|
||||
|
||||
describe('<Button>', function() {
|
||||
let shallowOptions;
|
||||
let ambManager;
|
||||
let downEvent;
|
||||
let enterEvent;
|
||||
let spaceEvent;
|
||||
let escapeEvent;
|
||||
let fEvent;
|
||||
|
||||
beforeEach(function() {
|
||||
ambManager = createMockManager();
|
||||
shallowOptions = {
|
||||
wrappingComponent: ManagerContext.Provider,
|
||||
wrappingComponentProps: { value: ambManager },
|
||||
};
|
||||
downEvent = createMockKeyEvent('ArrowDown');
|
||||
enterEvent = createMockKeyEvent('Enter');
|
||||
spaceEvent = createMockKeyEvent(' ');
|
||||
escapeEvent = createMockKeyEvent('Escape');
|
||||
fEvent = createMockKeyEvent(null, 70);
|
||||
});
|
||||
|
||||
test('DOM with only required props and text child', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('no onBlur prop when closeOnBlur is false', function() {
|
||||
const manager = createManager({ closeOnBlur: false });
|
||||
const shallowOptions = {
|
||||
wrappingComponent: ManagerContext.Provider,
|
||||
wrappingComponentProps: { value: manager }
|
||||
};
|
||||
const wrapper = shallow(el(Button, null, ''), shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper).props).not.toHaveProperty('onBlur');
|
||||
});
|
||||
|
||||
test('DOM with all possible props and element child', function() {
|
||||
const button = el(
|
||||
Button,
|
||||
{
|
||||
id: 'foo',
|
||||
className: 'bar',
|
||||
style: { top: 2 },
|
||||
tag: 'button',
|
||||
disabled: true,
|
||||
'data-something-something': 'seven' // arbitrary prop
|
||||
},
|
||||
el('span', null, 'hooha')
|
||||
);
|
||||
const wrapper = shallow(button, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('click', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
wrapper.simulate('click');
|
||||
|
||||
expect(ambManager.toggleMenu).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('click when disabled', function() {
|
||||
const wrapper = shallow(
|
||||
el(Button, { disabled: true }, 'foo'),
|
||||
shallowOptions
|
||||
).dive().dive();
|
||||
wrapper.simulate('click');
|
||||
|
||||
expect(ambManager.toggleMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('element has disabled attribute when disabled property is set to true', function() {
|
||||
const wrapper = shallow(
|
||||
el(Button, { disabled: true, tag: 'button' }, 'foo'),
|
||||
shallowOptions
|
||||
).dive().dive();
|
||||
|
||||
expect(wrapper.props().disabled).toBeTruthy();
|
||||
});
|
||||
|
||||
test('down arrow when closed', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
wrapper.simulate('keyDown', downEvent);
|
||||
|
||||
expect(downEvent.preventDefault).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.openMenu).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.openMenu).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
test('down arrow when open', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
ambManager.isOpen = true;
|
||||
wrapper.simulate('keyDown', downEvent);
|
||||
|
||||
expect(downEvent.preventDefault).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.openMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('enter key', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
wrapper.simulate('keyDown', enterEvent);
|
||||
|
||||
expect(enterEvent.preventDefault).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.toggleMenu).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('space key', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
wrapper.simulate('keyDown', spaceEvent);
|
||||
|
||||
expect(spaceEvent.preventDefault).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.toggleMenu).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('escape key', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
wrapper.simulate('keyDown', escapeEvent);
|
||||
|
||||
expect(ambManager.handleMenuKey).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.handleMenuKey.mock.calls[0][0].key).toBe('Escape');
|
||||
});
|
||||
|
||||
test('f key', function() {
|
||||
const wrapper = shallow(el(Button, null, 'foo'), shallowOptions).dive().dive();
|
||||
wrapper.simulate('keyDown', fEvent);
|
||||
|
||||
expect(ambManager.handleButtonNonArrowKey).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.handleButtonNonArrowKey.mock.calls[0][0].keyCode).toBe(
|
||||
70
|
||||
);
|
||||
});
|
||||
|
||||
test('enter key when disabled', function() {
|
||||
const wrapper = shallow(
|
||||
el(Button, { disabled: true }, 'foo'),
|
||||
shallowOptions
|
||||
).dive().dive();
|
||||
wrapper.simulate('keyDown', enterEvent);
|
||||
|
||||
expect(enterEvent.preventDefault).not.toHaveBeenCalled();
|
||||
expect(ambManager.toggleMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('<Button> rendered via renderToString', function() {
|
||||
test('does not throw', function() {
|
||||
const output = ReactDOMServer.renderToString(
|
||||
el(
|
||||
MockWrapper,
|
||||
{ mockManager: createMockManager() },
|
||||
el(Button, null, 'foo')
|
||||
)
|
||||
);
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
130
node_modules/react-aria-menubutton/src/__tests__/Menu.test.js
generated
vendored
Normal file
130
node_modules/react-aria-menubutton/src/__tests__/Menu.test.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
const React = require('react');
|
||||
const ReactDOMServer = require('react-dom/server');
|
||||
const shallow = require('enzyme').shallow;
|
||||
const mount = require('enzyme').mount;
|
||||
const shallowToJson = require('enzyme-to-json').shallowToJson;
|
||||
const ManagerContext = require('../ManagerContext');
|
||||
const Menu = require('../Menu');
|
||||
const MockWrapper = require('./helpers/MockWrapper');
|
||||
const createMockManager = require('./helpers/createMockManager');
|
||||
const createManager = require('../createManager');
|
||||
|
||||
const el = React.createElement;
|
||||
|
||||
describe('<Menu>', function() {
|
||||
let shallowOptions;
|
||||
let ambManager;
|
||||
|
||||
beforeEach(function() {
|
||||
ambManager = createMockManager();
|
||||
shallowOptions = {
|
||||
wrappingComponent: ManagerContext.Provider,
|
||||
wrappingComponentProps: { value: ambManager }
|
||||
};
|
||||
});
|
||||
|
||||
test('closed Menu DOM with only required props and element child', function() {
|
||||
const menuEl = el(Menu, null, el('div', null, 'foo'));
|
||||
const wrapper = shallow(menuEl, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('no onBlur prop when closeOnBlur is false', function() {
|
||||
const manager = createManager({ closeOnBlur: false });
|
||||
manager.isOpen = true;
|
||||
const shallowOptions = {
|
||||
wrappingComponent: ManagerContext.Provider,
|
||||
wrappingComponentProps: { value: manager }
|
||||
};
|
||||
const menuEl = el(Menu, null, el('div', null, 'foo'));
|
||||
const wrapper = shallow(menuEl, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper).props).not.toHaveProperty('onBlur');
|
||||
});
|
||||
|
||||
test('open Menu DOM with only required props and element child', function() {
|
||||
ambManager.isOpen = true;
|
||||
const menuEl = el(Menu, null, el('div', null, el('div', null, 'foo')));
|
||||
const wrapper = shallow(menuEl, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('closed menu DOM with all possible props and function child', function() {
|
||||
const childFunction = jest.fn().mockImplementation(function(menuState) {
|
||||
return 'isOpen = ' + menuState.isOpen;
|
||||
});
|
||||
const menuEl = el(
|
||||
Menu,
|
||||
{
|
||||
id: 'foo',
|
||||
className: 'bar',
|
||||
style: { bottom: 1 },
|
||||
tag: 'ul',
|
||||
'data-something-something': 'seven' // arbitrary prop
|
||||
},
|
||||
childFunction
|
||||
);
|
||||
const wrapper = shallow(menuEl, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
expect(childFunction).toHaveBeenCalledTimes(1);
|
||||
expect(childFunction.mock.calls[0]).toEqual([{ isOpen: false }]);
|
||||
});
|
||||
|
||||
test('open menu DOM with all possible props and function child', function() {
|
||||
ambManager.isOpen = true;
|
||||
const childFunction = jest.fn().mockImplementation(function(menuState) {
|
||||
return 'isOpen = ' + menuState.isOpen;
|
||||
});
|
||||
const menuEl = el(
|
||||
Menu,
|
||||
{
|
||||
id: 'bar',
|
||||
className: 'foo',
|
||||
style: { left: 1 },
|
||||
tag: 'section'
|
||||
},
|
||||
childFunction
|
||||
);
|
||||
const wrapper = shallow(menuEl, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
expect(childFunction).toHaveBeenCalledTimes(1);
|
||||
expect(childFunction.mock.calls[0]).toEqual([{ isOpen: true }]);
|
||||
});
|
||||
|
||||
test('menu updating', function() {
|
||||
ambManager.menuItems = [1, 2];
|
||||
const childFunction = jest.fn();
|
||||
|
||||
class LittleApp extends React.Component {
|
||||
state = { open: false };
|
||||
|
||||
toggleMenu = () => {
|
||||
this.setState({ open: !this.state.open });
|
||||
};
|
||||
|
||||
render() {
|
||||
return el(
|
||||
MockWrapper,
|
||||
{ mockManager: ambManager },
|
||||
el(Menu, null, childFunction)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const wrapper = mount(el(LittleApp));
|
||||
wrapper.instance().toggleMenu();
|
||||
expect(ambManager.clearItems).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('<Menu> rendered via renderToString', function() {
|
||||
test('does not throw', function() {
|
||||
const output = ReactDOMServer.renderToString(
|
||||
el(
|
||||
MockWrapper,
|
||||
{ mockManager: createMockManager() },
|
||||
el(Menu, null, el('div', null, 'foo'))
|
||||
)
|
||||
);
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
106
node_modules/react-aria-menubutton/src/__tests__/MenuItem.test.js
generated
vendored
Normal file
106
node_modules/react-aria-menubutton/src/__tests__/MenuItem.test.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
const React = require('react');
|
||||
const ReactDOMServer = require('react-dom/server');
|
||||
const shallow = require('enzyme').shallow;
|
||||
const shallowToJson = require('enzyme-to-json').shallowToJson;
|
||||
const ManagerContext = require('../ManagerContext');
|
||||
const MenuItem = require('../MenuItem');
|
||||
const MockWrapper = require('./helpers/MockWrapper');
|
||||
const createMockKeyEvent = require('./helpers/createMockKeyEvent');
|
||||
const createMockManager = require('./helpers/createMockManager');
|
||||
|
||||
const el = React.createElement;
|
||||
|
||||
describe('<MenuItem>', function() {
|
||||
let shallowOptions;
|
||||
let ambManager;
|
||||
|
||||
beforeEach(function() {
|
||||
ambManager = createMockManager();
|
||||
shallowOptions = {
|
||||
wrappingComponent: ManagerContext.Provider,
|
||||
wrappingComponentProps: { value: ambManager }
|
||||
};
|
||||
});
|
||||
|
||||
it('DOM with only required props', function() {
|
||||
const menuItem = el(MenuItem, null, 'foo');
|
||||
const wrapper = shallow(menuItem, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('DOM with all possible props and element child', function() {
|
||||
const menuItem = el(
|
||||
MenuItem,
|
||||
{
|
||||
className: 'foobar',
|
||||
id: 'hogwash',
|
||||
tag: 'li',
|
||||
style: { right: '1em' },
|
||||
text: 'horse',
|
||||
value: 'lamb',
|
||||
'data-something-something': 'seven' // arbitrary prop
|
||||
},
|
||||
el('a', { href: '#' }, 'foo')
|
||||
);
|
||||
const wrapper = shallow(menuItem, shallowOptions).dive().dive();
|
||||
expect(shallowToJson(wrapper)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('click without specified value prop', function() {
|
||||
const mockEvent = { bee: 'baa' };
|
||||
const menuItem = el(MenuItem, null, 'foo');
|
||||
const wrapper = shallow(menuItem, shallowOptions).dive().dive();
|
||||
wrapper.simulate('click', mockEvent);
|
||||
expect(ambManager.handleSelection).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.handleSelection.mock.calls[0]).toEqual([
|
||||
'foo',
|
||||
mockEvent
|
||||
]);
|
||||
});
|
||||
|
||||
it('click with specified value prop', function() {
|
||||
const mockEvent = { bee: 'baa' };
|
||||
const menuItem = el(MenuItem, { value: 'bar' }, 'foo');
|
||||
const wrapper = shallow(menuItem, shallowOptions).dive().dive();
|
||||
wrapper.simulate('click', mockEvent);
|
||||
expect(ambManager.handleSelection).toHaveBeenCalledTimes(1);
|
||||
expect(ambManager.handleSelection.mock.calls[0]).toEqual([
|
||||
'bar',
|
||||
mockEvent
|
||||
]);
|
||||
});
|
||||
|
||||
it('click with specified value prop', function() {
|
||||
const mockEnterEvent = createMockKeyEvent('Enter');
|
||||
const mockSpaceEvent = createMockKeyEvent(' ');
|
||||
const mockEscapeEvent = createMockKeyEvent('Escape');
|
||||
const menuItem = el(MenuItem, null, 'foo');
|
||||
const wrapper = shallow(menuItem, shallowOptions).dive().dive();
|
||||
|
||||
wrapper.simulate('keyDown', mockEnterEvent);
|
||||
wrapper.simulate('keyDown', mockSpaceEvent);
|
||||
wrapper.simulate('keyDown', mockEscapeEvent);
|
||||
expect(ambManager.handleSelection).toHaveBeenCalledTimes(2);
|
||||
expect(ambManager.handleSelection.mock.calls[0]).toEqual([
|
||||
'foo',
|
||||
mockEnterEvent
|
||||
]);
|
||||
expect(ambManager.handleSelection.mock.calls[1]).toEqual([
|
||||
'foo',
|
||||
mockSpaceEvent
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('<MenuItem> rendered via renderToString', function() {
|
||||
it('does not throw', function() {
|
||||
const output = ReactDOMServer.renderToString(
|
||||
el(
|
||||
MockWrapper,
|
||||
{ mockManager: createMockManager() },
|
||||
el(MenuItem, null, 'foo')
|
||||
)
|
||||
);
|
||||
expect(output).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
41
node_modules/react-aria-menubutton/src/__tests__/__snapshots__/Button.test.js.snap
generated
vendored
Normal file
41
node_modules/react-aria-menubutton/src/__tests__/__snapshots__/Button.test.js.snap
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Button> DOM with all possible props and element child 1`] = `
|
||||
<button
|
||||
aria-disabled={true}
|
||||
aria-expanded={false}
|
||||
aria-haspopup={true}
|
||||
className="bar"
|
||||
data-something-something="seven"
|
||||
disabled={true}
|
||||
id="foo"
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
role="button"
|
||||
style={
|
||||
Object {
|
||||
"top": 2,
|
||||
}
|
||||
}
|
||||
tabIndex=""
|
||||
>
|
||||
<span>
|
||||
hooha
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`<Button> DOM with only required props and text child 1`] = `
|
||||
<span
|
||||
aria-expanded={false}
|
||||
aria-haspopup={true}
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
foo
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`<Button> rendered via renderToString does not throw 1`] = `"<div><span role=\\"button\\" tabindex=\\"0\\" aria-haspopup=\\"true\\" aria-expanded=\\"false\\">foo</span></div>"`;
|
||||
54
node_modules/react-aria-menubutton/src/__tests__/__snapshots__/Menu.test.js.snap
generated
vendored
Normal file
54
node_modules/react-aria-menubutton/src/__tests__/__snapshots__/Menu.test.js.snap
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Menu> closed Menu DOM with only required props and element child 1`] = `""`;
|
||||
|
||||
exports[`<Menu> closed menu DOM with all possible props and function child 1`] = `
|
||||
<ul
|
||||
className="bar"
|
||||
data-something-something="seven"
|
||||
id="foo"
|
||||
onKeyDown={[Function]}
|
||||
role="menu"
|
||||
style={
|
||||
Object {
|
||||
"bottom": 1,
|
||||
}
|
||||
}
|
||||
tabIndex={-1}
|
||||
>
|
||||
isOpen = false
|
||||
</ul>
|
||||
`;
|
||||
|
||||
exports[`<Menu> open Menu DOM with only required props and element child 1`] = `
|
||||
<div
|
||||
onKeyDown={[Function]}
|
||||
role="menu"
|
||||
tabIndex={-1}
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<Menu> open menu DOM with all possible props and function child 1`] = `
|
||||
<section
|
||||
className="foo"
|
||||
id="bar"
|
||||
onKeyDown={[Function]}
|
||||
role="menu"
|
||||
style={
|
||||
Object {
|
||||
"left": 1,
|
||||
}
|
||||
}
|
||||
tabIndex={-1}
|
||||
>
|
||||
isOpen = true
|
||||
</section>
|
||||
`;
|
||||
|
||||
exports[`<Menu> rendered via renderToString does not throw 1`] = `"<div></div>"`;
|
||||
37
node_modules/react-aria-menubutton/src/__tests__/__snapshots__/MenuItem.test.js.snap
generated
vendored
Normal file
37
node_modules/react-aria-menubutton/src/__tests__/__snapshots__/MenuItem.test.js.snap
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<MenuItem> DOM with all possible props and element child 1`] = `
|
||||
<li
|
||||
className="foobar"
|
||||
data-something-something="seven"
|
||||
id="hogwash"
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
role="menuitem"
|
||||
style={
|
||||
Object {
|
||||
"right": "1em",
|
||||
}
|
||||
}
|
||||
tabIndex="-1"
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
>
|
||||
foo
|
||||
</a>
|
||||
</li>
|
||||
`;
|
||||
|
||||
exports[`<MenuItem> DOM with only required props 1`] = `
|
||||
<div
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
role="menuitem"
|
||||
tabIndex="-1"
|
||||
>
|
||||
foo
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<MenuItem> rendered via renderToString does not throw 1`] = `"<div><div role=\\"menuitem\\" tabindex=\\"-1\\">foo</div></div>"`;
|
||||
190
node_modules/react-aria-menubutton/src/__tests__/createManager.test.js
generated
vendored
Normal file
190
node_modules/react-aria-menubutton/src/__tests__/createManager.test.js
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/* globals Promise */
|
||||
|
||||
var createManager = require('../createManager');
|
||||
var createMockKeyEvent = require('./helpers/createMockKeyEvent');
|
||||
|
||||
var mockNode = document.createElement('button');
|
||||
var nodeOne = document.createElement('button');
|
||||
nodeOne.focus = jest.fn();
|
||||
var nodeTwo = document.createElement('button');
|
||||
nodeTwo.focus = jest.fn();
|
||||
document.body.appendChild(nodeOne);
|
||||
document.body.appendChild(nodeTwo);
|
||||
|
||||
function createManagerWithMockedElements(options) {
|
||||
var manager = createManager(options);
|
||||
manager.focusGroup.addMember({
|
||||
node: nodeOne,
|
||||
text: 'first'
|
||||
});
|
||||
manager.focusGroup.addMember({
|
||||
node: nodeTwo,
|
||||
text: 'second'
|
||||
});
|
||||
manager.button = {
|
||||
ref: { current: mockNode },
|
||||
setState: jest.fn()
|
||||
};
|
||||
manager.menu = {
|
||||
setState: jest.fn()
|
||||
};
|
||||
manager.focusItem = jest.fn();
|
||||
return manager;
|
||||
}
|
||||
|
||||
describe('createManager', function() {
|
||||
it('initalizes', function() {
|
||||
var manager = createManagerWithMockedElements();
|
||||
expect(manager.isOpen).toBe(false);
|
||||
expect(manager.options.closeOnSelection).toBeTruthy();
|
||||
expect(manager.options.closeOnBlur).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Manager#update', function() {
|
||||
var manager = createManagerWithMockedElements({
|
||||
onMenuToggle: jest.fn()
|
||||
});
|
||||
manager.update();
|
||||
expect(manager.menu.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.menu.setState.mock.calls[0]).toEqual([
|
||||
{ isOpen: manager.isOpen }
|
||||
]);
|
||||
expect(manager.button.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.button.setState.mock.calls[0]).toEqual([
|
||||
{ menuOpen: manager.isOpen }
|
||||
]);
|
||||
expect(manager.options.onMenuToggle).toHaveBeenCalledTimes(1);
|
||||
expect(manager.options.onMenuToggle.mock.calls[0]).toEqual([
|
||||
{ isOpen: manager.isOpen }
|
||||
]);
|
||||
});
|
||||
|
||||
it('Manager#openMenu without focusing in menu', function() {
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.openMenu({ focusMenu: false });
|
||||
expect(manager.isOpen).toBe(true);
|
||||
expect(manager.menu.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.menu.setState.mock.calls[0]).toEqual([{ isOpen: true }]);
|
||||
expect(manager.button.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.button.setState.mock.calls[0]).toEqual([{ menuOpen: true }]);
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(function() {
|
||||
expect(manager.focusItem).toHaveBeenCalledTimes(0);
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Manager#openMenu focusing in menu', function() {
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.openMenu();
|
||||
expect(manager.isOpen).toBe(true);
|
||||
expect(manager.menu.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.menu.setState.mock.calls[0]).toEqual([{ isOpen: true }]);
|
||||
expect(manager.button.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.button.setState.mock.calls[0]).toEqual([{ menuOpen: true }]);
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(function() {
|
||||
expect(manager.focusItem).toHaveBeenCalledTimes(1);
|
||||
expect(manager.focusItem.mock.calls[0]).toEqual([0]);
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Manager#closeMenu focusing on button', function() {
|
||||
mockNode.focus = jest.fn();
|
||||
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.isOpen = true;
|
||||
manager.closeMenu({ focusButton: true });
|
||||
|
||||
expect(manager.isOpen).toBe(false);
|
||||
expect(manager.menu.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.menu.setState.mock.calls[0]).toEqual([{ isOpen: false }]);
|
||||
expect(manager.button.setState).toHaveBeenCalledTimes(1);
|
||||
expect(manager.button.setState.mock.calls[0]).toEqual([
|
||||
{ menuOpen: false }
|
||||
]);
|
||||
expect(mockNode.focus).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('Manager#closeMenu without focusing on button', function() {
|
||||
mockNode.focus = jest.fn();
|
||||
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.isOpen = true;
|
||||
manager.closeMenu({ focusButton: false });
|
||||
|
||||
expect(mockNode.focus).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Manager#toggleMenu when closed', function() {
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.openMenu = jest.fn();
|
||||
manager.closeMenu = jest.fn();
|
||||
manager.toggleMenu();
|
||||
expect(manager.openMenu).toHaveBeenCalledTimes(1);
|
||||
expect(manager.closeMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Manager#toggleMenu when open', function() {
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.isOpen = true;
|
||||
manager.openMenu = jest.fn();
|
||||
manager.closeMenu = jest.fn();
|
||||
manager.toggleMenu();
|
||||
expect(manager.openMenu).not.toHaveBeenCalled();
|
||||
expect(manager.closeMenu).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('Manager#handleSelection A', function() {
|
||||
var mockOnSelection = jest.fn();
|
||||
var manager = createManagerWithMockedElements({
|
||||
onSelection: mockOnSelection
|
||||
});
|
||||
manager.closeMenu = jest.fn();
|
||||
manager.handleSelection('foo', { bar: 1 });
|
||||
expect(manager.closeMenu).toHaveBeenCalledTimes(1);
|
||||
expect(manager.closeMenu.mock.calls[0]).toEqual([{ focusButton: true }]);
|
||||
expect(mockOnSelection).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnSelection.mock.calls[0]).toEqual(['foo', { bar: 1 }]);
|
||||
});
|
||||
|
||||
it('Manager#handleSelection B', function() {
|
||||
var mockOnSelection = jest.fn();
|
||||
var manager = createManagerWithMockedElements({
|
||||
onSelection: mockOnSelection,
|
||||
closeOnSelection: false
|
||||
});
|
||||
manager.closeMenu = jest.fn();
|
||||
manager.handleSelection('foo', { bar: 1 });
|
||||
expect(manager.closeMenu).not.toHaveBeenCalled();
|
||||
expect(mockOnSelection).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnSelection.mock.calls[0]).toEqual(['foo', { bar: 1 }]);
|
||||
});
|
||||
|
||||
it('Manager#handleMenuKey on closed menu', function() {
|
||||
var escapeEvent = createMockKeyEvent('Escape');
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.closeMenu = jest.fn();
|
||||
|
||||
manager.handleMenuKey(escapeEvent);
|
||||
expect(escapeEvent.preventDefault).not.toHaveBeenCalled();
|
||||
expect(manager.closeMenu).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Manager#handleMenuKey on open menu', function() {
|
||||
var escapeEvent = createMockKeyEvent('Escape');
|
||||
var manager = createManagerWithMockedElements();
|
||||
manager.isOpen = true;
|
||||
manager.closeMenu = jest.fn();
|
||||
|
||||
manager.handleMenuKey(escapeEvent);
|
||||
expect(escapeEvent.preventDefault).toHaveBeenCalledTimes(1);
|
||||
expect(manager.closeMenu).toHaveBeenCalledTimes(1);
|
||||
expect(manager.closeMenu.mock.calls[0]).toEqual([{ focusButton: true }]);
|
||||
});
|
||||
});
|
||||
24
node_modules/react-aria-menubutton/src/__tests__/helpers/MockWrapper.js
generated
vendored
Normal file
24
node_modules/react-aria-menubutton/src/__tests__/helpers/MockWrapper.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const ManagerContext = require('../../ManagerContext');
|
||||
|
||||
class MockWrapper extends React.Component {
|
||||
static propTypes = {
|
||||
mockManager: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.manager = this.props.mockManager;
|
||||
}
|
||||
|
||||
render() {
|
||||
return React.createElement(
|
||||
ManagerContext.Provider,
|
||||
{ value: this.props.mockManager },
|
||||
React.createElement('div', null, this.props.children)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MockWrapper;
|
||||
7
node_modules/react-aria-menubutton/src/__tests__/helpers/createMockKeyEvent.js
generated
vendored
Normal file
7
node_modules/react-aria-menubutton/src/__tests__/helpers/createMockKeyEvent.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = function(key, keyCode) {
|
||||
return {
|
||||
key: key,
|
||||
keyCode: keyCode,
|
||||
preventDefault: jest.fn(),
|
||||
};
|
||||
};
|
||||
22
node_modules/react-aria-menubutton/src/__tests__/helpers/createMockManager.js
generated
vendored
Normal file
22
node_modules/react-aria-menubutton/src/__tests__/helpers/createMockManager.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
module.exports = function() {
|
||||
return {
|
||||
isOpen: false,
|
||||
toggleMenu: jest.fn(),
|
||||
handleMenuKey: jest.fn(),
|
||||
moveFocusDown: jest.fn(),
|
||||
openMenu: jest.fn(),
|
||||
handleKeyDown: jest.fn(),
|
||||
handleClick: jest.fn(),
|
||||
handleSelection: jest.fn(),
|
||||
handleButtonNonArrowKey: jest.fn(),
|
||||
focusItem: jest.fn(),
|
||||
menuItems: [1, 2],
|
||||
clearItems: jest.fn(),
|
||||
currentFocus: -1,
|
||||
addItem: jest.fn(),
|
||||
options: {
|
||||
closeOnBlur: true,
|
||||
closeOnSelection: true
|
||||
}
|
||||
};
|
||||
}
|
||||
5
node_modules/react-aria-menubutton/src/__tests__/helpers/jest-setup.js
generated
vendored
Normal file
5
node_modules/react-aria-menubutton/src/__tests__/helpers/jest-setup.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import './raf';
|
||||
import Enzyme from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
Enzyme.configure({ adapter: new Adapter() });
|
||||
3
node_modules/react-aria-menubutton/src/__tests__/helpers/raf.js
generated
vendored
Normal file
3
node_modules/react-aria-menubutton/src/__tests__/helpers/raf.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
global.requestAnimationFrame = (callback) => {
|
||||
setTimeout(callback, 0);
|
||||
};
|
||||
173
node_modules/react-aria-menubutton/src/createManager.js
generated
vendored
Normal file
173
node_modules/react-aria-menubutton/src/createManager.js
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
const createFocusGroup = require('focus-group');
|
||||
const externalStateControl = require('./externalStateControl');
|
||||
|
||||
const focusGroupOptions = {
|
||||
wrap: true,
|
||||
stringSearch: true
|
||||
};
|
||||
|
||||
const protoManager = {
|
||||
init(options) {
|
||||
this.updateOptions(options);
|
||||
|
||||
this.handleBlur = handleBlur.bind(this);
|
||||
this.handleSelection = handleSelection.bind(this);
|
||||
this.handleMenuKey = handleMenuKey.bind(this);
|
||||
|
||||
// "With focus on the drop-down menu, the Up and Down Arrow
|
||||
// keys move focus within the menu items, "wrapping" at the top and bottom."
|
||||
// "Typing a letter (printable character) key moves focus to the next
|
||||
// instance of a visible node whose title begins with that printable letter."
|
||||
//
|
||||
// All of the above is handled by focus-group.
|
||||
this.focusGroup = createFocusGroup(focusGroupOptions);
|
||||
|
||||
// These component references are added when the relevant components mount
|
||||
this.button = null;
|
||||
this.menu = null;
|
||||
|
||||
// State trackers
|
||||
this.isOpen = false;
|
||||
},
|
||||
|
||||
updateOptions(options) {
|
||||
const oldOptions = this.options;
|
||||
|
||||
this.options = options || this.options || {};
|
||||
|
||||
if (typeof this.options.closeOnSelection === 'undefined') {
|
||||
this.options.closeOnSelection = true;
|
||||
}
|
||||
|
||||
if (typeof this.options.closeOnBlur === 'undefined') {
|
||||
this.options.closeOnBlur = true;
|
||||
}
|
||||
|
||||
if (this.options.id) {
|
||||
externalStateControl.registerManager(this.options.id, this);
|
||||
}
|
||||
|
||||
if (oldOptions && oldOptions.id && oldOptions.id !== this.options.id) {
|
||||
externalStateControl.unregisterManager(this.options.id, this);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
focusItem(index) {
|
||||
this.focusGroup.focusNodeAtIndex(index);
|
||||
},
|
||||
|
||||
addItem(item) {
|
||||
this.focusGroup.addMember(item);
|
||||
},
|
||||
|
||||
clearItems() {
|
||||
this.focusGroup.clearMembers();
|
||||
},
|
||||
|
||||
handleButtonNonArrowKey(event) {
|
||||
this.focusGroup._handleUnboundKey(event);
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this.button = null;
|
||||
this.menu = null;
|
||||
this.focusGroup.deactivate();
|
||||
clearTimeout(this.blurTimer);
|
||||
clearTimeout(this.moveFocusTimer);
|
||||
},
|
||||
|
||||
update() {
|
||||
this.menu.setState({ isOpen: this.isOpen });
|
||||
this.button.setState({ menuOpen: this.isOpen });
|
||||
this.options.onMenuToggle &&
|
||||
this.options.onMenuToggle({ isOpen: this.isOpen });
|
||||
},
|
||||
|
||||
openMenu(openOptions) {
|
||||
if (this.isOpen) return;
|
||||
openOptions = openOptions || {};
|
||||
if (openOptions.focusMenu === undefined) {
|
||||
openOptions.focusMenu = true;
|
||||
}
|
||||
this.isOpen = true;
|
||||
this.update();
|
||||
this.focusGroup.activate();
|
||||
if (openOptions.focusMenu) {
|
||||
const self = this;
|
||||
this.moveFocusTimer = setTimeout(function() {
|
||||
self.focusItem(0);
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
|
||||
closeMenu(closeOptions) {
|
||||
if (!this.isOpen) return;
|
||||
closeOptions = closeOptions || {};
|
||||
this.isOpen = false;
|
||||
this.update();
|
||||
if (closeOptions.focusButton) {
|
||||
this.button.ref.current.focus();
|
||||
}
|
||||
},
|
||||
|
||||
toggleMenu(closeOptions, openOptions) {
|
||||
closeOptions = closeOptions || {};
|
||||
openOptions = openOptions || {};
|
||||
if (this.isOpen) {
|
||||
this.closeMenu(closeOptions);
|
||||
} else {
|
||||
this.openMenu(openOptions);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function handleBlur() {
|
||||
const self = this;
|
||||
self.blurTimer = setTimeout(function() {
|
||||
if (!self.button) return;
|
||||
const buttonNode = self.button.ref.current;
|
||||
if (!buttonNode) return;
|
||||
const activeEl = buttonNode.ownerDocument.activeElement;
|
||||
if (buttonNode && activeEl === buttonNode) return;
|
||||
const menuNode = self.menu.ref.current;
|
||||
if (menuNode === activeEl) {
|
||||
self.focusItem(0);
|
||||
return;
|
||||
}
|
||||
if (menuNode && menuNode.contains(activeEl)) return;
|
||||
if (self.isOpen) self.closeMenu({ focusButton: false });
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function handleSelection(value, event) {
|
||||
if (this.options.closeOnSelection) this.closeMenu({ focusButton: true });
|
||||
if (this.options.onSelection) this.options.onSelection(value, event);
|
||||
}
|
||||
|
||||
function handleMenuKey(event) {
|
||||
if (this.isOpen) {
|
||||
switch (event.key) {
|
||||
// With focus on the drop-down menu, pressing Escape closes
|
||||
// the menu and returns focus to the button.
|
||||
case 'Escape':
|
||||
event.preventDefault();
|
||||
this.closeMenu({ focusButton: true });
|
||||
break;
|
||||
case 'Home':
|
||||
event.preventDefault();
|
||||
this.focusGroup.moveFocusToFirst();
|
||||
break;
|
||||
case 'End':
|
||||
event.preventDefault();
|
||||
this.focusGroup.moveFocusToLast();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(options) {
|
||||
const newManager = Object.create(protoManager);
|
||||
newManager.init(options);
|
||||
return newManager;
|
||||
};
|
||||
31
node_modules/react-aria-menubutton/src/externalStateControl.js
generated
vendored
Normal file
31
node_modules/react-aria-menubutton/src/externalStateControl.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
const registeredManagers = {};
|
||||
|
||||
const errorCommon =
|
||||
'a menu outside a mounted Wrapper with an id, or a menu that does not exist';
|
||||
|
||||
function registerManager(menuId, manager) {
|
||||
registeredManagers[menuId] = manager;
|
||||
}
|
||||
|
||||
function unregisterManager(menuId) {
|
||||
delete registeredManagers[menuId];
|
||||
}
|
||||
|
||||
function openMenu(menuId, openOptions) {
|
||||
const manager = registeredManagers[menuId];
|
||||
if (!manager) throw new Error('Cannot open ' + errorCommon);
|
||||
manager.openMenu(openOptions);
|
||||
}
|
||||
|
||||
function closeMenu(menuId, closeOptions) {
|
||||
const manager = registeredManagers[menuId];
|
||||
if (!manager) throw new Error('Cannot close ' + errorCommon);
|
||||
manager.closeMenu(closeOptions);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
registerManager: registerManager,
|
||||
unregisterManager: unregisterManager,
|
||||
openMenu: openMenu,
|
||||
closeMenu: closeMenu
|
||||
};
|
||||
10
node_modules/react-aria-menubutton/src/index.js
generated
vendored
Normal file
10
node_modules/react-aria-menubutton/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
const externalStateControl = require('./externalStateControl');
|
||||
|
||||
module.exports = {
|
||||
Wrapper: require('./Wrapper'),
|
||||
Button: require('./Button'),
|
||||
Menu: require('./Menu'),
|
||||
MenuItem: require('./MenuItem'),
|
||||
openMenu: externalStateControl.openMenu,
|
||||
closeMenu: externalStateControl.closeMenu
|
||||
};
|
||||
8
node_modules/react-aria-menubutton/src/propTypes.js
generated
vendored
Normal file
8
node_modules/react-aria-menubutton/src/propTypes.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const PropTypes = require("prop-types");
|
||||
|
||||
module.exports = {
|
||||
refType: PropTypes.oneOfType([
|
||||
PropTypes.func,
|
||||
PropTypes.shape({ current: PropTypes.elementType })
|
||||
])
|
||||
};
|
||||
9
node_modules/react-aria-menubutton/src/specialAssign.js
generated
vendored
Normal file
9
node_modules/react-aria-menubutton/src/specialAssign.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module.exports = function(a, b, reserved) {
|
||||
reserved = reserved || {};
|
||||
// This will get id, className, style, etc.
|
||||
for (var x in b) {
|
||||
if (!b.hasOwnProperty(x)) continue;
|
||||
if (reserved[x]) continue;
|
||||
a[x] = b[x];
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user