()
| 71 | |
| 72 | @ft.component |
| 73 | def TodoAppView(): |
| 74 | state, _ = ft.use_state(lambda: TodoAppState()) |
| 75 | new_task_name, set_new_task_name = ft.use_state("") |
| 76 | new_task_field: ft.Ref = ft.Ref() |
| 77 | |
| 78 | async def add_task(): |
| 79 | state.add_task(new_task_name) |
| 80 | set_new_task_name("") |
| 81 | await cast(ft.TextField, new_task_field.current).focus() |
| 82 | |
| 83 | return ft.View( |
| 84 | scroll=ft.ScrollMode.AUTO, |
| 85 | controls=[ |
| 86 | ft.SafeArea( |
| 87 | content=ft.Column( |
| 88 | [ |
| 89 | Header(), |
| 90 | ft.Row( |
| 91 | controls=[ |
| 92 | ft.TextField( |
| 93 | ref=new_task_field, |
| 94 | hint_text="What needs to be done?", |
| 95 | on_submit=add_task, |
| 96 | value=new_task_name, |
| 97 | on_change=lambda e: set_new_task_name( |
| 98 | e.control.value |
| 99 | ), |
| 100 | autofocus=True, |
| 101 | expand=True, |
| 102 | ), |
| 103 | ft.FloatingActionButton( |
| 104 | icon=ft.Icons.ADD, |
| 105 | on_click=add_task, |
| 106 | ), |
| 107 | ], |
| 108 | ), |
| 109 | ft.Column( |
| 110 | spacing=25, |
| 111 | controls=[ |
| 112 | ft.Tabs( |
| 113 | selected_index=state.statuses.index(state.status), |
| 114 | length=len(state.statuses), |
| 115 | on_change=state.status_changed, |
| 116 | content=ft.TabBar( |
| 117 | scrollable=False, |
| 118 | tabs=[ |
| 119 | ft.Tab(label=tab) for tab in state.statuses |
| 120 | ], |
| 121 | ), |
| 122 | ), |
| 123 | ft.Column( |
| 124 | [ |
| 125 | TaskItemView( |
| 126 | task, |
| 127 | state.delete_task, |
| 128 | key=task.id, |
| 129 | ) |
| 130 | for task in state.get_tasks() |
nothing calls this directly
no test coverage detected