Skip to content

Commit

Permalink
refactor(ui): modal component reimplement
Browse files Browse the repository at this point in the history
  • Loading branch information
32penkin authored Jul 8, 2019
1 parent 241ade4 commit 97afa07
Show file tree
Hide file tree
Showing 17 changed files with 844 additions and 715 deletions.
32 changes: 16 additions & 16 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions docs/src/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,14 @@ export const structure = [
type: 'group',
name: 'Modals & Overlays',
},
{
type: 'tabs',
name: 'Modal',
icon: 'dialog.svg',
source: [
'Modal',
],
},
{
type: 'tabs',
name: 'Overflow Menu',
Expand All @@ -426,14 +434,6 @@ export const structure = [
},
],
},
{
type: 'tabs',
name: 'Modal',
icon: 'dialog.svg',
source: [
'Modal',
],
},
{
type: 'tabs',
name: 'Popover',
Expand Down
6 changes: 3 additions & 3 deletions src/framework/theme/modal/modalPanel.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
StyleSheet,
ViewProps,
} from 'react-native';
import { Modal } from '../../ui/modal/modal.component';
import { ModalResolver } from './modalResolver.component';
import {
ModalService,
ModalPresenting,
Expand Down Expand Up @@ -77,7 +77,7 @@ export class ModalPanel extends React.Component<ModalPanelProps, ModalPanelState
.find(item => this.state.components.get(item) === modal);
const closeOnBackdrop: boolean = this.state.backdrops.get(identifier);
return (
<Modal
<ModalResolver
{...modal.props}
visible={true}
isBackDropAllowed={closeOnBackdrop}
Expand All @@ -86,7 +86,7 @@ export class ModalPanel extends React.Component<ModalPanelProps, ModalPanelState
onCloseModal={this.hide}
>
{modal}
</Modal>
</ModalResolver>
);
}

Expand Down
129 changes: 129 additions & 0 deletions src/framework/theme/modal/modalResolver.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/

import React from 'react';
import {
View,
ViewProps,
StyleSheet,
TouchableOpacity,
TouchableOpacityProps,
} from 'react-native';

type ChildElement = React.ReactElement<any>;
type ChildrenProp = ChildElement | ChildElement[];

interface ComponentProps {
visible: boolean;
children: ChildrenProp;
isBackDropAllowed?: boolean;
identifier?: string;
onCloseModal?: (index: string) => void;
}

export type ModalResolverProps = ViewProps & ComponentProps;

export class ModalResolver extends React.Component<ModalResolverProps> {

static defaultProps: Partial<ModalResolverProps> = {
visible: false,
isBackDropAllowed: false,
};

private closeModal = (): void => {
if (this.props.onCloseModal) {
this.props.onCloseModal(this.props.identifier);
}
};

private closeOnBackdrop: () => void = () => {
if (this.props.isBackDropAllowed) {
this.closeModal();
}
};

private onStartShouldSetResponder = (): boolean => {
return true;
};

private onResponderRelease = (): void => {
return;
};

private onStartShouldSetResponderCapture = (): boolean => {
return false;
};

private renderComponentChild = (source: React.ReactElement<any>): React.ReactElement<any> => {
return React.cloneElement(source, {
onCloseModal: this.closeModal,
style: [source.props.style, this.props.style],
});
};

private renderComponentChildren = (source: React.ReactNode): React.ReactElement<any>[] => {
return React.Children.map(source, this.renderComponentChild);
};

private renderWithBackDrop = (component: React.ReactElement<ViewProps>):
React.ReactElement<TouchableOpacityProps> => {

return (
<TouchableOpacity
style={styles.container}
onPress={this.closeOnBackdrop}
activeOpacity={1}>
{component}
</TouchableOpacity>
);
};

private renderWithoutBackDrop = (component: React.ReactElement<ViewProps>): React.ReactElement<ViewProps> => {
return (
<View style={styles.notVisibleWrapper}>
<View
style={styles.container}
pointerEvents='none'/>
{component}
</View>
);
};

private renderComponent = (): React.ReactElement<TouchableOpacityProps | ViewProps> => {
const { children, isBackDropAllowed, ...derivedProps } = this.props;
const componentChildren: React.ReactElement<any>[] = this.renderComponentChildren(children);

const dialog: React.ReactElement<ViewProps> =
<View
{...derivedProps}
style={styles.contentWrapper}
onStartShouldSetResponder={this.onStartShouldSetResponder}
onResponderRelease={this.onResponderRelease}
onStartShouldSetResponderCapture={this.onStartShouldSetResponderCapture}
pointerEvents='box-none'>
{componentChildren}
</View>;

return isBackDropAllowed ?
this.renderWithBackDrop(dialog) : this.renderWithoutBackDrop(dialog);
};

public render(): React.ReactElement<ViewProps | TouchableOpacityProps> | null {
return this.props.visible ? this.renderComponent() : null;
}
}

const styles = StyleSheet.create({
container: StyleSheet.absoluteFillObject,
notVisibleWrapper: {
position: 'absolute',
width: 0,
height: 0,
},
contentWrapper: {
alignSelf: 'flex-start',
},
});
Loading

0 comments on commit 97afa07

Please sign in to comment.