Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit 4d17b77

Browse files
committed
feat(plugins/plugin-client-common): noTopTabs, allowing clients to use the sidebar instead of top tabs
1 parent 3192925 commit 4d17b77

File tree

4 files changed

+53
-31
lines changed

4 files changed

+53
-31
lines changed

plugins/plugin-client-common/src/components/Client/Kui.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ export class Kui extends React.PureComponent<Props, State> {
301301
title={this.props.initialTabTitle}
302302
onTabReady={this.state.commandLine && this._onTabReady}
303303
closeableTabs={this.props.closeableTabs}
304+
noTopTabs={this.props.noTopTabs}
304305
guidebooks={this.props.guidebooks}
305306
guidebooksCommand={this.props.guidebooksCommand}
306307
guidebooksExpanded={this.props.guidebooksExpanded}

plugins/plugin-client-common/src/components/Client/TabContainer.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,15 @@ type Props = TabContentOptions &
4747
TopTabStripeConfiguration &
4848
BrandingProps &
4949
GuidebookProps &
50-
Pick<CommonProps, 'closeableTabs'>
50+
Pick<CommonProps, 'closeableTabs' | 'noTopTabs'>
5151

5252
interface State {
5353
/** hamburger menu expanded? */
5454
isSidebarOpen: boolean
5555

56+
/** in noTopTabs mode, we indicate selected guidebook in the NavItem below */
57+
currentGuidebook?: string
58+
5659
/** list of current tabs; one TabContent for each */
5760
tabs: TabModel[]
5861

@@ -296,6 +299,7 @@ export default class TabContainer extends React.PureComponent<Props, State> {
296299
needsSidebar={this.needsSidebar}
297300
isSidebarOpen={this.state.isSidebarOpen}
298301
onToggleSidebar={this.toggleSidebar}
302+
noTopTabs={this.props.noTopTabs}
299303
closeableTabs={this.state.tabs.length > 1 && (this.props.closeableTabs || !isReadOnlyClient())}
300304
/>
301305
)
@@ -344,15 +348,25 @@ export default class TabContainer extends React.PureComponent<Props, State> {
344348
}
345349

346350
private sidebar() {
347-
const renderItem = (_: MenuItem, idx) =>
348-
isGuidebook(_) ? (
351+
// helps deal with isActive
352+
let first = true
353+
354+
const renderItem = (_: MenuItem, idx) => {
355+
const thisIsTheFirstNavItem = isGuidebook(_) && first
356+
if (thisIsTheFirstNavItem) {
357+
first = false
358+
}
359+
360+
return isGuidebook(_) ? (
349361
<NavItem
350362
key={idx}
351-
className="kui--sidebar-nav-item"
352363
data-title={_.notebook}
353-
onClick={() =>
364+
className="kui--sidebar-nav-item"
365+
isActive={_.notebook === this.state.currentGuidebook || thisIsTheFirstNavItem}
366+
onClick={() => {
354367
pexecInCurrentTab(`${this.props.guidebooksCommand || 'replay'} ${encodeComponent(_.filepath)}`)
355-
}
368+
this.setState({ currentGuidebook: _.notebook })
369+
}}
356370
>
357371
{_.notebook}
358372
</NavItem>
@@ -363,6 +377,7 @@ export default class TabContainer extends React.PureComponent<Props, State> {
363377
) : (
364378
undefined
365379
)
380+
}
366381

367382
const nav = this.needsSidebar && (
368383
<React.Fragment>

plugins/plugin-client-common/src/components/Client/TopTabStripe/index.tsx

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export type TopTabStripeConfiguration = TabConfiguration
6565
type Props = TopTabStripeConfiguration & {
6666
tabs: TabModel[]
6767
activeIdx: number
68+
noTopTabs: boolean
6869
closeableTabs: boolean
6970
onNewTab: () => void
7071
onCloseTab: (idx: number) => void
@@ -126,31 +127,33 @@ export default class TopTabStripe extends React.PureComponent<Props> {
126127
/** Render tabs */
127128
private tabs() {
128129
return (
129-
<React.Fragment>
130-
<Nav aria-label="Tabs" variant="horizontal" className="kui--header-tabs">
131-
<NavList className="kui--tab-list">
132-
{this.props.tabs.map((tab, idx) => (
133-
<Tab
134-
{...this.props}
135-
key={idx}
136-
idx={idx}
137-
uuid={tab.uuid}
138-
title={tab.title}
139-
closeable={this.props.closeableTabs}
140-
active={idx === this.props.activeIdx}
141-
onCloseTab={(idx: number) => this.props.onCloseTab(idx)}
142-
onSwitchTab={(idx: number) => this.props.onSwitchTab(idx)}
143-
/>
144-
))}
145-
</NavList>
146-
</Nav>
147-
{!isReadOnlyClient() && (
148-
<div className="kui--top-tab-buttons">
149-
<NewTabButton onNewTab={this.props.onNewTab} />
150-
<SplitTerminalButton />
151-
</div>
152-
)}
153-
</React.Fragment>
130+
!this.props.noTopTabs && (
131+
<React.Fragment>
132+
<Nav aria-label="Tabs" variant="horizontal" className="kui--header-tabs">
133+
<NavList className="kui--tab-list">
134+
{this.props.tabs.map((tab, idx) => (
135+
<Tab
136+
{...this.props}
137+
key={idx}
138+
idx={idx}
139+
uuid={tab.uuid}
140+
title={tab.title}
141+
closeable={this.props.closeableTabs}
142+
active={idx === this.props.activeIdx}
143+
onCloseTab={(idx: number) => this.props.onCloseTab(idx)}
144+
onSwitchTab={(idx: number) => this.props.onSwitchTab(idx)}
145+
/>
146+
))}
147+
</NavList>
148+
</Nav>
149+
{!isReadOnlyClient() && (
150+
<div className="kui--top-tab-buttons">
151+
<NewTabButton onNewTab={this.props.onNewTab} />
152+
<SplitTerminalButton />
153+
</div>
154+
)}
155+
</React.Fragment>
156+
)
154157
)
155158
}
156159

plugins/plugin-client-common/src/components/Client/props/Common.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ export default interface CommonProps {
2626

2727
/** Are tabs closeable? [default: true except for config.d/client.json readonly: true */
2828
closeableTabs?: boolean
29+
30+
/** Don't show top tabs [default: false] */
31+
noTopTabs?: boolean
2932
}

0 commit comments

Comments
 (0)