@nauedu/frontend-component-header 14.0.0-semantically-released

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 (59) hide show
  1. package/LICENSE +661 -0
  2. package/README.rst +113 -0
  3. package/dist/Avatar.js +45 -0
  4. package/dist/Avatar.js.map +1 -0
  5. package/dist/DesktopHeader.js +218 -0
  6. package/dist/DesktopHeader.js.map +1 -0
  7. package/dist/Header.js +86 -0
  8. package/dist/Header.js.map +1 -0
  9. package/dist/Header.messages.js +100 -0
  10. package/dist/Header.messages.js.map +1 -0
  11. package/dist/Header.test.jsx +127 -0
  12. package/dist/Icons.js +53 -0
  13. package/dist/Icons.js.map +1 -0
  14. package/dist/Logo.js +51 -0
  15. package/dist/Logo.js.map +1 -0
  16. package/dist/Menu/Menu.js +367 -0
  17. package/dist/Menu/Menu.js.map +1 -0
  18. package/dist/Menu/index.js +3 -0
  19. package/dist/Menu/index.js.map +1 -0
  20. package/dist/Menu/menu.scss +45 -0
  21. package/dist/MobileHeader.js +240 -0
  22. package/dist/MobileHeader.js.map +1 -0
  23. package/dist/__snapshots__/Header.test.jsx.snap +443 -0
  24. package/dist/generic/messages.js +15 -0
  25. package/dist/generic/messages.js.map +1 -0
  26. package/dist/i18n/index.js +31 -0
  27. package/dist/i18n/index.js.map +1 -0
  28. package/dist/i18n/messages/ar.json +30 -0
  29. package/dist/i18n/messages/ca.json +1 -0
  30. package/dist/i18n/messages/es_419.json +30 -0
  31. package/dist/i18n/messages/fr.json +30 -0
  32. package/dist/i18n/messages/fr_CA.json +30 -0
  33. package/dist/i18n/messages/he.json +1 -0
  34. package/dist/i18n/messages/id.json +1 -0
  35. package/dist/i18n/messages/ko_KR.json +2 -0
  36. package/dist/i18n/messages/pl.json +1 -0
  37. package/dist/i18n/messages/pt_BR.json +2 -0
  38. package/dist/i18n/messages/ru.json +1 -0
  39. package/dist/i18n/messages/th.json +1 -0
  40. package/dist/i18n/messages/uk.json +1 -0
  41. package/dist/i18n/messages/zh_CN.json +30 -0
  42. package/dist/index.js +6 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/index.scss +120 -0
  45. package/dist/learning-header/AnonymousUserMenu.js +24 -0
  46. package/dist/learning-header/AnonymousUserMenu.js.map +1 -0
  47. package/dist/learning-header/AuthenticatedUserDropdown.js +48 -0
  48. package/dist/learning-header/AuthenticatedUserDropdown.js.map +1 -0
  49. package/dist/learning-header/LearningHeader.js +121 -0
  50. package/dist/learning-header/LearningHeader.js.map +1 -0
  51. package/dist/learning-header/_header.scss +7 -0
  52. package/dist/learning-header/data/api.js +57 -0
  53. package/dist/learning-header/data/api.js.map +1 -0
  54. package/dist/learning-header/data/api.test.js +216 -0
  55. package/dist/learning-header/data/api.test.js.map +1 -0
  56. package/dist/learning-header/messages.js +40 -0
  57. package/dist/learning-header/messages.js.map +1 -0
  58. package/dist/setupTest.js +129 -0
  59. package/package.json +76 -0
@@ -0,0 +1,127 @@
1
+ import React from 'react';
2
+ import { IntlProvider } from '@edx/frontend-platform/i18n';
3
+ import TestRenderer from 'react-test-renderer';
4
+ import { AppContext } from '@edx/frontend-platform/react';
5
+ import { Context as ResponsiveContext } from 'react-responsive';
6
+
7
+ import Header from './index';
8
+
9
+ describe('<Header />', () => {
10
+ it('renders correctly for anonymous desktop', () => {
11
+ const component = (
12
+ <ResponsiveContext.Provider value={{ width: 1280 }}>
13
+ <IntlProvider locale="en" messages={{}}>
14
+ <AppContext.Provider
15
+ value={{
16
+ authenticatedUser: null,
17
+ config: {
18
+ LMS_BASE_URL: process.env.LMS_BASE_URL,
19
+ SITE_NAME: process.env.SITE_NAME,
20
+ LOGIN_URL: process.env.LOGIN_URL,
21
+ LOGOUT_URL: process.env.LOGOUT_URL,
22
+ LOGO_URL: process.env.LOGO_URL,
23
+ },
24
+ }}
25
+ >
26
+ <Header />
27
+ </AppContext.Provider>
28
+ </IntlProvider>
29
+ </ResponsiveContext.Provider>
30
+ );
31
+
32
+ const wrapper = TestRenderer.create(component);
33
+
34
+ expect(wrapper.toJSON()).toMatchSnapshot();
35
+ });
36
+
37
+ it('renders correctly for authenticated desktop', () => {
38
+ const component = (
39
+ <ResponsiveContext.Provider value={{ width: 1280 }}>
40
+ <IntlProvider locale="en" messages={{}}>
41
+ <AppContext.Provider
42
+ value={{
43
+ authenticatedUser: {
44
+ userId: 'abc123',
45
+ username: 'edX',
46
+ roles: [],
47
+ administrator: false,
48
+ },
49
+ config: {
50
+ LMS_BASE_URL: process.env.LMS_BASE_URL,
51
+ SITE_NAME: process.env.SITE_NAME,
52
+ LOGIN_URL: process.env.LOGIN_URL,
53
+ LOGOUT_URL: process.env.LOGOUT_URL,
54
+ LOGO_URL: process.env.LOGO_URL,
55
+ },
56
+ }}
57
+ >
58
+ <Header />
59
+ </AppContext.Provider>
60
+ </IntlProvider>
61
+ </ResponsiveContext.Provider>
62
+ );
63
+
64
+ const wrapper = TestRenderer.create(component);
65
+
66
+ expect(wrapper.toJSON()).toMatchSnapshot();
67
+ });
68
+
69
+ it('renders correctly for anonymous mobile', () => {
70
+ const component = (
71
+ <ResponsiveContext.Provider value={{ width: 500 }}>
72
+ <IntlProvider locale="en" messages={{}}>
73
+ <AppContext.Provider
74
+ value={{
75
+ authenticatedUser: null,
76
+ config: {
77
+ LMS_BASE_URL: process.env.LMS_BASE_URL,
78
+ SITE_NAME: process.env.SITE_NAME,
79
+ LOGIN_URL: process.env.LOGIN_URL,
80
+ LOGOUT_URL: process.env.LOGOUT_URL,
81
+ LOGO_URL: process.env.LOGO_URL,
82
+ },
83
+ }}
84
+ >
85
+ <Header />
86
+ </AppContext.Provider>
87
+ </IntlProvider>
88
+ </ResponsiveContext.Provider>
89
+ );
90
+
91
+ const wrapper = TestRenderer.create(component);
92
+
93
+ expect(wrapper.toJSON()).toMatchSnapshot();
94
+ });
95
+
96
+ it('renders correctly for authenticated mobile', () => {
97
+ const component = (
98
+ <ResponsiveContext.Provider value={{ width: 500 }}>
99
+ <IntlProvider locale="en" messages={{}}>
100
+ <AppContext.Provider
101
+ value={{
102
+ authenticatedUser: {
103
+ userId: 'abc123',
104
+ username: 'edX',
105
+ roles: [],
106
+ administrator: false,
107
+ },
108
+ config: {
109
+ LMS_BASE_URL: process.env.LMS_BASE_URL,
110
+ SITE_NAME: process.env.SITE_NAME,
111
+ LOGIN_URL: process.env.LOGIN_URL,
112
+ LOGOUT_URL: process.env.LOGOUT_URL,
113
+ LOGO_URL: process.env.LOGO_URL,
114
+ },
115
+ }}
116
+ >
117
+ <Header />
118
+ </AppContext.Provider>
119
+ </IntlProvider>
120
+ </ResponsiveContext.Provider>
121
+ );
122
+
123
+ const wrapper = TestRenderer.create(component);
124
+
125
+ expect(wrapper.toJSON()).toMatchSnapshot();
126
+ });
127
+ });
package/dist/Icons.js ADDED
@@ -0,0 +1,53 @@
1
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
+
3
+ import React from 'react';
4
+ export var MenuIcon = function MenuIcon(props) {
5
+ return /*#__PURE__*/React.createElement("svg", _extends({
6
+ width: "24px",
7
+ height: "24px",
8
+ viewBox: "0 0 24 24",
9
+ version: "1.1"
10
+ }, props), /*#__PURE__*/React.createElement("rect", {
11
+ fill: "currentColor",
12
+ x: "2",
13
+ y: "5",
14
+ width: "20",
15
+ height: "2"
16
+ }), /*#__PURE__*/React.createElement("rect", {
17
+ fill: "currentColor",
18
+ x: "2",
19
+ y: "11",
20
+ width: "20",
21
+ height: "2"
22
+ }), /*#__PURE__*/React.createElement("rect", {
23
+ fill: "currentColor",
24
+ x: "2",
25
+ y: "17",
26
+ width: "20",
27
+ height: "2"
28
+ }));
29
+ };
30
+ export var AvatarIcon = function AvatarIcon(props) {
31
+ return /*#__PURE__*/React.createElement("svg", _extends({
32
+ width: "24px",
33
+ height: "24px",
34
+ viewBox: "0 0 24 24",
35
+ version: "1.1"
36
+ }, props), /*#__PURE__*/React.createElement("path", {
37
+ d: "M4.10255106,18.1351061 C4.7170266,16.0581859 8.01891846,14.4720277 12,14.4720277 C15.9810815,14.4720277 19.2829734,16.0581859 19.8974489,18.1351061 C21.215206,16.4412566 22,14.3122775 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,14.3122775 2.78479405,16.4412566 4.10255106,18.1351061 Z M12,24 C5.372583,24 0,18.627417 0,12 C0,5.372583 5.372583,0 12,0 C18.627417,0 24,5.372583 24,12 C24,18.627417 18.627417,24 12,24 Z M12,13 C9.790861,13 8,11.209139 8,9 C8,6.790861 9.790861,5 12,5 C14.209139,5 16,6.790861 16,9 C16,11.209139 14.209139,13 12,13 Z",
38
+ fill: "currentColor"
39
+ }));
40
+ };
41
+ export var CaretIcon = function CaretIcon(props) {
42
+ return /*#__PURE__*/React.createElement("svg", _extends({
43
+ width: "16px",
44
+ height: "16px",
45
+ viewBox: "0 0 16 16",
46
+ version: "1.1"
47
+ }, props), /*#__PURE__*/React.createElement("path", {
48
+ d: "M7,4 L7,8 L11,8 L11,10 L5,10 L5,4 L7,4 Z",
49
+ fill: "currentColor",
50
+ transform: "translate(8.000000, 7.000000) rotate(-45.000000) translate(-8.000000, -7.000000) "
51
+ }));
52
+ };
53
+ //# sourceMappingURL=Icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Icons.jsx"],"names":["React","MenuIcon","props","AvatarIcon","CaretIcon"],"mappings":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AAEA,OAAO,IAAMC,QAAQ,GAAG,SAAXA,QAAW,CAAAC,KAAK;AAAA,sBAC3B;AACE,IAAA,KAAK,EAAC,MADR;AAEE,IAAA,MAAM,EAAC,MAFT;AAGE,IAAA,OAAO,EAAC,WAHV;AAIE,IAAA,OAAO,EAAC;AAJV,KAKMA,KALN,gBAOE;AAAM,IAAA,IAAI,EAAC,cAAX;AAA0B,IAAA,CAAC,EAAC,GAA5B;AAAgC,IAAA,CAAC,EAAC,GAAlC;AAAsC,IAAA,KAAK,EAAC,IAA5C;AAAiD,IAAA,MAAM,EAAC;AAAxD,IAPF,eAQE;AAAM,IAAA,IAAI,EAAC,cAAX;AAA0B,IAAA,CAAC,EAAC,GAA5B;AAAgC,IAAA,CAAC,EAAC,IAAlC;AAAuC,IAAA,KAAK,EAAC,IAA7C;AAAkD,IAAA,MAAM,EAAC;AAAzD,IARF,eASE;AAAM,IAAA,IAAI,EAAC,cAAX;AAA0B,IAAA,CAAC,EAAC,GAA5B;AAAgC,IAAA,CAAC,EAAC,IAAlC;AAAuC,IAAA,KAAK,EAAC,IAA7C;AAAkD,IAAA,MAAM,EAAC;AAAzD,IATF,CAD2B;AAAA,CAAtB;AAcP,OAAO,IAAMC,UAAU,GAAG,SAAbA,UAAa,CAAAD,KAAK;AAAA,sBAC7B;AACE,IAAA,KAAK,EAAC,MADR;AAEE,IAAA,MAAM,EAAC,MAFT;AAGE,IAAA,OAAO,EAAC,WAHV;AAIE,IAAA,OAAO,EAAC;AAJV,KAKMA,KALN,gBAOE;AACE,IAAA,CAAC,EAAC,6jBADJ;AAEE,IAAA,IAAI,EAAC;AAFP,IAPF,CAD6B;AAAA,CAAxB;AAeP,OAAO,IAAME,SAAS,GAAG,SAAZA,SAAY,CAAAF,KAAK;AAAA,sBAC5B;AACE,IAAA,KAAK,EAAC,MADR;AAEE,IAAA,MAAM,EAAC,MAFT;AAGE,IAAA,OAAO,EAAC,WAHV;AAIE,IAAA,OAAO,EAAC;AAJV,KAKMA,KALN,gBAOE;AACE,IAAA,CAAC,EAAC,0CADJ;AAEE,IAAA,IAAI,EAAC,cAFP;AAGE,IAAA,SAAS,EAAC;AAHZ,IAPF,CAD4B;AAAA,CAAvB","sourcesContent":["import React from 'react';\n\nexport const MenuIcon = props => (\n <svg\n width=\"24px\"\n height=\"24px\"\n viewBox=\"0 0 24 24\"\n version=\"1.1\"\n {...props}\n >\n <rect fill=\"currentColor\" x=\"2\" y=\"5\" width=\"20\" height=\"2\" />\n <rect fill=\"currentColor\" x=\"2\" y=\"11\" width=\"20\" height=\"2\" />\n <rect fill=\"currentColor\" x=\"2\" y=\"17\" width=\"20\" height=\"2\" />\n </svg>\n);\n\nexport const AvatarIcon = props => (\n <svg\n width=\"24px\"\n height=\"24px\"\n viewBox=\"0 0 24 24\"\n version=\"1.1\"\n {...props}\n >\n <path\n d=\"M4.10255106,18.1351061 C4.7170266,16.0581859 8.01891846,14.4720277 12,14.4720277 C15.9810815,14.4720277 19.2829734,16.0581859 19.8974489,18.1351061 C21.215206,16.4412566 22,14.3122775 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,14.3122775 2.78479405,16.4412566 4.10255106,18.1351061 Z M12,24 C5.372583,24 0,18.627417 0,12 C0,5.372583 5.372583,0 12,0 C18.627417,0 24,5.372583 24,12 C24,18.627417 18.627417,24 12,24 Z M12,13 C9.790861,13 8,11.209139 8,9 C8,6.790861 9.790861,5 12,5 C14.209139,5 16,6.790861 16,9 C16,11.209139 14.209139,13 12,13 Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport const CaretIcon = props => (\n <svg\n width=\"16px\"\n height=\"16px\"\n viewBox=\"0 0 16 16\"\n version=\"1.1\"\n {...props}\n >\n <path\n d=\"M7,4 L7,8 L11,8 L11,10 L5,10 L5,4 L7,4 Z\"\n fill=\"currentColor\"\n transform=\"translate(8.000000, 7.000000) rotate(-45.000000) translate(-8.000000, -7.000000) \"\n />\n </svg>\n);\n"],"file":"Icons.js"}
package/dist/Logo.js ADDED
@@ -0,0 +1,51 @@
1
+ var _excluded = ["src", "alt"],
2
+ _excluded2 = ["href", "src", "alt"];
3
+
4
+ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
5
+
6
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
7
+
8
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
9
+
10
+ import React from 'react';
11
+ import PropTypes from 'prop-types';
12
+
13
+ function Logo(_ref) {
14
+ var src = _ref.src,
15
+ alt = _ref.alt,
16
+ attributes = _objectWithoutProperties(_ref, _excluded);
17
+
18
+ return /*#__PURE__*/React.createElement("img", _extends({
19
+ src: src,
20
+ alt: alt
21
+ }, attributes));
22
+ }
23
+
24
+ Logo.propTypes = {
25
+ src: PropTypes.string.isRequired,
26
+ alt: PropTypes.string.isRequired
27
+ };
28
+
29
+ function LinkedLogo(_ref2) {
30
+ var href = _ref2.href,
31
+ src = _ref2.src,
32
+ alt = _ref2.alt,
33
+ attributes = _objectWithoutProperties(_ref2, _excluded2);
34
+
35
+ return /*#__PURE__*/React.createElement("a", _extends({
36
+ href: href
37
+ }, attributes), /*#__PURE__*/React.createElement("img", {
38
+ className: "d-block",
39
+ src: src,
40
+ alt: alt
41
+ }));
42
+ }
43
+
44
+ LinkedLogo.propTypes = {
45
+ href: PropTypes.string.isRequired,
46
+ src: PropTypes.string.isRequired,
47
+ alt: PropTypes.string.isRequired
48
+ };
49
+ export { LinkedLogo, Logo };
50
+ export default Logo;
51
+ //# sourceMappingURL=Logo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Logo.jsx"],"names":["React","PropTypes","Logo","src","alt","attributes","propTypes","string","isRequired","LinkedLogo","href"],"mappings":";;;;;;;;;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,OAAOC,SAAP,MAAsB,YAAtB;;AAEA,SAASC,IAAT,OAA2C;AAAA,MAA3BC,GAA2B,QAA3BA,GAA2B;AAAA,MAAtBC,GAAsB,QAAtBA,GAAsB;AAAA,MAAdC,UAAc;;AACzC,sBACE;AAAK,IAAA,GAAG,EAAEF,GAAV;AAAe,IAAA,GAAG,EAAEC;AAApB,KAA6BC,UAA7B,EADF;AAGD;;AAEDH,IAAI,CAACI,SAAL,GAAiB;AACfH,EAAAA,GAAG,EAAEF,SAAS,CAACM,MAAV,CAAiBC,UADP;AAEfJ,EAAAA,GAAG,EAAEH,SAAS,CAACM,MAAV,CAAiBC;AAFP,CAAjB;;AAKA,SAASC,UAAT,QAKG;AAAA,MAJDC,IAIC,SAJDA,IAIC;AAAA,MAHDP,GAGC,SAHDA,GAGC;AAAA,MAFDC,GAEC,SAFDA,GAEC;AAAA,MADEC,UACF;;AACD,sBACE;AAAG,IAAA,IAAI,EAAEK;AAAT,KAAmBL,UAAnB,gBACE;AAAK,IAAA,SAAS,EAAC,SAAf;AAAyB,IAAA,GAAG,EAAEF,GAA9B;AAAmC,IAAA,GAAG,EAAEC;AAAxC,IADF,CADF;AAKD;;AAEDK,UAAU,CAACH,SAAX,GAAuB;AACrBI,EAAAA,IAAI,EAAET,SAAS,CAACM,MAAV,CAAiBC,UADF;AAErBL,EAAAA,GAAG,EAAEF,SAAS,CAACM,MAAV,CAAiBC,UAFD;AAGrBJ,EAAAA,GAAG,EAAEH,SAAS,CAACM,MAAV,CAAiBC;AAHD,CAAvB;AAMA,SAASC,UAAT,EAAqBP,IAArB;AACA,eAAeA,IAAf","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\n\nfunction Logo({ src, alt, ...attributes }) {\n return (\n <img src={src} alt={alt} {...attributes} />\n );\n}\n\nLogo.propTypes = {\n src: PropTypes.string.isRequired,\n alt: PropTypes.string.isRequired,\n};\n\nfunction LinkedLogo({\n href,\n src,\n alt,\n ...attributes\n}) {\n return (\n <a href={href} {...attributes}>\n <img className=\"d-block\" src={src} alt={alt} />\n </a>\n );\n}\n\nLinkedLogo.propTypes = {\n href: PropTypes.string.isRequired,\n src: PropTypes.string.isRequired,\n alt: PropTypes.string.isRequired,\n};\n\nexport { LinkedLogo, Logo };\nexport default Logo;\n"],"file":"Logo.js"}
@@ -0,0 +1,367 @@
1
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
2
+
3
+ var _excluded = ["tag", "className"],
4
+ _excluded2 = ["tag", "className"];
5
+
6
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
7
+
8
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
9
+
10
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
11
+
12
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
13
+
14
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
15
+
16
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
17
+
18
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
19
+
20
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
21
+
22
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
23
+
24
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
25
+
26
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
27
+
28
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
29
+
30
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
31
+
32
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
33
+
34
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
35
+
36
+ import React from 'react';
37
+ import { CSSTransition } from 'react-transition-group';
38
+ import PropTypes from 'prop-types';
39
+
40
+ function MenuTrigger(_ref) {
41
+ var tag = _ref.tag,
42
+ className = _ref.className,
43
+ attributes = _objectWithoutProperties(_ref, _excluded);
44
+
45
+ return /*#__PURE__*/React.createElement(tag, _objectSpread({
46
+ className: "menu-trigger ".concat(className)
47
+ }, attributes));
48
+ }
49
+
50
+ MenuTrigger.propTypes = {
51
+ tag: PropTypes.string,
52
+ className: PropTypes.string
53
+ };
54
+ MenuTrigger.defaultProps = {
55
+ tag: 'div',
56
+ className: null
57
+ };
58
+ var MenuTriggerType = /*#__PURE__*/React.createElement(MenuTrigger, null).type;
59
+
60
+ function MenuContent(_ref2) {
61
+ var tag = _ref2.tag,
62
+ className = _ref2.className,
63
+ attributes = _objectWithoutProperties(_ref2, _excluded2);
64
+
65
+ return /*#__PURE__*/React.createElement(tag, _objectSpread({
66
+ className: ['menu-content', className].join(' ')
67
+ }, attributes));
68
+ }
69
+
70
+ MenuContent.propTypes = {
71
+ tag: PropTypes.string,
72
+ className: PropTypes.string
73
+ };
74
+ MenuContent.defaultProps = {
75
+ tag: 'div',
76
+ className: null
77
+ };
78
+ var menuPropTypes = {
79
+ tag: PropTypes.string,
80
+ onClose: PropTypes.func,
81
+ onOpen: PropTypes.func,
82
+ closeOnDocumentClick: PropTypes.bool,
83
+ respondToPointerEvents: PropTypes.bool,
84
+ className: PropTypes.string,
85
+ transitionTimeout: PropTypes.number,
86
+ transitionClassName: PropTypes.string,
87
+ children: PropTypes.arrayOf(PropTypes.node).isRequired
88
+ };
89
+
90
+ var Menu = /*#__PURE__*/function (_React$Component) {
91
+ _inherits(Menu, _React$Component);
92
+
93
+ var _super = _createSuper(Menu);
94
+
95
+ function Menu(props) {
96
+ var _this;
97
+
98
+ _classCallCheck(this, Menu);
99
+
100
+ _this = _super.call(this, props);
101
+ _this.menu = /*#__PURE__*/React.createRef();
102
+ _this.state = {
103
+ expanded: false
104
+ };
105
+ _this.onTriggerClick = _this.onTriggerClick.bind(_assertThisInitialized(_this));
106
+ _this.onCloseClick = _this.onCloseClick.bind(_assertThisInitialized(_this));
107
+ _this.onKeyDown = _this.onKeyDown.bind(_assertThisInitialized(_this));
108
+ _this.onDocumentClick = _this.onDocumentClick.bind(_assertThisInitialized(_this));
109
+ _this.onMouseEnter = _this.onMouseEnter.bind(_assertThisInitialized(_this));
110
+ _this.onMouseLeave = _this.onMouseLeave.bind(_assertThisInitialized(_this));
111
+ return _this;
112
+ } // Lifecycle Events
113
+
114
+
115
+ _createClass(Menu, [{
116
+ key: "componentWillUnmount",
117
+ value: function componentWillUnmount() {
118
+ document.removeEventListener('touchend', this.onDocumentClick, true);
119
+ document.removeEventListener('click', this.onDocumentClick, true); // Call onClose callback when unmounting and open
120
+
121
+ if (this.state.expanded && this.props.onClose) {
122
+ this.props.onClose();
123
+ }
124
+ } // Event handlers
125
+
126
+ }, {
127
+ key: "onDocumentClick",
128
+ value: function onDocumentClick(e) {
129
+ if (!this.props.closeOnDocumentClick) {
130
+ return;
131
+ }
132
+
133
+ var clickIsInMenu = this.menu.current === e.target || this.menu.current.contains(e.target);
134
+
135
+ if (clickIsInMenu) {
136
+ return;
137
+ }
138
+
139
+ this.close();
140
+ }
141
+ }, {
142
+ key: "onTriggerClick",
143
+ value: function onTriggerClick(e) {
144
+ // Let the browser follow the link of the trigger if the menu
145
+ // is already expanded and the trigger has an href attribute
146
+ if (this.state.expanded && e.target.getAttribute('href')) {
147
+ return;
148
+ }
149
+
150
+ e.preventDefault();
151
+ this.toggle();
152
+ }
153
+ }, {
154
+ key: "onCloseClick",
155
+ value: function onCloseClick() {
156
+ this.getFocusableElements()[0].focus();
157
+ this.close();
158
+ }
159
+ }, {
160
+ key: "onKeyDown",
161
+ value: function onKeyDown(e) {
162
+ if (!this.state.expanded) {
163
+ return;
164
+ }
165
+
166
+ switch (e.key) {
167
+ case 'Escape':
168
+ {
169
+ e.preventDefault();
170
+ e.stopPropagation();
171
+ this.getFocusableElements()[0].focus();
172
+ this.close();
173
+ break;
174
+ }
175
+
176
+ case 'Enter':
177
+ {
178
+ // Using focusable elements instead of a ref to the trigger
179
+ // because Hyperlink and Button can handle refs as functional components
180
+ if (document.activeElement === this.getFocusableElements()[0]) {
181
+ e.preventDefault();
182
+ this.toggle();
183
+ }
184
+
185
+ break;
186
+ }
187
+
188
+ case 'Tab':
189
+ {
190
+ e.preventDefault();
191
+
192
+ if (e.shiftKey) {
193
+ this.focusPrevious();
194
+ } else {
195
+ this.focusNext();
196
+ }
197
+
198
+ break;
199
+ }
200
+
201
+ case 'ArrowDown':
202
+ {
203
+ e.preventDefault();
204
+ this.focusNext();
205
+ break;
206
+ }
207
+
208
+ case 'ArrowUp':
209
+ {
210
+ e.preventDefault();
211
+ this.focusPrevious();
212
+ break;
213
+ }
214
+
215
+ default:
216
+ }
217
+ }
218
+ }, {
219
+ key: "onMouseEnter",
220
+ value: function onMouseEnter() {
221
+ if (!this.props.respondToPointerEvents) {
222
+ return;
223
+ }
224
+
225
+ this.open();
226
+ }
227
+ }, {
228
+ key: "onMouseLeave",
229
+ value: function onMouseLeave() {
230
+ if (!this.props.respondToPointerEvents) {
231
+ return;
232
+ }
233
+
234
+ this.close();
235
+ } // Internal functions
236
+
237
+ }, {
238
+ key: "getFocusableElements",
239
+ value: function getFocusableElements() {
240
+ return this.menu.current.querySelectorAll('button:not([disabled]), [href]:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])');
241
+ }
242
+ }, {
243
+ key: "getAttributesFromProps",
244
+ value: function getAttributesFromProps() {
245
+ var _this2 = this;
246
+
247
+ // Any extra props are attributes for the menu
248
+ var attributes = {};
249
+ Object.keys(this.props).filter(function (property) {
250
+ return menuPropTypes[property] === undefined;
251
+ }).forEach(function (property) {
252
+ attributes[property] = _this2.props[property];
253
+ });
254
+ return attributes;
255
+ }
256
+ }, {
257
+ key: "focusNext",
258
+ value: function focusNext() {
259
+ var focusableElements = Array.from(this.getFocusableElements());
260
+ var activeIndex = focusableElements.indexOf(document.activeElement);
261
+ var nextIndex = (activeIndex + 1) % focusableElements.length;
262
+ focusableElements[nextIndex].focus();
263
+ }
264
+ }, {
265
+ key: "focusPrevious",
266
+ value: function focusPrevious() {
267
+ var focusableElements = Array.from(this.getFocusableElements());
268
+ var activeIndex = focusableElements.indexOf(document.activeElement);
269
+ var previousIndex = (activeIndex || focusableElements.length) - 1;
270
+ focusableElements[previousIndex].focus();
271
+ }
272
+ }, {
273
+ key: "open",
274
+ value: function open() {
275
+ if (this.props.onOpen) {
276
+ this.props.onOpen();
277
+ }
278
+
279
+ this.setState({
280
+ expanded: true
281
+ }); // Listen to touchend and click events to ensure the menu
282
+ // can be closed on mobile, pointer, and mixed input devices
283
+
284
+ document.addEventListener('touchend', this.onDocumentClick, true);
285
+ document.addEventListener('click', this.onDocumentClick, true);
286
+ }
287
+ }, {
288
+ key: "close",
289
+ value: function close() {
290
+ if (this.props.onClose) {
291
+ this.props.onClose();
292
+ }
293
+
294
+ this.setState({
295
+ expanded: false
296
+ });
297
+ document.removeEventListener('touchend', this.onDocumentClick, true);
298
+ document.removeEventListener('click', this.onDocumentClick, true);
299
+ }
300
+ }, {
301
+ key: "toggle",
302
+ value: function toggle() {
303
+ if (this.state.expanded) {
304
+ this.close();
305
+ } else {
306
+ this.open();
307
+ }
308
+ }
309
+ }, {
310
+ key: "renderTrigger",
311
+ value: function renderTrigger(node) {
312
+ return /*#__PURE__*/React.cloneElement(node, {
313
+ onClick: this.onTriggerClick,
314
+ 'aria-haspopup': 'menu',
315
+ 'aria-expanded': this.state.expanded
316
+ });
317
+ }
318
+ }, {
319
+ key: "renderMenuContent",
320
+ value: function renderMenuContent(node) {
321
+ return /*#__PURE__*/React.createElement(CSSTransition, {
322
+ "in": this.state.expanded,
323
+ timeout: this.props.transitionTimeout,
324
+ classNames: this.props.transitionClassName,
325
+ unmountOnExit: true
326
+ }, node);
327
+ }
328
+ }, {
329
+ key: "render",
330
+ value: function render() {
331
+ var _this3 = this;
332
+
333
+ var className = this.props.className;
334
+ var wrappedChildren = React.Children.map(this.props.children, function (child) {
335
+ if (child.type === MenuTriggerType) {
336
+ return _this3.renderTrigger(child);
337
+ }
338
+
339
+ return _this3.renderMenuContent(child);
340
+ });
341
+ var rootClassName = this.state.expanded ? 'menu expanded' : 'menu';
342
+ return /*#__PURE__*/React.createElement(this.props.tag, _objectSpread({
343
+ className: "".concat(rootClassName, " ").concat(className),
344
+ ref: this.menu,
345
+ onKeyDown: this.onKeyDown,
346
+ onMouseEnter: this.onMouseEnter,
347
+ onMouseLeave: this.onMouseLeave
348
+ }, this.getAttributesFromProps()), wrappedChildren);
349
+ }
350
+ }]);
351
+
352
+ return Menu;
353
+ }(React.Component);
354
+
355
+ Menu.propTypes = menuPropTypes;
356
+ Menu.defaultProps = {
357
+ tag: 'div',
358
+ className: null,
359
+ onClose: null,
360
+ onOpen: null,
361
+ respondToPointerEvents: false,
362
+ closeOnDocumentClick: true,
363
+ transitionTimeout: 250,
364
+ transitionClassName: 'menu-content'
365
+ };
366
+ export { Menu, MenuTrigger, MenuContent };
367
+ //# sourceMappingURL=Menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Menu/Menu.jsx"],"names":["React","CSSTransition","PropTypes","MenuTrigger","tag","className","attributes","createElement","propTypes","string","defaultProps","MenuTriggerType","type","MenuContent","join","menuPropTypes","onClose","func","onOpen","closeOnDocumentClick","bool","respondToPointerEvents","transitionTimeout","number","transitionClassName","children","arrayOf","node","isRequired","Menu","props","menu","createRef","state","expanded","onTriggerClick","bind","onCloseClick","onKeyDown","onDocumentClick","onMouseEnter","onMouseLeave","document","removeEventListener","e","clickIsInMenu","current","target","contains","close","getAttribute","preventDefault","toggle","getFocusableElements","focus","key","stopPropagation","activeElement","shiftKey","focusPrevious","focusNext","open","querySelectorAll","Object","keys","filter","property","undefined","forEach","focusableElements","Array","from","activeIndex","indexOf","nextIndex","length","previousIndex","setState","addEventListener","cloneElement","onClick","wrappedChildren","Children","map","child","renderTrigger","renderMenuContent","rootClassName","ref","getAttributesFromProps","Component"],"mappings":"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","sourcesContent":["import React from 'react';\nimport { CSSTransition } from 'react-transition-group';\nimport PropTypes from 'prop-types';\n\nfunction MenuTrigger({ tag, className, ...attributes }) {\n return React.createElement(tag, {\n className: `menu-trigger ${className}`,\n ...attributes,\n });\n}\nMenuTrigger.propTypes = {\n tag: PropTypes.string,\n className: PropTypes.string,\n};\nMenuTrigger.defaultProps = {\n tag: 'div',\n className: null,\n};\nconst MenuTriggerType = <MenuTrigger />.type;\n\nfunction MenuContent({ tag, className, ...attributes }) {\n return React.createElement(tag, {\n className: ['menu-content', className].join(' '),\n ...attributes,\n });\n}\nMenuContent.propTypes = {\n tag: PropTypes.string,\n className: PropTypes.string,\n};\nMenuContent.defaultProps = {\n tag: 'div',\n className: null,\n};\n\nconst menuPropTypes = {\n tag: PropTypes.string,\n onClose: PropTypes.func,\n onOpen: PropTypes.func,\n closeOnDocumentClick: PropTypes.bool,\n respondToPointerEvents: PropTypes.bool,\n className: PropTypes.string,\n transitionTimeout: PropTypes.number,\n transitionClassName: PropTypes.string,\n children: PropTypes.arrayOf(PropTypes.node).isRequired,\n};\n\nclass Menu extends React.Component {\n constructor(props) {\n super(props);\n\n this.menu = React.createRef();\n this.state = {\n expanded: false,\n };\n\n this.onTriggerClick = this.onTriggerClick.bind(this);\n this.onCloseClick = this.onCloseClick.bind(this);\n this.onKeyDown = this.onKeyDown.bind(this);\n this.onDocumentClick = this.onDocumentClick.bind(this);\n this.onMouseEnter = this.onMouseEnter.bind(this);\n this.onMouseLeave = this.onMouseLeave.bind(this);\n }\n\n // Lifecycle Events\n componentWillUnmount() {\n document.removeEventListener('touchend', this.onDocumentClick, true);\n document.removeEventListener('click', this.onDocumentClick, true);\n\n // Call onClose callback when unmounting and open\n if (this.state.expanded && this.props.onClose) {\n this.props.onClose();\n }\n }\n\n // Event handlers\n onDocumentClick(e) {\n if (!this.props.closeOnDocumentClick) {\n return;\n }\n\n const clickIsInMenu = this.menu.current === e.target || this.menu.current.contains(e.target);\n if (clickIsInMenu) {\n return;\n }\n\n this.close();\n }\n\n onTriggerClick(e) {\n // Let the browser follow the link of the trigger if the menu\n // is already expanded and the trigger has an href attribute\n if (this.state.expanded && e.target.getAttribute('href')) {\n return;\n }\n\n e.preventDefault();\n this.toggle();\n }\n\n onCloseClick() {\n this.getFocusableElements()[0].focus();\n this.close();\n }\n\n onKeyDown(e) {\n if (!this.state.expanded) {\n return;\n }\n switch (e.key) {\n case 'Escape': {\n e.preventDefault();\n e.stopPropagation();\n this.getFocusableElements()[0].focus();\n this.close();\n break;\n }\n case 'Enter': {\n // Using focusable elements instead of a ref to the trigger\n // because Hyperlink and Button can handle refs as functional components\n if (document.activeElement === this.getFocusableElements()[0]) {\n e.preventDefault();\n this.toggle();\n }\n break;\n }\n case 'Tab': {\n e.preventDefault();\n if (e.shiftKey) {\n this.focusPrevious();\n } else {\n this.focusNext();\n }\n break;\n }\n case 'ArrowDown': {\n e.preventDefault();\n this.focusNext();\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n this.focusPrevious();\n break;\n }\n default:\n }\n }\n\n onMouseEnter() {\n if (!this.props.respondToPointerEvents) {\n return;\n }\n this.open();\n }\n\n onMouseLeave() {\n if (!this.props.respondToPointerEvents) {\n return;\n }\n this.close();\n }\n\n // Internal functions\n\n getFocusableElements() {\n return this.menu.current.querySelectorAll('button:not([disabled]), [href]:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]):not([disabled])');\n }\n\n getAttributesFromProps() {\n // Any extra props are attributes for the menu\n const attributes = {};\n Object.keys(this.props)\n .filter(property => menuPropTypes[property] === undefined)\n .forEach((property) => {\n attributes[property] = this.props[property];\n });\n return attributes;\n }\n\n focusNext() {\n const focusableElements = Array.from(this.getFocusableElements());\n const activeIndex = focusableElements.indexOf(document.activeElement);\n const nextIndex = (activeIndex + 1) % focusableElements.length;\n focusableElements[nextIndex].focus();\n }\n\n focusPrevious() {\n const focusableElements = Array.from(this.getFocusableElements());\n const activeIndex = focusableElements.indexOf(document.activeElement);\n const previousIndex = (activeIndex || focusableElements.length) - 1;\n focusableElements[previousIndex].focus();\n }\n\n open() {\n if (this.props.onOpen) {\n this.props.onOpen();\n }\n this.setState({ expanded: true });\n // Listen to touchend and click events to ensure the menu\n // can be closed on mobile, pointer, and mixed input devices\n document.addEventListener('touchend', this.onDocumentClick, true);\n document.addEventListener('click', this.onDocumentClick, true);\n }\n\n close() {\n if (this.props.onClose) {\n this.props.onClose();\n }\n this.setState({ expanded: false });\n document.removeEventListener('touchend', this.onDocumentClick, true);\n document.removeEventListener('click', this.onDocumentClick, true);\n }\n\n toggle() {\n if (this.state.expanded) {\n this.close();\n } else {\n this.open();\n }\n }\n\n renderTrigger(node) {\n return React.cloneElement(node, {\n onClick: this.onTriggerClick,\n 'aria-haspopup': 'menu',\n 'aria-expanded': this.state.expanded,\n });\n }\n\n renderMenuContent(node) {\n return (\n <CSSTransition\n in={this.state.expanded}\n timeout={this.props.transitionTimeout}\n classNames={this.props.transitionClassName}\n unmountOnExit\n >\n {node}\n </CSSTransition>\n );\n }\n\n render() {\n const { className } = this.props;\n\n const wrappedChildren = React.Children.map(this.props.children, (child) => {\n if (child.type === MenuTriggerType) {\n return this.renderTrigger(child);\n }\n return this.renderMenuContent(child);\n });\n\n const rootClassName = this.state.expanded ? 'menu expanded' : 'menu';\n\n return React.createElement(this.props.tag, {\n className: `${rootClassName} ${className}`,\n ref: this.menu,\n onKeyDown: this.onKeyDown,\n onMouseEnter: this.onMouseEnter,\n onMouseLeave: this.onMouseLeave,\n ...this.getAttributesFromProps(),\n }, wrappedChildren);\n }\n}\n\nMenu.propTypes = menuPropTypes;\nMenu.defaultProps = {\n tag: 'div',\n className: null,\n onClose: null,\n onOpen: null,\n respondToPointerEvents: false,\n closeOnDocumentClick: true,\n transitionTimeout: 250,\n transitionClassName: 'menu-content',\n};\n\nexport { Menu, MenuTrigger, MenuContent };\n"],"file":"Menu.js"}
@@ -0,0 +1,3 @@
1
+ import { Menu, MenuTrigger, MenuContent } from './Menu';
2
+ export { Menu, MenuTrigger, MenuContent };
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/Menu/index.jsx"],"names":["Menu","MenuTrigger","MenuContent"],"mappings":"AAAA,SAASA,IAAT,EAAeC,WAAf,EAA4BC,WAA5B,QAA+C,QAA/C;AAEA,SAASF,IAAT,EAAeC,WAAf,EAA4BC,WAA5B","sourcesContent":["import { Menu, MenuTrigger, MenuContent } from './Menu';\n\nexport { Menu, MenuTrigger, MenuContent };\n"],"file":"index.js"}