@imposium-hub/components 2.2.38 → 2.2.40-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/cjs/components/app-wrapper/AppWrapper.d.ts +1 -0
  2. package/dist/cjs/components/app-wrapper/AppWrapper.js +2 -2
  3. package/dist/cjs/components/app-wrapper/AppWrapper.js.map +1 -1
  4. package/dist/cjs/components/auth-gate/AuthGate.js +2 -2
  5. package/dist/cjs/components/auth-gate/AuthGate.js.map +1 -1
  6. package/dist/cjs/components/context-menu/AnimateComponent.d.ts +8 -0
  7. package/dist/cjs/components/context-menu/AnimateComponent.js +14 -0
  8. package/dist/cjs/components/context-menu/AnimateComponent.js.map +1 -0
  9. package/dist/cjs/components/context-menu/ContextMenu.d.ts +29 -0
  10. package/dist/cjs/components/context-menu/ContextMenu.js +168 -0
  11. package/dist/cjs/components/context-menu/ContextMenu.js.map +1 -0
  12. package/dist/cjs/components/context-menu/ContextMenuItem.d.ts +20 -0
  13. package/dist/cjs/components/context-menu/ContextMenuItem.js +60 -0
  14. package/dist/cjs/components/context-menu/ContextMenuItem.js.map +1 -0
  15. package/dist/cjs/components/context-menu/ContextMenuTrigger.d.ts +18 -0
  16. package/dist/cjs/components/context-menu/ContextMenuTrigger.js +71 -0
  17. package/dist/cjs/components/context-menu/ContextMenuTrigger.js.map +1 -0
  18. package/dist/cjs/components/context-menu/SubMenu.d.ts +14 -0
  19. package/dist/cjs/components/context-menu/SubMenu.js +97 -0
  20. package/dist/cjs/components/context-menu/SubMenu.js.map +1 -0
  21. package/dist/cjs/components/context-menu/helper.d.ts +2 -0
  22. package/dist/cjs/components/context-menu/helper.js +31 -0
  23. package/dist/cjs/components/context-menu/helper.js.map +1 -0
  24. package/dist/cjs/components/context-menu/registerEvent.d.ts +4 -0
  25. package/dist/cjs/components/context-menu/registerEvent.js +46 -0
  26. package/dist/cjs/components/context-menu/registerEvent.js.map +1 -0
  27. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.d.ts +15 -0
  28. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.js +91 -0
  29. package/dist/cjs/components/error-message-preview/ErrorMessagePreview.js.map +1 -0
  30. package/dist/cjs/components/tag/Tag.test.js.map +1 -1
  31. package/dist/cjs/index.d.ts +5 -1
  32. package/dist/cjs/index.js +9 -1
  33. package/dist/cjs/index.js.map +1 -1
  34. package/dist/cjs/services/Auth0.d.ts +1 -1
  35. package/dist/cjs/services/Auth0.js +2 -3
  36. package/dist/cjs/services/Auth0.js.map +1 -1
  37. package/dist/esm/components/app-wrapper/AppWrapper.d.ts +1 -0
  38. package/dist/esm/components/app-wrapper/AppWrapper.js +2 -2
  39. package/dist/esm/components/app-wrapper/AppWrapper.js.map +1 -1
  40. package/dist/esm/components/auth-gate/AuthGate.js +2 -2
  41. package/dist/esm/components/auth-gate/AuthGate.js.map +1 -1
  42. package/dist/esm/components/context-menu/AnimateComponent.d.ts +8 -0
  43. package/dist/esm/components/context-menu/AnimateComponent.js +8 -0
  44. package/dist/esm/components/context-menu/AnimateComponent.js.map +1 -0
  45. package/dist/esm/components/context-menu/ContextMenu.d.ts +29 -0
  46. package/dist/esm/components/context-menu/ContextMenu.js +108 -0
  47. package/dist/esm/components/context-menu/ContextMenu.js.map +1 -0
  48. package/dist/esm/components/context-menu/ContextMenuItem.d.ts +20 -0
  49. package/dist/esm/components/context-menu/ContextMenuItem.js +23 -0
  50. package/dist/esm/components/context-menu/ContextMenuItem.js.map +1 -0
  51. package/dist/esm/components/context-menu/ContextMenuTrigger.d.ts +18 -0
  52. package/dist/esm/components/context-menu/ContextMenuTrigger.js +34 -0
  53. package/dist/esm/components/context-menu/ContextMenuTrigger.js.map +1 -0
  54. package/dist/esm/components/context-menu/SubMenu.d.ts +14 -0
  55. package/dist/esm/components/context-menu/SubMenu.js +41 -0
  56. package/dist/esm/components/context-menu/SubMenu.js.map +1 -0
  57. package/dist/esm/components/context-menu/helper.d.ts +2 -0
  58. package/dist/esm/components/context-menu/helper.js +22 -0
  59. package/dist/esm/components/context-menu/helper.js.map +1 -0
  60. package/dist/esm/components/context-menu/registerEvent.d.ts +4 -0
  61. package/dist/esm/components/context-menu/registerEvent.js +41 -0
  62. package/dist/esm/components/context-menu/registerEvent.js.map +1 -0
  63. package/dist/esm/components/error-message-preview/ErrorMessagePreview.d.ts +15 -0
  64. package/dist/esm/components/error-message-preview/ErrorMessagePreview.js +35 -0
  65. package/dist/esm/components/error-message-preview/ErrorMessagePreview.js.map +1 -0
  66. package/dist/esm/components/tag/Tag.test.js.map +1 -1
  67. package/dist/esm/index.d.ts +5 -1
  68. package/dist/esm/index.js +5 -1
  69. package/dist/esm/index.js.map +1 -1
  70. package/dist/esm/services/Auth0.d.ts +1 -1
  71. package/dist/esm/services/Auth0.js +2 -2
  72. package/dist/esm/services/Auth0.js.map +1 -1
  73. package/dist/styles.css +141 -0
  74. package/dist/styles.less +145 -0
  75. package/less/components/context-menu.less +145 -0
  76. package/less/entry.less +2 -1
  77. package/package.json +4 -3
  78. package/src/components/app-wrapper/AppWrapper.tsx +3 -2
  79. package/src/components/auth-gate/AuthGate.tsx +3 -2
  80. package/src/components/context-menu/AnimateComponent.tsx +19 -0
  81. package/src/components/context-menu/ContextMenu.tsx +172 -0
  82. package/src/components/context-menu/ContextMenuItem.tsx +34 -0
  83. package/src/components/context-menu/ContextMenuTrigger.tsx +47 -0
  84. package/src/components/context-menu/SubMenu.tsx +70 -0
  85. package/src/components/context-menu/helper.ts +21 -0
  86. package/src/components/context-menu/registerEvent.ts +46 -0
  87. package/src/index.ts +9 -1
  88. package/src/services/Auth0.ts +2 -2
  89. /package/src/components/{tag → Tag}/Tag.test.tsx +0 -0
  90. /package/src/components/{tag → Tag}/Tag.tsx +0 -0
  91. /package/src/components/dropdown/{Dropdown.tsx → dropdown.tsx} +0 -0
package/dist/styles.less CHANGED
@@ -2977,3 +2977,148 @@ h3{
2977
2977
  }
2978
2978
  }
2979
2979
 
2980
+ .contextmenu {
2981
+ background: #161616;
2982
+ position: absolute;
2983
+ top: 20px;
2984
+ min-width: 125px;
2985
+ padding: 3px;
2986
+ z-index: 1000;
2987
+ .submenu {
2988
+ position: relative;
2989
+ &:hover>.contextmenu__item {
2990
+ background-color: #f1f1f1;
2991
+ }
2992
+ }
2993
+ .submenu__item {
2994
+ background-color: #ffffff;
2995
+ border-radius: 4px;
2996
+ border: solid 1px #cccccc;
2997
+ left: 100%;
2998
+ opacity: 0;
2999
+ padding: 5px 0;
3000
+ position: absolute;
3001
+ top: 0;
3002
+ visibility: hidden;
3003
+ width: 100%;
3004
+ }
3005
+ .submenu>.contextmenu__item {
3006
+ &:after {
3007
+ border-color: transparent transparent transparent #000000;
3008
+ border-style: solid;
3009
+ border-width: 5px 8px;
3010
+ content: '';
3011
+ height: 0;
3012
+ position: absolute;
3013
+ right: 0px;
3014
+ top: 50%;
3015
+ transform: translateY(-50%);
3016
+ transition: 0.2s;
3017
+ width: 0;
3018
+ }
3019
+ }
3020
+ }
3021
+ .contextmenu__item {
3022
+ padding: 3px;
3023
+ box-sizing: border-box;
3024
+ cursor: pointer;
3025
+ &:hover {
3026
+ &:not(.contextmenu__item--disabled) {
3027
+ background-color: #393939;
3028
+ }
3029
+ }
3030
+ }
3031
+ .contextmenu__item--disabled {
3032
+ cursor: no-drop;
3033
+ opacity: 0.5;
3034
+ }
3035
+ .fade-enter {
3036
+ opacity: 0;
3037
+ }
3038
+ .fade-enter-active {
3039
+ opacity: 1;
3040
+ transition: opacity 200ms;
3041
+ }
3042
+ .fade-exit {
3043
+ opacity: 1;
3044
+ }
3045
+ .fade-exit-active {
3046
+ opacity: 0;
3047
+ transition: opacity 200ms;
3048
+ }
3049
+ .zoom-enter {
3050
+ opacity: 0;
3051
+ transform-origin: top left;
3052
+ transform: scale(0.8);
3053
+ }
3054
+ .zoom-enter-active {
3055
+ opacity: 1;
3056
+ transform-origin: top left;
3057
+ transform: scale(1);
3058
+ transition: opacity 200ms, transform 200ms;
3059
+ }
3060
+ .zoom-exit {
3061
+ opacity: 1;
3062
+ transform-origin: top left;
3063
+ transform: scale(1);
3064
+ }
3065
+ .zoom-exit-active {
3066
+ opacity: 0;
3067
+ transform-origin: top left;
3068
+ transform: scale(0.8);
3069
+ transition: opacity 200ms, transform 200ms;
3070
+ }
3071
+ .toTopLeft-enter {
3072
+ opacity: 0;
3073
+ transform: translate(10px, 10px);
3074
+ }
3075
+ .toTopLeft-enter-active {
3076
+ opacity: 1;
3077
+ transform: translate(0px, 0px);
3078
+ transition: opacity 200ms, transform 200ms;
3079
+ }
3080
+ .toTopLeft-exit {
3081
+ opacity: 1;
3082
+ transform: translate(0px, 0px);
3083
+ }
3084
+ .toTopLeft-exit-active {
3085
+ opacity: 0;
3086
+ transform: translate(10px, 10px);
3087
+ transition: opacity 200ms, transform 200ms;
3088
+ }
3089
+ .rightToLeft-enter {
3090
+ opacity: 0;
3091
+ transform: translateX(10px);
3092
+ }
3093
+ .rightToLeft-enter-active {
3094
+ opacity: 1;
3095
+ transform: translateX(0px);
3096
+ transition: opacity 200ms, transform 200ms;
3097
+ }
3098
+ .rightToLeft-exit {
3099
+ opacity: 1;
3100
+ transform: translateX(0px);
3101
+ }
3102
+ .rightToLeft-exit-active {
3103
+ opacity: 0;
3104
+ transform: translateX(10px);
3105
+ transition: opacity 200ms, transform 200ms;
3106
+ }
3107
+ .pop-enter {
3108
+ opacity: 0;
3109
+ transform: scale(0.8);
3110
+ }
3111
+ .pop-enter-active {
3112
+ opacity: 1;
3113
+ transform: scale(1);
3114
+ transition: opacity 200ms, transform 200ms;
3115
+ }
3116
+ .pop-exit {
3117
+ opacity: 1;
3118
+ transform: scale(1);
3119
+ }
3120
+ .pop-exit-active {
3121
+ opacity: 0;
3122
+ transform: scale(0.8);
3123
+ transition: opacity 200ms, transform 200ms;
3124
+ }
@@ -0,0 +1,145 @@
1
+ .contextmenu {
2
+ background: #161616;
3
+ position: absolute;
4
+ top: 20px;
5
+ min-width: 125px;
6
+ padding: 3px;
7
+ z-index: 1000;
8
+ .submenu {
9
+ position: relative;
10
+ &:hover>.contextmenu__item {
11
+ background-color: #f1f1f1;
12
+ }
13
+ }
14
+ .submenu__item {
15
+ background-color: #ffffff;
16
+ border-radius: 4px;
17
+ border: solid 1px #cccccc;
18
+ left: 100%;
19
+ opacity: 0;
20
+ padding: 5px 0;
21
+ position: absolute;
22
+ top: 0;
23
+ visibility: hidden;
24
+ width: 100%;
25
+ }
26
+ .submenu>.contextmenu__item {
27
+ &:after {
28
+ border-color: transparent transparent transparent #000000;
29
+ border-style: solid;
30
+ border-width: 5px 8px;
31
+ content: '';
32
+ height: 0;
33
+ position: absolute;
34
+ right: 0px;
35
+ top: 50%;
36
+ transform: translateY(-50%);
37
+ transition: 0.2s;
38
+ width: 0;
39
+ }
40
+ }
41
+ }
42
+ .contextmenu__item {
43
+ padding: 3px;
44
+ box-sizing: border-box;
45
+ cursor: pointer;
46
+ &:hover {
47
+ &:not(.contextmenu__item--disabled) {
48
+ background-color: #393939;
49
+ }
50
+ }
51
+ }
52
+ .contextmenu__item--disabled {
53
+ cursor: no-drop;
54
+ opacity: 0.5;
55
+ }
56
+ .fade-enter {
57
+ opacity: 0;
58
+ }
59
+ .fade-enter-active {
60
+ opacity: 1;
61
+ transition: opacity 200ms;
62
+ }
63
+ .fade-exit {
64
+ opacity: 1;
65
+ }
66
+ .fade-exit-active {
67
+ opacity: 0;
68
+ transition: opacity 200ms;
69
+ }
70
+ .zoom-enter {
71
+ opacity: 0;
72
+ transform-origin: top left;
73
+ transform: scale(0.8);
74
+ }
75
+ .zoom-enter-active {
76
+ opacity: 1;
77
+ transform-origin: top left;
78
+ transform: scale(1);
79
+ transition: opacity 200ms, transform 200ms;
80
+ }
81
+ .zoom-exit {
82
+ opacity: 1;
83
+ transform-origin: top left;
84
+ transform: scale(1);
85
+ }
86
+ .zoom-exit-active {
87
+ opacity: 0;
88
+ transform-origin: top left;
89
+ transform: scale(0.8);
90
+ transition: opacity 200ms, transform 200ms;
91
+ }
92
+ .toTopLeft-enter {
93
+ opacity: 0;
94
+ transform: translate(10px, 10px);
95
+ }
96
+ .toTopLeft-enter-active {
97
+ opacity: 1;
98
+ transform: translate(0px, 0px);
99
+ transition: opacity 200ms, transform 200ms;
100
+ }
101
+ .toTopLeft-exit {
102
+ opacity: 1;
103
+ transform: translate(0px, 0px);
104
+ }
105
+ .toTopLeft-exit-active {
106
+ opacity: 0;
107
+ transform: translate(10px, 10px);
108
+ transition: opacity 200ms, transform 200ms;
109
+ }
110
+ .rightToLeft-enter {
111
+ opacity: 0;
112
+ transform: translateX(10px);
113
+ }
114
+ .rightToLeft-enter-active {
115
+ opacity: 1;
116
+ transform: translateX(0px);
117
+ transition: opacity 200ms, transform 200ms;
118
+ }
119
+ .rightToLeft-exit {
120
+ opacity: 1;
121
+ transform: translateX(0px);
122
+ }
123
+ .rightToLeft-exit-active {
124
+ opacity: 0;
125
+ transform: translateX(10px);
126
+ transition: opacity 200ms, transform 200ms;
127
+ }
128
+ .pop-enter {
129
+ opacity: 0;
130
+ transform: scale(0.8);
131
+ }
132
+ .pop-enter-active {
133
+ opacity: 1;
134
+ transform: scale(1);
135
+ transition: opacity 200ms, transform 200ms;
136
+ }
137
+ .pop-exit {
138
+ opacity: 1;
139
+ transform: scale(1);
140
+ }
141
+ .pop-exit-active {
142
+ opacity: 0;
143
+ transform: scale(0.8);
144
+ transition: opacity 200ms, transform 200ms;
145
+ }
package/less/entry.less CHANGED
@@ -36,4 +36,5 @@
36
36
  @import (inline) "components/variable-default-upload.less";
37
37
  @import (inline) "components/anchor-field.less";
38
38
  @import (inline) "components/advanced-number-field.less";
39
- @import (inline) "components/font-picker.less";
39
+ @import (inline) "components/font-picker.less";
40
+ @import (inline) "components/context-menu.less";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imposium-hub/components",
3
- "version": "2.2.38",
3
+ "version": "2.2.40-0",
4
4
  "description": "React & Typescript component / asset library for Imposium front-ends",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -17,7 +17,7 @@
17
17
  "watch-ts-cjs": "npm run build-ts-cjs -- --watch",
18
18
  "lint": "npx eslint \"./src/**/*.*\"",
19
19
  "lint-fix": "npm run lint -- --fix",
20
- "deploy": "npx np --no-tests --message 'v%s'",
20
+ "deploy": "npx np --no-tests --any-branch --message 'v%s'",
21
21
  "release": "npm run check-formatting && npm run lint && npm run build && npm run deploy",
22
22
  "format": "prettier --write \"**/*.{,js,json,jsx,ts,tsx,md}\"",
23
23
  "check-formatting": "prettier --check \"**/*.{,js,json,jsx,ts,tsx,md}\"",
@@ -45,7 +45,8 @@
45
45
  "moment": "^2.29.1",
46
46
  "react-color": "^2.18.0",
47
47
  "react-merge-refs": "^1.1.0",
48
- "react-moveable": "^0.26.1"
48
+ "react-moveable": "^0.26.1",
49
+ "react-transition-group": "^4.4.5"
49
50
  },
50
51
  "peerDependencies": {
51
52
  "@fortawesome/fontawesome-svg-core": "^6.1.1",
@@ -11,6 +11,7 @@ import { checkStoryId, getLastModifiedStoryInOrg, validateAccessLevel } from '..
11
11
 
12
12
  export interface IAppWrapperProps {
13
13
  children: React.ReactChildren;
14
+ auth0Domain: string;
14
15
  auth0ClientId: string;
15
16
  organizationId: string;
16
17
  baseUrl: string;
@@ -59,10 +60,10 @@ class AppWrapper extends React.Component<IAppWrapperProps, IAppWrapperState> {
59
60
  }
60
61
 
61
62
  public componentDidMount = (): void => {
62
- const { auth, access, auth0ClientId, isFreshUser } = this.props;
63
+ const { auth, access, auth0ClientId, auth0Domain, isFreshUser } = this.props;
63
64
  const session: IHubSession = SessionService.getSession();
64
65
 
65
- AuthService.bindToClient(auth0ClientId);
66
+ AuthService.bindToClient(auth0ClientId, auth0Domain);
66
67
 
67
68
  // If cookie, auth or access data is missing / mismatched,
68
69
  // silently check auth0 session and refresh flow on success
@@ -9,6 +9,7 @@ import { cacheAccessData } from '../../redux/actions/access';
9
9
 
10
10
  interface IAuthGateProps {
11
11
  auth0ClientId: string;
12
+ auth0Domain: string;
12
13
  auth0Hash: string;
13
14
  onAuthenticated: () => any;
14
15
  baseUrl?: string;
@@ -24,9 +25,9 @@ class AuthGate extends React.PureComponent<IAuthGateProps> {
24
25
  }
25
26
 
26
27
  public componentDidMount = (): void => {
27
- const { auth0ClientId, auth0Hash, onAuthenticated, baseUrl } = this.props;
28
+ const { auth0ClientId, auth0Hash, auth0Domain, onAuthenticated, baseUrl } = this.props;
28
29
 
29
- AuthService.bindToClient(auth0ClientId);
30
+ AuthService.bindToClient(auth0ClientId, auth0Domain);
30
31
 
31
32
  if (!auth0Hash) {
32
33
  AuthService.login();
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import CSSTransition from 'react-transition-group/CSSTransition';
3
+
4
+ const AnimateComponent = ({ children, isVisible, timeout, className }) => {
5
+ const nodeRef = React.useRef(null);
6
+
7
+ return (
8
+ <CSSTransition
9
+ nodeRef={nodeRef}
10
+ in={isVisible}
11
+ timeout={timeout}
12
+ classNames={className}
13
+ unmountOnExit>
14
+ {children}
15
+ </CSSTransition>
16
+ );
17
+ };
18
+
19
+ export default AnimateComponent;
@@ -0,0 +1,172 @@
1
+ import React, { useRef, useEffect, useState, useCallback } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import { registerEvent, callHideEvent } from './registerEvent';
4
+ import AnimateComponent from './AnimateComponent';
5
+ import { throttle } from './helper';
6
+
7
+ const ContextMenu = ({
8
+ children,
9
+ id,
10
+ appendTo,
11
+ hideOnLeave,
12
+ onMouseLeave,
13
+ onHide,
14
+ onShow,
15
+ preventHideOnScroll,
16
+ preventHideOnResize,
17
+ attributes,
18
+ animation
19
+ }) => {
20
+ const contextMenuEl = useRef(null);
21
+ const [isVisible, setVisible] = useState(false);
22
+ const [clientPosition, setClientPosition] = useState(null);
23
+
24
+ const showMenu = (e) => {
25
+ const { position } = e;
26
+
27
+ setVisible(true);
28
+ setClientPosition(position);
29
+ };
30
+
31
+ const hideMenu = () => {
32
+ setVisible(false);
33
+ if (onHide) onHide();
34
+ };
35
+
36
+ const handleMouseLeave = useCallback((e) => {
37
+ e.preventDefault();
38
+
39
+ onMouseLeave(e);
40
+
41
+ if (hideOnLeave) callHideEvent(id);
42
+ }, []);
43
+
44
+ const clickOutsideCallback = (event) => {
45
+ if (contextMenuEl.current && !contextMenuEl.current.contains(event.target)) {
46
+ callHideEvent(id);
47
+ }
48
+ };
49
+
50
+ const contextMenuCallback = (event) => {
51
+ let targetElement = event.target;
52
+
53
+ do {
54
+ if (targetElement.classList && targetElement.classList.contains('menu-trigger')) {
55
+ return;
56
+ }
57
+ targetElement = targetElement.parentNode;
58
+ } while (targetElement);
59
+
60
+ callHideEvent(id);
61
+ };
62
+
63
+ const onScrollHideCallback = throttle(() => {
64
+ callHideEvent(id);
65
+ }, 200);
66
+
67
+ const onResizeHideCallback = throttle(() => {
68
+ callHideEvent(id);
69
+ }, 200);
70
+
71
+ useEffect(() => {
72
+ registerEvent(id, showMenu, hideMenu);
73
+
74
+ // detect click outside
75
+ document.addEventListener('mousedown', clickOutsideCallback);
76
+
77
+ // detect right click outside
78
+ document.addEventListener('contextmenu', contextMenuCallback);
79
+
80
+ // on scroll hide handled
81
+ if (!preventHideOnScroll) {
82
+ window.addEventListener('scroll', onScrollHideCallback);
83
+ }
84
+
85
+ // on resize hide handled
86
+ if (!preventHideOnResize) {
87
+ window.addEventListener('resize', onResizeHideCallback);
88
+ }
89
+
90
+ return () => {
91
+ document.removeEventListener('mousedown', clickOutsideCallback);
92
+ document.removeEventListener('contextmenu', contextMenuCallback);
93
+ window.removeEventListener('scroll', onScrollHideCallback);
94
+ window.removeEventListener('resize', onResizeHideCallback);
95
+ };
96
+ }, []);
97
+
98
+ useEffect(() => {
99
+ if (isVisible) {
100
+ const { clientY, clientX } = clientPosition;
101
+ const { innerHeight: windowInnerHeight, innerWidth: windowInnerWidth } = window;
102
+ const { offsetHeight: elemHeight, offsetWidth: elemWidth } = contextMenuEl.current;
103
+
104
+ let newClientY = clientY;
105
+ let newClientX = clientX;
106
+
107
+ if (windowInnerHeight < clientY + elemHeight) newClientY = clientY - elemHeight;
108
+ if (windowInnerWidth < clientX + elemWidth) newClientX = clientX - elemWidth;
109
+
110
+ contextMenuEl.current.style.top = `${newClientY + 2}px`;
111
+ contextMenuEl.current.style.left = `${newClientX + 2}px`;
112
+
113
+ if (onShow) onShow();
114
+ }
115
+ }, [isVisible, clientPosition]);
116
+
117
+ const childrenWithProps = React.Children.map(children, (child) =>
118
+ React.cloneElement(child, { id })
119
+ );
120
+
121
+ const ContextComponent = () => (
122
+ <div
123
+ className={`contextmenu`}
124
+ ref={contextMenuEl}
125
+ onMouseLeave={handleMouseLeave}
126
+ {...attributes}>
127
+ {childrenWithProps}
128
+ </div>
129
+ );
130
+
131
+ const PortalContextComponent = () =>
132
+ ReactDOM.createPortal(<ContextComponent />, document.querySelector(appendTo));
133
+
134
+ if (document.readyState === 'complete' && appendTo) {
135
+ return animation ? (
136
+ <AnimateComponent
137
+ isVisible={isVisible}
138
+ timeout={200}
139
+ className={animation}>
140
+ <PortalContextComponent />
141
+ </AnimateComponent>
142
+ ) : (
143
+ <PortalContextComponent />
144
+ );
145
+ }
146
+
147
+ return animation ? (
148
+ <AnimateComponent
149
+ isVisible={isVisible}
150
+ timeout={200}
151
+ className={animation}>
152
+ <ContextComponent />
153
+ </AnimateComponent>
154
+ ) : (
155
+ <ContextComponent />
156
+ );
157
+ };
158
+
159
+ export default ContextMenu;
160
+
161
+ ContextMenu.defaultProps = {
162
+ appendTo: null,
163
+ hideOnLeave: false,
164
+ preventHideOnResize: false,
165
+ preventHideOnScroll: false,
166
+ attributes: {},
167
+ className: '',
168
+ animation: 'fade',
169
+ onMouseLeave: () => null,
170
+ onHide: () => null,
171
+ onShow: () => null
172
+ };
@@ -0,0 +1,34 @@
1
+ import React, { useCallback, useRef } from 'react';
2
+ import { callHideEvent } from './registerEvent';
3
+
4
+ const ContextMenuItem = ({ children, onClick, disabled, preventClose, attributes, className }) => {
5
+ const contextMenuItem = useRef(null);
6
+
7
+ const handleClickEvent = useCallback((e) => {
8
+ if (disabled) return;
9
+ onClick(e);
10
+
11
+ if (!preventClose) callHideEvent('ID_NOT_REQUIRED');
12
+ }, []);
13
+
14
+ return (
15
+ <div
16
+ className={`${disabled ? 'contextmenu__item--disabled' : 'contextmenu__item'}`}
17
+ onClick={handleClickEvent}
18
+ {...attributes}
19
+ ref={contextMenuItem}>
20
+ {children}
21
+ </div>
22
+ );
23
+ };
24
+
25
+ export default ContextMenuItem;
26
+
27
+ ContextMenuItem.defaultProps = {
28
+ disabled: false,
29
+ preventClose: false,
30
+ attributes: {},
31
+ className: '',
32
+ onClick: () => null,
33
+ onItemHover: () => null
34
+ };
@@ -0,0 +1,47 @@
1
+ import React, { useRef, useCallback } from 'react';
2
+ import { callShowEvent, callHideEvent } from './registerEvent';
3
+
4
+ const ContextMenuTrigger = ({ children, id, disableWhileShiftPressed, attributes, disable }) => {
5
+ const menuTrigger = useRef(null);
6
+
7
+ const handleContextMenu = useCallback((e) => {
8
+ if (disable) return;
9
+ if (disableWhileShiftPressed && e.nativeEvent.shiftKey) {
10
+ callHideEvent(id);
11
+ return;
12
+ }
13
+ e.preventDefault();
14
+ e.stopPropagation();
15
+
16
+ const { clientX, clientY } = e.nativeEvent;
17
+ const opts = {
18
+ position: {
19
+ clientY,
20
+ clientX
21
+ },
22
+ id
23
+ };
24
+
25
+ callShowEvent(opts);
26
+ }, []);
27
+
28
+ return (
29
+ <div
30
+ className='menu-trigger'
31
+ ref={menuTrigger}
32
+ {...attributes}
33
+ onContextMenu={(e) => handleContextMenu(e)}>
34
+ {children}
35
+ </div>
36
+ );
37
+ };
38
+
39
+ export default ContextMenuTrigger;
40
+
41
+ ContextMenuTrigger.defaultProps = {
42
+ attributes: {},
43
+ disable: false,
44
+ renderTag: 'div',
45
+ disableWhileShiftPressed: false,
46
+ className: ''
47
+ };