diff --git a/src/components/Card/CardPlate.js b/src/components/Card/Card.js similarity index 52% rename from src/components/Card/CardPlate.js rename to src/components/Card/Card.js index 61c10aac..7625e4f4 100644 --- a/src/components/Card/CardPlate.js +++ b/src/components/Card/Card.js @@ -1,5 +1,11 @@ // @flow import React from 'react'; + +import { CardHeader, cardHeaderTheme } from './CardHeader'; +import { CardBody, cardBodyTheme } from './CardBody'; +import { CardSection, cardSectionTheme } from './CardSection'; +import { CardFooter, cardFooterTheme } from './CardFooter'; + import { Paper } from '../Paper'; import type { PropSizes } from '../../types'; @@ -12,7 +18,14 @@ type CardPlateProps = { borderRadius?: 'top' | 'bottom' | 'all', }; -const CardPlate = ({ children, paddingOuter, padding, ...rest }: CardPlateProps) => ( +const theme = { + ...cardHeaderTheme, + ...cardBodyTheme, + ...cardSectionTheme, + ...cardFooterTheme, +}; + +const Card = ({ children, paddingOuter, padding, ...rest }: CardPlateProps) => ( { typeof children === 'function' @@ -26,8 +39,13 @@ const CardPlate = ({ children, paddingOuter, padding, ...rest }: CardPlateProps) ); -CardPlate.defaultProps = { +Card.defaultProps = { padding: 'md', }; -export { CardPlate }; +Card.Header = CardHeader; +Card.Body = CardBody; +Card.Section = CardSection; +Card.Footer = CardFooter; + +export { Card, theme }; diff --git a/src/components/Card/Card.stories.js b/src/components/Card/Card.stories.js index b39e44f1..a4e7d4ce 100644 --- a/src/components/Card/Card.stories.js +++ b/src/components/Card/Card.stories.js @@ -13,53 +13,53 @@ export default (asStory) => { asStory('Components/Card', module, (story, { Card }) => { story .add('default', () => ( - + Header Body



- Footer -
+ Footer + )) .add('with custom offsets', () => ( - + Header Body



- Footer -
+ Footer + )) .add('without footer', () => ( - + Header Body



-
+ )) .add('without multiple sections', () => ( - + Header Section



Section



Section



- Footer -
+ Footer + )) .add('without header', () => ( - + Body



- Footer -
+ Footer + )) .add('with scrollable body', () => ( - + Header Section







Section







Section







- Footer -
+ Footer +
)); }); diff --git a/src/components/Card/Card.test.js b/src/components/Card/Card.test.js index 79e8a80a..ef4870b2 100644 --- a/src/components/Card/Card.test.js +++ b/src/components/Card/Card.test.js @@ -6,7 +6,7 @@ describe('', () => { it('should render Card components', () => { const wrapper = mount( - + Header @@ -14,7 +14,7 @@ describe('', () => { Footer - + , ); @@ -26,7 +26,7 @@ describe('', () => { it('should render Card components with render prop', () => { const wrapper = mount( - + { ({ someArg }: *) => ( Header @@ -36,7 +36,7 @@ describe('', () => { Footer ) } - + , ); diff --git a/src/components/Card/index.js b/src/components/Card/index.js index 0a640c4f..b1546f02 100644 --- a/src/components/Card/index.js +++ b/src/components/Card/index.js @@ -1,24 +1,3 @@ // @flow -import { CardPlate } from './CardPlate'; -import { CardHeader, cardHeaderTheme } from './CardHeader'; -import { CardBody, cardBodyTheme } from './CardBody'; -import { CardSection, cardSectionTheme } from './CardSection'; -import { CardFooter, cardFooterTheme } from './CardFooter'; - -const Card = { - Plate: CardPlate, - Header: CardHeader, - Body: CardBody, - Section: CardSection, - Footer: CardFooter, -}; - -const theme = { - ...cardHeaderTheme, - ...cardBodyTheme, - ...cardSectionTheme, - ...cardFooterTheme, -}; - -export { Card, theme }; +export { Card, theme } from './Card'; diff --git a/src/components/DateInput/DateInput.js b/src/components/DateInput/DateInput.js index 27814726..0784ff47 100644 --- a/src/components/DateInput/DateInput.js +++ b/src/components/DateInput/DateInput.js @@ -131,7 +131,7 @@ class DateInput extends React.Component { const mask = withTime ? utils.DATETIME_MASK : utils.DATE_MASK; return ( - { - + ); } } diff --git a/src/components/Dialog/Dialog.js b/src/components/Dialog/Dialog.js index b1ee3832..fe785f11 100644 --- a/src/components/Dialog/Dialog.js +++ b/src/components/Dialog/Dialog.js @@ -1,23 +1,111 @@ -import { DialogBody as Body, theme as dialogBodyTheme } from './DialogBody'; -import { DialogFooter as Footer, theme as dialogFooterTheme } from './DialogFooter'; -import { DialogHeader as Header, theme as dialogHeaderTheme } from './DialogHeader'; -import { DialogPlate as Plate, theme as dialogPlateTheme } from './DialogPlate'; - -const Dialog = { - Body, - Footer, - Header, - Plate, -}; +import React from 'react'; + +import { createStyledTag, createComponentTheme } from '../../utils'; +import { Modal } from '../Modal'; +import { Card } from '../Card'; +import type { PropSizes } from '../../types'; + +import { DialogBody, theme as dialogBodyTheme } from './DialogBody'; +import { DialogFooter, theme as dialogFooterTheme } from './DialogFooter'; +import { DialogHeader, theme as dialogHeaderTheme } from './DialogHeader'; + +type DialogPlateProps = {| + children?: React$Node, + isOpen?: boolean, + onClose?: (any) => void, + onOpen?: (any) => void, + shouldCloseOnOverlayClick?: boolean, + shouldCloseOnEscPress ?: boolean, + padding?: PropSizes, + tagName?: string, +|}; + +const name = 'dialog'; + +const dialogTheme = createComponentTheme(name, { + modifiers: { + size: { + xs: { + width: '300px', + }, + sm: { + width: '400px', + }, + md: { + width: '500px', + }, + lg: { + width: '600px', + }, + xl: { + width: '800px', + }, + }, + }, + defaults: { + size: 'md', + padding: 'md', + }, +}); const theme = { + ...dialogTheme, ...dialogBodyTheme, ...dialogFooterTheme, ...dialogHeaderTheme, - ...dialogPlateTheme, }; -export { - Dialog, - theme, +const DialogTag = createStyledTag(name, { + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + maxHeight: '90%', + flex: '0 1 90%', +}); + +const Dialog = ({ + children, + id, + isOpen, + onOpen, + onClose, + shouldCloseOnOverlayClick, + shouldCloseOnEscPress, + size, + args, + tagName, + ...rest + }: DialogPlateProps) => { + return ( + + { + ({ args, onClose }) => ( + + + { children } + + + ) + } + + ); +}; + +Dialog.defaultProps = { + ...dialogTheme[name].defaults, + tagName: 'div', }; + +Dialog.Body = DialogBody; +Dialog.Header = DialogHeader; +Dialog.Footer = DialogFooter; + +export { Dialog, theme }; diff --git a/src/components/Dialog/Dialog.stories.js b/src/components/Dialog/Dialog.stories.js index 1d448bf4..145badc8 100644 --- a/src/components/Dialog/Dialog.stories.js +++ b/src/components/Dialog/Dialog.stories.js @@ -4,7 +4,7 @@ export default (asStory) => { asStory('Components/Dialog', module, (story, { ModalContext, Dialog, Paragraph, Button }) => { story .add('with default header, body, actions and footer', () => ( - + @@ -15,14 +15,14 @@ export default (asStory) => { - + )) .add('with state', () => ( { ({ openModal, closeModal }) => ( - closeModal('ID') }> + closeModal('ID') }> { ({ args, onClose }) => ( @@ -39,7 +39,7 @@ export default (asStory) => { ) } - + ) diff --git a/src/components/Dialog/Dialog.test.js b/src/components/Dialog/Dialog.test.js index 2d757a38..caea1cfc 100644 --- a/src/components/Dialog/Dialog.test.js +++ b/src/components/Dialog/Dialog.test.js @@ -7,7 +7,7 @@ import { Modal } from '../Modal'; describe('', () => { it('should render dialog content', () => { const wrapper = mount( - + body-text @@ -15,7 +15,7 @@ describe('', () => { footer-text - , + , ); expect(wrapper.find(Dialog.Header).text()).toBe('header-text'); @@ -26,15 +26,16 @@ describe('', () => { it('should call onClose callback', () => { const onClose = jest.fn(); const wrapper = mount( - + - , + , ); wrapper.find('CloseTag').simulate('click'); expect(onClose).toHaveBeenCalled(); }); + it('should pass props to the Modal component', () => { const onClose = jest.fn(); const onOpen = jest.fn(); @@ -55,43 +56,46 @@ describe('', () => { }; const wrapper = shallow( - , + , ); const { children, ...passedProps } = wrapper.find(Modal).props(); expect(passedProps).toEqual(modalProps); }); + it('should call onClose callback on overlay click', () => { const onClose = jest.fn(); const wrapper = mount( - + - , + , ); wrapper.find('OverlayTag').simulate('mouseDown'); expect(onClose).toHaveBeenCalled(); }); + it('should not call onClose callback on overlay click', () => { const onClose = jest.fn(); const wrapper = mount( - + - , + , ); wrapper.find('OverlayTag').simulate('mouseDown'); expect(onClose).toHaveBeenCalled(); }); + it('should call onClose callback on escape with shouldCloseOnOverlayClick=false', () => { const onClose = jest.fn(); const wrapper = mount( - + - , + , ); wrapper.find('OverlayTag').simulate('mouseDown'); diff --git a/src/components/Dialog/DialogPlate.js b/src/components/Dialog/DialogPlate.js deleted file mode 100644 index 0969f76a..00000000 --- a/src/components/Dialog/DialogPlate.js +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react'; - -import { createStyledTag, createComponentTheme } from '../../utils'; -import { Modal } from '../Modal'; -import { Card } from '../Card'; -import type { PropSizes } from '../../types'; - -type DialogPlateProps = {| - children?: React$Node, - isOpen?: boolean, - onClose?: (any) => void, - onOpen?: (any) => void, - shouldCloseOnOverlayClick?: boolean, - shouldCloseOnEscPress ?: boolean, - padding?: PropSizes, - tagName?: string, -|}; - -const name = 'dialogPlate'; - -const theme = createComponentTheme(name, { - modifiers: { - size: { - xs: { - width: '300px', - }, - sm: { - width: '400px', - }, - md: { - width: '500px', - }, - lg: { - width: '600px', - }, - xl: { - width: '800px', - }, - }, - }, - defaults: { - size: 'md', - padding: 'md', - }, -}); - -const StyledTag = createStyledTag(name, { - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - maxHeight: '90%', - flex: '0 1 90%', -}); - -function DialogPlate({ - children, - id, - isOpen, - onOpen, - onClose, - shouldCloseOnOverlayClick, - shouldCloseOnEscPress, - size, - args, - tagName, - ...rest - }: DialogPlateProps) { - return ( - - { - ({ args, onClose }) => ( - - - { children } - - - ) - } - - ); -} - -DialogPlate.defaultProps = { - ...theme[name].defaults, - tagName: 'div', -}; - -export { DialogPlate, theme }; diff --git a/src/components/Dropdown/Dropdown.js b/src/components/Dropdown/Dropdown.js index 858b80ad..3d88a89e 100644 --- a/src/components/Dropdown/Dropdown.js +++ b/src/components/Dropdown/Dropdown.js @@ -1,25 +1,121 @@ // @flow -import { DropdownPlate as Plate } from './DropdownPlate'; -import { DropdownHead as Head } from './DropdownHead'; -import { DropdownBody as Body } from './DropdownBody'; -import { theme as dropdownHeadTheme } from './DropdownHead.theme'; -import { theme as dropdownBodyTheme } from './DropdownBody.theme'; -import { theme as dropdownPlateTheme } from './DropdownPlate.theme'; - -const Dropdown = { - Head, - Body, - Plate, -}; - -const theme = { - ...dropdownHeadTheme, - ...dropdownBodyTheme, - ...dropdownPlateTheme, -}; - -export { - Dropdown, - theme, -}; +import React, { Component } from 'react'; +import fp from 'lodash/fp'; +import { compose, withStateHandlers, branch, setDisplayName } from 'recompose'; +import { Manager } from 'react-popper'; + +import { DropdownContext } from './DropdownContext'; +import { DropdownTag } from './Dropdown.theme'; +import { DropdownHead } from './DropdownHead'; +import { DropdownBody } from './DropdownBody'; + +type DropdownControlledProps = {| + /** Open state of the dropdown */ + isOpen: boolean, + /** When true then plate */ + stretch?: boolean, + /** Callback to close dropdown */ + onCloseDropdown?: () => void, + /** Callback to open dropdown */ + onOpenDropdown?: () => void, + children: React$Node, +|} + +type DropdownUncontroledProps = {| + /** Default opened state for the uncontorlled mode */ + defaultOpen?: boolean, + /** When true then plate */ + stretch?: boolean, + children: React$Node, +|} + +type DropdownContextData = {| + isOpen: boolean, + toggleDropdown: () => void, + closeDropdown?: () => void, + targetWidth?: number, + outsideClickIgnoreClass: string, +|} + + +/** When component has defaultOpen prop then adds hoc with isOpen state */ +const dropDownEnhancer: any = compose( + setDisplayName('Dropdown'), + branch( + (props) => !fp.isNil(props.defaultOpen), + withStateHandlers( + (props): { isOpen: boolean } => ({ isOpen: props.defaultOpen }), + { + onOpenDropdown: () => () => ({ isOpen: true }), + onCloseDropdown: () => () => ({ isOpen: false }), + }, + ), + ), +); + + +const DropdownPlate = dropDownEnhancer( + class DropdownPlateBase extends Component { + instanceIndex: number; + dropdownRef: ?HTMLElement; + + /** needs for the onclickoutside ignore target */ + static instancesCount = 0; + + constructor(props: DropdownControlledProps) { + super(props); + + this.instanceIndex = DropdownPlateBase.instancesCount++; + } + + toggleDropdown = () => { + const { isOpen, onOpenDropdown, onCloseDropdown } = this.props; + + isOpen + ? onCloseDropdown && onCloseDropdown() + : onOpenDropdown && onOpenDropdown(); + } + + setDropdownRef = (ref: *) => { + this.dropdownRef = ref; + } + + getDropdownWidth = () => { + return this.dropdownRef ? this.dropdownRef.offsetWidth : undefined; + } + + getIgnoreClickOutsideClass = () => `ignore-react-onclickoutside-${this.instanceIndex}`; + + render() { + const { children, onCloseDropdown, isOpen, ...rest } = this.props; + + const contextData: DropdownContextData = { + isOpen, + toggleDropdown: this.toggleDropdown, + closeDropdown: onCloseDropdown, + targetWidth: this.getDropdownWidth(), + outsideClickIgnoreClass: this.getIgnoreClickOutsideClass(), + }; + + return ( + + + + { children } + + + + ); + } + }, +); + +const Dropdown = (props: DropdownControlledProps | DropdownUncontroledProps) => ( + +); + +Dropdown.Head = DropdownHead; +Dropdown.Body = DropdownBody; + +export { Dropdown }; diff --git a/src/components/Dropdown/Dropdown.stories.js b/src/components/Dropdown/Dropdown.stories.js index 035fd46a..415fb86f 100644 --- a/src/components/Dropdown/Dropdown.stories.js +++ b/src/components/Dropdown/Dropdown.stories.js @@ -6,78 +6,78 @@ export default (asStory: *) => { asStory('Components/Dropdown', module, (story, { Dropdown, Button, Icon, Menu }) => { story .add('default', () => ( - + Body - + )) .add('with pin to right', () => ( - + Body - + )) .add('with stretch target', () => ( - + Body - + )) .add('with stretch body', () => ( - + Body - + )) .add('with custom body width', () => ( - + Body - + )) .add('with custom offset', () => ( - + Body - + )) .add('with dark background', () => ( - + Body - + )) .add('without background', () => ( - + Body - + )) .add('without close on outside click', () => ( - + Body - + )) .add('with force render', () => ( - + Body - + )) .add('with menu', () => ( - + - + Tramman Gripman Proalliance - + - + )); }); }; diff --git a/src/components/Dropdown/Dropdown.theme.js b/src/components/Dropdown/Dropdown.theme.js new file mode 100644 index 00000000..9fecaf8f --- /dev/null +++ b/src/components/Dropdown/Dropdown.theme.js @@ -0,0 +1,32 @@ +// @flow + +import { createStyledTag, createComponentTheme } from '../../utils'; +import { theme as dropdownHeadTheme } from './DropdownHead.theme'; +import { theme as dropdownBodyTheme } from './DropdownBody.theme'; + +const name = 'dropdown'; + +const dropdownTheme = createComponentTheme(name, { + modifiers: { + stretch: { + height: '100%', + width: '100%', + }, + }, + defaults: {}, +}); + +const DropdownTag = createStyledTag(name, {}); + +const theme = { + ...dropdownTheme, + ...dropdownHeadTheme, + ...dropdownBodyTheme, +}; + + +export { + theme, + DropdownTag, +}; + diff --git a/src/components/Dropdown/DropdownHead.js b/src/components/Dropdown/DropdownHead.js index f474aac6..671c7a60 100644 --- a/src/components/Dropdown/DropdownHead.js +++ b/src/components/Dropdown/DropdownHead.js @@ -28,7 +28,7 @@ type DropdownHeadPropsEnhanced = HOCBase; const DropdownHead = dropdownHeadEnhancer( - class DropdownHeadBase extends PureComponent { + class DropdownHead extends PureComponent { onClick = (event: MouseEvent) => { const { dropdown: { toggleDropdown }, stopClickPropagation, onClick } = this.props; diff --git a/src/components/Dropdown/DropdownPlate.js b/src/components/Dropdown/DropdownPlate.js deleted file mode 100644 index 39baa4b5..00000000 --- a/src/components/Dropdown/DropdownPlate.js +++ /dev/null @@ -1,112 +0,0 @@ -// @flow - -import React, { Component } from 'react'; -import fp from 'lodash/fp'; -import { compose, withStateHandlers, branch, setDisplayName } from 'recompose'; -import { Manager } from 'react-popper'; - -import { DropdownContext } from './DropdownContext'; -import { DropdownPlateTag } from './DropdownPlate.theme'; - -type DropdownControlledProps = {| - /** Open state of the dropdown */ - isOpen: boolean, - /** When true then plate */ - stretch?: boolean, - /** Callback to close dropdown */ - onCloseDropdown?: () => void, - /** Callback to open dropdown */ - onOpenDropdown?: () => void, - children: React$Node, -|} - -type DropdownUncontroledProps = {| - /** Default opened state for the uncontorlled mode */ - defaultOpen?: boolean, - /** When true then plate */ - stretch?: boolean, - children: React$Node, -|} - -type DropdownContextData = {| - isOpen: boolean, - toggleDropdown: () => void, - closeDropdown?: () => void, - targetWidth?: number, - outsideClickIgnoreClass: string, -|} - - -/** When component has defaultOpen prop then adds hoc with isOpen state */ -const dropDownEnhancer: { (any): React$ComponentType } = compose( - setDisplayName('Dropdown.Plate'), - branch( - (props) => !fp.isNil(props.defaultOpen), - withStateHandlers( - (props): { isOpen: boolean } => ({ isOpen: props.defaultOpen }), - { - onOpenDropdown: () => () => ({ isOpen: true }), - onCloseDropdown: () => () => ({ isOpen: false }), - }, - ), - ), -); - - -const DropdownPlate = dropDownEnhancer( - class DropdownPlateBase extends Component { - instanceIndex: number; - dropdownRef: ?HTMLElement; - - /** needs for the onclickoutside ignore target */ - static instancesCount = 0; - - constructor(props: DropdownControlledProps) { - super(props); - - this.instanceIndex = DropdownPlateBase.instancesCount++; - } - - toggleDropdown = () => { - const { isOpen, onOpenDropdown, onCloseDropdown } = this.props; - - isOpen - ? onCloseDropdown && onCloseDropdown() - : onOpenDropdown && onOpenDropdown(); - } - - setDropdownRef = (ref: *) => { - this.dropdownRef = ref; - } - - getDropdownWidth = () => { - return this.dropdownRef ? this.dropdownRef.offsetWidth : undefined; - } - - getIgnoreClickOutsideClass = () => `ignore-react-onclickoutside-${this.instanceIndex}`; - - render() { - const { children, onCloseDropdown, isOpen, ...rest } = this.props; - - const contextData: DropdownContextData = { - isOpen, - toggleDropdown: this.toggleDropdown, - closeDropdown: onCloseDropdown, - targetWidth: this.getDropdownWidth(), - outsideClickIgnoreClass: this.getIgnoreClickOutsideClass(), - }; - - return ( - - - - { children } - - - - ); - } - }, -); - -export { DropdownPlate }; diff --git a/src/components/Dropdown/DropdownPlate.theme.js b/src/components/Dropdown/DropdownPlate.theme.js deleted file mode 100644 index a8993fa6..00000000 --- a/src/components/Dropdown/DropdownPlate.theme.js +++ /dev/null @@ -1,23 +0,0 @@ -// @flow - -import { createStyledTag, createComponentTheme } from '../../utils'; - -const name = 'dropdownHead'; - -const theme = createComponentTheme(name, { - modifiers: { - stretch: { - height: '100%', - width: '100%', - }, - }, - defaults: {}, -}); - -const DropdownPlateTag = createStyledTag(name, {}); - -export { - theme, - DropdownPlateTag, -}; - diff --git a/src/components/Dropdown/Dropdowon.test.js b/src/components/Dropdown/Dropdowon.test.js index add4efe0..bc0ac29f 100644 --- a/src/components/Dropdown/Dropdowon.test.js +++ b/src/components/Dropdown/Dropdowon.test.js @@ -1,18 +1,18 @@ // @flow import * as React from 'react'; -import { Dropdown } from './Dropdown'; +import { Dropdown } from './'; describe('', () => { it('should open and close dropdwon by changing the props', () => { const wrapper = mount( - + Head
Body
-
, +
, ); expect(wrapper.find(Dropdown.Head).text()).toBe('Head'); @@ -32,12 +32,12 @@ describe('', () => { const onCloseDropdown = jest.fn(); const wrapper = mount( - + Head
Body
-
, +
, ); wrapper.find(Dropdown.Head).simulate('click'); @@ -51,12 +51,12 @@ describe('', () => { it('should open and close dropdwon by clicking to head', () => { const wrapper = mount( - + Head
Body
-
, +
, ); expect(wrapper.find('.body')).toHaveLength(1); @@ -75,14 +75,14 @@ describe('', () => { const onCloseDropdown = jest.fn(); const wrapper = mount( - + Head { ({ closeDropdown }: *) => (
) } - , + , ); diff --git a/src/components/Dropdown/index.js b/src/components/Dropdown/index.js index a556fb34..5618f0b8 100644 --- a/src/components/Dropdown/index.js +++ b/src/components/Dropdown/index.js @@ -1,3 +1,4 @@ // @flow -export { Dropdown, theme } from './Dropdown'; +export { Dropdown } from './Dropdown'; +export { theme } from './Dropdown.theme'; diff --git a/src/components/Form/FormPlate.js b/src/components/Form/Form.js similarity index 50% rename from src/components/Form/FormPlate.js rename to src/components/Form/Form.js index 14c97445..272f70d2 100644 --- a/src/components/Form/FormPlate.js +++ b/src/components/Form/Form.js @@ -5,6 +5,13 @@ import React from 'react'; import { createStyledTag, createComponentTheme } from '../../utils'; import { FlexLayout } from '../FlexLayout'; +import { FormField, theme as formFieldTheme } from './FormField'; +import { FormSection } from './FormSection'; +import { FormSectionBody } from './FormSectionBody'; +import { FormError, theme as formErrorTheme } from './FormError'; +import { FormSectionTitle, theme as formSectionTitleTheme } from './FormSectionTitle'; + + type FormPlateProps = { /** callback called on form submit */ onSubmit?: Function, @@ -16,9 +23,9 @@ type FormPlateProps = { component?: React$Node, }; -const name = 'formPlate'; +const name = 'form'; -const theme = createComponentTheme(name, { +const formTheme = createComponentTheme(name, { modifiers: { stretch: { height: '100%', @@ -30,37 +37,47 @@ const theme = createComponentTheme(name, { }, }); -const FormStyledTag = createStyledTag(name, { +const theme = { + ...formTheme, + ...formFieldTheme, + ...formSectionTitleTheme, + ...formErrorTheme, +}; + +const FormTag = createStyledTag(name, { flex: 1, }); -function FormPlate({ +const Form = ({ children, onSubmit, component, ...rest - }: FormPlateProps) { + }: FormPlateProps) => { return ( - - + { children } - + ); -} +}; -FormPlate.defaultProps = { +Form.defaultProps = { ...theme[name].defaults, component: 'form', direction: 'column', gap: 'md', alignItems: 'stretch', - }; -export { FormPlate, theme }; +Form.Field = FormField; +Form.Section = FormSection; +Form.SectionBody = FormSectionBody; +Form.SectionTitle = FormSectionTitle; +Form.Error = FormError; + +export { Form, theme }; diff --git a/src/components/Form/Form.stories.js b/src/components/Form/Form.stories.js index 308896bf..cd8993b6 100644 --- a/src/components/Form/Form.stories.js +++ b/src/components/Form/Form.stories.js @@ -8,16 +8,16 @@ export default (asStory) => { asStory('Components/Form', module, (story, { Form, InputField }) => { story .add('without groups', () => ( - +
- + )) .add('with groups', () => ( - +
Some section 1 @@ -33,10 +33,10 @@ export default (asStory) => { - +
)) .add('with form error', () => ( - +
@@ -45,10 +45,10 @@ export default (asStory) => { - + )) .add('with form error is null', () => ( - +
@@ -57,7 +57,7 @@ export default (asStory) => { - + )); }); }; diff --git a/src/components/Form/Form.test.js b/src/components/Form/Form.test.js index 58ccbf6c..5611212c 100644 --- a/src/components/Form/Form.test.js +++ b/src/components/Form/Form.test.js @@ -7,7 +7,7 @@ describe('
', () => { it('should render form components', () => { const wrapper = mount( - + Some section 1 @@ -21,7 +21,7 @@ describe('', () => { - +
, ); diff --git a/src/components/Form/index.js b/src/components/Form/index.js index a655ddc2..f0fd18ed 100644 --- a/src/components/Form/index.js +++ b/src/components/Form/index.js @@ -1,30 +1,3 @@ // @flow -import { FormField as Field, theme as formFieldTheme, ControlErrorTag } from './FormField'; -import { FormPlate as Plate, theme as formPlateTheme } from './FormPlate'; -import { FormSection as Section } from './FormSection'; -import { FormSectionBody as SectionBody } from './FormSectionBody'; -import { FormError as Error, theme as formErrorTheme } from './FormError'; -import { FormSectionTitle as SectionTitle, theme as formSectionTitleTheme } from './FormSectionTitle'; - -const Form = { - Field, - Plate, - Error, - Section, - SectionTitle, - SectionBody, - ControlErrorTag, -}; - -const theme = { - ...formFieldTheme, - ...formPlateTheme, - ...formSectionTitleTheme, - ...formErrorTheme, -}; - -export { - Form, - theme, -}; +export { Form, theme } from './Form'; diff --git a/src/components/Menu/Menu.js b/src/components/Menu/Menu.js index f929c852..dc6957b1 100644 --- a/src/components/Menu/Menu.js +++ b/src/components/Menu/Menu.js @@ -1,17 +1,48 @@ -import { MenuPlate as Plate, theme as menuPlateTheme } from './MenuPlate'; -import { MenuItem as Item, theme as menuItemTheme } from './MenuItem'; +// @flow -const Menu = { - Plate, - Item, -}; +import React from 'react'; + +import { createStyledTag, createComponentTheme } from '../../utils'; +import { Paper } from '../Paper'; + +import { MenuItem, theme as menuItemTheme } from './MenuItem'; + + +type MenuPlateProps = {| + children?: React$Node, +|}; + +const name = 'menu'; + +const menuTheme = createComponentTheme(name, { + root: { + paddingTop: '8px', + paddingBottom: '8px', + }, +}); const theme = { - ...menuPlateTheme, + ...menuTheme, ...menuItemTheme, }; -export { - Menu, - theme, -}; + +const MenuTag = createStyledTag(name, () => ({ + display: 'flex', + flexDirection: 'column', + boxSizing: 'border-box', + overflow: 'hidden', +})); + +const Menu = ({ children, ...rest }: MenuPlateProps) => ( + + + { children } + + +); + +Menu.Item = MenuItem; + + +export { Menu, theme }; diff --git a/src/components/Menu/Menu.stories.js b/src/components/Menu/Menu.stories.js index 422ebc71..2c8e3233 100644 --- a/src/components/Menu/Menu.stories.js +++ b/src/components/Menu/Menu.stories.js @@ -4,11 +4,11 @@ export default (asStory) => { asStory('Components/Menu', module, (story, { Menu }) => { story .add('with some items', () => ( - + Tramman Gripman Proalliance - + )); }); }; diff --git a/src/components/Menu/Menu.test.js b/src/components/Menu/Menu.test.js index 451e4af5..9ff8c133 100644 --- a/src/components/Menu/Menu.test.js +++ b/src/components/Menu/Menu.test.js @@ -6,11 +6,11 @@ describe('', () => { it('should render Menu components', () => { const wrapper = mount( - + Tramman Gripman Proalliance - + , ); diff --git a/src/components/Menu/MenuPlate.js b/src/components/Menu/MenuPlate.js deleted file mode 100644 index 6ff4c2ac..00000000 --- a/src/components/Menu/MenuPlate.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; - -import { createStyledTag, createComponentTheme } from '../../utils'; -import { Paper } from '../Paper'; - -type MenuPlateProps = {| - children?: React$Node, -|}; - -const name = 'menuPlate'; - -const theme = createComponentTheme(name, { - root: { - paddingTop: '8px', - paddingBottom: '8px', - }, -}); - -const StyledTag = createStyledTag(name, () => ({ - display: 'flex', - flexDirection: 'column', - boxSizing: 'border-box', - overflow: 'hidden', -})); - -const MenuPlate = ({ children, ...rest }: MenuPlateProps) => ( - - - { children } - - -); - -MenuPlate.displayName = 'Menu.Plate'; - -export { MenuPlate, theme }; diff --git a/src/components/Menu/index.js b/src/components/Menu/index.js index 8b6d5347..f2511b0b 100644 --- a/src/components/Menu/index.js +++ b/src/components/Menu/index.js @@ -1 +1,3 @@ +// @flow + export { Menu, theme } from './Menu'; diff --git a/src/components/Navigation/Navigation.js b/src/components/Navigation/Navigation.js index c59412a2..2c7ac706 100644 --- a/src/components/Navigation/Navigation.js +++ b/src/components/Navigation/Navigation.js @@ -1,17 +1,65 @@ -import { NavigationItem as Item, theme as navigationItemTheme } from './NavigationItem'; -import { NavigationPlate as Plate, theme as navigationPlateTheme } from './NavigationPlate'; +import React from 'react'; +import fp from 'lodash/fp'; -const Navigation = { - Item, - Plate, -}; +import { createStyledTag, createComponentTheme } from '../../utils'; +import { PALETTE } from '../../theme'; + +import { NavigationItem, theme as navigationItemTheme } from './NavigationItem'; + + +type NavigationProps = {| + children?: React.Node, + color: $Keys +|}; + +const name = 'navigationPlate'; + +const navigationTheme = createComponentTheme(name, { + root: { + width: '60px', + }, + modifiers: { + color: fp.mapValues((color) => ({ + backgroundColor: color, + }), PALETTE), + }, +}); const theme = { + ...navigationTheme, ...navigationItemTheme, - ...navigationPlateTheme, }; -export { - Navigation, - theme, +const NavigationTag = createStyledTag(name, { + display: 'flex', + flexDirection: 'column', + height: '100%', + + '&:hover': { + width: 'auto', + + '.NavigationItem-label': { + display: 'flex', + }, + }, +}); + +const Navigation = ({ + children, + color, + ...rest + }: NavigationProps) => { + return ( + + { + React.Children.map(children, child => + React.cloneElement(child, { color: child.props.color || color }), + ) + } + + ); }; + +Navigation.Item = NavigationItem; + +export { Navigation, theme }; diff --git a/src/components/Navigation/Navigation.stories.js b/src/components/Navigation/Navigation.stories.js index 74aa8db9..d80344f0 100644 --- a/src/components/Navigation/Navigation.stories.js +++ b/src/components/Navigation/Navigation.stories.js @@ -4,11 +4,11 @@ export default (asStory) => { asStory('Components/Navigation', module, (story, { Navigation }) => { story .add('without groups', () => ( - + - + )); }); }; diff --git a/src/components/Navigation/Navigation.test.js b/src/components/Navigation/Navigation.test.js index ff5105c0..8472b033 100644 --- a/src/components/Navigation/Navigation.test.js +++ b/src/components/Navigation/Navigation.test.js @@ -5,9 +5,9 @@ import { Navigation } from './Navigation'; describe('', () => { it('should render navigation', () => { const wrapper = shallow( - + - , + , ); expect(wrapper).toMatchInlineSnapshot(` @@ -31,14 +31,14 @@ describe('', () => { const Link = () => null; const wrapper = mount( - + - , + , ); expect(wrapper.find(Link).props().to).toBe('/jobs'); diff --git a/src/components/Navigation/NavigationPlate.js b/src/components/Navigation/NavigationPlate.js deleted file mode 100644 index 51df78be..00000000 --- a/src/components/Navigation/NavigationPlate.js +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import fp from 'lodash/fp'; - -import { createStyledTag, createComponentTheme } from '../../utils'; -import { PALETTE } from '../../theme'; - -type NavigationPlateProps = {| - children?: React.Node, - color: $Keys -|}; - -const name = 'navigationPlate'; - -const theme = createComponentTheme(name, { - root: { - width: '60px', - }, - modifiers: { - color: fp.mapValues((color) => ({ - backgroundColor: color, - }), PALETTE), - }, -}); - -const StyledTag = createStyledTag(name, { - display: 'flex', - flexDirection: 'column', - height: '100%', - - '&:hover': { - width: 'auto', - - '.NavigationItem-label': { - display: 'flex', - }, - }, -}); - -function NavigationPlate({ - children, - color, - ...rest - }: NavigationPlateProps) { - return ( - - { - React.Children.map(children, child => - React.cloneElement(child, { color: child.props.color || color }), - ) - } - - ); -} - -export { NavigationPlate, theme }; diff --git a/src/components/SecondaryNavigation/SecondNavigation.stories.js b/src/components/SecondaryNavigation/SecondNavigation.stories.js index 54824ed2..38ba72a4 100644 --- a/src/components/SecondaryNavigation/SecondNavigation.stories.js +++ b/src/components/SecondaryNavigation/SecondNavigation.stories.js @@ -4,12 +4,12 @@ export default (asStory) => { asStory('Components/SecondaryNavigation', module, (story, { SecondaryNavigation }) => { story .add('secondary navigation', () => ( - + - + )); }); }; diff --git a/src/components/SecondaryNavigation/SecondaryNavigation.js b/src/components/SecondaryNavigation/SecondaryNavigation.js index c88083e7..b199e336 100644 --- a/src/components/SecondaryNavigation/SecondaryNavigation.js +++ b/src/components/SecondaryNavigation/SecondaryNavigation.js @@ -1,19 +1,42 @@ -import { - SecondaryNavigationPlate as Plate, - theme as secondaryNavigationPlateTheme, -} from './SecondaryNavigationPlate'; -import { - SecondaryNavigationItem as Item, - theme as secondaryNavigationItemTheme, -} from './SecondaryNavigationItem'; - -export const SecondaryNavigation = { - Item, - Plate, +// @flow + +import React from 'react'; + +import { GREY_COLORS } from '../../theme/dsmColors'; +import { createStyledTag, createComponentTheme } from '../../utils'; +import { SecondaryNavigationItem, theme as secondaryNavigationItemTheme } from './SecondaryNavigationItem'; + +type SecondaryNavigationProps = { + children: React$Node, }; -export const theme = { - ...secondaryNavigationPlateTheme, +const name = 'secondaryNavigation'; + +const secondaryNavigationTheme = createComponentTheme(name, { + root: { + backgroundColor: GREY_COLORS.DSM_LIGHT_GREY_3, + }, +}); + +const theme = { + ...secondaryNavigationTheme, ...secondaryNavigationItemTheme, }; +const SecondaryNavigationTag = createStyledTag(name, { + display: 'flex', + flexDirection: 'column', + height: '100%', + width: 'auto', +}); + +const SecondaryNavigation = ({ children, ...rest }: SecondaryNavigationProps) => ( + + { children } + +); + +SecondaryNavigation.Item = SecondaryNavigationItem; + +export { SecondaryNavigation, theme }; + diff --git a/src/components/SecondaryNavigation/SecondaryNavigation.test.js b/src/components/SecondaryNavigation/SecondaryNavigation.test.js index 7bd68155..8d1f2656 100644 --- a/src/components/SecondaryNavigation/SecondaryNavigation.test.js +++ b/src/components/SecondaryNavigation/SecondaryNavigation.test.js @@ -6,12 +6,12 @@ describe('', () => { it('should render SecondaryNavigation components', () => { const wrapper = mount( - + - + , ); diff --git a/src/components/SecondaryNavigation/SecondaryNavigationPlate.js b/src/components/SecondaryNavigation/SecondaryNavigationPlate.js deleted file mode 100644 index 45a3072e..00000000 --- a/src/components/SecondaryNavigation/SecondaryNavigationPlate.js +++ /dev/null @@ -1,32 +0,0 @@ -// @flow - -import React from 'react'; - -import { GREY_COLORS } from '../../theme/dsmColors'; -import { createStyledTag, createComponentTheme } from '../../utils'; - -type SecondaryNavigationPlateProps = { - children: React$Node, -}; - -const name = 'secondaryNavigationPlate'; - -export const theme = createComponentTheme(name, { - root: { - backgroundColor: GREY_COLORS.DSM_LIGHT_GREY_3, - }, -}); - -const StyledTag = createStyledTag(name, { - display: 'flex', - flexDirection: 'column', - height: '100%', - width: 'auto', -}); - -export const SecondaryNavigationPlate = ({ children, ...rest }: SecondaryNavigationPlateProps) => ( - - { children } - -); - diff --git a/src/components/Table/Table.js b/src/components/Table/Table.js index 23faa10a..2ad6e901 100644 --- a/src/components/Table/Table.js +++ b/src/components/Table/Table.js @@ -1,29 +1,37 @@ // @flow +import React from 'react'; + +import { Grid } from '../Grid'; +import { createStyledTag, createComponentTheme } from '../../utils'; import { theme as tableActionTheme } from './TableAction'; import { theme as tableNoDataTheme } from './TableNoData'; -import { TablePlate as Plate, theme as tablePlateTheme } from './TablePlate'; -import { TableHeader as Header, theme as tableHeaderTheme } from './TableHeader'; -import { TableBody as Body, theme as tableBodyTheme } from './TableBody'; -import { TableBodyRow as BodyRow, theme as tableBodyRowTheme } from './TableBodyRow'; -import { TableFooter as Footer, theme as tableFooterTheme } from './TableFooter'; -import { TableHeaderCell as HeaderCell, theme as tableHeaderCellTheme } from './TableHeaderCell'; -import { TableBodyCell as BodyCell, theme as tableBodyCellTheme } from './TableBodyCell'; - -const Table = { - Plate, - Header, - Body, - BodyRow, - Footer, - HeaderCell, - BodyCell, +import { TableHeader, theme as tableHeaderTheme } from './TableHeader'; +import { TableBody, theme as tableBodyTheme } from './TableBody'; +import { TableBodyRow, theme as tableBodyRowTheme } from './TableBodyRow'; +import { TableFooter, theme as tableFooterTheme } from './TableFooter'; +import { TableHeaderCell, theme as tableHeaderCellTheme } from './TableHeaderCell'; +import { TableBodyCell, theme as tableBodyCellTheme } from './TableBodyCell'; + + +type TablePlateProps = { + children?: React$Node, + stretch?: boolean, }; +const name = 'tablePlate'; + +const tableTheme = createComponentTheme(name, { + modifiers: { + }, + defaults: { + }, +}); + const theme = { + ...tableTheme, ...tableActionTheme, ...tableNoDataTheme, - ...tablePlateTheme, ...tableHeaderTheme, ...tableBodyTheme, ...tableBodyRowTheme, @@ -32,7 +40,25 @@ const theme = { ...tableBodyCellTheme, }; -export { - Table, - theme, +const TableTag = createStyledTag(name); + +function Table({ + children, + ...rest + }: TablePlateProps) { + return { children }; +} + +Table.defaultProps = { + rows: 'auto 1fr auto', + stretch: true, }; + +Table.Header = TableHeader; +Table.Body = TableBody; +Table.BodyRow = TableBodyRow; +Table.Footer = TableFooter; +Table.HeaderCell = TableHeaderCell; +Table.BodyCell = TableBodyCell; + +export { Table, theme }; diff --git a/src/components/Table/Table.stories.js b/src/components/Table/Table.stories.js index 7a91e5dc..f69a69e4 100644 --- a/src/components/Table/Table.stories.js +++ b/src/components/Table/Table.stories.js @@ -219,7 +219,7 @@ export default (asStory) => { story .add('table with data', () => (
- + Id Name @@ -248,27 +248,27 @@ export default (asStory) => { { client.updatedAt } - + - + alert('Delete') }>Delete - + - + ) } - +
)) .add('table with scroll', () => (
- + Id Name @@ -297,27 +297,27 @@ export default (asStory) => { { client.updatedAt } - + - + alert('Delete') }>Delete - + - + ) } - +
)) .add('table with loader', () => (
- + Id Name @@ -327,13 +327,13 @@ export default (asStory) => { alert('Create') } /> - +
)) .add('without data', () => (
- + Id Name @@ -344,13 +344,13 @@ export default (asStory) => { - +
)) .add('with custom action button', () => (
- + Id Name @@ -371,7 +371,7 @@ export default (asStory) => { ) } /> - +
)); }); diff --git a/src/components/Table/Table.test.js b/src/components/Table/Table.test.js index 1dd8472a..ded514a2 100644 --- a/src/components/Table/Table.test.js +++ b/src/components/Table/Table.test.js @@ -32,7 +32,7 @@ describe('', () => { it('should render table', () => { const wrapper = mount( - +
Id Name @@ -41,7 +41,7 @@ describe('
', () => { { renderTableBody } Footer - +
, ); @@ -60,7 +60,7 @@ describe('', () => { const onActionClick = jest.fn(); const wrapper = mount( - +
Id Name @@ -68,7 +68,7 @@ describe('
', () => { { renderTableBody } - , +
, ); expect(wrapper.find(TableAction).text()).toBe('Create Client'); @@ -80,7 +80,7 @@ describe('', () => { it('should render with custom action button', () => { const wrapper = mount( - +
Id Name @@ -88,7 +88,7 @@ describe('
', () => { Create Client }> { renderTableBody } - , +
, ); expect(wrapper.find(TableAction).text()).toBe('Create Client'); @@ -96,7 +96,7 @@ describe('', () => { it('should render without data', () => { const wrapper = mount( - +
Id Name @@ -104,7 +104,7 @@ describe('
', () => { Create Client }> { renderTableBody } - , +
, ); expect(wrapper.find(Table.BodyRow)).toHaveLength(0); diff --git a/src/components/Table/TablePlate.js b/src/components/Table/TablePlate.js deleted file mode 100644 index e07409f2..00000000 --- a/src/components/Table/TablePlate.js +++ /dev/null @@ -1,35 +0,0 @@ -// @flow -import React from 'react'; - -import { Grid } from '../Grid'; -import { createStyledTag, createComponentTheme } from '../../utils'; - -type TablePlateProps = { - children?: React$Node, - stretch?: boolean, -}; - -const name = 'tablePlate'; - -const theme = createComponentTheme(name, { - modifiers: { - }, - defaults: { - }, -}); - -const TablePlateTag = createStyledTag(name); - -function TablePlate({ - children, - ...rest - }: TablePlateProps) { - return { children }; -} - -TablePlate.defaultProps = { - rows: 'auto 1fr auto', - stretch: true, -}; - -export { TablePlate, theme }; diff --git a/src/components/Tabs/TabsPlate.js b/src/components/Tabs/Tabs.js similarity index 84% rename from src/components/Tabs/TabsPlate.js rename to src/components/Tabs/Tabs.js index cf332c3d..d71e87b7 100644 --- a/src/components/Tabs/TabsPlate.js +++ b/src/components/Tabs/Tabs.js @@ -3,8 +3,11 @@ import React from 'react'; import fp from 'lodash/fp'; import { compose, withStateHandlers, branch, setDisplayName } from 'recompose'; + import { createStyledTag } from '../../utils'; import { TabsContext } from './TabsContext'; +import { TabPanel } from './TabPanel'; +import { TabTitle } from './TabTitle'; type TabsProps = { @@ -23,7 +26,21 @@ type WithStateTabsProps = { const TabPlateTag = createStyledTag('tabPlate', {}); -const TabsPlateBase = ({ + +const tabsEnhancer: { (any): React$ComponentType } = compose( + setDisplayName('TabsPlate'), + branch( + (props) => !fp.isNil(props.defaultSelectedTabId), + withStateHandlers( + (props) => ({ selectedTabId: props.defaultSelectedTabId }), + { + onSelect: () => (tabId) => ({ selectedTabId: tabId }), + }, + ), + ), +); + +const TabsPlate = tabsEnhancer(({ children, onSelect, selectedTabId, @@ -41,21 +58,12 @@ const TabsPlateBase = ({ ); -}; +}); -const tabsEnhancer: { (any): React$ComponentType } = compose( - setDisplayName('TabsPlate'), - branch( - (props) => !fp.isNil(props.defaultSelectedTabId), - withStateHandlers( - (props) => ({ selectedTabId: props.defaultSelectedTabId }), - { - onSelect: () => (tabId) => ({ selectedTabId: tabId }), - }, - ), - ), -); +const Tabs = (props: *) => ; + +Tabs.Title = TabTitle; +Tabs.Panel = TabPanel; -const TabsPlate = tabsEnhancer(TabsPlateBase); -export { TabsPlate }; +export { Tabs }; diff --git a/src/components/Tabs/Tabs.stories.js b/src/components/Tabs/Tabs.stories.js index 312c2ad3..81b14d7e 100644 --- a/src/components/Tabs/Tabs.stories.js +++ b/src/components/Tabs/Tabs.stories.js @@ -4,27 +4,27 @@ export default (asStory: *) => { asStory('Components/Tabs', module, (story, { Tabs, Row, Button }) => { story .add('default', () => ( - + Body-1 Body-2 - + )) .add('with force render', () => ( - + Body-1 Body-2 - + )) .add('with selected title', () => ( - + { ({ selected }) => } @@ -39,7 +39,7 @@ export default (asStory: *) => { Body-1 Body-2 Body-3 - + )); }); }; diff --git a/src/components/Tabs/Tabs.test.js b/src/components/Tabs/Tabs.test.js index 3457848a..2f3276fe 100644 --- a/src/components/Tabs/Tabs.test.js +++ b/src/components/Tabs/Tabs.test.js @@ -5,7 +5,7 @@ import { Tabs } from './'; describe('', () => { it('should render selected tab', () => { const wrapper = mount( - +
Tab-1
Tab-2
@@ -14,7 +14,7 @@ describe('', () => {
Body-2
-
, +
, ); expect(wrapper.find('.body-1').text()).toBe('Body-1'); @@ -29,12 +29,12 @@ describe('', () => { it('should render head as a render prop', () => { const wrapper = mount( - + { ({ selected }) =>
Tab-1 is { selected && 'selected' }
}
{ ({ selected }) =>
Tab-2 is { !selected && 'not selected' }
}
Body-1 Body-2 -
, +
, ); expect(wrapper.find('.head-1').text()).toBe('Tab-1 is selected'); @@ -45,7 +45,7 @@ describe('', () => { it('should call onSelect callback', () => { const onSelect = jest.fn(); const wrapper = mount( - +
Tab-1
Tab-2
@@ -54,7 +54,7 @@ describe('', () => {
Body-2
-
, +
, ); wrapper.find(Tabs.Title).at(0).simulate('click'); @@ -67,7 +67,7 @@ describe('', () => { it('should toggle tabs in statefull mode', () => { const wrapper = mount( - +
Tab-1
Tab-2
@@ -76,7 +76,7 @@ describe('', () => {
Body-2
-
, +
, ); wrapper.find(Tabs.Title).at(1).simulate('click'); @@ -92,7 +92,7 @@ describe('', () => { it('should render panels with force', () => { const onSelect = jest.fn(); const wrapper = mount( - +
Tab-1
Tab-2
@@ -101,7 +101,7 @@ describe('', () => { Body-2 -
, +
, ); expect(wrapper.find('.body-1').text()).toBe('Body-1'); diff --git a/src/components/Tabs/index.js b/src/components/Tabs/index.js index 44a9d98b..7acaab46 100644 --- a/src/components/Tabs/index.js +++ b/src/components/Tabs/index.js @@ -1,12 +1,3 @@ //@flow -import { TabsPlate } from './TabsPlate'; -import { TabPanel } from './TabPanel'; -import { TabTitle } from './TabTitle'; -const Tabs = { - Plate: TabsPlate, - Title: TabTitle, - Panel: TabPanel, -}; - -export { Tabs }; +export { Tabs } from './Tabs';