diff --git a/src/renderer/components/TabList/TabList.tsx b/src/renderer/components/TabList/TabList.tsx deleted file mode 100644 index 921fe7d7e..000000000 --- a/src/renderer/components/TabList/TabList.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React, { PropsWithChildren, useState, useEffect } from 'react' -import classNames from 'classnames' -import useTranslationFunction from '../../hooks/useTranslationFunction' -import styles from './styles.module.scss' - -interface TabListProps { - tabNames: string[] - tabChangeCb: (newTab: string) => void -} - -export default function TabList({ - tabNames, - tabChangeCb, - children, -}: PropsWithChildren) { - const [currentTab, setCurrentTab] = useState(0) - useEffect( - () => tabChangeCb(tabNames[currentTab]), - [currentTab, tabChangeCb, tabNames] - ) - const [tabs, extra] = (function () { - if (Array.isArray(children)) { - if (children.length === 2) { - return children - } else if (children.length == 1) { - return [children, null] - // will it really happen? --Farooq - } else { - throw new Error('TabList must have exactly 1 or 2 children') - } - } else { - return [children, null] - } - })() - const childToRender = Array.isArray(tabs) ? tabs[currentTab] : tabs - return ( - <> - - {extra} - - {childToRender} - - ) -} - -interface TabListHeaderProps { - currentTab: number - onChangeTab: (newTab: number) => void - tabs: string[] -} - -function TabListHeader({ - currentTab, - onChangeTab, - tabs, - children, -}: PropsWithChildren) { - return ( -
-
    - {tabs.map((tab: string, index: number) => { - if (index == currentTab) { - return ( - - ) - } else { - return ( - - ) - } - })} -
- {children} -
- ) -} - -interface TabHeaderProps { - name: string - isFocused?: boolean - onClick: () => void -} - -function TabHeader({ name, isFocused, onClick }: TabHeaderProps) { - const tx = useTranslationFunction() - - return ( -
  • - {tx(name)} -
  • - ) -} diff --git a/src/renderer/components/TabList/index.ts b/src/renderer/components/TabList/index.ts deleted file mode 100644 index 83e548d39..000000000 --- a/src/renderer/components/TabList/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import TabList from './TabList' - -export default TabList diff --git a/src/renderer/components/TabList/index.tsx b/src/renderer/components/TabList/index.tsx new file mode 100644 index 000000000..c5ee73833 --- /dev/null +++ b/src/renderer/components/TabList/index.tsx @@ -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 + * + * + * + * + * + * ``` + * Another example using the "extra" child + * ```js + * Extra child

    }> + * + * + *
    + * ``` + */ +export default function TabList({ + tabNames, + tabChangeCb, + children, + extra, +}: PropsWithChildren) { + const [currentTab, setCurrentTab] = useState(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 ( + <> + + {extra} + + {childToRender} + + ) +} + +interface TabListHeaderProps { + currentTab: number + onChangeTab: (newTab: number) => void + tabs: TabName[] +} + +function TabListHeader({ + currentTab, + onChangeTab, + tabs, + children, +}: PropsWithChildren) { + return ( +
    +
      + {tabs.map((tab: string, index: number) => { + return ( + + ) + })} +
    + {children} +
    + ) +} + +interface TabHeaderProps { + name: string + isFocused?: boolean + onClick: () => void +} + +function TabHeader({ name, isFocused, onClick }: TabHeaderProps) { + const tx = useTranslationFunction() + + return ( +
  • + {tx(name)} +
  • + ) +} diff --git a/src/renderer/components/TabList/styles.module.scss b/src/renderer/components/TabList/styles.module.scss index 87ddd527c..94159cb14 100644 --- a/src/renderer/components/TabList/styles.module.scss +++ b/src/renderer/components/TabList/styles.module.scss @@ -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; }