Tab components
Summary: _typescript_ Reviewed By: passy Differential Revision: D16830058 fbshipit-source-id: 22825fdad0924f1f8cdebcbb7a56e0c55ad3b5f3
This commit is contained in:
committed by
Facebook Github Bot
parent
00c2a4dd29
commit
56d4a83184
10
.eslintrc.js
10
.eslintrc.js
@@ -57,7 +57,15 @@ module.exports = {
|
|||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
rules: {
|
rules: {
|
||||||
'prettier/prettier': [2, {...prettierConfig, parser: 'typescript'}],
|
'prettier/prettier': [2, {...prettierConfig, parser: 'typescript'}],
|
||||||
'@typescript-eslint/no-unused-vars': [1, {argsIgnorePattern: '^_'}],
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
caughtErrorsIgnorePattern: '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,34 +5,39 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default function Tab(props: {|
|
import {WidthProperty} from 'csstype';
|
||||||
|
|
||||||
|
export type Props = {
|
||||||
/**
|
/**
|
||||||
* Label of this tab to show in the tab list.
|
* Label of this tab to show in the tab list.
|
||||||
*/
|
*/
|
||||||
label: React$Node,
|
label: React.ReactNode;
|
||||||
/**
|
/**
|
||||||
* Whether this tab is closable.
|
* Whether this tab is closable.
|
||||||
*/
|
*/
|
||||||
closable?: boolean,
|
closable?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether this tab is hidden. Useful for when you want a tab to be
|
* 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
|
* inaccessible via the user but you want to manually set the `active` props
|
||||||
* yourself.
|
* yourself.
|
||||||
*/
|
*/
|
||||||
hidden?: boolean,
|
hidden?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether this tab should always be included in the DOM and have its
|
* Whether this tab should always be included in the DOM and have its
|
||||||
* visibility toggled.
|
* visibility toggled.
|
||||||
*/
|
*/
|
||||||
persist?: boolean,
|
persist?: boolean;
|
||||||
/**
|
/**
|
||||||
* Callback for when tab is closed.
|
* Callback for when tab is closed.
|
||||||
*/
|
*/
|
||||||
onClose?: () => void,
|
onClose?: () => void;
|
||||||
/**
|
/**
|
||||||
* Contents of this tab.
|
* 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");
|
throw new Error("don't render me");
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import FlexColumn from './FlexColumn.js';
|
import FlexColumn from './FlexColumn.js';
|
||||||
import styled from '../styled/index.js';
|
import styled from 'react-emotion';
|
||||||
import Orderable from './Orderable.tsx';
|
import Orderable from './Orderable';
|
||||||
import FlexRow from './FlexRow.js';
|
import FlexRow from './FlexRow.js';
|
||||||
import {colors} from './colors.tsx';
|
import {colors} from './colors';
|
||||||
import Tab from './Tab.js';
|
import Tab, {Props as TabProps} from './Tab';
|
||||||
|
import {WidthProperty} from 'csstype';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
const TabList = styled(FlexRow)({
|
const TabList = styled(FlexRow)({
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
});
|
});
|
||||||
|
|
||||||
const TabListItem = styled('div')(props => ({
|
const TabListItem = styled('div')(
|
||||||
|
(props: {active?: boolean; width?: WidthProperty<number>}) => ({
|
||||||
backgroundColor: props.active ? colors.light15 : colors.light02,
|
backgroundColor: props.active ? colors.light15 : colors.light02,
|
||||||
borderBottom: '1px solid #dddfe2',
|
borderBottom: '1px solid #dddfe2',
|
||||||
boxShadow: props.active ? 'inset 0px 0px 3px rgba(0,0,0,0.25)' : 'none',
|
boxShadow: props.active ? 'inset 0px 0px 3px rgba(0,0,0,0.25)' : 'none',
|
||||||
@@ -34,7 +37,8 @@ const TabListItem = styled('div')(props => ({
|
|||||||
'&:hover': {
|
'&:hover': {
|
||||||
backgroundColor: props.active ? colors.light15 : colors.light05,
|
backgroundColor: props.active ? colors.light15 : colors.light05,
|
||||||
},
|
},
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const TabListAddItem = styled(TabListItem)({
|
const TabListAddItem = styled(TabListItem)({
|
||||||
borderRight: 'none',
|
borderRight: 'none',
|
||||||
@@ -75,59 +79,59 @@ const TabContent = styled('div')({
|
|||||||
/**
|
/**
|
||||||
* A Tabs component.
|
* A Tabs component.
|
||||||
*/
|
*/
|
||||||
export default function Tabs(props: {|
|
export default function Tabs(props: {
|
||||||
/**
|
/**
|
||||||
* Callback for when the active tab has changed.
|
* 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.
|
* The key of the default active tab.
|
||||||
*/
|
*/
|
||||||
defaultActive?: string,
|
defaultActive?: string;
|
||||||
/**
|
/**
|
||||||
* The key of the currently active tab.
|
* The key of the currently active tab.
|
||||||
*/
|
*/
|
||||||
active?: ?string,
|
active?: string | null | undefined;
|
||||||
/**
|
/**
|
||||||
* Tab elements.
|
* Tab elements.
|
||||||
*/
|
*/
|
||||||
children?: Array<React$Element<any>>,
|
children?: React.ReactElement<TabProps>[] | React.ReactElement<TabProps>;
|
||||||
/**
|
/**
|
||||||
* Whether the tabs can be reordered by the user.
|
* Whether the tabs can be reordered by the user.
|
||||||
*/
|
*/
|
||||||
orderable?: boolean,
|
orderable?: boolean;
|
||||||
/**
|
/**
|
||||||
* Callback when the tab order changes.
|
* Callback when the tab order changes.
|
||||||
*/
|
*/
|
||||||
onOrder?: (order: Array<string>) => void,
|
onOrder?: (order: Array<string>) => void;
|
||||||
/**
|
/**
|
||||||
* Order of tabs.
|
* Order of tabs.
|
||||||
*/
|
*/
|
||||||
order?: Array<string>,
|
order?: Array<string>;
|
||||||
/**
|
/**
|
||||||
* Whether to include the contents of every tab in the DOM and just toggle
|
* Whether to include the contents of every tab in the DOM and just toggle
|
||||||
* its visibility.
|
* its visibility.
|
||||||
*/
|
*/
|
||||||
persist?: boolean,
|
persist?: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether to include a button to create additional items.
|
* Whether to include a button to create additional items.
|
||||||
*/
|
*/
|
||||||
newable?: boolean,
|
newable?: boolean;
|
||||||
/**
|
/**
|
||||||
* Callback for when the new button is clicked.
|
* Callback for when the new button is clicked.
|
||||||
*/
|
*/
|
||||||
onNew?: () => void,
|
onNew?: () => void;
|
||||||
/**
|
/**
|
||||||
* Elements to insert before all tabs in the tab list.
|
* 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.
|
* Elements to insert after all tabs in the tab list.
|
||||||
*/
|
*/
|
||||||
after?: Array<React$Node>,
|
after?: Array<React.ReactNode>;
|
||||||
|}) {
|
}) {
|
||||||
const {onActive} = props;
|
const {onActive} = props;
|
||||||
const active: ?string =
|
const active: string | undefined =
|
||||||
props.active == null ? props.defaultActive : props.active;
|
props.active == null ? props.defaultActive : props.active;
|
||||||
|
|
||||||
// array of other components that aren't tabs
|
// array of other components that aren't tabs
|
||||||
@@ -143,8 +147,9 @@ export default function Tabs(props: {|
|
|||||||
const tabContents = [];
|
const tabContents = [];
|
||||||
const tabSiblings = [];
|
const tabSiblings = [];
|
||||||
|
|
||||||
function add(comps) {
|
function add(comps: React.ReactElement | React.ReactElement[]) {
|
||||||
for (const comp of [].concat(comps || [])) {
|
const compsArray: React.ReactElement<TabProps>[] = [].concat(comps || []);
|
||||||
|
for (const comp of compsArray) {
|
||||||
if (Array.isArray(comp)) {
|
if (Array.isArray(comp)) {
|
||||||
add(comp);
|
add(comp);
|
||||||
continue;
|
continue;
|
||||||
@@ -194,7 +199,7 @@ export default function Tabs(props: {|
|
|||||||
onMouseDown={
|
onMouseDown={
|
||||||
!isActive &&
|
!isActive &&
|
||||||
onActive &&
|
onActive &&
|
||||||
((event: SyntheticMouseEvent<>) => {
|
((event: React.MouseEvent) => {
|
||||||
if (event.target !== closeButton) {
|
if (event.target !== closeButton) {
|
||||||
onActive(key);
|
onActive(key);
|
||||||
}
|
}
|
||||||
@@ -67,8 +67,8 @@ export {
|
|||||||
} from './components/data-inspector/DataDescription.js';
|
} from './components/data-inspector/DataDescription.js';
|
||||||
|
|
||||||
// tabs
|
// tabs
|
||||||
export {default as Tabs} from './components/Tabs.js';
|
export {default as Tabs} from './components/Tabs.tsx';
|
||||||
export {default as Tab} from './components/Tab.js';
|
export {default as Tab} from './components/Tab.tsx';
|
||||||
|
|
||||||
// inputs
|
// inputs
|
||||||
export {default as Input} from './components/Input.js';
|
export {default as Input} from './components/Input.js';
|
||||||
|
|||||||
Reference in New Issue
Block a user