Skip to content

Commit a0491cb

Browse files
authored
fix(ui): modal component/service/panel, popover fix
1 parent fb5e93d commit a0491cb

15 files changed

+513
-771
lines changed

src/framework/theme/component/modal/modalPanel.component.tsx

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,83 +4,94 @@ import {
44
StyleSheet,
55
ViewProps,
66
} from 'react-native';
7-
import { ModalService } from '../../service';
7+
import {
8+
ModalPresenting,
9+
ModalService,
10+
} from '../../service';
811
import { Modal } from '../../../ui/modal/modal.component';
12+
import { ModalComponentCloseProps } from '@kitten/theme';
913

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

1418
interface ModalPanelState {
15-
dialogComponents: Map<string, React.ReactElement<any>>;
16-
backdropValues: Map<string, boolean>;
19+
components: Map<string, React.ReactElement<ModalComponentCloseProps>>;
20+
backdrops: Map<string, boolean>;
1721
}
1822

19-
export class ModalPanel extends React.Component<ModalPanelProps, ModalPanelState> {
23+
export class ModalPanel extends React.Component<ModalPanelProps, ModalPanelState> implements ModalPresenting {
2024

2125
public state: ModalPanelState = {
22-
dialogComponents: new Map(),
23-
backdropValues: new Map(),
26+
components: new Map(),
27+
backdrops: new Map(),
2428
};
2529

2630
public componentDidMount(): void {
27-
ModalService.setComponent(this);
31+
ModalService.mount(this);
2832
}
2933

3034
public componentWillUnmount(): void {
31-
ModalService.setComponent(null);
35+
ModalService.unmount();
3236
}
3337

34-
public onCloseModal = (identifier: string) => {
35-
const components: Map<string, React.ReactElement<any>> = this.state.dialogComponents;
38+
public hide = (identifier: string): void => {
39+
const component: React.ReactElement<ModalComponentCloseProps> = this.state.components
40+
.get(identifier);
41+
if (component) {
42+
component.props.onRequestClose && component.props.onRequestClose();
43+
}
44+
const components: Map<string, React.ReactElement<any>> = this.state.components;
3645
components.delete(identifier);
37-
const backdropValues: Map<string, boolean> = this.state.backdropValues;
38-
backdropValues.delete(identifier);
46+
const backdrops: Map<string, boolean> = this.state.backdrops;
47+
backdrops.delete(identifier);
3948
this.setState({
40-
dialogComponents: components,
41-
backdropValues: backdropValues,
49+
components: components,
50+
backdrops: backdrops,
4251
});
4352
};
4453

45-
public showDialog(dialogComponent: React.ReactElement<any>, closeOnBackDrop: boolean): void {
54+
public show(dialogComponent: React.ReactElement<any>, closeOnBackDrop: boolean): string {
4655
const key: string = this.generateUniqueComponentKey();
47-
const componentsMap: Map<string, React.ReactElement<any>> = this.state.dialogComponents
56+
const componentsMap: Map<string, React.ReactElement<any>> = this.state.components
4857
.set(key, dialogComponent);
49-
const backdropsMap: Map<string, boolean> = this.state.backdropValues.set(key, closeOnBackDrop);
58+
const backdrops: Map<string, boolean> = this.state.backdrops.set(key, closeOnBackDrop);
5059
this.setState({
51-
dialogComponents: componentsMap,
52-
backdropValues: backdropsMap,
60+
components: componentsMap,
61+
backdrops: backdrops,
5362
});
63+
return key;
5464
}
5565

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

6070
private areThereAnyComponents(): boolean {
61-
return this.state.dialogComponents && this.state.dialogComponents.size !== 0;
71+
return this.state.components && this.state.components.size !== 0;
6272
}
6373

6474
private renderModal(modal: React.ReactElement<any>, index: number) {
65-
const allModalKeys: string[] = Array.from(this.state.dialogComponents.keys());
75+
const allModalKeys: string[] = Array.from(this.state.components.keys());
6676
const identifier: string = allModalKeys
67-
.find(item => this.state.dialogComponents.get(item) === modal);
68-
const closeOnBackdrop: boolean = this.state.backdropValues.get(identifier);
77+
.find(item => this.state.components.get(item) === modal);
78+
const closeOnBackdrop: boolean = this.state.backdrops.get(identifier);
6979
return (
7080
<Modal
81+
{...modal.props}
7182
visible={true}
7283
isBackDropAllowed={closeOnBackdrop}
7384
key={index}
7485
identifier={identifier}
75-
onCloseModal={this.onCloseModal}
86+
onCloseModal={this.hide}
7687
>
7788
{modal}
7889
</Modal>
7990
);
8091
}
8192

8293
private renderModals() {
83-
return Array.from(this.state.dialogComponents.values())
94+
return Array.from(this.state.components.values())
8495
.map((component: React.ReactElement<any>, i: number) =>
8596
this.renderModal(component, i));
8697
}

src/framework/theme/component/modal/modalPanel.spec.tsx

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ jest.useFakeTimers();
1919
describe('@modal panel checks', () => {
2020

2121
const showModalTestId: string = '@modal/show';
22-
const hideModalTestId: string = '@modal/hide';
22+
const hideModalTestIdInner: string = '@modal/hide-inner';
23+
const hideModalTestIdOuter: string = '@modal/hide-outer';
2324

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

2930
class ModalPanelTest extends React.Component<HooksProps> {
3031

31-
componentDidMount(): void {
32-
this.props.componentDidMount && this.props.componentDidMount();
32+
private modalId: string = '';
33+
34+
public componentDidMount(): void {
35+
if (this.props.componentDidMount) {
36+
this.props.componentDidMount();
37+
}
38+
}
39+
40+
public componentWillUnmount() {
41+
if (this.props.componentWillUnmount) {
42+
this.props.componentWillUnmount();
43+
}
3344
}
3445

35-
componentWillUnmount() {
36-
this.props.componentWillUnmount && this.props.componentWillUnmount();
46+
public showModal() {
47+
this.modalId = ModalService.show(<TestModal onRequestClose={() => 1}/>, true);
3748
}
3849

39-
showModal() {
40-
ModalService.showDialog(<TestModal/>, true);
50+
public hideModal() {
51+
ModalService.hide(this.modalId);
4152
}
4253

43-
render() {
54+
public render() {
4455
return (
4556
<ModalPanel>
4657
<View>
@@ -51,6 +62,11 @@ describe('@modal panel checks', () => {
5162
onPress={() => this.showModal()}
5263
testID={showModalTestId}
5364
/>
65+
<Button
66+
title='Hide Modal'
67+
onPress={() => this.hideModal()}
68+
testID={hideModalTestIdOuter}
69+
/>
5470
</ModalPanel>
5571
);
5672
}
@@ -65,7 +81,7 @@ describe('@modal panel checks', () => {
6581
<Button
6682
title='Close Modal'
6783
onPress={this.props.onCloseModal}
68-
testID={hideModalTestId}
84+
testID={hideModalTestIdInner}
6985
/>
7086
</View>
7187
);
@@ -101,10 +117,17 @@ describe('@modal panel checks', () => {
101117
expect(componentWillUnmount).toHaveBeenCalled();
102118
});
103119

104-
it('* close modal checking', () => {
120+
it('* close modal checking inner', () => {
121+
const application = render(<ModalPanelTest/>);
122+
fireEvent.press(application.getByTestId(showModalTestId));
123+
fireEvent.press(application.getByTestId(hideModalTestIdInner));
124+
expect(application).toMatchSnapshot();
125+
});
126+
127+
it('* close modal checking outer', () => {
105128
const application = render(<ModalPanelTest/>);
106129
fireEvent.press(application.getByTestId(showModalTestId));
107-
fireEvent.press(application.getByTestId(hideModalTestId));
130+
fireEvent.press(application.getByTestId(hideModalTestIdOuter));
108131
expect(application).toMatchSnapshot();
109132
});
110133

0 commit comments

Comments
 (0)