refactor(desktop): render shell menu items directly
Call renderActionItem instead of declaring an Item component inside shellSections, which minted a new component type on every render and remounted the menu rows. Restore the tree-group file doc comment above its imports.
This commit is contained in:
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
|
||||
import { toggleTargetZoneTabStrip } from '@/components/pane-shell/tree/store'
|
||||
import { type ActionItemSpec, type MenuKit, renderActionItem } from '@/components/ui/actions-menu'
|
||||
import { type MenuKit, renderActionItem } from '@/components/ui/actions-menu'
|
||||
import { type Translations, useI18n } from '@/i18n'
|
||||
import { openCommandPalette } from '@/store/command-palette'
|
||||
import { toggleProfileRailVisible } from '@/store/profile-rail-prefs'
|
||||
@@ -19,34 +19,26 @@ function shellSections(
|
||||
t: Translations,
|
||||
primaryOnly: boolean
|
||||
): ReactNode[][] {
|
||||
const Item = ({ icon, label, onSelect }: ActionItemSpec) => renderActionItem(kit, { icon, label, onSelect })
|
||||
const newChat = renderActionItem(kit, {
|
||||
icon: 'add',
|
||||
key: 'shell-new-chat',
|
||||
label: t.commandCenter.nav.newChat.title,
|
||||
onSelect: () => navigateToWorkspacePage(navigate, NEW_CHAT_ROUTE)
|
||||
})
|
||||
|
||||
const newChat = (
|
||||
<Item
|
||||
icon="add"
|
||||
key="shell-new-chat"
|
||||
label={t.commandCenter.nav.newChat.title}
|
||||
onSelect={() => navigateToWorkspacePage(navigate, NEW_CHAT_ROUTE)}
|
||||
/>
|
||||
)
|
||||
const settings = renderActionItem(kit, {
|
||||
icon: 'settings-gear',
|
||||
key: 'shell-settings',
|
||||
label: t.commandCenter.settings,
|
||||
onSelect: () => navigateToWorkspacePage(navigate, SETTINGS_ROUTE)
|
||||
})
|
||||
|
||||
const settings = (
|
||||
<Item
|
||||
icon="settings-gear"
|
||||
key="shell-settings"
|
||||
label={t.commandCenter.settings}
|
||||
onSelect={() => navigateToWorkspacePage(navigate, SETTINGS_ROUTE)}
|
||||
/>
|
||||
)
|
||||
|
||||
const update = (
|
||||
<Item
|
||||
icon="cloud-download"
|
||||
key="shell-update"
|
||||
label={t.commandCenter.updateHermes}
|
||||
onSelect={requestActiveUpdate}
|
||||
/>
|
||||
)
|
||||
const update = renderActionItem(kit, {
|
||||
icon: 'cloud-download',
|
||||
key: 'shell-update',
|
||||
label: t.commandCenter.updateHermes,
|
||||
onSelect: requestActiveUpdate
|
||||
})
|
||||
|
||||
if (primaryOnly) {
|
||||
return [[newChat, settings, update]]
|
||||
@@ -55,38 +47,43 @@ function shellSections(
|
||||
return [
|
||||
[
|
||||
newChat,
|
||||
canOpenNewWindow() ? (
|
||||
<Item
|
||||
icon="multiple-windows"
|
||||
key="shell-new-window"
|
||||
label={t.keybinds.actions['session.newWindow']}
|
||||
onSelect={() => void openNewWindow()}
|
||||
/>
|
||||
) : null,
|
||||
<Item icon="search" key="shell-palette" label={t.commandCenter.paletteTitle} onSelect={openCommandPalette} />
|
||||
canOpenNewWindow()
|
||||
? renderActionItem(kit, {
|
||||
icon: 'multiple-windows',
|
||||
key: 'shell-new-window',
|
||||
label: t.keybinds.actions['session.newWindow'],
|
||||
onSelect: () => void openNewWindow()
|
||||
})
|
||||
: null,
|
||||
renderActionItem(kit, {
|
||||
icon: 'search',
|
||||
key: 'shell-palette',
|
||||
label: t.commandCenter.paletteTitle,
|
||||
onSelect: openCommandPalette
|
||||
})
|
||||
].filter(Boolean),
|
||||
[
|
||||
<Item
|
||||
icon="layout-statusbar"
|
||||
key="shell-statusbar"
|
||||
label={t.keybinds.actions['view.toggleStatusbar']}
|
||||
onSelect={toggleStatusbarVisible}
|
||||
/>,
|
||||
<Item
|
||||
icon="organization"
|
||||
key="shell-profile-rail"
|
||||
label={t.keybinds.actions['view.toggleProfileRail']}
|
||||
onSelect={toggleProfileRailVisible}
|
||||
/>,
|
||||
renderActionItem(kit, {
|
||||
icon: 'layout-statusbar',
|
||||
key: 'shell-statusbar',
|
||||
label: t.keybinds.actions['view.toggleStatusbar'],
|
||||
onSelect: toggleStatusbarVisible
|
||||
}),
|
||||
renderActionItem(kit, {
|
||||
icon: 'organization',
|
||||
key: 'shell-profile-rail',
|
||||
label: t.keybinds.actions['view.toggleProfileRail'],
|
||||
onSelect: toggleProfileRailVisible
|
||||
}),
|
||||
// The pointer-only way back to a hidden tab strip: right-clicking the
|
||||
// shell reaches this menu from anywhere, including a zone that has no
|
||||
// chrome left to right-click.
|
||||
<Item
|
||||
icon="layout-menubar"
|
||||
key="shell-tabstrip"
|
||||
label={t.keybinds.actions['view.toggleTabStrip']}
|
||||
onSelect={() => void toggleTargetZoneTabStrip()}
|
||||
/>,
|
||||
renderActionItem(kit, {
|
||||
icon: 'layout-menubar',
|
||||
key: 'shell-tabstrip',
|
||||
label: t.keybinds.actions['view.toggleTabStrip'],
|
||||
onSelect: () => void toggleTargetZoneTabStrip()
|
||||
}),
|
||||
settings
|
||||
],
|
||||
[update]
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useStore } from '@nanostores/react'
|
||||
/**
|
||||
* Group node renderer — a ZONE: header strip (tabs when stacked, minimize
|
||||
* chevron) + the active pane's content, resolved from the contribution
|
||||
@@ -9,6 +8,8 @@ import { useStore } from '@nanostores/react'
|
||||
* every zone lights up as a whole-region drop target. Right-click opens the
|
||||
* contextual zone menu (tab close verbs + header/minimize toggles).
|
||||
*/
|
||||
|
||||
import { useStore } from '@nanostores/react'
|
||||
import { type CSSProperties, Fragment, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { ShellMenuItems } from '@/app/context-menu/shell-menu-items'
|
||||
|
||||
Reference in New Issue
Block a user