@@ -18,12 +18,16 @@ interface EpicDropdownProps {
18
18
selectedEpic ?: EpicCategoryDTO ;
19
19
epicList : EpicCategoryDTO [ ] ;
20
20
onEpicChange : ( epicId : number | undefined ) => void ;
21
+ lastRankValue ?: string ;
22
+ onCloseDropdown : ( ) => void ;
21
23
}
22
24
23
25
const EpicDropdown = ( {
24
26
selectedEpic,
25
27
epicList,
26
28
onEpicChange,
29
+ lastRankValue,
30
+ onCloseDropdown,
27
31
} : EpicDropdownProps ) => {
28
32
const { socket } : { socket : Socket } = useOutletContext ( ) ;
29
33
const { emitEpicCreateEvent } = useEpicEmitEvent ( socket ) ;
@@ -39,26 +43,29 @@ const EpicDropdown = ({
39
43
setValue ( value ) ;
40
44
} ;
41
45
46
+ const handleCreateButtonClick = ( ) => {
47
+ if ( value . length > 10 ) {
48
+ alert ( "에픽 이름은 10자 이하여야 합니다." ) ;
49
+ return ;
50
+ }
51
+
52
+ const rankValue =
53
+ lastRankValue !== undefined
54
+ ? LexoRank . parse ( lastRankValue ) . genNext ( ) . toString ( )
55
+ : LexoRank . middle ( ) . toString ( ) ;
56
+
57
+ emitEpicCreateEvent ( { name : value , color : epicColor , rankValue } ) ;
58
+ setValue ( "" ) ;
59
+ setEpicColor ( getNewColor ( Object . keys ( CATEGORY_COLOR ) ) ) ;
60
+ } ;
61
+
42
62
const handleEnterKeydown = ( event : React . KeyboardEvent ) => {
43
63
if ( event . nativeEvent . isComposing ) {
44
64
return ;
45
65
}
46
66
47
67
if ( event . key === "Enter" && value ) {
48
- if ( value . length > 10 ) {
49
- alert ( "에픽 이름은 10자 이하여야 합니다." ) ;
50
- return ;
51
- }
52
-
53
- const rankValue = epicList . length
54
- ? LexoRank . parse ( epicList [ epicList . length - 1 ] . rankValue )
55
- . genNext ( )
56
- . toString ( )
57
- : LexoRank . middle ( ) . toString ( ) ;
58
-
59
- emitEpicCreateEvent ( { name : value , color : epicColor , rankValue } ) ;
60
- setValue ( "" ) ;
61
- setEpicColor ( getNewColor ( Object . keys ( CATEGORY_COLOR ) ) ) ;
68
+ handleCreateButtonClick ( ) ;
62
69
}
63
70
} ;
64
71
@@ -76,12 +83,20 @@ const EpicDropdown = ({
76
83
}
77
84
} ;
78
85
86
+ const handleESCClick = ( event : KeyboardEvent ) => {
87
+ if ( event . key === "Escape" ) {
88
+ onCloseDropdown ( ) ;
89
+ }
90
+ } ;
91
+
79
92
useEffect ( ( ) => {
80
93
socket . on ( "backlog" , handleEpicEvent ) ;
81
94
inputElementRef . current ?. focus ( ) ;
95
+ window . addEventListener ( "keydown" , handleESCClick ) ;
82
96
83
97
return ( ) => {
84
98
socket . off ( "backlog" , handleEpicEvent ) ;
99
+ window . removeEventListener ( "keydown" , handleESCClick ) ;
85
100
} ;
86
101
} , [ ] ) ;
87
102
@@ -107,10 +122,13 @@ const EpicDropdown = ({
107
122
/>
108
123
</ div >
109
124
{ value ? (
110
- < div className = "flex items-center gap-2 p-1" >
125
+ < button
126
+ className = "flex items-center gap-2 p-1"
127
+ onClick = { handleCreateButtonClick }
128
+ >
111
129
< span > 생성</ span >
112
130
< CategoryChip content = { value } bgColor = { epicColor } />
113
- </ div >
131
+ </ button >
114
132
) : (
115
133
< ul className = "max-h-[16rem] overflow-y-auto scrollbar-thin pt-1" >
116
134
{ ...epicList . map ( ( epic ) => (
0 commit comments