From 71dd6f73b416f4aff0ca1e0249b9b5fb9446a06f Mon Sep 17 00:00:00 2001 From: Yauhen Date: Fri, 26 Jul 2019 14:20:04 +0300 Subject: [PATCH] feat(ui/theme): "modal-team" missing update functionality add --- src/framework/theme/modal/modal.service.tsx | 10 + .../theme/modal/modalPanel.component.tsx | 14 ++ src/framework/ui/modal/modal.component.tsx | 12 +- src/framework/ui/modal/modal.spec.tsx | 96 ++++++++- .../ui/popover/popover.component.tsx | 17 +- src/framework/ui/support/typings/type.ts | 2 + src/playground/package-lock.json | 195 ++++++++---------- 7 files changed, 228 insertions(+), 118 deletions(-) diff --git a/src/framework/theme/modal/modal.service.tsx b/src/framework/theme/modal/modal.service.tsx index c1211d402..5b4483b94 100644 --- a/src/framework/theme/modal/modal.service.tsx +++ b/src/framework/theme/modal/modal.service.tsx @@ -17,6 +17,8 @@ import { ModalPresentingBased } from '../../ui/support/typings'; * * @method {(identifier: string) => string} hide - Hides component from a modal window and returns empty string. * + * @method {(identifier: string, children: React.ReactNode) => void} update - Updates component from a modal window. + * * @example Simple Usage example * * ``` @@ -87,6 +89,12 @@ class ModalServiceType { } } + public update(identifier: string, children: React.ReactNode): void { + if (this.panel) { + this.panel.update(identifier, children); + } + } + public hide(identifier: string): string { if (this.panel) { return this.panel.hide(identifier); @@ -104,6 +112,8 @@ export interface ModalPresenting { config: ModalPresentingConfig): string; hide(identifier: string): string; + + update(identifier: string, children: React.ReactNode): void; } export const ModalService = new ModalServiceType(); diff --git a/src/framework/theme/modal/modalPanel.component.tsx b/src/framework/theme/modal/modalPanel.component.tsx index c9800a9f2..790fbca49 100644 --- a/src/framework/theme/modal/modalPanel.component.tsx +++ b/src/framework/theme/modal/modalPanel.component.tsx @@ -66,6 +66,20 @@ export class ModalPanel extends React.Component = panelChild.element; + + panelChild.element = React.cloneElement(childElement, { + children: children, + }); + + const components: Map = this.state.components; + components.delete(identifier); + components.set(identifier, panelChild); + this.setState({ components }); + } + private generateUniqueComponentKey = (): string => { return Math.random().toString(36).substring(2); }; diff --git a/src/framework/ui/modal/modal.component.tsx b/src/framework/ui/modal/modal.component.tsx index f097a497f..3243dee6d 100644 --- a/src/framework/ui/modal/modal.component.tsx +++ b/src/framework/ui/modal/modal.component.tsx @@ -106,14 +106,18 @@ export class Modal extends React.Component { private contentSize: Size = initialContentSize; private id: string = ''; - public componentWillReceiveProps(nextProps: ModalProps): void { - this.handleVisibility(nextProps); + public componentDidUpdate(prevProps: ModalProps): void { + if (prevProps.visible !== this.props.visible) { + this.handleVisibility(this.props); + } else if (prevProps.visible && this.props.visible) { + ModalService.update(this.id, this.props.children); + } } - private handleVisibility = (nextProps: ModalProps): void => { + private handleVisibility = (props: ModalProps): void => { const { allowBackdrop, onBackdropPress } = this.props; - if (nextProps.visible) { + if (props.visible) { const element: React.ReactElement = this.renderModal(); this.id = ModalService.show(element, { allowBackdrop, onBackdropPress }); } else { diff --git a/src/framework/ui/modal/modal.spec.tsx b/src/framework/ui/modal/modal.spec.tsx index 18a9e6c0a..230bbbfd0 100644 --- a/src/framework/ui/modal/modal.spec.tsx +++ b/src/framework/ui/modal/modal.spec.tsx @@ -15,7 +15,10 @@ import { Modal, baseModalTestId, } from './modal.component'; -import { StyleType } from '@kitten/theme'; +import { + ModalPanel, + StyleType, +} from '@kitten/theme'; const buttonShowModalTestId: string = '@button-show-modal'; const buttonHideModalTestId: string = '@button-hide-modal'; @@ -99,3 +102,94 @@ describe('@modal component checks', () => { }); }); + +describe('@modal panel checks', () => { + + const showModalButtonTestId: string = '@modal/button-show'; + const changeModalTextButtonTestId: string = '@modal/button-change-text'; + const modalTextTestId: string = '@modal/text'; + + interface Props { + textValue: string; + redTextValue: string; + } + + interface State { + modalVisible: boolean; + isModalTextRed: boolean; + } + + class TestApplication extends React.Component { + + public state: State = { + modalVisible: false, + isModalTextRed: false, + }; + + private setModalVisible = (): void => { + const modalVisible: boolean = !this.state.modalVisible; + + this.setState({ modalVisible }); + }; + + private setModalTextRed = (): void => { + const isModalTextRed: boolean = !this.state.isModalTextRed; + + this.setState({ isModalTextRed }); + }; + + + public render(): React.ReactNode { + const { textValue, redTextValue } = this.props; + const { modalVisible, isModalTextRed } = this.state; + const modalTextStyle: StyleType = isModalTextRed ? { color: 'red' } : null; + const modalTextValue: string = isModalTextRed ? redTextValue : textValue; + + return ( + +