main.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env python3
  2. from dataclasses import dataclass
  3. from nicegui import ui
  4. @dataclass
  5. class TodoItem:
  6. name: str
  7. done: bool = False
  8. items: list[TodoItem] = [
  9. TodoItem('Buy milk', done=True),
  10. TodoItem('Clean the house'),
  11. TodoItem('Call mom'),
  12. ]
  13. def add(name: str) -> None:
  14. items.append(TodoItem(name))
  15. add_input.value = None
  16. render_list.refresh()
  17. def remove(item: TodoItem) -> None:
  18. items.remove(item)
  19. render_list.refresh()
  20. def toggle(item: TodoItem) -> None:
  21. item.done = not item.done
  22. render_list.refresh()
  23. def rename(item: TodoItem, name: str) -> None:
  24. item.name = name
  25. render_list.refresh()
  26. with ui.card().classes('w-80 items-stretch'):
  27. ui.label('Todo list').classes('text-semibold text-2xl')
  28. add_input = ui.input('New item')
  29. add_input.on('keydown.enter', lambda: add(add_input.value))
  30. @ui.refreshable
  31. def render_list():
  32. if not items:
  33. ui.label('List is empty.')
  34. return
  35. ui.linear_progress(sum(item.done for item in items) / len(items), show_value=False)
  36. with ui.row():
  37. ui.label(f'Completed: {sum(item.done for item in items)}')
  38. ui.label(f'Remaining: {sum(not item.done for item in items)}')
  39. for item in items:
  40. with ui.row().classes('items-center'):
  41. ui.checkbox(value=item.done, on_change=lambda _, item=item: toggle(item))
  42. input = ui.input(value=item.name).classes('flex-grow')
  43. input.on('keydown.enter', lambda _, item=item, input=input: rename(item, input.value))
  44. ui.button(on_click=lambda _, item=item: remove(item)).props('flat fab-mini icon=delete color=grey')
  45. render_list()
  46. ui.run()