mirror of
https://github.com/tauri-apps/tauri-docs.git
synced 2026-01-31 00:35:16 +01:00
Add comprehensive system tray menu and submenu icon examples to documentation (#3393)
Co-authored-by: Vitor Ayres <gitkey@virtuaires.com.br> Co-authored-by: Tony <legendmastertony@gmail.com>
This commit is contained in:
@@ -308,6 +308,8 @@ See [`TrayIconEvent`][rust TrayIconEvent] for more information on the event type
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
For detailed information about creating menus, including menu items, submenus, and dynamic updates, see the [Window Menu](/learn/window-menu/) documentation.
|
||||
|
||||
[`TrayIcon.new`]: /reference/javascript/api/namespacetray/#new
|
||||
[`TrayIconOptions`]: /reference/javascript/api/namespacetray/#trayiconoptions
|
||||
[`TrayIconBuilder`]: https://docs.rs/tauri/2.0.0/tauri/tray/struct.TrayIconBuilder.html
|
||||
|
||||
@@ -121,19 +121,34 @@ Put this at the top of your `<body>` tag:
|
||||
<div class="controls">
|
||||
<button id="titlebar-minimize" title="minimize">
|
||||
<!-- https://api.iconify.design/mdi:window-minimize.svg -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path fill="currentColor" d="M19 13H5v-2h14z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button id="titlebar-maximize" title="maximize">
|
||||
<!-- https://api.iconify.design/mdi:window-maximize.svg -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path fill="currentColor" d="M4 4h16v16H4zm2 4v10h12V8z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button id="titlebar-close" title="close">
|
||||
<!-- https://api.iconify.design/mdi:close.svg -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M13.46 12L19 17.54V19h-1.46L12 13.46L6.46 19H5v-1.46L10.54 12L5 6.46V5h1.46L12 10.54L17.54 5H19v1.46z"
|
||||
|
||||
@@ -11,7 +11,7 @@ Native application menus can be attached to both to a window or system tray. Ava
|
||||
|
||||
## Creating a base-level menu
|
||||
|
||||
To create a base-level native window menu, and attach to a window:
|
||||
To create a base-level native window menu, and attach to a window. You can create various types of menu items including basic items, check items, and separators:
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="JavaScript">
|
||||
@@ -30,13 +30,36 @@ const menu = await Menu.new({
|
||||
console.log('quit pressed');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'check_item',
|
||||
text: 'Check Item',
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
type: 'Separator',
|
||||
},
|
||||
{
|
||||
id: 'disabled_item',
|
||||
text: 'Disabled Item',
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
text: 'Status: Processing...',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// If a window was not created with an explicit menu or had one set explicitly,
|
||||
// this menu will be assigned to it.
|
||||
menu.setAsAppMenu().then((res) => {
|
||||
menu.setAsAppMenu().then(async (res) => {
|
||||
console.log('menu set success', res);
|
||||
|
||||
// Update individual menu item text
|
||||
const statusItem = await menu.get('status');
|
||||
if (statusItem) {
|
||||
await statusItem.setText('Status: Ready');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
@@ -45,21 +68,32 @@ menu.setAsAppMenu().then((res) => {
|
||||
<TabItem label="Rust">
|
||||
|
||||
```rust
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
use tauri::menu::{MenuBuilder};
|
||||
use tauri::menu::MenuBuilder;
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
let menu = MenuBuilder::new(app)
|
||||
.text("open", "Open")
|
||||
.text("close", "Close")
|
||||
.check("check_item", "Check Item")
|
||||
.separator()
|
||||
.text("disabled_item", "Disabled Item")
|
||||
.text("status", "Status: Processing...")
|
||||
.build()?;
|
||||
|
||||
app.set_menu(menu)?;
|
||||
app.set_menu(menu.clone())?;
|
||||
|
||||
// Update individual menu item text
|
||||
menu
|
||||
.get("status")
|
||||
.unwrap()
|
||||
.as_menuitem_unchecked()
|
||||
.set_text("Status: Ready")?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!());
|
||||
}
|
||||
```
|
||||
|
||||
@@ -147,6 +181,10 @@ Multi-level menus allow you to group menu items under categories like "File," "E
|
||||
|
||||
**Note:** When using submenus on MacOS, all items must be grouped under a submenu. Top-level items will be ignored. Additionally, the first submenu will be placed under the application's about menu by default, regardless of the `text` label. You should include a submenu as the first entry (say, an "About" submenu) to fill this space.
|
||||
|
||||
:::note
|
||||
Icon support for submenus is available since Tauri 2.8.0.
|
||||
:::
|
||||
|
||||
<Tabs>
|
||||
<TabItem label="JavaScript">
|
||||
|
||||
@@ -169,6 +207,7 @@ const aboutSubmenu = await Submenu.new({
|
||||
|
||||
const fileSubmenu = await Submenu.new({
|
||||
text: 'File',
|
||||
icon: 'folder', // Optional: Add an icon to the submenu
|
||||
items: [
|
||||
await MenuItem.new({
|
||||
id: 'new',
|
||||
@@ -219,6 +258,11 @@ const menu = await Menu.new({
|
||||
});
|
||||
|
||||
menu.setAsAppMenu();
|
||||
|
||||
// You can also update the submenu icon dynamically
|
||||
fileSubmenu.setIcon('document');
|
||||
// Or set a native icon (only one type applies per platform)
|
||||
fileSubmenu.setNativeIcon('NSFolder');
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -226,12 +270,17 @@ menu.setAsAppMenu();
|
||||
<TabItem label="Rust">
|
||||
|
||||
```rust
|
||||
use tauri::menu::{CheckMenuItemBuilder, MenuBuilder, SubmenuBuilder};
|
||||
use tauri::{
|
||||
image::Image,
|
||||
menu::{CheckMenuItemBuilder, IconMenuItemBuilder, MenuBuilder, SubmenuBuilder},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
let menu_image = Image::from_bytes(include_bytes!("../icons/menu.png")).unwrap();
|
||||
let file_menu = SubmenuBuilder::new(app, "File")
|
||||
.submenu_icon(menu_image)) // Optional: Add an icon to the submenu
|
||||
.text("open", "Open")
|
||||
.text("quit", "Quit")
|
||||
.build()?;
|
||||
@@ -248,7 +297,7 @@ fn main() {
|
||||
.enabled(false)
|
||||
.build(app)?;
|
||||
|
||||
// Load icon from path
|
||||
// Load icon from path
|
||||
let icon_image = Image::from_bytes(include_bytes!("../icons/icon.png")).unwrap();
|
||||
|
||||
let icon_item = IconMenuItemBuilder::new("icon")
|
||||
@@ -261,13 +310,21 @@ fn main() {
|
||||
.build()?;
|
||||
|
||||
let menu = MenuBuilder::new(app)
|
||||
.items(&[&file_menu, &other_item,&icon_item])
|
||||
.items(&[&file_menu, &other_item, &icon_item])
|
||||
.build()?;
|
||||
|
||||
app.set_menu(menu)?;
|
||||
|
||||
let menu_image_update =
|
||||
Image::from_bytes(include_bytes!("../icons/menu_update.png")).unwrap();
|
||||
// You can also update the submenu icon dynamically
|
||||
file_menu.set_icon(Some(menu_image_update))?;
|
||||
// Or set a native icon (only one type applies per platform)
|
||||
file_menu.set_native_icon(Some(tauri::menu::NativeIcon::Folder))?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!());
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user