Skip to content

Commit

Permalink
Mobile: BottomSheet design tweaks v2 (#13855)
Browse files Browse the repository at this point in the history
* Mobile BottomSheet: Added the posibility of selecting the cell  separator style.

* Mobile BottomSheet: Increased space between top and table

* Mobile BottomSheet: Truncating long values at the middle of the string.

* Fix lint issues

* Fix syntax error to pass CI

* Fix lint issue

* Mobile Picker: Tweak Android styles.

* Mobile BottomSheet: Simplified Android cell styling.

* Mobile: Fix swipe to dismiss on BottomSheet

* Fix lint issues

* Mobile BottomSheet: Fixes sensibility of pan vs tap gestures on swipe to dismiss.

* Fix lint issues

* Fixed failed tests

* Mobile BottomSheet cell: Removed unnecessary variable init.

* Fixed set state after component is unmounted

* Revert "Fixed set state after component is unmounted"

This reverts commit 787df73.
  • Loading branch information
etoledom authored and youknowriad committed Mar 6, 2019
1 parent 2867264 commit b8fcb2d
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 89 deletions.
7 changes: 4 additions & 3 deletions packages/block-library/src/image/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ class ImageEdit extends React.Component {

getMediaOptionsItems() {
return [
{ icon: 'wordpress-alt', value: MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_CHOOSE_FROM_DEVICE, label: __( 'Choose from device' ) },
{ icon: 'format-image', value: MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_CHOOSE_FROM_DEVICE, label: __( 'Choose from device' ) },
{ icon: 'camera', value: MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_TAKE_PHOTO, label: __( 'Take a Photo' ) },
{ icon: 'format-image', value: MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_WORD_PRESS_LIBRARY, label: __( 'WordPress Media Library' ) },
{ icon: 'wordpress-alt', value: MEDIA_UPLOAD_BOTTOM_SHEET_VALUE_WORD_PRESS_LIBRARY, label: __( 'WordPress Media Library' ) },
];
}

Expand Down Expand Up @@ -273,12 +273,13 @@ class ImageEdit extends React.Component {
label={ __( 'Alt Text' ) }
value={ alt || '' }
valuePlaceholder={ __( 'None' ) }
separatorType={ 'fullWidth' }
onChangeValue={ this.updateAlt }
/>
<BottomSheet.Cell
label={ __( 'Clear All Settings' ) }
labelStyle={ styles.clearSettingsButton }
drawSeparator={ false }
separatorType={ 'none' }
onPress={ this.onClearSettings }
/>
</BottomSheet>
Expand Down
184 changes: 115 additions & 69 deletions packages/editor/src/components/mobile/bottom-sheet/cell.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,85 +7,131 @@ import { TouchableOpacity, Text, View, TextInput, I18nManager } from 'react-nati
* WordPress dependencies
*/
import { Dashicon } from '@wordpress/components';
import { Component } from '@wordpress/element';

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

export default function Cell( props ) {
const {
onPress,
label,
value,
valuePlaceholder = '',
drawSeparator = true,
icon,
labelStyle = {},
valueStyle = {},
onChangeValue,
children,
editable = true,
...valueProps
} = props;
export default class Cell extends Component {
constructor() {
super( ...arguments );
this.state = {
isEditingValue: false,
};
}

const showValue = value !== undefined;
const isValueEditable = editable && onChangeValue !== undefined;
const defaultLabelStyle = showValue ? styles.cellLabel : styles.cellLabelCentered;
const separatorStyle = showValue ? styles.cellSeparator : styles.separator;
let valueTextInput;

const onCellPress = () => {
if ( isValueEditable ) {
valueTextInput.focus();
} else if ( onPress !== undefined ) {
onPress();
componentDidUpdate() {
if ( this.state.isEditingValue ) {
this._valueTextInput.focus();
}
};
}

const getValueComponent = () => {
const styleRTL = I18nManager.isRTL && styles.cellValueRTL;
const style = { ...styles.cellValue, ...valueStyle, ...styleRTL };
render() {
const {
onPress,
label,
value,
valuePlaceholder = '',
icon,
labelStyle = {},
valueStyle = {},
onChangeValue,
children,
editable = true,
separatorType,
style = {},
...valueProps
} = this.props;

return isValueEditable ? (
<TextInput
ref={ ( c ) => valueTextInput = c }
numberOfLines={ 1 }
style={ style }
value={ value }
placeholder={ valuePlaceholder }
placeholderTextColor={ '#87a6bc' }
onChangeText={ onChangeValue }
editable={ isValueEditable }
{ ...valueProps }
/>
) : (
<Text style={ { ...styles.cellValue, ...valueStyle } }>
{ value }
</Text>
);
};
const showValue = value !== undefined;
const isValueEditable = editable && onChangeValue !== undefined;
const defaultLabelStyle = showValue || icon !== undefined ? styles.cellLabel : styles.cellLabelCentered;
const drawSeparator = ( separatorType && separatorType !== 'none' ) || separatorStyle === undefined;

const onCellPress = () => {
if ( isValueEditable ) {
this.setState( { isEditingValue: true } );
} else if ( onPress !== undefined ) {
onPress();
}
};

const finishEditing = () => {
this.setState( { isEditingValue: false } );
};

return (
<TouchableOpacity onPress={ onCellPress } >
<View style={ styles.cellContainer }>
<View style={ styles.cellRowContainer }>
{ icon && (
<View style={ styles.cellRowContainer }>
<Dashicon icon={ icon } size={ 24 } />
<View style={ { width: 12 } } />
</View>
) }
<Text numberOfLines={ 1 } style={ { ...defaultLabelStyle, ...labelStyle } }>
{ label }
</Text>
const separatorStyle = () => {
const leftMarginStyle = { ...styles.cellSeparator, ...platformStyles.separatorMarginLeft };
switch ( separatorType ) {
case 'leftMargin':
return leftMarginStyle;
case 'fullWidth':
return styles.separator;
case 'none':
return undefined;
case undefined:
return showValue ? leftMarginStyle : styles.separator;
}
};

const getValueComponent = () => {
const styleRTL = I18nManager.isRTL && styles.cellValueRTL;
const finalStyle = { ...styles.cellValue, ...valueStyle, ...styleRTL };

// To be able to show the `middle` ellipsizeMode on editable cells
// we show the TextInput just when the user wants to edit the value,
// and the Text component to display it.
// We also show the TextInput to display placeholder.
const shouldShowPlaceholder = isValueEditable && value === '';
return this.state.isEditingValue || shouldShowPlaceholder ? (
<TextInput
ref={ ( c ) => this._valueTextInput = c }
numberOfLines={ 1 }
style={ finalStyle }
value={ value }
placeholder={ valuePlaceholder }
placeholderTextColor={ '#87a6bc' }
onChangeText={ onChangeValue }
editable={ isValueEditable }
pointerEvents={ this.state.isEditingValue ? 'auto' : 'none' }
onBlur={ finishEditing }
{ ...valueProps }
/>
) : (
<Text
style={ { ...styles.cellValue, ...valueStyle } }
numberOfLines={ 1 }
ellipsizeMode={ 'middle' }
>
{ value }
</Text>
);
};

return (
<TouchableOpacity onPress={ onCellPress } style={ { ...styles.clipToBounds, ...style } } >
<View style={ styles.cellContainer }>
<View style={ styles.cellRowContainer }>
{ icon && (
<View style={ styles.cellRowContainer }>
<Dashicon icon={ icon } size={ 24 } />
<View style={ platformStyles.labelIconSeparator } />
</View>
) }
<Text numberOfLines={ 1 } style={ { ...defaultLabelStyle, ...labelStyle } }>
{ label }
</Text>
</View>
{ showValue && getValueComponent() }
{ children }
</View>
{ showValue && getValueComponent() }
{ children }
</View>
{ drawSeparator && (
<View style={ separatorStyle } />
) }
</TouchableOpacity>
);
{ drawSeparator && (
<View style={ separatorStyle() } />
) }
</TouchableOpacity>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.labelIconSeparator {
width: 32px;
}

.separatorMarginLeft {
margin-left: 56px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.labelIconSeparator {
width: 12px;
}

.separatorMarginLeft {
margin-left: 36px;
}
23 changes: 19 additions & 4 deletions packages/editor/src/components/mobile/bottom-sheet/index.native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { Text, View, KeyboardAvoidingView, Platform } from 'react-native';
import { Text, View, KeyboardAvoidingView, Platform, PanResponder } from 'react-native';
import Modal from 'react-native-modal';
import SafeArea from 'react-native-safe-area';

Expand Down Expand Up @@ -50,7 +50,18 @@ class BottomSheet extends Component {
}

render() {
const { title = '', isVisible, leftButton, rightButton, hideHeader } = this.props;
const { title = '', isVisible, leftButton, rightButton, hideHeader, style = {} } = this.props;

const panResponder = PanResponder.create( {
onMoveShouldSetPanResponder: ( evt, gestureState ) => {
// Activates swipe down over child Touchables if the swipe is long enough.
// With this we can adjust sensibility on the swipe vs tap gestures.
if ( gestureState.dy > 3 ) {
gestureState.dy = 0;
return true;
}
},
} );

return (
<Modal
Expand All @@ -65,14 +76,18 @@ class BottomSheet extends Component {
onBackButtonPress={ this.props.onClose }
onSwipe={ this.props.onClose }
swipeDirection="down"
onMoveShouldSetResponder={ panResponder.panHandlers.onMoveShouldSetResponder }
onMoveShouldSetResponderCapture={ panResponder.panHandlers.onMoveShouldSetResponderCapture }
>
<KeyboardAvoidingView
behavior={ Platform.OS === 'ios' && 'padding' }
style={ { ...styles.content, borderColor: 'rgba(0, 0, 0, 0.1)' } }
style={ { ...styles.content, borderColor: 'rgba(0, 0, 0, 0.1)', ...style } }
keyboardVerticalOffset={ -this.state.safeAreaBottomInset }
>
<View style={ styles.dragIndicator } />
{ hideHeader || (
{ hideHeader ? (
<View style={ styles.emptyHeaderSpace } />
) : (
<View>
<View style={ styles.head }>
<View style={ { flex: 1 } }>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
.dragIndicator {
background-color: $light-gray-400;
height: 4px;
width: 10%;
width: 36px;
margin: auto;
border-radius: 2px;
}
Expand All @@ -19,6 +19,10 @@
width: 100%;
}

.emptyHeaderSpace {
height: 14;
}

.content {
padding: 6px 16px 0 16px;
background-color: $white;
Expand All @@ -33,6 +37,7 @@
justify-content: space-between;
align-items: center;
align-content: center;
min-height: 48;
}

.title {
Expand Down Expand Up @@ -63,11 +68,14 @@
align-items: center;
}

.clipToBounds {
overflow: hidden;
}

.cellSeparator {
background-color: $light-gray-400;
height: 1px;
width: 100%;
margin-left: 36px;
}

.cellRowContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default class Picker extends Component {
<BottomSheet
isVisible={ this.state.isVisible }
onClose={ this.onClose }
style={ { paddingBottom: 20 } }
hideHeader
>
<View>
Expand All @@ -48,13 +49,14 @@ export default class Picker extends Component {
icon={ option.icon }
key={ index }
label={ option.label }
separatorType={ 'none' }
onPress={ () => this.onCellPress( option.value ) }
/>
) }
{ ! this.props.hideCancelButton && <BottomSheet.Cell
label={ __( 'Cancel' ) }
onPress={ this.onClose }
drawSeparator={ false }
separatorType={ 'none' }
/> }
</View>
</BottomSheet>
Expand Down
10 changes: 0 additions & 10 deletions packages/editor/src/components/mobile/picker/styles.android.scss

This file was deleted.

0 comments on commit b8fcb2d

Please sign in to comment.