Panel Actions
Built-in panel actions, custom menu items, and new-tab hooks.
Panel actions are for commands that belong to the panel shell: menus, maximize and minimize controls, and app-defined new-tab behavior. Open the menu and use the new-tab demo to see how Tilery leaves product-specific commands to your app.
The tab bar stays built in, but renderPanelActions and onNewTab let you extend the controls without replacing the whole header.
const actionsLayout: TileryInitialLayout<TabData> = {
type: 'group',
direction: 'horizontal',
children: [
{
type: 'panel',
id: 'explorer',
size: 30,
tabs: [
{
id: 'files',
data: {
title: 'Files',
body: 'Project files, outlines, and search results live here.',
},
},
],
},
{
type: 'group',
direction: 'vertical',
size: 70,
children: [
{
type: 'panel',
id: 'editor',
size: 62,
tabs: [
{
id: 'readme',
data: {
title: 'README.md',
body: 'The editor menu includes one app-defined command.',
},
},
{
id: 'notes',
data: {
title: 'Notes',
body: 'Built-in actions stay available beside custom commands.',
},
},
],
},
{
type: 'panel',
id: 'terminal',
size: 38,
tabs: [
{
id: 'shell',
data: {
title: 'Terminal',
body: '$ pnpm test',
},
},
],
},
],
},
],
};
<Tilery<TabData>
initialLayout={actionsLayout}
showActionsButton={true}
renderActionsButtonIcon={EllipsisIcon}
renderPanelActions={(panel, ctx) =>
panel.id === 'editor' ? (
<button
type="button"
className="tilery__panel-menu-item"
onClick={() => {
panel.setActiveTab('readme');
ctx.closeMenu();
}}>
Focus README
</button>
) : null
}
renderTabHeader={renderHeader}
renderTabContent={renderContent}
/>const newTabLayout: TileryInitialLayout<TabData> = {
type: 'group',
direction: 'horizontal',
children: [
{
type: 'panel',
id: 'drafts',
size: 55,
tabs: [
{
id: 'draft-0',
data: {
title: 'Draft 0',
body: 'The plus button asks the host app for a new tab object.',
},
},
],
},
{
type: 'panel',
id: 'reference',
size: 45,
tabs: [
{
id: 'api',
data: {
title: 'API Notes',
body: 'The reference panel does not show the new-tab affordance.',
},
},
],
},
],
};
const newTabCounterRef = useRef(0);
const tileryRef = useRef<TileryController | null>(null);
<Tilery<TabData>
ref={tileryRef as React.Ref<TileryController>}
initialLayout={newTabLayout}
showNewTabButton={(panel) => panel.id === 'drafts'}
onNewTab={(panel: TileryPanel) => {
newTabCounterRef.current += 1;
return {
id: `${panel.id}-${newTabCounterRef.current}`,
data: {
title: `Draft ${newTabCounterRef.current}`,
body: 'This tab was supplied by the host application.',
},
};
}}
renderTabHeader={renderHeader}
renderTabContent={renderContent}
/>Related
- Component Props — See action button and new-tab props.
- Programmatic Control — Open and manage tabs from app workflows.