1
1
import React , { useState , useEffect , useRef } from "react" ;
2
+ import styled from "styled-components" ;
2
3
import { Priorities } from "@core/constants/core.constants" ;
3
4
import { ContextMenuPosition } from "./GridContextMenuWrapper" ;
4
5
@@ -7,13 +8,66 @@ interface ContextMenuProps {
7
8
onClose : ( ) => void ;
8
9
}
9
10
11
+ const MenuWrapper = styled . ul < { position : ContextMenuPosition | null } > `
12
+ position: absolute;
13
+ top: ${ ( { position } ) => position ?. y || 0 } px;
14
+ left: ${ ( { position } ) => position ?. x || 0 } px;
15
+ background-color: white;
16
+ border: 1px solid #ccc;
17
+ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
18
+ border-radius: 8px;
19
+ padding: 5px 0;
20
+ list-style: none;
21
+ z-index: 1000;
22
+ min-width: 160px;
23
+ ` ;
24
+
25
+ const PriorityContainer = styled . div `
26
+ display: flex;
27
+ justify-content: center;
28
+ gap: 10px;
29
+ padding: 10px;
30
+ ` ;
31
+
32
+ const PriorityCircle = styled . div < { color : string ; selected : boolean } > `
33
+ width: 20px;
34
+ height: 20px;
35
+ border-radius: 50%;
36
+ border: 2px solid ${ ( { color } ) => color } ;
37
+ background-color: ${ ( { selected, color } ) =>
38
+ selected ? color : "transparent" } ;
39
+ cursor: pointer;
40
+ transition: all 0.2s ease-in-out;
41
+ ` ;
42
+
43
+ const MenuItem = styled . li `
44
+ padding: 10px 12px;
45
+ cursor: pointer;
46
+ user-select: none;
47
+ font-size: 14px;
48
+ color: #333;
49
+ white-space: nowrap;
50
+ display: flex;
51
+ align-items: center;
52
+ gap: 8px;
53
+ border-bottom: 1px solid #eee;
54
+
55
+ &:last-child {
56
+ border-bottom: none;
57
+ }
58
+
59
+ &:hover {
60
+ background-color: #f5f5f5;
61
+ }
62
+ ` ;
63
+
10
64
const ContextMenu = ( { position, onClose } : ContextMenuProps ) => {
11
65
const menuRef = useRef < HTMLUListElement > ( null ) ;
12
66
const [ selectedPriority , setSelectedPriority ] = useState (
13
67
Priorities . UNASSIGNED
14
68
) ;
15
69
16
- // TODO: Get colors from a constant
70
+ // TODO: Use colors from constant
17
71
const priorities = [
18
72
{ id : "work" , value : Priorities . WORK , color : "rgb(200, 236, 249)" } ,
19
73
{ id : "self" , value : Priorities . SELF , color : "rgb(149, 189, 219)" } ,
@@ -25,11 +79,7 @@ const ContextMenu = ({ position, onClose }: ContextMenuProps) => {
25
79
] ;
26
80
27
81
const actions = [
28
- {
29
- id : "edit" ,
30
- label : "✏️ Edit" ,
31
- onClick : ( ) => alert ( "Edit clicked" ) ,
32
- } ,
82
+ { id : "edit" , label : "✏️ Edit" , onClick : ( ) => alert ( "Edit clicked" ) } ,
33
83
{
34
84
id : "delete" ,
35
85
label : "🗑️ Delete" ,
@@ -60,92 +110,29 @@ const ContextMenu = ({ position, onClose }: ContextMenuProps) => {
60
110
} , [ onClose ] ) ;
61
111
62
112
return (
63
- < ul
64
- ref = { menuRef }
65
- style = { {
66
- position : "absolute" ,
67
- top : position ?. y ,
68
- left : position ?. x ,
69
- backgroundColor : "white" ,
70
- border : "1px solid #ccc" ,
71
- boxShadow : "0px 4px 6px rgba(0,0,0,0.1)" ,
72
- borderRadius : "8px" ,
73
- padding : "5px 0" ,
74
- listStyle : "none" ,
75
- zIndex : 1000 ,
76
- minWidth : "160px" ,
77
- } }
78
- >
79
- { /* Priority Selection */ }
80
- < div
81
- style = { {
82
- display : "flex" ,
83
- justifyContent : "center" ,
84
- gap : "10px" ,
85
- padding : "10px" ,
86
- } }
87
- >
113
+ < MenuWrapper ref = { menuRef } position = { position } >
114
+ < PriorityContainer >
88
115
{ priorities . map ( ( priority ) => (
89
- < div
116
+ < PriorityCircle
90
117
key = { priority . id }
118
+ color = { priority . color }
119
+ selected = { selectedPriority === priority . value }
91
120
onClick = { ( ) => setSelectedPriority ( priority . value ) }
92
- style = { {
93
- width : "20px" ,
94
- height : "20px" ,
95
- borderRadius : "50%" ,
96
- border : `2px solid ${ priority . color } ` ,
97
- backgroundColor :
98
- selectedPriority === priority . value
99
- ? priority . color
100
- : "transparent" ,
101
- cursor : "pointer" ,
102
- transition : "all 0.2s ease-in-out" ,
103
- boxShadow :
104
- selectedPriority === priority . value
105
- ? `0px 0px 0px 0px ${ priority . color } `
106
- : "none" ,
107
- } }
108
121
/>
109
122
) ) }
110
- </ div >
111
-
112
- { /* Edit and Delete Options */ }
113
- { actions . map ( ( item , i ) => {
114
- const isLast = i === actions . length - 1 ;
115
-
116
- return (
117
- < li
118
- key = { item . id }
119
- onClick = { ( ) => {
120
- item . onClick ( ) ;
121
- onClose ( ) ;
122
- } }
123
- style = { {
124
- padding : "10px 12px" ,
125
- cursor : "pointer" ,
126
- userSelect : "none" ,
127
- fontSize : "14px" ,
128
- color : "#333" ,
129
- whiteSpace : "nowrap" ,
130
- display : "flex" ,
131
- alignItems : "center" ,
132
- gap : "8px" ,
133
- borderBottom : ! isLast ? "1px solid #eee" : "none" ,
134
- } }
135
- onMouseEnter = { ( e ) => {
136
- const target = e . target as HTMLElement ;
137
- target . style . backgroundColor = "#f5f5f5" ;
138
- } }
139
- onMouseLeave = { ( e ) => {
140
- const target = e . target as HTMLElement ;
141
- target . style . backgroundColor = "white" ;
142
- } }
143
- >
144
- { item . label }
145
- </ li >
146
- ) ;
147
- } ) }
148
- </ ul >
123
+ </ PriorityContainer >
124
+ { actions . map ( ( item ) => (
125
+ < MenuItem
126
+ key = { item . id }
127
+ onClick = { ( ) => {
128
+ item . onClick ( ) ;
129
+ onClose ( ) ;
130
+ } }
131
+ >
132
+ { item . label }
133
+ </ MenuItem >
134
+ ) ) }
135
+ </ MenuWrapper >
149
136
) ;
150
137
} ;
151
138
0 commit comments