@dhis2-ui/menu 9.10.3 → 9.11.1-beta.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/build/cjs/flyout-menu/__tests__/flyout-menu.test.js +44 -0
- package/build/cjs/flyout-menu/features/accepts_children/index.js +0 -1
- package/build/cjs/flyout-menu/features/position/index.js +4 -4
- package/build/cjs/flyout-menu/features/toggles_submenus/index.js +0 -1
- package/build/cjs/flyout-menu/{flyout-menu.stories.e2e.js → flyout-menu.e2e.stories.js} +2 -20
- package/build/cjs/flyout-menu/flyout-menu.js +37 -19
- package/build/cjs/flyout-menu/{flyout-menu.stories.js → flyout-menu.prod.stories.js} +28 -38
- package/build/cjs/flyout-menu/index.js +0 -1
- package/build/cjs/index.js +0 -5
- package/build/cjs/menu/__tests__/menu.test.js +11 -50
- package/build/cjs/menu/features/accepts_children/index.js +0 -1
- package/build/cjs/menu/helpers.js +2 -10
- package/build/cjs/menu/index.js +0 -1
- package/build/cjs/menu/menu.e2e.stories.js +14 -0
- package/build/cjs/menu/menu.js +12 -20
- package/build/cjs/menu/{menu.stories.js → menu.prod.stories.js} +18 -17
- package/build/cjs/menu/use-menu.js +12 -20
- package/build/cjs/menu-divider/index.js +0 -1
- package/build/cjs/menu-divider/menu-divider.js +3 -11
- package/build/cjs/menu-divider/{menu-divider.stories.js → menu-divider.prod.stories.js} +11 -15
- package/build/cjs/menu-item/__tests__/menu-item.test.js +1 -5
- package/build/cjs/menu-item/features/accepts_href/index.js +1 -2
- package/build/cjs/menu-item/features/accepts_icon/index.js +0 -1
- package/build/cjs/menu-item/features/accepts_label/index.js +1 -2
- package/build/cjs/menu-item/features/accepts_suffix/index.js +0 -1
- package/build/cjs/menu-item/features/accepts_target/index.js +1 -2
- package/build/cjs/menu-item/features/is_clickable/index.js +0 -1
- package/build/cjs/menu-item/index.js +0 -1
- package/build/cjs/menu-item/{menu-item.stories.e2e.js → menu-item.e2e.stories.js} +2 -20
- package/build/cjs/menu-item/menu-item.js +48 -38
- package/build/cjs/menu-item/{menu-item.stories.js → menu-item.prod.stories.js} +22 -46
- package/build/cjs/menu-item/menu-item.styles.js +2 -5
- package/build/cjs/menu-section-header/features/accepts_label/index.js +1 -2
- package/build/cjs/menu-section-header/index.js +0 -1
- package/build/cjs/menu-section-header/{menu-section-header.stories.e2e.js → menu-section-header.e2e.stories.js} +2 -10
- package/build/cjs/menu-section-header/menu-section-header.js +3 -12
- package/build/cjs/menu-section-header/{menu-section-header.stories.js → menu-section-header.prod.stories.js} +11 -19
- package/build/es/flyout-menu/__tests__/flyout-menu.test.js +41 -0
- package/build/es/flyout-menu/features/position/index.js +4 -3
- package/build/es/flyout-menu/{flyout-menu.stories.e2e.js → flyout-menu.e2e.stories.js} +0 -2
- package/build/es/flyout-menu/flyout-menu.js +35 -9
- package/build/es/flyout-menu/{flyout-menu.stories.js → flyout-menu.prod.stories.js} +28 -13
- package/build/es/menu/__tests__/menu.test.js +10 -8
- package/build/es/menu/helpers.js +2 -6
- package/build/es/menu/menu.e2e.stories.js +6 -0
- package/build/es/menu/menu.js +9 -9
- package/build/es/menu/{menu.stories.js → menu.prod.stories.js} +18 -1
- package/build/es/menu/use-menu.js +12 -16
- package/build/es/menu-divider/menu-divider.js +2 -4
- package/build/es/menu-divider/{menu-divider.stories.js → menu-divider.prod.stories.js} +7 -3
- package/build/es/menu-item/features/accepts_href/index.js +1 -1
- package/build/es/menu-item/features/accepts_label/index.js +1 -1
- package/build/es/menu-item/features/accepts_target/index.js +1 -1
- package/build/es/menu-item/menu-item.js +46 -24
- package/build/es/menu-item/{menu-item.stories.js → menu-item.prod.stories.js} +14 -9
- package/build/es/menu-item/menu-item.styles.js +1 -1
- package/build/es/menu-section-header/features/accepts_label/index.js +1 -1
- package/build/es/menu-section-header/menu-section-header.js +2 -4
- package/build/es/menu-section-header/{menu-section-header.stories.js → menu-section-header.prod.stories.js} +7 -3
- package/package.json +11 -11
- package/types/index.d.ts +4 -0
- package/build/cjs/menu/menu.stories.e2e.js +0 -11
- package/build/es/menu/menu.stories.e2e.js +0 -4
- /package/build/es/menu-item/{menu-item.stories.e2e.js → menu-item.e2e.stories.js} +0 -0
- /package/build/es/menu-section-header/{menu-section-header.stories.e2e.js → menu-section-header.e2e.stories.js} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("@testing-library/react");
|
|
4
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
5
|
+
var _react2 = _interopRequireDefault(require("react"));
|
|
6
|
+
var _menuItem = require("../../menu-item/menu-item.js");
|
|
7
|
+
var _flyoutMenu = require("../flyout-menu.js");
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
describe('Flyout Menu Component', () => {
|
|
10
|
+
it('can handle navigation of submenus', () => {
|
|
11
|
+
const {
|
|
12
|
+
getByText,
|
|
13
|
+
queryByText,
|
|
14
|
+
getAllByRole
|
|
15
|
+
} = (0, _react.render)( /*#__PURE__*/_react2.default.createElement(_flyoutMenu.FlyoutMenu, null, /*#__PURE__*/_react2.default.createElement(_menuItem.MenuItem, {
|
|
16
|
+
label: "Item 1"
|
|
17
|
+
}), /*#__PURE__*/_react2.default.createElement(_menuItem.MenuItem, {
|
|
18
|
+
label: "Item 2"
|
|
19
|
+
}, /*#__PURE__*/_react2.default.createElement(_menuItem.MenuItem, {
|
|
20
|
+
label: "Item 2 a"
|
|
21
|
+
}))));
|
|
22
|
+
const itemOne = getByText(/Item 1/i);
|
|
23
|
+
const itemTwo = getByText(/Item 2/i);
|
|
24
|
+
let submenuChild = queryByText(/Item 2 a/i);
|
|
25
|
+
const menuItems = getAllByRole('menuitem');
|
|
26
|
+
expect(menuItems.length).toBe(2);
|
|
27
|
+
expect(menuItems[0]).toBe(itemOne.parentNode);
|
|
28
|
+
expect(menuItems[1]).toBe(itemTwo.parentNode);
|
|
29
|
+
expect(submenuChild).not.toBeInTheDocument();
|
|
30
|
+
_userEvent.default.tab();
|
|
31
|
+
expect(menuItems[0].parentNode).toHaveFocus();
|
|
32
|
+
expect(menuItems[1].parentNode).not.toHaveFocus();
|
|
33
|
+
_userEvent.default.keyboard('{ArrowDown}');
|
|
34
|
+
expect(menuItems[0].parentNode).not.toHaveFocus();
|
|
35
|
+
expect(menuItems[1].parentNode).toHaveFocus();
|
|
36
|
+
_userEvent.default.keyboard('{ArrowRight}');
|
|
37
|
+
submenuChild = getByText(/Item 2 a/i);
|
|
38
|
+
expect(submenuChild).toBeInTheDocument();
|
|
39
|
+
expect(submenuChild.parentElement.parentElement).toHaveFocus();
|
|
40
|
+
_userEvent.default.keyboard('{ArrowLeft}');
|
|
41
|
+
expect(queryByText(/Item 2 a/i)).not.toBeInTheDocument();
|
|
42
|
+
expect(menuItems[1].parentNode).toHaveFocus();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _cypressCucumberPreprocessor = require("@badeball/cypress-cucumber-preprocessor");
|
|
4
|
-
|
|
5
4
|
(0, _cypressCucumberPreprocessor.Given)('a FlyoutMenu with children is rendered', () => {
|
|
6
5
|
cy.visitStory('FlyoutMenu', 'With Children');
|
|
7
6
|
cy.get('[data-test="dhis2-uicore-menu"]').should('be.visible');
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _cypressCucumberPreprocessor = require("@badeball/cypress-cucumber-preprocessor");
|
|
4
|
-
|
|
5
4
|
const CLOSE_TO_DELTA = 1;
|
|
6
5
|
(0, _cypressCucumberPreprocessor.Given)('there is enough space to the right of the MenuItem to fit the SubMenu', () => {
|
|
7
6
|
cy.visitStory('FlyoutMenu', 'Default Position');
|
|
@@ -30,8 +29,10 @@ const CLOSE_TO_DELTA = 1;
|
|
|
30
29
|
(0, _cypressCucumberPreprocessor.Then)('the SubMenu is rendered on top of the MenuItem', () => {
|
|
31
30
|
getMenuItemAndSubMenuRects().should(_ref3 => {
|
|
32
31
|
let [menuItemRect, subMenuRect] = _ref3;
|
|
33
|
-
expect(subMenuRect.left).to.be.at.most(menuItemRect.
|
|
34
|
-
expect(subMenuRect.right).to.be.at.least(menuItemRect.
|
|
32
|
+
expect(subMenuRect.left).to.be.at.most(menuItemRect.right);
|
|
33
|
+
expect(subMenuRect.right).to.be.at.least(menuItemRect.left);
|
|
34
|
+
expect(subMenuRect.top).to.be.at.most(menuItemRect.bottom);
|
|
35
|
+
expect(subMenuRect.bottom).to.be.at.least(menuItemRect.top);
|
|
35
36
|
});
|
|
36
37
|
});
|
|
37
38
|
(0, _cypressCucumberPreprocessor.Then)('the top of the MenuItem is aligned with the top of the SubMenu wrapper', () => {
|
|
@@ -40,7 +41,6 @@ const CLOSE_TO_DELTA = 1;
|
|
|
40
41
|
expect(menuItemRect.top).to.closeTo(popperRect.top, CLOSE_TO_DELTA);
|
|
41
42
|
});
|
|
42
43
|
});
|
|
43
|
-
|
|
44
44
|
function getMenuItemAndSubMenuRects() {
|
|
45
45
|
return cy.getPositionsBySelectors('[data-test="dhis2-uicore-menuitem"]', '[data-test="dhis2-uicore-popper"]');
|
|
46
46
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _cypressCucumberPreprocessor = require("@badeball/cypress-cucumber-preprocessor");
|
|
4
|
-
|
|
5
4
|
(0, _cypressCucumberPreprocessor.Given)('a FlyoutMenu with two SubMenus is rendered', () => {
|
|
6
5
|
cy.visitStory('FlyoutMenu', 'Toggles Sub Menus');
|
|
7
6
|
cy.get('[data-test="dhis2-uicore-menu"]').should('be.visible');
|
|
@@ -4,23 +4,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.WithChildren = exports.TogglesSubMenus = exports.ShiftIntoView = exports.FlippedPosition = exports.DefaultPosition = void 0;
|
|
7
|
-
|
|
8
7
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
9
|
-
|
|
10
8
|
var _menu = require("@dhis2-ui/menu");
|
|
11
|
-
|
|
12
9
|
var _react = _interopRequireDefault(require("react"));
|
|
13
|
-
|
|
14
10
|
var _flyoutMenu = require("./flyout-menu.js");
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var _default = {
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
var _default = exports.default = {
|
|
19
13
|
title: 'FlyoutMenu',
|
|
20
14
|
component: _flyoutMenu.FlyoutMenu
|
|
21
15
|
};
|
|
22
|
-
exports.default = _default;
|
|
23
|
-
|
|
24
16
|
const MenuItemSubMenuPositions = () => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, null, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
25
17
|
label: "Item 1"
|
|
26
18
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
@@ -28,35 +20,25 @@ const MenuItemSubMenuPositions = () => /*#__PURE__*/_react.default.createElement
|
|
|
28
20
|
padding: 30
|
|
29
21
|
}
|
|
30
22
|
}, "SubMenu 1")));
|
|
31
|
-
|
|
32
23
|
const WithChildren = () => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, null, "I am a child");
|
|
33
|
-
|
|
34
24
|
exports.WithChildren = WithChildren;
|
|
35
|
-
|
|
36
25
|
const TogglesSubMenus = () => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, null, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
37
26
|
label: "Item 1"
|
|
38
27
|
}, "SubMenu 1"), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
39
28
|
label: "Item 2"
|
|
40
29
|
}, "SubMenu 2"));
|
|
41
|
-
|
|
42
30
|
exports.TogglesSubMenus = TogglesSubMenus;
|
|
43
|
-
|
|
44
31
|
const DefaultPosition = () => /*#__PURE__*/_react.default.createElement(MenuItemSubMenuPositions, null);
|
|
45
|
-
|
|
46
32
|
exports.DefaultPosition = DefaultPosition;
|
|
47
|
-
|
|
48
33
|
const FlippedPosition = () => /*#__PURE__*/_react.default.createElement("div", {
|
|
49
34
|
className: "jsx-2297277891"
|
|
50
35
|
}, /*#__PURE__*/_react.default.createElement(MenuItemSubMenuPositions, null), /*#__PURE__*/_react.default.createElement(_style.default, {
|
|
51
36
|
id: "2297277891"
|
|
52
37
|
}, ["div.jsx-2297277891{text-align:right;}"]));
|
|
53
|
-
|
|
54
38
|
exports.FlippedPosition = FlippedPosition;
|
|
55
|
-
|
|
56
39
|
const ShiftIntoView = () => /*#__PURE__*/_react.default.createElement("div", {
|
|
57
40
|
className: "jsx-3052292650"
|
|
58
41
|
}, /*#__PURE__*/_react.default.createElement(MenuItemSubMenuPositions, null), /*#__PURE__*/_react.default.createElement(_style.default, {
|
|
59
42
|
id: "3052292650"
|
|
60
43
|
}, ["html,body,#root{position:relative;width:200px;max-width:200px;overflow:hidden;}", "#root{border:3px dashed grey;}"]));
|
|
61
|
-
|
|
62
44
|
exports.ShiftIntoView = ShiftIntoView;
|
|
@@ -4,23 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.FlyoutMenu = void 0;
|
|
7
|
-
|
|
8
7
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
9
|
-
|
|
10
8
|
var _uiConstants = require("@dhis2/ui-constants");
|
|
11
|
-
|
|
12
9
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
13
|
-
|
|
14
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
-
|
|
22
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
-
|
|
11
|
+
var _index = require("../menu/index.js");
|
|
12
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
13
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
14
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
24
15
|
const FlyoutMenu = _ref => {
|
|
25
16
|
let {
|
|
26
17
|
children,
|
|
@@ -28,17 +19,44 @@ const FlyoutMenu = _ref => {
|
|
|
28
19
|
dataTest,
|
|
29
20
|
dense,
|
|
30
21
|
maxHeight,
|
|
31
|
-
maxWidth
|
|
22
|
+
maxWidth,
|
|
23
|
+
closeMenu
|
|
32
24
|
} = _ref;
|
|
33
25
|
const [openedSubMenu, setOpenedSubMenu] = (0, _react.useState)(null);
|
|
34
|
-
|
|
35
26
|
const toggleSubMenu = index => {
|
|
36
27
|
const toggleValue = index === openedSubMenu ? null : index;
|
|
37
28
|
setOpenedSubMenu(toggleValue);
|
|
38
29
|
};
|
|
39
|
-
|
|
30
|
+
const divRef = (0, _react.useRef)(null);
|
|
31
|
+
(0, _react.useEffect)(() => {
|
|
32
|
+
if (!divRef.current) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const div = divRef.current;
|
|
36
|
+
const handleFocus = event => {
|
|
37
|
+
if (event.target === div) {
|
|
38
|
+
if (div !== null && div !== void 0 && div.children && div.children.length > 0) {
|
|
39
|
+
div.children[0].focus();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const handleKeyDown = event => {
|
|
44
|
+
if (event.key === 'Escape') {
|
|
45
|
+
event.preventDefault();
|
|
46
|
+
closeMenu && closeMenu();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
div.addEventListener('focus', handleFocus);
|
|
50
|
+
div.addEventListener('keydown', handleKeyDown);
|
|
51
|
+
return () => {
|
|
52
|
+
div.removeEventListener('focus', handleFocus);
|
|
53
|
+
div.removeEventListener('keydown', handleKeyDown);
|
|
54
|
+
};
|
|
55
|
+
}, [closeMenu]);
|
|
40
56
|
return /*#__PURE__*/_react.default.createElement("div", {
|
|
41
57
|
"data-test": dataTest,
|
|
58
|
+
tabIndex: 0,
|
|
59
|
+
ref: divRef,
|
|
42
60
|
className: _style.default.dynamic([["3833750986", [_uiConstants.colors.white, _uiConstants.colors.grey200, _uiConstants.elevations.e300, dense ? '128' : '180', maxWidth, maxHeight, _uiConstants.spacers.dp4]]]) + " " + (className || "")
|
|
43
61
|
}, /*#__PURE__*/_react.default.createElement(_index.Menu, {
|
|
44
62
|
dense: dense
|
|
@@ -48,9 +66,8 @@ const FlyoutMenu = _ref => {
|
|
|
48
66
|
}) : child)), /*#__PURE__*/_react.default.createElement(_style.default, {
|
|
49
67
|
id: "3833750986",
|
|
50
68
|
dynamic: [_uiConstants.colors.white, _uiConstants.colors.grey200, _uiConstants.elevations.e300, dense ? '128' : '180', maxWidth, maxHeight, _uiConstants.spacers.dp4]
|
|
51
|
-
}, [
|
|
69
|
+
}, [`div.__jsx-style-dynamic-selector{background:${_uiConstants.colors.white};border:1px solid ${_uiConstants.colors.grey200};border-radius:3px;box-shadow:${_uiConstants.elevations.e300};display:inline-block;min-width:${dense ? '128' : '180'}px;max-width:${maxWidth};max-height:${maxHeight};padding:${_uiConstants.spacers.dp4} 0;overflow:auto;}`]));
|
|
52
70
|
};
|
|
53
|
-
|
|
54
71
|
exports.FlyoutMenu = FlyoutMenu;
|
|
55
72
|
FlyoutMenu.defaultProps = {
|
|
56
73
|
dataTest: 'dhis2-uicore-menu',
|
|
@@ -61,8 +78,9 @@ FlyoutMenu.propTypes = {
|
|
|
61
78
|
/** Typically, but not limited to, `MenuItem` components */
|
|
62
79
|
children: _propTypes.default.node,
|
|
63
80
|
className: _propTypes.default.string,
|
|
81
|
+
/** when Escape key is pressed, this function is called to close the flyout menu */
|
|
82
|
+
closeMenu: _propTypes.default.func,
|
|
64
83
|
dataTest: _propTypes.default.string,
|
|
65
|
-
|
|
66
84
|
/** Menu uses smaller dimensions */
|
|
67
85
|
dense: _propTypes.default.bool,
|
|
68
86
|
maxHeight: _propTypes.default.string,
|
|
@@ -4,27 +4,34 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.WithVariousChildren = exports.WithSubMenus = exports.WithCustomMenuItem = exports.MaxWidth = exports.MaxHeight = exports.DropDownMenu = exports.Dense = exports.Default = void 0;
|
|
7
|
-
|
|
7
|
+
var _uiIcons = require("@dhis2/ui-icons");
|
|
8
8
|
var _layer = require("@dhis2-ui/layer");
|
|
9
|
-
|
|
10
9
|
var _menu = require("@dhis2-ui/menu");
|
|
11
|
-
|
|
12
10
|
var _popper = require("@dhis2-ui/popper");
|
|
13
|
-
|
|
14
|
-
var _uiIcons = require("@dhis2/ui-icons");
|
|
15
|
-
|
|
16
11
|
var _react = _interopRequireWildcard(require("react"));
|
|
17
|
-
|
|
18
12
|
var _flyoutMenu = require("./flyout-menu.js");
|
|
13
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
14
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
15
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
16
|
+
const description = `
|
|
17
|
+
Use menus to provide access to options and actions where space is limited and displaying all the options would be impractical. For example, providing access to a range of actions for every dashboard item displayed. Containing all those actions in menus keeps the page manageable.
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
The menu component is flexible in where it can be used and its contents can be flexible too. However, the most common use case is a menu containing menu items.
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
Make sure the menu item labels are short and easy to understand. One word is often enough to describe an action or option. Do not use sentences as labels. Some examples of good menu item labels:
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
- "Save"
|
|
24
|
+
- "Open as map"
|
|
25
|
+
- "Export PDF"
|
|
26
|
+
- "Duplicate"
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
See more about how to use menus at the [design system](https://github.com/dhis2/design-system/blob/master/molecules/menu.md).
|
|
29
|
+
|
|
30
|
+
\`\`\`js
|
|
31
|
+
import { FlyoutMenu } from 'dhis2/ui'
|
|
32
|
+
\`\`\`
|
|
33
|
+
`;
|
|
34
|
+
var _default = exports.default = {
|
|
28
35
|
title: 'Flyout Menu',
|
|
29
36
|
component: _flyoutMenu.FlyoutMenu,
|
|
30
37
|
parameters: {
|
|
@@ -35,21 +42,16 @@ var _default = {
|
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
44
|
};
|
|
38
|
-
exports.default = _default;
|
|
39
|
-
|
|
40
45
|
const Default = args => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, args, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
41
46
|
label: "Item 1"
|
|
42
47
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
43
48
|
label: "Item 2"
|
|
44
49
|
}));
|
|
45
|
-
|
|
46
50
|
exports.Default = Default;
|
|
47
|
-
const Dense = Default.bind({});
|
|
48
|
-
exports.Dense = Dense;
|
|
51
|
+
const Dense = exports.Dense = Default.bind({});
|
|
49
52
|
Dense.args = {
|
|
50
53
|
dense: true
|
|
51
54
|
};
|
|
52
|
-
|
|
53
55
|
const MaxHeight = args => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, args, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
54
56
|
label: "Item 1"
|
|
55
57
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
@@ -71,12 +73,10 @@ const MaxHeight = args => /*#__PURE__*/_react.default.createElement(_flyoutMenu.
|
|
|
71
73
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
72
74
|
label: "Item 10"
|
|
73
75
|
}));
|
|
74
|
-
|
|
75
76
|
exports.MaxHeight = MaxHeight;
|
|
76
77
|
MaxHeight.args = {
|
|
77
78
|
maxHeight: '250px'
|
|
78
79
|
};
|
|
79
|
-
|
|
80
80
|
const MaxWidth = args => /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, null, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
81
81
|
label: "Short item 1"
|
|
82
82
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
@@ -86,16 +86,16 @@ const MaxWidth = args => /*#__PURE__*/_react.default.createElement(_react.defaul
|
|
|
86
86
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
87
87
|
label: "Item 2 - with a lot of text and using a default maxWidth value of 380px"
|
|
88
88
|
})), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, args, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
89
|
-
label:
|
|
89
|
+
label: `Item 1 - with a lot of text and using a custom maxWidth value of
|
|
90
|
+
${args.maxWidth}`
|
|
90
91
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
91
|
-
label:
|
|
92
|
+
label: `Item 2 - with a lot of text and using a custom maxWidth value of
|
|
93
|
+
${args.maxWidth}`
|
|
92
94
|
})));
|
|
93
|
-
|
|
94
95
|
exports.MaxWidth = MaxWidth;
|
|
95
96
|
MaxWidth.args = {
|
|
96
97
|
maxWidth: '300px'
|
|
97
98
|
};
|
|
98
|
-
|
|
99
99
|
const WithSubMenus = args => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, args, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
100
100
|
label: "Item 1"
|
|
101
101
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
@@ -127,7 +127,6 @@ const WithSubMenus = args => /*#__PURE__*/_react.default.createElement(_flyoutMe
|
|
|
127
127
|
})), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
128
128
|
label: "Item 5"
|
|
129
129
|
}));
|
|
130
|
-
|
|
131
130
|
exports.WithSubMenus = WithSubMenus;
|
|
132
131
|
WithSubMenus.parameters = {
|
|
133
132
|
docs: {
|
|
@@ -136,7 +135,6 @@ WithSubMenus.parameters = {
|
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
137
|
};
|
|
139
|
-
|
|
140
138
|
const WithVariousChildren = args => /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, args, /*#__PURE__*/_react.default.createElement(_menu.MenuSectionHeader, {
|
|
141
139
|
label: "Section with sub-menus"
|
|
142
140
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
@@ -178,7 +176,6 @@ const WithVariousChildren = args => /*#__PURE__*/_react.default.createElement(_f
|
|
|
178
176
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuDivider, null), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
179
177
|
label: "Item 3"
|
|
180
178
|
}));
|
|
181
|
-
|
|
182
179
|
exports.WithVariousChildren = WithVariousChildren;
|
|
183
180
|
WithVariousChildren.parameters = {
|
|
184
181
|
docs: {
|
|
@@ -187,13 +184,10 @@ WithVariousChildren.parameters = {
|
|
|
187
184
|
}
|
|
188
185
|
}
|
|
189
186
|
};
|
|
190
|
-
|
|
191
187
|
const DropDownMenu = args => {
|
|
192
188
|
const ref = (0, _react.useRef)();
|
|
193
189
|
const [open, setOpen] = (0, _react.useState)(false);
|
|
194
|
-
|
|
195
190
|
const toggle = () => setOpen(!open);
|
|
196
|
-
|
|
197
191
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("button", {
|
|
198
192
|
ref: ref,
|
|
199
193
|
onClick: toggle
|
|
@@ -202,13 +196,14 @@ const DropDownMenu = args => {
|
|
|
202
196
|
}, /*#__PURE__*/_react.default.createElement(_popper.Popper, {
|
|
203
197
|
reference: ref,
|
|
204
198
|
placement: "bottom-start"
|
|
205
|
-
}, /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu,
|
|
199
|
+
}, /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, _extends({}, args, {
|
|
200
|
+
closeMenu: toggle
|
|
201
|
+
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
206
202
|
label: "Item 1"
|
|
207
203
|
}), /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
208
204
|
label: "Item 2"
|
|
209
205
|
})))));
|
|
210
206
|
};
|
|
211
|
-
|
|
212
207
|
exports.DropDownMenu = DropDownMenu;
|
|
213
208
|
DropDownMenu.parameters = {
|
|
214
209
|
docs: {
|
|
@@ -220,7 +215,6 @@ DropDownMenu.parameters = {
|
|
|
220
215
|
}
|
|
221
216
|
}
|
|
222
217
|
};
|
|
223
|
-
|
|
224
218
|
const WithCustomMenuItem = args => {
|
|
225
219
|
// You should not create custom components in the render cycle
|
|
226
220
|
// this is just for demo purposes
|
|
@@ -234,20 +228,16 @@ const WithCustomMenuItem = args => {
|
|
|
234
228
|
const WIDTH = 1400;
|
|
235
229
|
const centerY = (window.screen.height - HEIGHT) / 2;
|
|
236
230
|
const centerX = (window.screen.width - WIDTH) / 2;
|
|
237
|
-
|
|
238
|
-
const onClick = () => window.open(to, 'Popup', ['menubar=no', 'location=no', 'resizable=no', 'scrollbars=no', 'status=no', "width=".concat(WIDTH), "height=".concat(HEIGHT), "top=".concat(centerY), "left=".concat(centerX)].join());
|
|
239
|
-
|
|
231
|
+
const onClick = () => window.open(to, 'Popup', ['menubar=no', 'location=no', 'resizable=no', 'scrollbars=no', 'status=no', `width=${WIDTH}`, `height=${HEIGHT}`, `top=${centerY}`, `left=${centerX}`].join());
|
|
240
232
|
return /*#__PURE__*/_react.default.createElement(_menu.MenuItem, _extends({
|
|
241
233
|
onClick: onClick,
|
|
242
234
|
label: children
|
|
243
235
|
}, rest));
|
|
244
236
|
};
|
|
245
|
-
|
|
246
237
|
return /*#__PURE__*/_react.default.createElement(_flyoutMenu.FlyoutMenu, args, /*#__PURE__*/_react.default.createElement(_menu.MenuItem, {
|
|
247
238
|
label: "A normal menu item"
|
|
248
239
|
}), /*#__PURE__*/_react.default.createElement(PopupWindowMenuItem, {
|
|
249
240
|
to: "http://dhis2.org"
|
|
250
241
|
}, "A custom menu item (popup window)"));
|
|
251
242
|
};
|
|
252
|
-
|
|
253
243
|
exports.WithCustomMenuItem = WithCustomMenuItem;
|
package/build/cjs/index.js
CHANGED
|
@@ -33,13 +33,8 @@ Object.defineProperty(exports, "MenuSectionHeader", {
|
|
|
33
33
|
return _index3.MenuSectionHeader;
|
|
34
34
|
}
|
|
35
35
|
});
|
|
36
|
-
|
|
37
36
|
var _index = require("./menu-divider/index.js");
|
|
38
|
-
|
|
39
37
|
var _index2 = require("./menu-item/index.js");
|
|
40
|
-
|
|
41
38
|
var _index3 = require("./menu-section-header/index.js");
|
|
42
|
-
|
|
43
39
|
var _index4 = require("./menu/index.js");
|
|
44
|
-
|
|
45
40
|
var _index5 = require("./flyout-menu/index.js");
|
|
@@ -1,25 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _input = require("@dhis2-ui/input");
|
|
4
|
-
|
|
5
4
|
var _react = require("@testing-library/react");
|
|
6
|
-
|
|
7
5
|
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
8
|
-
|
|
9
6
|
var _enzyme = require("enzyme");
|
|
10
|
-
|
|
11
7
|
var _react2 = _interopRequireDefault(require("react"));
|
|
12
|
-
|
|
13
8
|
var _menuDivider = require("../../menu-divider/menu-divider.js");
|
|
14
|
-
|
|
15
9
|
var _menuItem = require("../../menu-item/menu-item.js");
|
|
16
|
-
|
|
17
10
|
var _menuSectionHeader = require("../../menu-section-header/menu-section-header.js");
|
|
18
|
-
|
|
19
11
|
var _menu = require("../menu.js");
|
|
20
|
-
|
|
21
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
22
|
-
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
13
|
describe('Menu Component', () => {
|
|
24
14
|
const menuDataTest = 'data-test-menu';
|
|
25
15
|
const menuItemDataTest = 'data-test-menu-item';
|
|
@@ -85,11 +75,9 @@ describe('Menu Component', () => {
|
|
|
85
75
|
const menuItem1 = getByText(/Menu item 1/i);
|
|
86
76
|
const menuItem2 = getByText(/Menu item 2/i);
|
|
87
77
|
expect(menu).not.toHaveFocus();
|
|
88
|
-
|
|
89
|
-
|
|
78
|
+
_userEvent.default.tab();
|
|
79
|
+
// check if LI parent node has focus or not
|
|
90
80
|
// headers and dividers do not receive focus
|
|
91
|
-
|
|
92
|
-
|
|
93
81
|
expect(header.parentNode.parentNode).not.toHaveFocus();
|
|
94
82
|
expect(divider.parentNode.parentNode).not.toHaveFocus();
|
|
95
83
|
expect(menuItem2.parentNode.parentNode).not.toHaveFocus();
|
|
@@ -114,18 +102,13 @@ describe('Menu Component', () => {
|
|
|
114
102
|
})));
|
|
115
103
|
const menuItem1 = getByText(/Menu item 1/i);
|
|
116
104
|
const menuItem2 = getByText(/Menu item 2/i);
|
|
117
|
-
|
|
118
105
|
_userEvent.default.tab();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
106
|
+
expect(menuItem1.parentNode.parentNode).toHaveFocus();
|
|
107
|
+
// simulate arrowDown press
|
|
122
108
|
_userEvent.default.keyboard('{ArrowDown}');
|
|
123
|
-
|
|
124
109
|
expect(menuItem1.parentNode.parentNode).not.toHaveFocus();
|
|
125
110
|
expect(menuItem2.parentNode.parentNode).toHaveFocus();
|
|
126
|
-
|
|
127
111
|
_userEvent.default.keyboard('{ArrowDown}');
|
|
128
|
-
|
|
129
112
|
expect(menuItem1.parentNode.parentNode).toHaveFocus();
|
|
130
113
|
expect(menuItem2.parentNode.parentNode).not.toHaveFocus();
|
|
131
114
|
});
|
|
@@ -148,18 +131,14 @@ describe('Menu Component', () => {
|
|
|
148
131
|
})));
|
|
149
132
|
const menuItem1 = getByText(/Menu item 1/i);
|
|
150
133
|
const menuItem2 = getByText(/Menu item 2/i);
|
|
151
|
-
|
|
152
134
|
_userEvent.default.tab();
|
|
135
|
+
expect(menuItem1.parentNode.parentNode).toHaveFocus();
|
|
153
136
|
|
|
154
|
-
|
|
155
|
-
|
|
137
|
+
// simulate arrowUp press
|
|
156
138
|
_userEvent.default.keyboard('{ArrowUp}');
|
|
157
|
-
|
|
158
139
|
expect(menuItem1.parentNode.parentNode).not.toHaveFocus();
|
|
159
140
|
expect(menuItem2.parentNode.parentNode).toHaveFocus();
|
|
160
|
-
|
|
161
141
|
_userEvent.default.keyboard('{ArrowUp}');
|
|
162
|
-
|
|
163
142
|
expect(menuItem1.parentNode.parentNode).toHaveFocus();
|
|
164
143
|
expect(menuItem2.parentNode.parentNode).not.toHaveFocus();
|
|
165
144
|
});
|
|
@@ -176,17 +155,11 @@ describe('Menu Component', () => {
|
|
|
176
155
|
label: "Click menu item"
|
|
177
156
|
})));
|
|
178
157
|
const clickableItem = getByText(/Click menu item/i);
|
|
179
|
-
|
|
180
158
|
_userEvent.default.tab();
|
|
181
|
-
|
|
182
159
|
expect(clickableItem.parentNode.parentNode).toHaveFocus();
|
|
183
|
-
|
|
184
160
|
_userEvent.default.keyboard('[Space]');
|
|
185
|
-
|
|
186
161
|
expect(onClick).toHaveBeenCalledTimes(1);
|
|
187
|
-
|
|
188
162
|
_userEvent.default.keyboard('{Enter}');
|
|
189
|
-
|
|
190
163
|
expect(onClick).toHaveBeenCalledTimes(2);
|
|
191
164
|
});
|
|
192
165
|
it('can handle non MenuItem components', () => {
|
|
@@ -209,28 +182,21 @@ describe('Menu Component', () => {
|
|
|
209
182
|
}, "Span 2"))));
|
|
210
183
|
const nonListMenuItem = getByText(/span 1/i);
|
|
211
184
|
const listMenuItem = getByText(/link 2/i);
|
|
212
|
-
const plainListItem = getByText(/span 2/i);
|
|
185
|
+
const plainListItem = getByText(/span 2/i);
|
|
213
186
|
|
|
187
|
+
// all children must be list items
|
|
214
188
|
expect(nonListMenuItem.parentElement.nodeName).toBe('LI');
|
|
215
|
-
|
|
216
189
|
_userEvent.default.tab();
|
|
217
|
-
|
|
218
190
|
expect(nonListMenuItem.parentElement).toHaveFocus();
|
|
219
191
|
expect(nonListMenuItem.parentElement.tabIndex).toBe(0);
|
|
220
192
|
expect(onClick).toHaveBeenCalledTimes(0);
|
|
221
|
-
|
|
222
193
|
_userEvent.default.keyboard('[Space]');
|
|
223
|
-
|
|
224
194
|
expect(onClick).toHaveBeenCalledTimes(1);
|
|
225
|
-
|
|
226
195
|
_userEvent.default.keyboard('{ArrowDown}');
|
|
227
|
-
|
|
228
196
|
expect(listMenuItem.parentElement).toHaveFocus();
|
|
229
|
-
|
|
230
197
|
_userEvent.default.keyboard('{ArrowDown}');
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
198
|
+
expect(nonListMenuItem.parentElement).toHaveFocus();
|
|
199
|
+
// non menu items do not receive focus
|
|
234
200
|
expect(plainListItem.parentElement).not.toHaveFocus();
|
|
235
201
|
});
|
|
236
202
|
it('does not hijack input change value if space entered [bug]', () => {
|
|
@@ -249,15 +215,10 @@ describe('Menu Component', () => {
|
|
|
249
215
|
})));
|
|
250
216
|
const inputField = getByPlaceholderText('test');
|
|
251
217
|
inputField.focus();
|
|
252
|
-
|
|
253
218
|
_userEvent.default.keyboard('t');
|
|
254
|
-
|
|
255
219
|
_userEvent.default.keyboard('e');
|
|
256
|
-
|
|
257
220
|
_userEvent.default.keyboard(' ');
|
|
258
|
-
|
|
259
221
|
_userEvent.default.keyboard('st');
|
|
260
|
-
|
|
261
222
|
expect(inputField.value).toBe('te st');
|
|
262
223
|
expect(onChange).toHaveBeenCalled();
|
|
263
224
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _cypressCucumberPreprocessor = require("@badeball/cypress-cucumber-preprocessor");
|
|
4
|
-
|
|
5
4
|
(0, _cypressCucumberPreprocessor.Given)('a Menu with children is rendered', () => {
|
|
6
5
|
cy.visitStory('Menu', 'With children');
|
|
7
6
|
cy.get('[data-test="dhis2-uicore-menulist"]').should('be.visible');
|