Skip to content

Commit

Permalink
fix and beautify TabList
Browse files Browse the repository at this point in the history
  • Loading branch information
farooqkz committed Sep 17, 2024
1 parent baf5eaf commit ebeb095
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 121 deletions.
109 changes: 0 additions & 109 deletions src/renderer/components/TabList/TabList.tsx

This file was deleted.

3 changes: 0 additions & 3 deletions src/renderer/components/TabList/index.ts

This file was deleted.

128 changes: 128 additions & 0 deletions src/renderer/components/TabList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, { PropsWithChildren, useState, useEffect, ReactNode } from 'react'
import classNames from 'classnames'
import useTranslationFunction from '../../hooks/useTranslationFunction'
import styles from './styles.module.scss'

type TabName = string

interface TabListProps {
tabNames: TabName[]
tabChangeCb?: (newTab: TabName) => void
extra?: ReactNode
}

/**
* TabList component can be used to render one element/component
* at a time, called "current tab" which is switchable by a tab header. E.g.
* Each time one of the "tabs" is shown and user can switch between them by clicking on the
* tab names above in the header. TabList component also supports a secondary "extra"
* child to be rendered at the right of tab header. An example is shown below:
* ```js
* <TabList tabs={["Tab one", "Tab two", "Tab 3"]}>
* <TabOneComponent />
* <TabTwoComponent />
* <TabThreeComponent />
* </TabList>
* ```
* Another example using the "extra" child
* ```js
* <TabList tabs={["Tab uno", "Tab zwei"]} extra={<p>Extra child</p>}>
* <TabOne />
* <TabTwo />
* </TabList>
* ```
*/
export default function TabList({
tabNames,
tabChangeCb,
children,
extra,
}: PropsWithChildren<TabListProps>) {
const [currentTab, setCurrentTab] = useState<number>(0)
useEffect(
() => tabChangeCb && tabChangeCb(tabNames[currentTab]),
[currentTab, tabChangeCb, tabNames]
)

if (Array.isArray(children)) {
if (children.length != tabNames.length) {
throw new Error(
'Number of tab components inequal to number of tabs specified in tabNames'
)
}
} else {
if (tabNames.length !== 1) {
throw new Error(
'You have provided one child but specified multiple tab names'
)
}
}
const childToRender = Array.isArray(children)
? children[currentTab]
: children
return (
<>
<TabListHeader
currentTab={currentTab}
onChangeTab={setCurrentTab}
tabs={tabNames}
>
{extra}
</TabListHeader>
{childToRender}
</>
)
}

interface TabListHeaderProps {
currentTab: number
onChangeTab: (newTab: number) => void
tabs: TabName[]
}

function TabListHeader({
currentTab,
onChangeTab,
tabs,
children,
}: PropsWithChildren<TabListHeaderProps>) {
return (
<div className={styles.tablistHeader}>
<ul className={styles.tablistHeaderUl}>
{tabs.map((tab: string, index: number) => {
return (
<TabHeader
name={tab}
key={tab}
isFocused={index === currentTab}
onClick={onChangeTab.bind(null, index)}
/>
)
})}
</ul>
{children}
</div>
)
}

interface TabHeaderProps {
name: string
isFocused?: boolean
onClick: () => void
}

function TabHeader({ name, isFocused, onClick }: TabHeaderProps) {
const tx = useTranslationFunction()

return (
<li
key={name}
className={classNames(styles.tabHeader, {
[styles['focused']]: isFocused,
})}
onClick={onClick}
>
{tx(name)}
</li>
)
}
22 changes: 13 additions & 9 deletions src/renderer/components/TabList/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
.tablist-header {
.tablistHeader {
display: flex;
flex-direction: row;
justify-content: start;
flex-grow: 3 1;
flex-grow: (3, 1);
}

.tablist-header-ul {
.tablistHeaderUl {
display: flex;
flex-direction: row;
flex-grow: 1;
justify-content: start;
}

.tab-header {
.tabHeader {
outline: none;
width: 100%;
height: 0.35rem;
box-shadow: 0 2.45rem 0 0;
.focused {
box-shadow: 0 2.45rem 0 0 var(--delta-btn-tab-selected-bg);
}
height: 1.4rem;
padding-left: 6px;
border-left: 6px double transparent;
border-radius: 6px;
}

.focused {
border-left-color: var(--delta-btn-tab-selected-bg) !important;
border-radius: 6px;
}

0 comments on commit ebeb095

Please sign in to comment.