Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile bottom sheet component #13612

Merged
merged 18 commits into from
Feb 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
/**
* Internal dependencies
*/
import { MediaPlaceholder, RichText, BlockControls, InspectorControls } from '@wordpress/editor';
import { MediaPlaceholder, RichText, BlockControls, InspectorControls, BottomSheet } from '@wordpress/editor';
import { Toolbar, ToolbarButton, Spinner, Dashicon } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import ImageSize from './image-size';
Expand All @@ -33,6 +33,7 @@ export default class ImageEdit extends React.Component {
super( props );

this.state = {
showSettings: false,
progress: 0,
isUploadInProgress: false,
isUploadFailed: false,
Expand Down Expand Up @@ -168,7 +169,11 @@ export default class ImageEdit extends React.Component {
}

const onImageSettingsButtonPressed = () => {
this.setState( { showSettings: true } );
};

const onImageSettingsClose = () => {
this.setState( { showSettings: false } );
};

const toolbarEditButton = (
Expand All @@ -181,12 +186,21 @@ export default class ImageEdit extends React.Component {
</Toolbar>
);

const inlineToolbarButtons = (
<ToolbarButton
label={ __( 'Image Settings' ) }
icon="admin-generic"
onClick={ onImageSettingsButtonPressed }
/>
const getInspectorControls = () => (
<BottomSheet
isVisible={ this.state.showSettings }
title={ __( 'Image Settings' ) }
onClose={ onImageSettingsClose }
rightButton={
<BottomSheet.Button
text={ __( 'Done' ) }
color={ '#0087be' }
onPress={ onImageSettingsClose }
/>
}
>
<BottomSheet.Cell label={ __( 'Alt Text' ) } value={ __( 'None' ) } onPress={ () => {} } />
</BottomSheet>
);

const showSpinner = this.state.isUploadInProgress;
Expand All @@ -201,7 +215,11 @@ export default class ImageEdit extends React.Component {
{ toolbarEditButton }
</BlockControls>
<InspectorControls>
{ inlineToolbarButtons }
<ToolbarButton
label={ __( 'Image Settings' ) }
icon="admin-generic"
onClick={ onImageSettingsButtonPressed }
/>
</InspectorControls>
<ImageSize src={ url } >
{ ( sizes ) => {
Expand All @@ -222,6 +240,7 @@ export default class ImageEdit extends React.Component {

return (
<View style={ { flex: 1 } } >
{ getInspectorControls() }
<ImageBackground
style={ { width: finalWidth, height: finalHeight, opacity } }
resizeMethod="scale"
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/components/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { default as PostTitle } from './post-title';
export { default as EditorHistoryRedo } from './editor-history/redo';
export { default as EditorHistoryUndo } from './editor-history/undo';
export { default as InspectorControls } from './inspector-controls';
export { default as BottomSheet } from './mobile/bottom-sheet';
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* External dependencies
*/
import { TouchableOpacity, View, Text } from 'react-native';

/**
* Internal dependencies
*/
import styles from './styles.scss';

export default function Button( props ) {
const {
onPress,
disabled,
text,
color,
} = props;

return (
<TouchableOpacity
accessible={ true }
onPress={ onPress }
disabled={ disabled }
>
<View style={ { flexDirection: 'row', justifyContent: 'center' } }>
<Text style={ { ...styles.buttonText, color } }>
{ text }
</Text>
</View>
</TouchableOpacity>
);
}
24 changes: 24 additions & 0 deletions packages/editor/src/components/mobile/bottom-sheet/cell.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* External dependencies
*/
import { TouchableOpacity, Text } from 'react-native';

/**
* Internal dependencies
*/
import styles from './styles.scss';

export default function Cell( props ) {
const {
onPress,
label,
value,
} = props;

return (
<TouchableOpacity style={ styles.cellContainer } onPress={ onPress }>
<Text style={ styles.cellLabel }>{ label }</Text>
<Text style={ styles.cellValue }>{ value }</Text>
</TouchableOpacity>
);
}
90 changes: 90 additions & 0 deletions packages/editor/src/components/mobile/bottom-sheet/index.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* External dependencies
*/
import { Text, View } from 'react-native';
import Modal from 'react-native-modal';
import SafeArea from 'react-native-safe-area';

/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';

/**
* Internal dependencies
*/
import styles from './styles.scss';
import Button from './button';
import Cell from './cell';

class BottomSheet extends Component {
constructor() {
super( ...arguments );
this.onSafeAreaInsetsUpdate = this.onSafeAreaInsetsUpdate.bind( this );
this.state = {
safeAreaBottomInset: 0,
};

SafeArea.getSafeAreaInsetsForRootView().then( this.onSafeAreaInsetsUpdate );
}

componentDidMount() {
SafeArea.addEventListener( 'safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsUpdate );
}

componentWillUnmount() {
SafeArea.removeEventListener( 'safeAreaInsetsForRootViewDidChange', this.onSafeAreaInsetsUpdate );
}

onSafeAreaInsetsUpdate( result ) {
const { safeAreaInsets } = result;
if ( this.state.safeAreaBottomInset !== safeAreaInsets.bottom ) {
this.setState( { safeAreaBottomInset: safeAreaInsets.bottom } );
}
}

render() {
const { isVisible, leftButton, rightButton } = this.props;

return (
<Modal
isVisible={ isVisible }
style={ styles.bottomModal }
animationInTiming={ 500 }
animationOutTiming={ 500 }
backdropTransitionInTiming={ 500 }
backdropTransitionOutTiming={ 500 }
onBackdropPress={ this.props.onClose }
onSwipe={ this.props.onClose }
swipeDirection="down"
>
<View style={ { ...styles.content, borderColor: 'rgba(0, 0, 0, 0.1)' } }>
<View style={ styles.dragIndicator } />
<View style={ styles.head }>
<View style={ { flex: 1 } }>
{ leftButton }
</View>
<View style={ styles.titleContainer }>
<Text style={ styles.title }>
{ this.props.title }
</Text>
</View>
<View style={ { flex: 1 } }>
{ rightButton }
</View>
</View>

<View style={ styles.separator } />
{ this.props.children }
<View style={ { flexGrow: 1 } }></View>
<View style={ { height: this.state.safeAreaBottomInset } } />
</View>
</Modal>
);
}
}

BottomSheet.Button = Button;
BottomSheet.Cell = Cell;

export default BottomSheet;
82 changes: 82 additions & 0 deletions packages/editor/src/components/mobile/bottom-sheet/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//Bottom Sheet

.bottomModal {
justify-content: flex-end;
margin: 0;
}

.dragIndicator {
background-color: $light-gray-400;
height: 4px;
width: 10%;
top: -12px;
margin: auto;
border-radius: 2px;
}

.separator {
background-color: $light-gray-400;
height: 1px;
width: 100%;
margin: auto;
}

.content {
background-color: $white;
padding: 18px 10px 5px 10px;
justify-content: center;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
}

.head {
flex-direction: row;
width: 100%;
margin-bottom: 5px;
justify-content: space-between;
align-items: center;
align-content: center;
}

.title {
color: $dark-gray-600;
font-size: 18px;
font-weight: 600;
text-align: center;
}

.titleContainer {
justify-content: center;
flex: 2;
align-content: center;
}

// Button

.buttonText {
font-size: 18px;
padding: 5px;
}

// Cell

//Bottom Sheet

.cellContainer {
flex-direction: row;
min-height: 50;
justify-content: space-between;
padding-left: 12;
padding-right: 12;
align-items: center;
}

.cellLabel {
font-size: 18px;
color: #000;
}

.cellValue {
font-size: 18px;
color: $dark-gray-400;
}