mirror of https://github.com/tauri-apps/tauri
fix(api/menu): fix submenus when created using an object in `items` field in the object passed to `Menu/Submenu.new` (#11441)
* fix(api/menu): fix submenus when created using an object in `items` field in the object passed to `Menu/Submenu.new` closes #11435 also closes #11422 as I included the docs in this PR * Update .changes/js-submenu-in-options.md * Update packages/api/src/menu/base.ts --------- Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.app>
This commit is contained in:
parent
ce864cebfd
commit
54cbf59b5a
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@tauri-apps/api": "patch:bug"
|
||||
---
|
||||
|
||||
Fix submenu created as a menu item instead of a submenu when created by using an object in the `items` field in the options object passed to `Menu.new` or `Submenu.new`.
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,10 @@ use crate::{image::Image, menu::*, Manager, Runtime};
|
|||
|
||||
/// A builder type for [`Menu`]
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **macOS**: if using [`MenuBuilder`] for the global menubar, it can only contain [`Submenu`]s
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
|
|
|
@ -147,6 +147,10 @@ macro_rules! gen_wrappers {
|
|||
gen_wrappers!(
|
||||
/// A type that is either a menu bar on the window
|
||||
/// on Windows and Linux or as a global menu in the menubar on macOS.
|
||||
///
|
||||
/// ## Platform-specific:
|
||||
///
|
||||
/// - **macOS**: if using [`Menu`] for the global menubar, it can only contain [`Submenu`]s
|
||||
Menu(MenuInner),
|
||||
/// A menu item inside a [`Menu`] or [`Submenu`] and contains only text.
|
||||
MenuItem(MenuItemInner, MenuItem),
|
||||
|
|
|
@ -300,12 +300,13 @@ impl PredefinedMenuItemPayload {
|
|||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
// Note, order matters for untagged enum deserialization
|
||||
enum MenuItemPayloadKind {
|
||||
ExistingItem((ResourceId, ItemKind)),
|
||||
Predefined(PredefinedMenuItemPayload),
|
||||
Check(CheckMenuItemPayload),
|
||||
Submenu(SubmenuPayload),
|
||||
Icon(IconMenuItemPayload),
|
||||
Submenu(SubmenuPayload),
|
||||
MenuItem(MenuItemPayload),
|
||||
}
|
||||
|
||||
|
|
|
@ -26,11 +26,11 @@ function injectChannel(
|
|||
| PredefinedMenuItemOptions
|
||||
| CheckMenuItemOptions
|
||||
):
|
||||
| MenuItemOptions
|
||||
| SubmenuOptions
|
||||
| IconMenuItemOptions
|
||||
| PredefinedMenuItemOptions
|
||||
| (CheckMenuItemOptions & { handler?: Channel<string> }) {
|
||||
| ((MenuItemOptions | IconMenuItemOptions | CheckMenuItemOptions) & {
|
||||
handler?: Channel<string>
|
||||
}) {
|
||||
if ('items' in i) {
|
||||
i.items = i.items?.map((item) =>
|
||||
'rid' in item ? item : injectChannel(item)
|
||||
|
@ -49,14 +49,7 @@ export async function newMenu(
|
|||
opts?: unknown
|
||||
): Promise<[number, string]> {
|
||||
const handler = new Channel<string>()
|
||||
let items: null | Array<
|
||||
| [number, string]
|
||||
| MenuItemOptions
|
||||
| SubmenuOptions
|
||||
| IconMenuItemOptions
|
||||
| PredefinedMenuItemOptions
|
||||
| CheckMenuItemOptions
|
||||
> = null
|
||||
|
||||
if (opts && typeof opts === 'object') {
|
||||
if ('action' in opts && opts.action) {
|
||||
handler.onmessage = opts.action as () => void
|
||||
|
@ -64,16 +57,21 @@ export async function newMenu(
|
|||
}
|
||||
|
||||
if ('items' in opts && opts.items) {
|
||||
items = (
|
||||
opts.items as Array<
|
||||
function prepareItem(
|
||||
i:
|
||||
| { rid: number; kind: string }
|
||||
| MenuItemOptions
|
||||
| SubmenuOptions
|
||||
| IconMenuItemOptions
|
||||
| PredefinedMenuItemOptions
|
||||
| CheckMenuItemOptions
|
||||
>
|
||||
).map((i) => {
|
||||
):
|
||||
| [number, string]
|
||||
| SubmenuOptions
|
||||
| PredefinedMenuItemOptions
|
||||
| MenuItemOptions
|
||||
| IconMenuItemOptions
|
||||
| CheckMenuItemOptions {
|
||||
if ('rid' in i) {
|
||||
return [i.rid, i.kind]
|
||||
}
|
||||
|
@ -86,14 +84,22 @@ export async function newMenu(
|
|||
i.icon = transformImage(i.icon)
|
||||
}
|
||||
|
||||
if ('items' in i && i.items) {
|
||||
// @ts-expect-error the `prepareItem` return doesn't exactly match
|
||||
// this is fine, because the difference is in `[number, string]` variant
|
||||
i.items = i.items.map(prepareItem)
|
||||
}
|
||||
|
||||
return injectChannel(i)
|
||||
})
|
||||
}
|
||||
|
||||
opts.items = (opts.items as []).map(prepareItem)
|
||||
}
|
||||
}
|
||||
|
||||
return invoke('plugin:menu|new', {
|
||||
kind,
|
||||
options: opts ? { ...opts, items } : undefined,
|
||||
options: opts,
|
||||
handler
|
||||
})
|
||||
}
|
||||
|
|
|
@ -133,6 +133,13 @@ export enum NativeIcon {
|
|||
export interface IconMenuItemOptions extends MenuItemOptions {
|
||||
/**
|
||||
* Icon to be used for the new icon menu item.
|
||||
*
|
||||
* Note that you may need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* To enable it, change your Cargo.toml file:
|
||||
* ```toml
|
||||
* [dependencies]
|
||||
* tauri = { version = "...", features = ["...", "image-png"] }
|
||||
* ```
|
||||
*/
|
||||
icon?: NativeIcon | string | Image | Uint8Array | ArrayBuffer | number[]
|
||||
}
|
||||
|
|
|
@ -68,6 +68,10 @@ export interface MenuOptions {
|
|||
|
||||
/** A type that is either a menu bar on the window
|
||||
* on Windows and Linux or as a global menu in the menubar on macOS.
|
||||
*
|
||||
* #### Platform-specific:
|
||||
*
|
||||
* - **macOS**: if using {@linkcode Menu} for the global menubar, it can only contain {@linkcode Submenu}s.
|
||||
*/
|
||||
export class Menu extends MenuItemBase {
|
||||
/** @ignore */
|
||||
|
|
|
@ -79,7 +79,7 @@ export interface TrayIconOptions {
|
|||
/**
|
||||
* The tray icon which could be icon bytes or path to the icon file.
|
||||
*
|
||||
* Note that you need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* Note that you may need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* To enable it, change your Cargo.toml file:
|
||||
* ```toml
|
||||
* [dependencies]
|
||||
|
@ -196,7 +196,7 @@ export class TrayIcon extends Resource {
|
|||
/**
|
||||
* Sets a new tray icon. If `null` is provided, it will remove the icon.
|
||||
*
|
||||
* Note that you need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* Note that you may need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* To enable it, change your Cargo.toml file:
|
||||
* ```toml
|
||||
* [dependencies]
|
||||
|
|
|
@ -1463,7 +1463,7 @@ class Window {
|
|||
* await getCurrentWindow().setIcon('/tauri/awesome.png');
|
||||
* ```
|
||||
*
|
||||
* Note that you need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* Note that you may need the `image-ico` or `image-png` Cargo features to use this API.
|
||||
* To enable it, change your Cargo.toml file:
|
||||
* ```toml
|
||||
* [dependencies]
|
||||
|
|
Loading…
Reference in New Issue