@imposium-hub/components 2.2.38 → 2.2.39

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 (61) hide show
  1. package/dist/cjs/components/context-menu/AnimateComponent.d.ts +8 -0
  2. package/dist/cjs/components/context-menu/AnimateComponent.js +14 -0
  3. package/dist/cjs/components/context-menu/AnimateComponent.js.map +1 -0
  4. package/dist/cjs/components/context-menu/ContextMenu.d.ts +29 -0
  5. package/dist/cjs/components/context-menu/ContextMenu.js +168 -0
  6. package/dist/cjs/components/context-menu/ContextMenu.js.map +1 -0
  7. package/dist/cjs/components/context-menu/ContextMenuItem.d.ts +20 -0
  8. package/dist/cjs/components/context-menu/ContextMenuItem.js +60 -0
  9. package/dist/cjs/components/context-menu/ContextMenuItem.js.map +1 -0
  10. package/dist/cjs/components/context-menu/ContextMenuTrigger.d.ts +18 -0
  11. package/dist/cjs/components/context-menu/ContextMenuTrigger.js +71 -0
  12. package/dist/cjs/components/context-menu/ContextMenuTrigger.js.map +1 -0
  13. package/dist/cjs/components/context-menu/SubMenu.d.ts +14 -0
  14. package/dist/cjs/components/context-menu/SubMenu.js +97 -0
  15. package/dist/cjs/components/context-menu/SubMenu.js.map +1 -0
  16. package/dist/cjs/components/context-menu/helper.d.ts +2 -0
  17. package/dist/cjs/components/context-menu/helper.js +31 -0
  18. package/dist/cjs/components/context-menu/helper.js.map +1 -0
  19. package/dist/cjs/components/context-menu/registerEvent.d.ts +4 -0
  20. package/dist/cjs/components/context-menu/registerEvent.js +46 -0
  21. package/dist/cjs/components/context-menu/registerEvent.js.map +1 -0
  22. package/dist/cjs/index.d.ts +5 -1
  23. package/dist/cjs/index.js +9 -1
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/esm/components/context-menu/AnimateComponent.d.ts +8 -0
  26. package/dist/esm/components/context-menu/AnimateComponent.js +8 -0
  27. package/dist/esm/components/context-menu/AnimateComponent.js.map +1 -0
  28. package/dist/esm/components/context-menu/ContextMenu.d.ts +29 -0
  29. package/dist/esm/components/context-menu/ContextMenu.js +108 -0
  30. package/dist/esm/components/context-menu/ContextMenu.js.map +1 -0
  31. package/dist/esm/components/context-menu/ContextMenuItem.d.ts +20 -0
  32. package/dist/esm/components/context-menu/ContextMenuItem.js +23 -0
  33. package/dist/esm/components/context-menu/ContextMenuItem.js.map +1 -0
  34. package/dist/esm/components/context-menu/ContextMenuTrigger.d.ts +18 -0
  35. package/dist/esm/components/context-menu/ContextMenuTrigger.js +34 -0
  36. package/dist/esm/components/context-menu/ContextMenuTrigger.js.map +1 -0
  37. package/dist/esm/components/context-menu/SubMenu.d.ts +14 -0
  38. package/dist/esm/components/context-menu/SubMenu.js +41 -0
  39. package/dist/esm/components/context-menu/SubMenu.js.map +1 -0
  40. package/dist/esm/components/context-menu/helper.d.ts +2 -0
  41. package/dist/esm/components/context-menu/helper.js +22 -0
  42. package/dist/esm/components/context-menu/helper.js.map +1 -0
  43. package/dist/esm/components/context-menu/registerEvent.d.ts +4 -0
  44. package/dist/esm/components/context-menu/registerEvent.js +41 -0
  45. package/dist/esm/components/context-menu/registerEvent.js.map +1 -0
  46. package/dist/esm/index.d.ts +5 -1
  47. package/dist/esm/index.js +5 -1
  48. package/dist/esm/index.js.map +1 -1
  49. package/dist/styles.css +141 -0
  50. package/dist/styles.less +145 -0
  51. package/less/components/context-menu.less +145 -0
  52. package/less/entry.less +2 -1
  53. package/package.json +3 -2
  54. package/src/components/context-menu/AnimateComponent.tsx +19 -0
  55. package/src/components/context-menu/ContextMenu.tsx +172 -0
  56. package/src/components/context-menu/ContextMenuItem.tsx +34 -0
  57. package/src/components/context-menu/ContextMenuTrigger.tsx +47 -0
  58. package/src/components/context-menu/SubMenu.tsx +70 -0
  59. package/src/components/context-menu/helper.ts +21 -0
  60. package/src/components/context-menu/registerEvent.ts +46 -0
  61. package/src/index.ts +9 -1
package/dist/styles.css CHANGED
@@ -2898,3 +2898,144 @@ h3 {
2898
2898
  #font-picker.expanded ul {
2899
2899
  max-height: 200px;
2900
2900
  }
2901
+ .contextmenu {
2902
+ background: #161616;
2903
+ position: absolute;
2904
+ top: 20px;
2905
+ min-width: 125px;
2906
+ padding: 3px;
2907
+ z-index: 1000;
2908
+ }
2909
+ .contextmenu .submenu {
2910
+ position: relative;
2911
+ }
2912
+ .contextmenu .submenu:hover > .contextmenu__item {
2913
+ background-color: #f1f1f1;
2914
+ }
2915
+ .contextmenu .submenu__item {
2916
+ background-color: #ffffff;
2917
+ border-radius: 4px;
2918
+ border: solid 1px #cccccc;
2919
+ left: 100%;
2920
+ opacity: 0;
2921
+ padding: 5px 0;
2922
+ position: absolute;
2923
+ top: 0;
2924
+ visibility: hidden;
2925
+ width: 100%;
2926
+ }
2927
+ .contextmenu .submenu > .contextmenu__item:after {
2928
+ border-color: transparent transparent transparent #000000;
2929
+ border-style: solid;
2930
+ border-width: 5px 8px;
2931
+ content: '';
2932
+ height: 0;
2933
+ position: absolute;
2934
+ right: 0px;
2935
+ top: 50%;
2936
+ transform: translateY(-50%);
2937
+ transition: 0.2s;
2938
+ width: 0;
2939
+ }
2940
+ .contextmenu__item {
2941
+ padding: 3px;
2942
+ box-sizing: border-box;
2943
+ cursor: pointer;
2944
+ }
2945
+ .contextmenu__item:hover:not(.contextmenu__item--disabled) {
2946
+ background-color: #393939;
2947
+ }
2948
+ .contextmenu__item--disabled {
2949
+ cursor: no-drop;
2950
+ opacity: 0.5;
2951
+ }
2952
+ .fade-enter {
2953
+ opacity: 0;
2954
+ }
2955
+ .fade-enter-active {
2956
+ opacity: 1;
2957
+ transition: opacity 200ms;
2958
+ }
2959
+ .fade-exit {
2960
+ opacity: 1;
2961
+ }
2962
+ .fade-exit-active {
2963
+ opacity: 0;
2964
+ transition: opacity 200ms;
2965
+ }
2966
+ .zoom-enter {
2967
+ opacity: 0;
2968
+ transform-origin: top left;
2969
+ transform: scale(0.8);
2970
+ }
2971
+ .zoom-enter-active {
2972
+ opacity: 1;
2973
+ transform-origin: top left;
2974
+ transform: scale(1);
2975
+ transition: opacity 200ms, transform 200ms;
2976
+ }
2977
+ .zoom-exit {
2978
+ opacity: 1;
2979
+ transform-origin: top left;
2980
+ transform: scale(1);
2981
+ }
2982
+ .zoom-exit-active {
2983
+ opacity: 0;
2984
+ transform-origin: top left;
2985
+ transform: scale(0.8);
2986
+ transition: opacity 200ms, transform 200ms;
2987
+ }
2988
+ .toTopLeft-enter {
2989
+ opacity: 0;
2990
+ transform: translate(10px, 10px);
2991
+ }
2992
+ .toTopLeft-enter-active {
2993
+ opacity: 1;
2994
+ transform: translate(0px, 0px);
2995
+ transition: opacity 200ms, transform 200ms;
2996
+ }
2997
+ .toTopLeft-exit {
2998
+ opacity: 1;
2999
+ transform: translate(0px, 0px);
3000
+ }
3001
+ .toTopLeft-exit-active {
3002
+ opacity: 0;
3003
+ transform: translate(10px, 10px);
3004
+ transition: opacity 200ms, transform 200ms;
3005
+ }
3006
+ .rightToLeft-enter {
3007
+ opacity: 0;
3008
+ transform: translateX(10px);
3009
+ }
3010
+ .rightToLeft-enter-active {
3011
+ opacity: 1;
3012
+ transform: translateX(0px);
3013
+ transition: opacity 200ms, transform 200ms;
3014
+ }
3015
+ .rightToLeft-exit {
3016
+ opacity: 1;
3017
+ transform: translateX(0px);
3018
+ }
3019
+ .rightToLeft-exit-active {
3020
+ opacity: 0;
3021
+ transform: translateX(10px);
3022
+ transition: opacity 200ms, transform 200ms;
3023
+ }
3024
+ .pop-enter {
3025
+ opacity: 0;
3026
+ transform: scale(0.8);
3027
+ }
3028
+ .pop-enter-active {
3029
+ opacity: 1;
3030
+ transform: scale(1);
3031
+ transition: opacity 200ms, transform 200ms;
3032
+ }
3033
+ .pop-exit {
3034
+ opacity: 1;
3035
+ transform: scale(1);
3036
+ }
3037
+ .pop-exit-active {
3038
+ opacity: 0;
3039
+ transform: scale(0.8);
3040
+ transition: opacity 200ms, transform 200ms;
3041
+ }
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.39",
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",
@@ -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",
@@ -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
+ };