MenuBarExtra
组件可用于创建填充 macOS 菜单栏 附加 部分的命令。
起步
如果您还没有扩展,请按照 入门 指南操作,然后返回此页面。现在您的扩展已准备就绪,让我们打开其 package.json
文件并向其 commands
数组添加一个新条目,确保其 mode
属性设置为 menu-bar
。对于本指南,我们添加以下内容:
复制 {
"name": "github-pull-requests",
"title": "Pull Requests",
"subtitle": "GitHub",
"description": "See your GitHub pull requests at a glance",
"mode": "menu-bar"
},
在扩展 src/
文件夹中创建 github-pull-requests.tsx
并添加以下内容:
复制 import { MenuBarExtra } from "@raycast/api";
export default function Command() {
return (
<MenuBarExtra icon="https://github.githubassets.com/favicons/favicon.png" tooltip="Your Pull Requests">
<MenuBarExtra.Item title="Seen" />
<MenuBarExtra.Item
title="Example Seen Pull Request"
onAction={() => {
console.log("seen pull request clicked");
}}
/>
<MenuBarExtra.Item title="Unseen" />
<MenuBarExtra.Item
title="Example Unseen Pull Request"
onAction={() => {
console.log("unseen pull request clicked");
}}
/>
</MenuBarExtra>
);
}
如果您的本地服务器正在运行,该命令应该出现在您的根搜索中,并且运行该命令应该会导致 GitHub
图标出现在您的菜单栏中。
当然,如果我们每次都必须告诉它自行更新,那么我们的拉取请求命令就没有多大用处。要向我们的命令添加后台刷新,我们需要打开之前修改的 package.json
文件,并向命令配置对象添加一个 interval
键:
复制 {
"name": "github-pull-requests",
"title": "Pull Requests",
"subtitle": "GitHub",
"description": "See your GitHub pull requests at a glance",
"mode": "menu-bar",
"interval": "5m"
}
您的根搜索应类似于:
运行一次应该将其激活为:
生命周期
尽管 menu-bar
命令可能会导致项目永久显示在 macOS 菜单栏中,但它们并不是长期存在的进程。相反,与其他命令一样,Raycast 根据需要将它们加载到内存中,执行它们的代码,然后尝试在下一个方便的时间卸载它们。有五个不同的事件可以让菜单栏的项目被放置在菜单栏中,所以让我们逐一介绍一下。
从根搜索
与任何其他命令一样,menu-bar
命令可以直接从 Raycast 的根搜索运行。最终,菜单栏中会显示一个新项目(如果您有足够的空间并且命令返回 MenuBarExtra
),或者如果命令返回 null
,则上一个项目消失。在这种情况下,Raycast 会加载您的命令代码,执行它,等待 MenuBarExtra
的 isLoading
属性切换为 false
,然后卸载命令。
如果您的命令返回 MenuBarExtra
,那么它不能设置 isLoading
- 在这种情况下,Raycast 将渲染并立即更新命令,或者在执行异步任务(例如 API 调用)时将其设置为 true
,当异步任务完成后将其立即立即设置为 false
。与上面相同,Raycast 将加载命令代码,执行它,等待 MenuBarExtra
的 isLoading
属性切换为 false
,然后卸载命令。
按设定的时间间隔
如果您的 menu-bar
命令使用并且激活了 后台刷新 ,Raycast 将按设定的时间间隔运行该命令。在您的命令中,您可以使用 environment.launchType
来检查它是在后台启动还是由用户启动。
当用户单击菜单栏中命令的图标/标题时
view
命令或 no-view
命令的最大区别之一是 menu-bar
命令有一个额外的入口:当用户单击菜单栏中的项目时。如果该项目有一个菜单(即 MenuBarExtra
提供至少一个子菜单),Raycast 将加载命令代码,执行它并在菜单打开时将其保留在内存中。当菜单关闭时(通过用户单击外部或通过单击 MenuBarExtra.Item
),命令将被卸载。
当 Raycast 重新启动时
这种情况假设您的命令至少运行过一次,导致菜单栏中放置了一个项目。如果是这种情况,退出并再次启动 Raycast 应该会在菜单栏中放置相同的项目。不过,该项目会从 Raycast 的数据库中恢复 - 而不是通过加载和执行命令来恢复。
当在首选项中重新启用菜单栏命令时
这种情况应该与 Raycast 重新启动时的工作方式相同。
最佳实践
确保命令完成执行后将 isLoading
设置为 false
避免在 MenuBarExtra
, MenuBarExtra.Submenu
或 MenuBarExtra.Item
中设置长标题
不要将相同的 MenuBarExtra.Items
放在同一级别(MenuBarExtra
的直接子项或同一子菜单中),因为它们的 onAction
处理程序将无法正确执行
API 参考
将一个项目添加到菜单栏,如果其 children
属性非空,则可以选择附加菜单。
例子
复制 import { Icon, MenuBarExtra, open } from "@raycast/api";
const data = {
archivedBookmarks: [{ name: "Google Search", url: "www.google.com" }],
newBookmarks: [{ name: "Raycast", url: "www.raycast.com" }],
};
export default function Command() {
return (
<MenuBarExtra icon={Icon.Bookmark}>
<MenuBarExtra.Section title="New">
{data?.newBookmarks.map((bookmark) => (
<MenuBarExtra.Item key={bookmark.url} title={bookmark.name} onAction={() => open(bookmark.url)} />
))}
</MenuBarExtra.Section>
<MenuBarExtra.Section title="Archived">
{data?.archivedBookmarks.map((bookmark) => (
<MenuBarExtra.Item key={bookmark.url} title={bookmark.name} onAction={() => open(bookmark.url)} />
))}
</MenuBarExtra.Section>
</MenuBarExtra>
);
}
参数
MenuBarExtra.Item
s, MenuBarExtra.Submenu
s, MenuBarExtra.Separator
或两者的混合
提示 Raycast 不应卸载该命令,因为它仍在执行。如果您设置使用 isLoading
,则需要确保在正在执行的任务(例如 API 调用)结束时将其设置为 false
,以便 Raycast 可以卸载该命令。
MenuBarExtra 或 MenuBarExtra.Submenu 中的一项
例子
ItemWithTitle.tsx ItemWithTitleAndIcon.tsx ItemWithAction.tsx
仅提供 title
属性的项目将被渲染为禁用。使用它来创建章节标题。
复制 import { Icon, MenuBarExtra } from "@raycast/api";
export default function Command() {
return (
<MenuBarExtra icon={Icon.Bookmark}>
<MenuBarExtra.Item title="Raycast.com" />
</MenuBarExtra>
);
}
同样,提供 title
和 icon
的也将表现为禁用。
复制 import { Icon, MenuBarExtra } from "@raycast/api";
export default function Command() {
return (
<MenuBarExtra icon={Icon.Bookmark}>
<MenuBarExtra.Item icon="raycast.png" title="Raycast.com" />
</MenuBarExtra>
);
}
与 title
(以及可选的 icon
)一起提供 onAction
属性的项目不会表现为禁用。当用户单击菜单栏中的此项时,将执行操作处理程序。
复制 import { Icon, MenuBarExtra, open } from "@raycast/api";
export default function Command() {
return (
<MenuBarExtra icon={Icon.Bookmark}>
<MenuBarExtra.Item icon="raycast.png" title="Raycast.com" onAction={() => open("https://raycast.com")} />
</MenuBarExtra>
);
}
属性
MenuBarExtra.Submenus
在人们与它交互时展示出来。它们可以分组,但请记住,子菜单会增加界面的复杂性 - 因此请谨慎使用它们!
Example
Bookmarks.tsx
复制 import { Icon, MenuBarExtra, open } from "@raycast/api";
export default function Command() {
return (
<MenuBarExtra icon={Icon.Bookmark}>
<MenuBarExtra.Item icon="raycast.png" title="Raycast.com" onAction={() => open("https://raycast.com")} />
<MenuBarExtra.Submenu icon="github.png" title="GitHub">
<MenuBarExtra.Item title="Pull Requests" onAction={() => open("https://github.com/pulls")} />
<MenuBarExtra.Item title="Issues" onAction={() => open("https://github.com/issues")} />
</MenuBarExtra.Submenu>
<MenuBarExtra.Submenu title="Disabled"></MenuBarExtra.Submenu>
</MenuBarExtra>
);
}
参数
MenuBarExtra.Item
s, MenuBarExtra.Submenu
s, MenuBarExtra.Separator
或两者的混合
用于对相关菜单项进行分组的项。它有一个可选的标题,并且在各部分之间自动添加分隔符。
例子
复制 import { Icon, MenuBarExtra, open } from "@raycast/api";
const data = {
archivedBookmarks: [{ name: "Google Search", url: "www.google.com" }],
newBookmarks: [{ name: "Raycast", url: "www.raycast.com" }],
};
export default function Command() {
return (
<MenuBarExtra icon={Icon.Bookmark}>
<MenuBarExtra.Section title="New">
{data?.newBookmarks.map((bookmark) => (
<MenuBarExtra.Item key={bookmark.url} title={bookmark.name} onAction={() => open(bookmark.url)} />
))}
</MenuBarExtra.Section>
<MenuBarExtra.Section title="Archived">
{data?.archivedBookmarks.map((bookmark) => (
<MenuBarExtra.Item key={bookmark.url} title={bookmark.name} onAction={() => open(bookmark.url)} />
))}
</MenuBarExtra.Section>
</MenuBarExtra>
);
}
属性
类型
回调中描述 Action 事件的接口。
属性
"left-click"
或 "right-click"
例子
复制 import { MenuBarExtra } from "@raycast/api";
export default function Command() {
return (
<MenuBarExtra>
<MenuBarExtra.Item
title="Log Action Event Type"
onAction={(event: MenuBarExtra.ActionEvent) => console.log("Action Event Type", event.type)}
/>
</MenuBarExtra>
);
}