From b0dd0108bf4f8d3cad3fd6d82ed32f6b3c5b454b Mon Sep 17 00:00:00 2001 From: Robert Baruck Date: Thu, 6 Dec 2018 11:36:52 +0100 Subject: [PATCH] REFACTOR: migrate DropDown component to TS --- .../__snapshots__/wrapper.spec.tsx.snap | 8 +- .../DropDown/{index.spec.js => index.spec.ts} | 0 .../src/DropDown/{index.js => index.ts} | 22 +++-- .../src/DropDown/wrapper.spec.tsx | 5 +- .../src/DropDown/wrapper.tsx | 90 +++++++++---------- 5 files changed, 64 insertions(+), 61 deletions(-) rename packages/react-ui-components/src/DropDown/{index.spec.js => index.spec.ts} (100%) rename packages/react-ui-components/src/DropDown/{index.js => index.ts} (72%) diff --git a/packages/react-ui-components/src/DropDown/__snapshots__/wrapper.spec.tsx.snap b/packages/react-ui-components/src/DropDown/__snapshots__/wrapper.spec.tsx.snap index faf5a98f81..f0d3cc0fba 100644 --- a/packages/react-ui-components/src/DropDown/__snapshots__/wrapper.spec.tsx.snap +++ b/packages/react-ui-components/src/DropDown/__snapshots__/wrapper.spec.tsx.snap @@ -6,7 +6,13 @@ exports[` should render correctly. 1`] = ` onClose={[Function]} onToggle={[Function]} style="default" - theme={Object {}} + theme={ + Object { + "dropDown": "dropDownClassName", + "dropDown--padded": "paddedClassName", + "dropDown__btn": "btnClassName", + } + } > Foo children diff --git a/packages/react-ui-components/src/DropDown/index.spec.js b/packages/react-ui-components/src/DropDown/index.spec.ts similarity index 100% rename from packages/react-ui-components/src/DropDown/index.spec.js rename to packages/react-ui-components/src/DropDown/index.spec.ts diff --git a/packages/react-ui-components/src/DropDown/index.js b/packages/react-ui-components/src/DropDown/index.ts similarity index 72% rename from packages/react-ui-components/src/DropDown/index.js rename to packages/react-ui-components/src/DropDown/index.ts index 8bb41f15b3..b5caaa2bcb 100644 --- a/packages/react-ui-components/src/DropDown/index.js +++ b/packages/react-ui-components/src/DropDown/index.ts @@ -1,26 +1,24 @@ import {themr} from '@friendsofreactjs/react-css-themr'; -import identifiers from '../identifiers'; -import style from './style.css'; + +import identifiers from '@neos-project/react-ui-components/src/identifiers'; import ContextDropDownWrapper, { StatelessDropDownWrapper, ContextDropDownHeader, ContextDropDownContents -} from './wrapper'; +} from '@neos-project/react-ui-components/src/DropDown/wrapper'; + +import style from './style.css'; const DropDown = themr(identifiers.dropDown, style)(ContextDropDownWrapper); const StatelessDropDown = themr(identifiers.dropDown, style)(StatelessDropDownWrapper); const DropDownHeader = themr(identifiers.dropDownHeader, style)(ContextDropDownHeader); const DropDownContents = themr(identifiers.dropDownContents, style)(ContextDropDownContents); -// -// Dependency injection -// -import injectProps from './../_lib/injectProps'; -import Icon from './../Icon'; - -DropDown.Header = injectProps({ - IconComponent: Icon -})(DropDownHeader); +// @ts-ignore +DropDown.Header = DropDownHeader; +// @ts-ignore DropDown.Contents = DropDownContents; +// @ts-ignore DropDown.Stateless = StatelessDropDown; + export default DropDown; diff --git a/packages/react-ui-components/src/DropDown/wrapper.spec.tsx b/packages/react-ui-components/src/DropDown/wrapper.spec.tsx index 36984dfa44..ea70483a63 100644 --- a/packages/react-ui-components/src/DropDown/wrapper.spec.tsx +++ b/packages/react-ui-components/src/DropDown/wrapper.spec.tsx @@ -2,7 +2,7 @@ import React from 'react'; import {shallow} from 'enzyme'; import toJson from 'enzyme-to-json'; -import {DropDownWrapper, DropDownWrapperProps, defaultProps} from '@neos-project/react-ui-components/src/DropDown/wrapper'; +import {DropDownWrapper, DropDownWrapperProps, defaultProps} from './wrapper'; describe('', () => { const props: DropDownWrapperProps = { @@ -36,10 +36,12 @@ describe('', () => { it('should set the "isOpen" state value to opposite when calling the toggle method.', () => { const wrapper = shallow(); + // @ts-ignore wrapper.instance().handleToggle(); expect(wrapper.state('isOpen')).toBe(true); + // @ts-ignore wrapper.instance().handleToggle(); expect(wrapper.state('isOpen')).toBe(false); @@ -47,6 +49,7 @@ describe('', () => { it('should set the "isOpen" state value to false when calling the close method.', () => { const wrapper = shallow(); + // @ts-ignore wrapper.instance().handleClose(); expect(wrapper.state('isOpen')).toBe(false); diff --git a/packages/react-ui-components/src/DropDown/wrapper.tsx b/packages/react-ui-components/src/DropDown/wrapper.tsx index 8d3c4a7653..95f3a72746 100644 --- a/packages/react-ui-components/src/DropDown/wrapper.tsx +++ b/packages/react-ui-components/src/DropDown/wrapper.tsx @@ -7,6 +7,7 @@ import enhanceWithClickOutside from 'react-click-outside'; import { PickDefaultProps } from '../../types'; import ShallowDropDownHeader from './header'; import ShallowDropDownContents from './contents'; +import PropTypes from 'prop-types'; export interface DropDownWrapperProps { /** @@ -60,33 +61,6 @@ interface DropDownWrapperState { readonly isOpen: boolean; } -export default class DropDownWrapper extends PureComponent { - public static readonly defaultProps = defaultProps; - - constructor(props: DropDownWrapperProps) { - super(props); - this.state = { - isOpen: props.isOpen - }; - } - - public render(): JSX.Element { - return ; - } - - private readonly handleToggle = (event: MouseEvent) => { - if (this.props.onToggle) { - this.props.onToggle(event); - } - - this.setState({isOpen: !this.state.isOpen}); - } - - private readonly handleClose = () => { - this.setState({isOpen: false}); - } -} - export interface StatelessDropDownWrapperWithoutClickOutsideBehaviorProps extends DropDownWrapperProps { onToggle: (event: MouseEvent) => void; onClose: (event?: MouseEvent) => void; @@ -100,7 +74,12 @@ export interface ChildContext { class StatelessDropDownWrapperWithoutClickOutsideBehavior extends PureComponent { public static readonly defaultProps = defaultProps; - public getChildContext = (): ChildContext => ({ + public static readonly childContextTypes = { + toggleDropDown: PropTypes.func.isRequired, + closeDropDown: PropTypes.func.isRequired, + }; + + public readonly getChildContext = (): ChildContext => ({ toggleDropDown: this.handleToggle, closeDropDown: this.handleClose, }) @@ -125,16 +104,11 @@ class StatelessDropDownWrapperWithoutClickOutsideBehavior extends PureComponent< return (
- {React.Children.map(children, child => { - if (React.isValidElement<{context: ChildContext}>(child)) { - return React.cloneElement(child, { - ...child.props, - context: this.getChildContext() - }); - } else { - return child; - } - })} + {React.Children.map( + children, + // @ts-ignore + child => typeof child.type === 'string' ? child : + )}
); } @@ -161,13 +135,41 @@ class StatelessDropDownWrapperWithoutClickOutsideBehavior extends PureComponent< export const StatelessDropDownWrapper = enhanceWithClickOutside(StatelessDropDownWrapperWithoutClickOutsideBehavior); +export class DropDownWrapper extends PureComponent { + public static readonly defaultProps = defaultProps; + + constructor(props: DropDownWrapperProps) { + super(props); + this.state = { + isOpen: props.isOpen + }; + } + + public render(): JSX.Element { + return ; + } + + private readonly handleToggle = (event: MouseEvent) => { + if (this.props.onToggle) { + this.props.onToggle(event); + } + + this.setState({isOpen: !this.state.isOpen}); + } + + private readonly handleClose = () => { + this.setState({isOpen: false}); + } +} + +export default DropDownWrapper; export interface ContextDropDownProps extends DropDownWrapperProps { isDropdownOpen?: boolean; } export class ContextDropDownHeader extends PureComponent { - public static contextTypes = { + public static readonly contextTypes = { toggleDropDown: PropTypes.func.isRequired }; @@ -177,15 +179,9 @@ export class ContextDropDownHeader extends PureComponent { return ; } } -export class ContextDropDownContents extends PureComponent { - public static propTypes = { - /** - * The propagated isOpen state from the dropDown - */ - isDropdownOpen: PropTypes.bool - }; - public static contextTypes = { +export class ContextDropDownContents extends PureComponent { + public static readonly contextTypes = { closeDropDown: PropTypes.func.isRequired };