Skip to content

Commit

Permalink
Add closeMode to TabView
Browse files Browse the repository at this point in the history
  • Loading branch information
diogoko authored and melloware committed May 30, 2023
1 parent 7772554 commit 0e887a9
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 2 deletions.
6 changes: 6 additions & 0 deletions api-generator/components/tabview.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ const TabViewProps = [
type: 'boolean',
default: 'false',
description: 'When enabled displays buttons at each side of the tab headers to scroll the tab list.'
},
{
name: 'closeMode',
type: 'string',
default: 'auto',
description: 'Use "manual" to programmatically control dynamic tabs visibility when the close button of a closable tab is clicked.'
}
];

Expand Down
10 changes: 9 additions & 1 deletion components/doc/common/apidoc/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -36649,6 +36649,14 @@
"default": "false",
"description": "Defines if tab can be removed."
},
{
"name": "closeMode",
"optional": true,
"readonly": false,
"type": "\"auto\" | \"manual\"",
"default": "auto",
"description": "How closable tabs are managed."
},
{
"name": "style",
"optional": true,
Expand Down Expand Up @@ -44360,4 +44368,4 @@
}
}
}
}
}
111 changes: 111 additions & 0 deletions components/doc/tabview/dynamicdoc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { TabView, TabPanel } from '../../lib/tabview/TabView';
import { Button } from '../../lib/button/Button';
import { DocSectionCode } from '../common/docsectioncode';
import { DocSectionText } from '../common/docsectiontext';
import { useState } from 'react';

const createClient = () => {
const id = Math.floor(Math.random() * 1000000);

return { id, name: `Client ${id}` };
};

export function DynamicDoc(props) {
const code = {
basic: `
<TabView
closeMode="manual"
onTabClose={(e) => setDynamicTabs([...dynamicTabs.slice(0, e.index), ...dynamicTabs.slice(e.index + 1)])}
>
{dynamicTabs.map((tab) => (
<TabPanel key={tab.id} header={tab.name} closable>
<p>Name: {tab.name}</p>
</TabPanel>
))}
</TabView>
`,
javascript: `
import React from 'react';
import { TabView, TabPanel } from 'primereact/tabview';
import { Button } from 'primereact/button';
const createClient = () => {
const id = Math.floor(Math.random() * 1000000);
return { id, name: \`Client \${id}\` };
};
export default function DynamicDemo() {
const [dynamicTabs, setDynamicTabs] = useState([createClient(), createClient(), createClient()]);
return (
<div className="card">
<div className="flex flex-wrap gap-2 mb-3">
<Button onClick={() => setDynamicTabs([...dynamicTabs, createClient()])} className="p-button-text" label="Add" />
</div>
<TabView closeMode="manual" onTabClose={(e) => setDynamicTabs([...dynamicTabs.slice(0, e.index), ...dynamicTabs.slice(e.index + 1)])}>
{dynamicTabs.map((tab) => (
<TabPanel key={tab.id} header={tab.name} closable>
<p>Name: {tab.name}</p>
</TabPanel>
))}
</TabView>
</div>
)
}
`,
typescript: `
import React from 'react';
import { TabView, TabPanel } from 'primereact/tabview';
import { Button } from 'primereact/button';
const createClient = () => {
const id = Math.floor(Math.random() * 1000000);
return { id, name: \`Client \${id}\` };
};
export default function DynamicDemo() {
const [dynamicTabs, setDynamicTabs] = useState([createClient(), createClient(), createClient()]);
return (
<div className="card">
<div className="flex flex-wrap gap-2 mb-3">
<Button onClick={() => setDynamicTabs([...dynamicTabs, createClient()])} className="p-button-text" label="Add" />
</div>
<TabView closeMode="manual" onTabClose={(e) => setDynamicTabs([...dynamicTabs.slice(0, e.index), ...dynamicTabs.slice(e.index + 1)])}>
{dynamicTabs.map((tab) => (
<TabPanel key={tab.id} header={tab.name} closable>
<p>Name: {tab.name}</p>
</TabPanel>
))}
</TabView>
</div>
)
}
`
};

const [dynamicTabs, setDynamicTabs] = useState([createClient(), createClient(), createClient()]);

return (
<>
<DocSectionText {...props}>
<p>
It is possible to have dynamic tabs by generating the children <i>TabPanel</i> components using standard React techniques. If the tabs are closable, set <i>closeMode</i> to "manual" and manage the children in the <i>onTabClose</i> event.
</p>
</DocSectionText>
<div className="card">
<div className="flex flex-wrap gap-2 mb-3">
<Button onClick={() => setDynamicTabs([...dynamicTabs, createClient()])} className="p-button-text" label="Add" />
</div>
<TabView closeMode="manual" onTabClose={(e) => setDynamicTabs([...dynamicTabs.slice(0, e.index), ...dynamicTabs.slice(e.index + 1)])}>
{dynamicTabs.map((tab) => (
<TabPanel key={tab.id} header={tab.name} closable>
<p>Name: {tab.name}</p>
</TabPanel>
))}
</TabView>
</div>
<DocSectionCode code={code} />
</>
);
}
4 changes: 3 additions & 1 deletion components/lib/tabview/TabView.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ export const TabView = React.forwardRef((inProps, ref) => {
return;
}

setHiddenTabsState([...hiddenTabsState, index]);
if (props.closeMode !== 'manual') {
setHiddenTabsState([...hiddenTabsState, index]);
}

if (props.onTabClose) {
props.onTabClose({ originalEvent: event, index });
Expand Down
1 change: 1 addition & 0 deletions components/lib/tabview/TabViewBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const TabViewBase = ComponentBase.extend({
id: null,
activeIndex: 0,
className: null,
closeMode: 'auto',
onBeforeTabChange: null,
onBeforeTabClose: null,
onTabChange: null,
Expand Down
5 changes: 5 additions & 0 deletions components/lib/tabview/tabview.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ export interface TabViewProps extends Omit<React.DetailedHTMLProps<React.HTMLAtt
* @readonly
*/
children?: React.ReactNode | undefined;
/**
* How the visibility of closable tabs is managed.
* @defaultValue 'auto'
*/
closeMode?: 'auto' | 'manual';
/**
* Style class of the panels container of the tabview.
*/
Expand Down
6 changes: 6 additions & 0 deletions pages/tabview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BasicDoc } from '../../components/doc/tabview/basicdoc';
import { ClosableDoc } from '../../components/doc/tabview/closabledoc';
import { ControlledDoc } from '../../components/doc/tabview/controlleddoc';
import { DisabledDoc } from '../../components/doc/tabview/disableddoc';
import { DynamicDoc } from '../../components/doc/tabview/dynamicdoc';
import { HeaderIconDoc } from '../../components/doc/tabview/headericondoc';
import { ImportDoc } from '../../components/doc/tabview/importdoc';
import { ScrollableDoc } from '../../components/doc/tabview/scrollabledoc';
Expand Down Expand Up @@ -50,6 +51,11 @@ const TabViewDemo = () => {
label: 'Closable',
component: ClosableDoc
},
{
id: 'dynamic',
label: 'Dynamic',
component: DynamicDoc
},
{
id: 'scrollable',
label: 'Scrollable',
Expand Down

0 comments on commit 0e887a9

Please sign in to comment.