Skip to content

Commit 4f93c46

Browse files
committed
feat(ui-tabs): extends the customization of Tab component
Closes: CLX-276 Adds the possibility to disable built-in styling of a `Tab` to replace with a custom component through `renderTitle` - adds `customTab` flag to `Panel` to remove the default styling from the `Tab` - adds `alignTab` prop to `Panel` to allow to customzie the `Tabs`'s relative alignment in the container flexbox
1 parent 7be2226 commit 4f93c46

File tree

6 files changed

+47
-18
lines changed

6 files changed

+47
-18
lines changed

packages/ui-tabs/src/Tabs/Panel/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ class Panel extends Component<TabsPanelProps> {
5656
isSelected: false,
5757
padding: 'small',
5858
active: false,
59-
unmountOnExit: true
59+
unmountOnExit: true,
60+
customTab: false
6061
}
6162

6263
componentDidMount() {

packages/ui-tabs/src/Tabs/Panel/props.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import type {
3535
import type {
3636
OtherHTMLAttributes,
3737
PropValidators,
38+
Renderable,
3839
TabsPanelTheme
3940
} from '@instructure/shared-types'
4041

@@ -43,7 +44,7 @@ type TabsPanelOwnProps = {
4344
* The content that will be rendered in the corresponding <Tab /> and will label
4445
* this `<Tabs.Panel />` for screen readers
4546
*/
46-
renderTitle: React.ReactNode | (() => React.ReactNode)
47+
renderTitle: Renderable
4748
children?: React.ReactNode
4849
variant?: 'default' | 'secondary'
4950
isSelected?: boolean
@@ -67,6 +68,16 @@ type TabsPanelOwnProps = {
6768
* When set to false, the tabPanel only will be hidden, but not dismounted when not active
6869
*/
6970
unmountOnExit?: boolean
71+
72+
/**
73+
* When set to true, the tab will be rendered with minimal styling to enable a custom design
74+
*/
75+
customTab?: boolean
76+
77+
/**
78+
* Aligning the tab in the flex container
79+
*/
80+
alignTab?: string
7081
}
7182

7283
type PropKeys = keyof TabsPanelOwnProps
@@ -93,7 +104,9 @@ const propTypes: PropValidators<PropKeys> = {
93104
textAlign: PropTypes.oneOf(['start', 'center', 'end']),
94105
elementRef: PropTypes.func,
95106
active: PropTypes.bool,
96-
unmountOnExit: PropTypes.bool
107+
unmountOnExit: PropTypes.bool,
108+
customTab: PropTypes.bool,
109+
alignTab: PropTypes.string
97110
}
98111

99112
const allowedProps: AllowedPropKeys = [
@@ -110,7 +123,9 @@ const allowedProps: AllowedPropKeys = [
110123
'textAlign',
111124
'elementRef',
112125
'active',
113-
'unmountOnExit'
126+
'unmountOnExit',
127+
'customTab',
128+
'alignTab'
114129
]
115130

116131
export type { TabsPanelProps, TabsPanelStyle }

packages/ui-tabs/src/Tabs/Tab/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class Tab extends Component<TabsTabProps> {
9696
controls,
9797
children,
9898
styles,
99+
customTab,
100+
align,
99101
...props
100102
} = this.props
101103

packages/ui-tabs/src/Tabs/Tab/props.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ type TabsTabOwnProps = {
5050
tabData: { index: number; id: string }
5151
) => void
5252
children?: Renderable
53+
customTab?: boolean
54+
align?: string
5355
}
5456

5557
type PropKeys = keyof TabsTabOwnProps
@@ -71,7 +73,9 @@ const propTypes: PropValidators<PropKeys> = {
7173
isSelected: PropTypes.bool,
7274
onClick: PropTypes.func,
7375
onKeyDown: PropTypes.func,
74-
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
76+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
77+
customTab: PropTypes.bool,
78+
align: PropTypes.string
7579
}
7680

7781
const allowedProps: AllowedPropKeys = [
@@ -83,7 +87,9 @@ const allowedProps: AllowedPropKeys = [
8387
'isSelected',
8488
'onClick',
8589
'onKeyDown',
86-
'children'
90+
'children',
91+
'customTab',
92+
'align'
8793
]
8894

8995
export type { TabsTabProps, TabsTabStyle }

packages/ui-tabs/src/Tabs/Tab/styles.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const generateStyle = (
4949
componentTheme: TabsTabTheme,
5050
props: TabsTabProps
5151
): TabsTabStyle => {
52-
const { variant, isSelected, isDisabled } = props
52+
const { variant, isSelected, isDisabled, customTab, align } = props
5353

5454
const variants = {
5555
default: {
@@ -132,20 +132,23 @@ const generateStyle = (
132132
return {
133133
tab: {
134134
label: 'tab',
135-
fontFamily: componentTheme.fontFamily,
136-
fontWeight: componentTheme.fontWeight,
137-
lineHeight: componentTheme.lineHeight,
138-
fontSize: componentTheme.fontSize,
139-
cursor: 'pointer',
140-
userSelect: 'none',
141-
whiteSpace: 'nowrap',
135+
...(!customTab && {
136+
fontFamily: componentTheme.fontFamily,
137+
fontWeight: componentTheme.fontWeight,
138+
lineHeight: componentTheme.lineHeight,
139+
fontSize: componentTheme.fontSize,
140+
cursor: 'pointer',
141+
userSelect: 'none',
142+
whiteSpace: 'nowrap',
142143

143-
...((isSelected || isDisabled) && { cursor: 'default' }),
144-
...(isDisabled && { opacity: 0.5 }),
144+
...((isSelected || isDisabled) && { cursor: 'default' }),
145+
...(isDisabled && { opacity: 0.5 }),
145146

146-
...focusRingStyles,
147+
...focusRingStyles,
147148

148-
...variants[variant!]
149+
...variants[variant!]
150+
}),
151+
...(align && { alignSelf: align })
149152
}
150153
}
151154
}

packages/ui-tabs/src/Tabs/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ class Tabs extends Component<TabsProps, TabsState> {
352352
isDisabled={panel.props.isDisabled}
353353
onClick={this.handleTabClick}
354354
onKeyDown={this.handleTabKeyDown}
355+
customTab={panel.props.customTab}
356+
align={panel.props.alignTab}
355357
>
356358
{panel.props.renderTitle}
357359
</Tab>

0 commit comments

Comments
 (0)