Skip to content

Commit

Permalink
fix(ui): modal component/service/panel, popover fix
Browse files Browse the repository at this point in the history
  • Loading branch information
32penkin authored Mar 7, 2019
1 parent fb5e93d commit a0491cb
Show file tree
Hide file tree
Showing 15 changed files with 513 additions and 771 deletions.
61 changes: 36 additions & 25 deletions src/framework/theme/component/modal/modalPanel.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,94 @@ import {
StyleSheet,
ViewProps,
} from 'react-native';
import { ModalService } from '../../service';
import {
ModalPresenting,
ModalService,
} from '../../service';
import { Modal } from '../../../ui/modal/modal.component';
import { ModalComponentCloseProps } from '@kitten/theme';

export interface ModalPanelProps {
children: React.ReactElement<any> | React.ReactElement<any>[];
}

interface ModalPanelState {
dialogComponents: Map<string, React.ReactElement<any>>;
backdropValues: Map<string, boolean>;
components: Map<string, React.ReactElement<ModalComponentCloseProps>>;
backdrops: Map<string, boolean>;
}

export class ModalPanel extends React.Component<ModalPanelProps, ModalPanelState> {
export class ModalPanel extends React.Component<ModalPanelProps, ModalPanelState> implements ModalPresenting {

public state: ModalPanelState = {
dialogComponents: new Map(),
backdropValues: new Map(),
components: new Map(),
backdrops: new Map(),
};

public componentDidMount(): void {
ModalService.setComponent(this);
ModalService.mount(this);
}

public componentWillUnmount(): void {
ModalService.setComponent(null);
ModalService.unmount();
}

public onCloseModal = (identifier: string) => {
const components: Map<string, React.ReactElement<any>> = this.state.dialogComponents;
public hide = (identifier: string): void => {
const component: React.ReactElement<ModalComponentCloseProps> = this.state.components
.get(identifier);
if (component) {
component.props.onRequestClose && component.props.onRequestClose();
}
const components: Map<string, React.ReactElement<any>> = this.state.components;
components.delete(identifier);
const backdropValues: Map<string, boolean> = this.state.backdropValues;
backdropValues.delete(identifier);
const backdrops: Map<string, boolean> = this.state.backdrops;
backdrops.delete(identifier);
this.setState({
dialogComponents: components,
backdropValues: backdropValues,
components: components,
backdrops: backdrops,
});
};

public showDialog(dialogComponent: React.ReactElement<any>, closeOnBackDrop: boolean): void {
public show(dialogComponent: React.ReactElement<any>, closeOnBackDrop: boolean): string {
const key: string = this.generateUniqueComponentKey();
const componentsMap: Map<string, React.ReactElement<any>> = this.state.dialogComponents
const componentsMap: Map<string, React.ReactElement<any>> = this.state.components
.set(key, dialogComponent);
const backdropsMap: Map<string, boolean> = this.state.backdropValues.set(key, closeOnBackDrop);
const backdrops: Map<string, boolean> = this.state.backdrops.set(key, closeOnBackDrop);
this.setState({
dialogComponents: componentsMap,
backdropValues: backdropsMap,
components: componentsMap,
backdrops: backdrops,
});
return key;
}

private generateUniqueComponentKey = (): string => {
return Math.random().toString(36).substring(2);
};

private areThereAnyComponents(): boolean {
return this.state.dialogComponents && this.state.dialogComponents.size !== 0;
return this.state.components && this.state.components.size !== 0;
}

private renderModal(modal: React.ReactElement<any>, index: number) {
const allModalKeys: string[] = Array.from(this.state.dialogComponents.keys());
const allModalKeys: string[] = Array.from(this.state.components.keys());
const identifier: string = allModalKeys
.find(item => this.state.dialogComponents.get(item) === modal);
const closeOnBackdrop: boolean = this.state.backdropValues.get(identifier);
.find(item => this.state.components.get(item) === modal);
const closeOnBackdrop: boolean = this.state.backdrops.get(identifier);
return (
<Modal
{...modal.props}
visible={true}
isBackDropAllowed={closeOnBackdrop}
key={index}
identifier={identifier}
onCloseModal={this.onCloseModal}
onCloseModal={this.hide}
>
{modal}
</Modal>
);
}

private renderModals() {
return Array.from(this.state.dialogComponents.values())
return Array.from(this.state.components.values())
.map((component: React.ReactElement<any>, i: number) =>
this.renderModal(component, i));
}
Expand Down
45 changes: 34 additions & 11 deletions src/framework/theme/component/modal/modalPanel.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ jest.useFakeTimers();
describe('@modal panel checks', () => {

const showModalTestId: string = '@modal/show';
const hideModalTestId: string = '@modal/hide';
const hideModalTestIdInner: string = '@modal/hide-inner';
const hideModalTestIdOuter: string = '@modal/hide-outer';

interface HooksProps {
componentDidMount?: () => void;
Expand All @@ -28,19 +29,29 @@ describe('@modal panel checks', () => {

class ModalPanelTest extends React.Component<HooksProps> {

componentDidMount(): void {
this.props.componentDidMount && this.props.componentDidMount();
private modalId: string = '';

public componentDidMount(): void {
if (this.props.componentDidMount) {
this.props.componentDidMount();
}
}

public componentWillUnmount() {
if (this.props.componentWillUnmount) {
this.props.componentWillUnmount();
}
}

componentWillUnmount() {
this.props.componentWillUnmount && this.props.componentWillUnmount();
public showModal() {
this.modalId = ModalService.show(<TestModal onRequestClose={() => 1}/>, true);
}

showModal() {
ModalService.showDialog(<TestModal/>, true);
public hideModal() {
ModalService.hide(this.modalId);
}

render() {
public render() {
return (
<ModalPanel>
<View>
Expand All @@ -51,6 +62,11 @@ describe('@modal panel checks', () => {
onPress={() => this.showModal()}
testID={showModalTestId}
/>
<Button
title='Hide Modal'
onPress={() => this.hideModal()}
testID={hideModalTestIdOuter}
/>
</ModalPanel>
);
}
Expand All @@ -65,7 +81,7 @@ describe('@modal panel checks', () => {
<Button
title='Close Modal'
onPress={this.props.onCloseModal}
testID={hideModalTestId}
testID={hideModalTestIdInner}
/>
</View>
);
Expand Down Expand Up @@ -101,10 +117,17 @@ describe('@modal panel checks', () => {
expect(componentWillUnmount).toHaveBeenCalled();
});

it('* close modal checking', () => {
it('* close modal checking inner', () => {
const application = render(<ModalPanelTest/>);
fireEvent.press(application.getByTestId(showModalTestId));
fireEvent.press(application.getByTestId(hideModalTestIdInner));
expect(application).toMatchSnapshot();
});

it('* close modal checking outer', () => {
const application = render(<ModalPanelTest/>);
fireEvent.press(application.getByTestId(showModalTestId));
fireEvent.press(application.getByTestId(hideModalTestId));
fireEvent.press(application.getByTestId(hideModalTestIdOuter));
expect(application).toMatchSnapshot();
});

Expand Down
Loading

0 comments on commit a0491cb

Please sign in to comment.