Skip to content

Commit

Permalink
Mobile bottom sheet component (#13612)
Browse files Browse the repository at this point in the history
* rnmobile: Implement image settings button using InspectorControls.Slot pattern.

* rnmobile: Add missing semicolon

* rnmobile: Adding bottom-sheet component to mobile

* rnmobile: Styling bottom-sheet header

* rnmobile: Bottom-sheet clean up

* rnmobile: Fix lint issues on bottom-sheet related code.

* rnmobile: Fix small lint issues

* rnmobile: Move inline toolbar button definition out of constant.

* rnmobile: Remove extra white-spaces

* revert package-lock.json changes

* rnmobile: Fix merge issue

* rnmobile: exporting component BottomSheet.Button to be used as bottom-sheet header buttons

* rnmobile: Adding BottomSheet.Cell component as an extraction for BottomSheet users.

* Fix lint issues

* Reverting changes to package-lock.json

* Fix merge issues
  • Loading branch information
etoledom authored and youknowriad committed Mar 6, 2019
1 parent cca1364 commit 19ac5bb
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 8 deletions.
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;
}

0 comments on commit 19ac5bb

Please sign in to comment.