Skip to content

Commit

Permalink
feat(ui-tabs): extends the customization of Tab component
Browse files Browse the repository at this point in the history
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
  • Loading branch information
szalonna committed Dec 12, 2024
1 parent 7be2226 commit 4f93c46
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 18 deletions.
3 changes: 2 additions & 1 deletion packages/ui-tabs/src/Tabs/Panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class Panel extends Component<TabsPanelProps> {
isSelected: false,
padding: 'small',
active: false,
unmountOnExit: true
unmountOnExit: true,
customTab: false
}

componentDidMount() {
Expand Down
21 changes: 18 additions & 3 deletions packages/ui-tabs/src/Tabs/Panel/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type {
import type {
OtherHTMLAttributes,
PropValidators,
Renderable,
TabsPanelTheme
} from '@instructure/shared-types'

Expand All @@ -43,7 +44,7 @@ type TabsPanelOwnProps = {
* The content that will be rendered in the corresponding <Tab /> and will label
* this `<Tabs.Panel />` for screen readers
*/
renderTitle: React.ReactNode | (() => React.ReactNode)
renderTitle: Renderable
children?: React.ReactNode
variant?: 'default' | 'secondary'
isSelected?: boolean
Expand All @@ -67,6 +68,16 @@ type TabsPanelOwnProps = {
* When set to false, the tabPanel only will be hidden, but not dismounted when not active
*/
unmountOnExit?: boolean

/**
* When set to true, the tab will be rendered with minimal styling to enable a custom design
*/
customTab?: boolean

/**
* Aligning the tab in the flex container
*/
alignTab?: string
}

type PropKeys = keyof TabsPanelOwnProps
Expand All @@ -93,7 +104,9 @@ const propTypes: PropValidators<PropKeys> = {
textAlign: PropTypes.oneOf(['start', 'center', 'end']),
elementRef: PropTypes.func,
active: PropTypes.bool,
unmountOnExit: PropTypes.bool
unmountOnExit: PropTypes.bool,
customTab: PropTypes.bool,
alignTab: PropTypes.string
}

const allowedProps: AllowedPropKeys = [
Expand All @@ -110,7 +123,9 @@ const allowedProps: AllowedPropKeys = [
'textAlign',
'elementRef',
'active',
'unmountOnExit'
'unmountOnExit',
'customTab',
'alignTab'
]

export type { TabsPanelProps, TabsPanelStyle }
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-tabs/src/Tabs/Tab/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class Tab extends Component<TabsTabProps> {
controls,
children,
styles,
customTab,
align,
...props
} = this.props

Expand Down
10 changes: 8 additions & 2 deletions packages/ui-tabs/src/Tabs/Tab/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type TabsTabOwnProps = {
tabData: { index: number; id: string }
) => void
children?: Renderable
customTab?: boolean
align?: string
}

type PropKeys = keyof TabsTabOwnProps
Expand All @@ -71,7 +73,9 @@ const propTypes: PropValidators<PropKeys> = {
isSelected: PropTypes.bool,
onClick: PropTypes.func,
onKeyDown: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
customTab: PropTypes.bool,
align: PropTypes.string
}

const allowedProps: AllowedPropKeys = [
Expand All @@ -83,7 +87,9 @@ const allowedProps: AllowedPropKeys = [
'isSelected',
'onClick',
'onKeyDown',
'children'
'children',
'customTab',
'align'
]

export type { TabsTabProps, TabsTabStyle }
Expand Down
27 changes: 15 additions & 12 deletions packages/ui-tabs/src/Tabs/Tab/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const generateStyle = (
componentTheme: TabsTabTheme,
props: TabsTabProps
): TabsTabStyle => {
const { variant, isSelected, isDisabled } = props
const { variant, isSelected, isDisabled, customTab, align } = props

const variants = {
default: {
Expand Down Expand Up @@ -132,20 +132,23 @@ const generateStyle = (
return {
tab: {
label: 'tab',
fontFamily: componentTheme.fontFamily,
fontWeight: componentTheme.fontWeight,
lineHeight: componentTheme.lineHeight,
fontSize: componentTheme.fontSize,
cursor: 'pointer',
userSelect: 'none',
whiteSpace: 'nowrap',
...(!customTab && {
fontFamily: componentTheme.fontFamily,
fontWeight: componentTheme.fontWeight,
lineHeight: componentTheme.lineHeight,
fontSize: componentTheme.fontSize,
cursor: 'pointer',
userSelect: 'none',
whiteSpace: 'nowrap',

...((isSelected || isDisabled) && { cursor: 'default' }),
...(isDisabled && { opacity: 0.5 }),
...((isSelected || isDisabled) && { cursor: 'default' }),
...(isDisabled && { opacity: 0.5 }),

...focusRingStyles,
...focusRingStyles,

...variants[variant!]
...variants[variant!]
}),
...(align && { alignSelf: align })
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-tabs/src/Tabs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ class Tabs extends Component<TabsProps, TabsState> {
isDisabled={panel.props.isDisabled}
onClick={this.handleTabClick}
onKeyDown={this.handleTabKeyDown}
customTab={panel.props.customTab}
align={panel.props.alignTab}
>
{panel.props.renderTitle}
</Tab>
Expand Down

0 comments on commit 4f93c46

Please sign in to comment.