From 7a0f2b7b442c857a0093f7bb08fd4c6a9ea24fe0 Mon Sep 17 00:00:00 2001 From: Peter Pal Hudak Date: Wed, 18 Oct 2023 13:46:08 +0200 Subject: [PATCH] feat(ui-tabs): add active property to tabs Closes: INSTUI-3876 Add support for multiple tabs->one tab panel. This makes using React Router easier with less boilerplate code. --- packages/ui-tabs/src/Tabs/Panel/index.tsx | 4 +++- packages/ui-tabs/src/Tabs/Panel/props.ts | 11 +++++++++-- packages/ui-tabs/src/Tabs/index.tsx | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/ui-tabs/src/Tabs/Panel/index.tsx b/packages/ui-tabs/src/Tabs/Panel/index.tsx index 9520ce4732..985cba5800 100644 --- a/packages/ui-tabs/src/Tabs/Panel/index.tsx +++ b/packages/ui-tabs/src/Tabs/Panel/index.tsx @@ -55,7 +55,8 @@ class Panel extends Component { textAlign: 'start', variant: 'default', isSelected: false, - padding: 'small' + padding: 'small', + active: 'false' } componentDidMount() { @@ -92,6 +93,7 @@ class Panel extends Component { isDisabled, isSelected, styles, + active, ...props } = this.props const isHidden = !isSelected || !!isDisabled diff --git a/packages/ui-tabs/src/Tabs/Panel/props.ts b/packages/ui-tabs/src/Tabs/Panel/props.ts index e7f3d0af80..f2ec364e0b 100644 --- a/packages/ui-tabs/src/Tabs/Panel/props.ts +++ b/packages/ui-tabs/src/Tabs/Panel/props.ts @@ -58,6 +58,11 @@ type TabsPanelOwnProps = { * provides a reference to the underlying html root element */ elementRef?: (element: HTMLDivElement | null) => void + /** + * Only one `` can be marked as active. The marked panel's content is rendered + * for all the ``s. + */ + active?: boolean } type PropKeys = keyof TabsPanelOwnProps @@ -82,7 +87,8 @@ const propTypes: PropValidators = { labelledBy: PropTypes.string, padding: ThemeablePropTypes.spacing, textAlign: PropTypes.oneOf(['start', 'center', 'end']), - elementRef: PropTypes.func + elementRef: PropTypes.func, + active: PropTypes.bool } const allowedProps: AllowedPropKeys = [ @@ -97,7 +103,8 @@ const allowedProps: AllowedPropKeys = [ 'labelledBy', 'padding', 'textAlign', - 'elementRef' + 'elementRef', + 'active' ] export type { TabsPanelProps, TabsPanelStyle } diff --git a/packages/ui-tabs/src/Tabs/index.tsx b/packages/ui-tabs/src/Tabs/index.tsx index 48af2ac5b7..44c2d34953 100644 --- a/packages/ui-tabs/src/Tabs/index.tsx +++ b/packages/ui-tabs/src/Tabs/index.tsx @@ -430,6 +430,17 @@ class Tabs extends Component { ...props } = this.props + const activePanels = (React.Children.toArray(children) as PanelChild[]) + .filter((child) => matchComponentTypes(child, [Panel])) + .filter((child) => child.props.active) + + if ( + activePanels.length > + 1 /*|| (activePanelCount === 1 && React.Children.toArray(children).length > 1)*/ + ) { + error(false, `[Tabs] Only one Panel can be marked as active.`) + } + const selectedChildIndex = ( React.Children.toArray(children) as PanelChild[] ) @@ -447,7 +458,11 @@ class Tabs extends Component { const id = uid() tabs.push(this.createTab(index, id, selected, child)) - panels.push(this.clonePanel(index, id, selected, child)) + if (activePanels.length === 1) { + panels.push(this.clonePanel(index, id, selected, activePanels[0])) + } else { + panels.push(this.clonePanel(index, id, selected, child)) + } index++ } else {