11import { PlusIcon } from "lucide-react" ;
2- import { useState } from "react" ;
2+ import { useEffect , useRef , useState } from "react" ;
33import { Button } from "./ui/button" ;
44import { Input } from "./ui/input" ;
55
66export default function MemberList ( ) {
77 // メンバー名の配列を状態として管理
88 const [ members , setMembers ] = useState < string [ ] > ( [ "" ] ) ;
9+ // 各inputへの参照を保持
10+ const inputRefs = useRef < ( HTMLInputElement | null ) [ ] > ( [ ] ) ;
911
1012 // メンバー追加関数
1113 const handleAddMember = ( ) => {
12- setMembers ( [ ...members , "" ] ) ;
14+ setMembers ( ( prev ) => [ ...prev , "" ] ) ;
1315 } ;
1416
1517 // 入力内容を更新する関数
@@ -21,37 +23,61 @@ export default function MemberList() {
2123
2224 // メンバー削除関数
2325 const handleDeleteMember = ( index : number ) => {
26+ // アラートの表示
27+ alert ( "本当に削除しますか" ) ;
28+
2429 // フィルターで指定index以外を残す
25- const updated = members . filter ( ( _ , i ) => i !== index ) ;
26- setMembers ( updated ) ;
30+ setMembers ( ( prev ) => prev . filter ( ( _ , i ) => i !== index ) ) ;
31+ } ;
32+
33+ const handleKeyDown = (
34+ e : React . KeyboardEvent < HTMLInputElement > ,
35+ index : number ,
36+ ) => {
37+ if ( e . key === "Enter" ) {
38+ e . preventDefault ( ) ;
39+
40+ // 最後の要素なら新しい入力欄を追加
41+ if ( index === members . length - 1 ) {
42+ handleAddMember ( ) ;
43+ } else {
44+ // 次の入力欄にフォーカス
45+ inputRefs . current [ index + 1 ] ?. focus ( ) ;
46+ }
47+ }
2748 } ;
2849
50+ // メンバー追加時に自動で新しい欄にフォーカス
51+ useEffect ( ( ) => {
52+ if ( inputRefs . current [ members . length - 1 ] ) {
53+ inputRefs . current [ members . length - 1 ] ?. focus ( ) ;
54+ }
55+ } , [ members . length ] ) ;
56+
2957 return (
30- < div style = { { padding : "10px" } } >
31- < h2 > メンバー一覧</ h2 >
58+ < div className = "p-4" >
59+ < h2 className = "mb-2 font-semibold text-xl" > メンバー一覧</ h2 >
3260
3361 { members . map ( ( member , index ) => (
34- < div
35- key = { index }
36- style = { {
37- marginBottom : "8px" ,
38- display : "flex" ,
39- alignItems : "center" ,
40- gap : "8px" ,
41- } }
42- >
62+ < div key = { index } className = "mb-2 flex items-center gap-2" >
4363 < Input
64+ //各inputを登録
65+ ref = { ( el ) => {
66+ inputRefs . current [ index ] = el ;
67+ } }
4468 type = "text"
4569 value = { member }
4670 placeholder = { `メンバー${ index + 1 } ` }
4771 onChange = { ( e ) => handleChange ( index , e . target . value ) }
72+ onKeyDown = { ( e ) => handleKeyDown ( e , index ) }
73+ className = "rounded-md border px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-400"
4874 />
4975
5076 { /* 削除ボタン */ }
5177 < Button
5278 onClick = { ( ) => handleDeleteMember ( index ) }
5379 variant = "destructive"
54- className = "cursor-pointer"
80+ className = "cursor-pointer hover:bg-red-700 "
5581 >
5682 削除
5783 </ Button >
@@ -62,7 +88,7 @@ export default function MemberList() {
6288 < Button
6389 onClick = { handleAddMember }
6490 variant = "outline"
65- className = "cursor-pointer"
91+ className = "mt-2 cursor-pointer"
6692 >
6793 < PlusIcon />
6894 メンバーを追加
0 commit comments