```
import flet as ft
from flet import Icons


class RemovableTextInput(ft.Card):
    def __init__(self, on_delete=None, on_duplicate=None, **kwargs):
        super().__init__(expand=True)
        self.on_delete = on_delete
        self.on_duplicate = on_duplicate

        self.title_field = ft.TextField(hint_text="タイトル", expand=True, **kwargs)
        self.content_field = ft.TextField(hint_text="内容", multiline=True, expand=True, **kwargs)

        duplicate_button = ft.IconButton(
            icon=Icons.COPY_OUTLINED,
            tooltip="コピー",
            on_click=self._on_duplicate_click,
        )

        delete_button = ft.IconButton(
            icon=Icons.CLOSE,
            icon_size=20,
            tooltip="削除",
            on_click=self._on_delete_click,
        )

        self.content = ft.Row(
            controls=[
                ft.Column(
                    controls=[self.title_field, self.content_field, ],
                    expand=True
                ),
                ft.Column(
                    controls=[duplicate_button, delete_button, ],
                )
            ],
            spacing=5,
        )

    def _on_delete_click(self, e):
        if self.on_delete:
            self.on_delete(self)

    def _on_duplicate_click(self, e):
        if self.on_duplicate:
            self.on_duplicate(self)

    def get_values(self):
        return {
            "title": self.title_field.value,
            "content": self.content_field.value
        }


def main(page: ft.Page):
    page.title = "削除可能なTextField"
    page.padding = 20

    field_container = ft.Column(spacing=10)

    # 削除確認ダイアログ
    def confirm_delete(field):
        def close_dialog(e):
            dialog.open = False
            page.update()

        def yes_click(e):
            field_container.controls.remove(field)
            dialog.open = False
            page.update()

        dialog = ft.AlertDialog(
            modal=True,
            title=ft.Text("削除の確認"),
            content=ft.Text("このフィールドを削除してもよろしいですか？"),
            actions=[
                ft.TextButton("いいえ", on_click=close_dialog),
                ft.TextButton("はい", on_click=yes_click),
            ],
            actions_alignment=ft.MainAxisAlignment.END,
        )

        page.overlay.append(dialog)
        dialog.open = True
        page.update()

    def duplicate_field(field):
        values = field.get_values()
        new_field = RemovableTextInput(
            on_delete=confirm_delete,
            on_duplicate=duplicate_field
        )
        new_field.title_field.value = values["title"]
        new_field.content_field.value = values["content"]

        # 元のフィールドの次に挿入
        index = field_container.controls.index(field)
        field_container.controls.insert(index + 1, new_field)
        page.update()

    def add_field(e):
        new_field = RemovableTextInput(
            on_delete=confirm_delete,
            on_duplicate=duplicate_field
        )
        field_container.controls.append(new_field)
        page.update()

    # 初期フィールドを3つ追加
    for _ in range(3):
        field_container.controls.append(
            RemovableTextInput(
                on_delete=confirm_delete,
                on_duplicate=duplicate_field
            )
        )

    page.add(
        ft.Text(
            "Xボタンでフィールドを削除",
            size=20,
            weight=ft.FontWeight.BOLD
        ),
        field_container,
        ft.ElevatedButton("フィールドを追加", on_click=add_field),
    )


ft.app(target=main)
```

```
`RemovableTextInput`の左にハンドルをつけて、D&Dで入れ替えられるようにしたい。 他の`RemovableTextInput`の上にドロップするのではなく、ドロップした位置に応じて入れ替わるように。ドラッグ中もリアルタイムで入れ替えを行い、ドロップで確定するタイプ。
```