{"id":13598509,"url":"https://github.com/shuoli84/tui-menu","last_synced_at":"2025-12-30T15:58:47.012Z","repository":{"id":63922171,"uuid":"571645765","full_name":"shuoli84/tui-menu","owner":"shuoli84","description":"A menu widget for tui-rs ecosystem","archived":false,"fork":false,"pushed_at":"2025-01-13T20:04:38.000Z","size":56,"stargazers_count":32,"open_issues_count":2,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-10T01:03:40.203Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shuoli84.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-28T15:23:20.000Z","updated_at":"2025-03-25T12:40:17.000Z","dependencies_parsed_at":"2024-04-03T03:32:04.145Z","dependency_job_id":"b6cf3234-f06a-4879-b73e-e3f63853ea11","html_url":"https://github.com/shuoli84/tui-menu","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuoli84%2Ftui-menu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuoli84%2Ftui-menu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuoli84%2Ftui-menu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuoli84%2Ftui-menu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shuoli84","download_url":"https://codeload.github.com/shuoli84/tui-menu/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248191700,"owners_count":21062555,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T17:00:53.192Z","updated_at":"2025-12-25T13:04:02.112Z","avatar_url":"https://github.com/shuoli84.png","language":"Rust","funding_links":[],"categories":["📦 Libraries"],"sub_categories":["🧩 Widgets"],"readme":"# tui-menu\n\nA menu widget for [Ratatui](https://crates.io/crates/ratatui).\n\n![Demo](https://vhs.charm.sh/vhs-73WyYtjPZG8s9uOuEspiD7.gif)\n## Features\n\n- Sub menu groups.\n- Intuitive movement.\n- Item's data is generic as long as it ```Clone```able.\n\n## Try\n\n``` bash\ncargo run --example basic\n```\n\n## Example\n\ntake a look at examples/basic.rs\n\n### Render\n\n```rust\n// menu should be draw at last, so it can stay on top of other content\nlet menu = Menu::new();\nframe.render_stateful_widget(menu, chunks[0], \u0026mut app.menu);\n```\n\n### Create nested menu tree\n\nNote: MenuItems can be created from any type that implements `Clone`. Using an enum is just one\noption which can work. You could use strings or your own state types.\n\n```rust\n#[derive(Debug, Clone)]\nenum Action {\n    FileNew,\n    FileOpen,\n    FileOpenRecent(String),\n    FileSaveAs,\n    Exit,\n    EditCopy,\n    EditCut,\n    EditPaste,\n    AboutAuthor,\n    AboutHelp,\n}\n\nlet menu = MenuState::new(vec![\n    MenuItem::group(\n        \"File\",\n        vec![\n            MenuItem::item(\"New\", Action::FileNew),\n            MenuItem::item(\"Open\", Action::FileOpen),\n            MenuItem::group(\n                \"Open recent\",\n                [\"file_1.txt\", \"file_2.txt\"]\n                    .iter()\n                    .map(|\u0026f| MenuItem::item(f, Action::FileOpenRecent(f.into())))\n                    .collect(),\n            ),\n            MenuItem::item(\"Save as\", Action::FileSaveAs),\n            MenuItem::item(\"Exit\", Action::Exit),\n        ],\n    ),\n    MenuItem::group(\n        \"Edit\",\n        vec![\n            MenuItem::item(\"Copy\", Action::EditCopy),\n            MenuItem::item(\"Cut\", Action::EditCut),\n            MenuItem::item(\"Paste\", Action::EditPaste),\n        ],\n    ),\n    MenuItem::group(\n        \"About\",\n        vec![\n            MenuItem::item(\"Author\", Action::AboutAuthor),\n            MenuItem::item(\"Help\", Action::AboutHelp),\n        ],\n    ),\n]),\n```\n\n### Consume events\n\n``` rust\nfor e in menu.drain_events() {\n    match e {\n        MenuEvent::Selected(item) =\u003e match item {\n            Action::Exit =\u003e {\n                return Ok(());\n            }\n            Action::FileNew =\u003e {\n                self.content.clear();\n            }\n            Action::FileOpenRecent(file) =\u003e {\n                self.content = format!(\"content of {file}\");\n            }\n            action =\u003e {\n                self.content = format!(\"{action:?} not implemented\");\n            }\n        },\n    }\n    // close the menu once the event has been handled.\n    menu.reset();\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuoli84%2Ftui-menu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshuoli84%2Ftui-menu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuoli84%2Ftui-menu/lists"}