Tab components

Summary: _typescript_

Reviewed By: passy

Differential Revision: D16830058

fbshipit-source-id: 22825fdad0924f1f8cdebcbb7a56e0c55ad3b5f3
This commit is contained in:
Daniel Büchele
2019-08-20 03:18:32 -07:00
committed by Facebook Github Bot
parent 00c2a4dd29
commit 56d4a83184
4 changed files with 69 additions and 51 deletions

View File

@@ -57,7 +57,15 @@ module.exports = {
parser: '@typescript-eslint/parser',
rules: {
'prettier/prettier': [2, {...prettierConfig, parser: 'typescript'}],
'@typescript-eslint/no-unused-vars': [1, {argsIgnorePattern: '^_'}],
'@typescript-eslint/no-unused-vars': [
1,
{
ignoreRestSiblings: true,
varsIgnorePattern: '^_',
argsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
},
},
],

View File

@@ -5,34 +5,39 @@
* @format
*/
export default function Tab(props: {|
import {WidthProperty} from 'csstype';
export type Props = {
/**
* Label of this tab to show in the tab list.
*/
label: React$Node,
label: React.ReactNode;
/**
* Whether this tab is closable.
*/
closable?: boolean,
closable?: boolean;
/**
* Whether this tab is hidden. Useful for when you want a tab to be
* inaccessible via the user but you want to manually set the `active` props
* yourself.
*/
hidden?: boolean,
hidden?: boolean;
/**
* Whether this tab should always be included in the DOM and have its
* visibility toggled.
*/
persist?: boolean,
persist?: boolean;
/**
* Callback for when tab is closed.
*/
onClose?: () => void,
onClose?: () => void;
/**
* Contents of this tab.
*/
children?: React$Node,
|}) {
children?: React.ReactNode;
width?: WidthProperty<number>;
};
export default function Tab(_props: Props) {
throw new Error("don't render me");
}

View File

@@ -6,35 +6,39 @@
*/
import FlexColumn from './FlexColumn.js';
import styled from '../styled/index.js';
import Orderable from './Orderable.tsx';
import styled from 'react-emotion';
import Orderable from './Orderable';
import FlexRow from './FlexRow.js';
import {colors} from './colors.tsx';
import Tab from './Tab.js';
import {colors} from './colors';
import Tab, {Props as TabProps} from './Tab';
import {WidthProperty} from 'csstype';
import React from 'react';
const TabList = styled(FlexRow)({
alignItems: 'stretch',
});
const TabListItem = styled('div')(props => ({
backgroundColor: props.active ? colors.light15 : colors.light02,
borderBottom: '1px solid #dddfe2',
boxShadow: props.active ? 'inset 0px 0px 3px rgba(0,0,0,0.25)' : 'none',
color: colors.dark80,
flex: 1,
fontSize: 13,
lineHeight: '28px',
overflow: 'hidden',
padding: '0 10px',
position: 'relative',
textAlign: 'center',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
const TabListItem = styled('div')(
(props: {active?: boolean; width?: WidthProperty<number>}) => ({
backgroundColor: props.active ? colors.light15 : colors.light02,
borderBottom: '1px solid #dddfe2',
boxShadow: props.active ? 'inset 0px 0px 3px rgba(0,0,0,0.25)' : 'none',
color: colors.dark80,
flex: 1,
fontSize: 13,
lineHeight: '28px',
overflow: 'hidden',
padding: '0 10px',
position: 'relative',
textAlign: 'center',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
'&:hover': {
backgroundColor: props.active ? colors.light15 : colors.light05,
},
}));
'&:hover': {
backgroundColor: props.active ? colors.light15 : colors.light05,
},
}),
);
const TabListAddItem = styled(TabListItem)({
borderRight: 'none',
@@ -75,59 +79,59 @@ const TabContent = styled('div')({
/**
* A Tabs component.
*/
export default function Tabs(props: {|
export default function Tabs(props: {
/**
* Callback for when the active tab has changed.
*/
onActive?: (key: ?string) => void,
onActive?: (key: string | null | undefined) => void;
/**
* The key of the default active tab.
*/
defaultActive?: string,
defaultActive?: string;
/**
* The key of the currently active tab.
*/
active?: ?string,
active?: string | null | undefined;
/**
* Tab elements.
*/
children?: Array<React$Element<any>>,
children?: React.ReactElement<TabProps>[] | React.ReactElement<TabProps>;
/**
* Whether the tabs can be reordered by the user.
*/
orderable?: boolean,
orderable?: boolean;
/**
* Callback when the tab order changes.
*/
onOrder?: (order: Array<string>) => void,
onOrder?: (order: Array<string>) => void;
/**
* Order of tabs.
*/
order?: Array<string>,
order?: Array<string>;
/**
* Whether to include the contents of every tab in the DOM and just toggle
* its visibility.
*/
persist?: boolean,
persist?: boolean;
/**
* Whether to include a button to create additional items.
*/
newable?: boolean,
newable?: boolean;
/**
* Callback for when the new button is clicked.
*/
onNew?: () => void,
onNew?: () => void;
/**
* Elements to insert before all tabs in the tab list.
*/
before?: Array<React$Node>,
before?: Array<React.ReactNode>;
/**
* Elements to insert after all tabs in the tab list.
*/
after?: Array<React$Node>,
|}) {
after?: Array<React.ReactNode>;
}) {
const {onActive} = props;
const active: ?string =
const active: string | undefined =
props.active == null ? props.defaultActive : props.active;
// array of other components that aren't tabs
@@ -143,8 +147,9 @@ export default function Tabs(props: {|
const tabContents = [];
const tabSiblings = [];
function add(comps) {
for (const comp of [].concat(comps || [])) {
function add(comps: React.ReactElement | React.ReactElement[]) {
const compsArray: React.ReactElement<TabProps>[] = [].concat(comps || []);
for (const comp of compsArray) {
if (Array.isArray(comp)) {
add(comp);
continue;
@@ -194,7 +199,7 @@ export default function Tabs(props: {|
onMouseDown={
!isActive &&
onActive &&
((event: SyntheticMouseEvent<>) => {
((event: React.MouseEvent) => {
if (event.target !== closeButton) {
onActive(key);
}

View File

@@ -67,8 +67,8 @@ export {
} from './components/data-inspector/DataDescription.js';
// tabs
export {default as Tabs} from './components/Tabs.js';
export {default as Tab} from './components/Tab.js';
export {default as Tabs} from './components/Tabs.tsx';
export {default as Tab} from './components/Tab.tsx';
// inputs
export {default as Input} from './components/Input.js';