Skip to content

Commit

Permalink
[RNMobile] Update Slider to reflect changes immediately (#22421)
Browse files Browse the repository at this point in the history
* update attr in `onChange` instead of `onChangeEnd`

* block of adding non-digit signs

* Fix regex that removes non-digits

* fix the issue with dots and remove the possibility to add dots if toFixed === 0

* Add changelog note
  • Loading branch information
dratwas committed Aug 24, 2020
1 parent 8ce1274 commit 1c71b24
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 52 deletions.
124 changes: 72 additions & 52 deletions packages/components/src/mobile/bottom-sheet/range-cell.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,29 @@ import Cell from './cell';
import styles from './range-cell.scss';
import borderStyles from './borderStyles.scss';

const isIOS = Platform.OS === 'ios';

class BottomSheetRangeCell extends Component {
constructor( props ) {
super( props );
this.handleToggleFocus = this.handleToggleFocus.bind( this );
this.handleChange = this.handleChange.bind( this );
this.handleValueSave = this.handleValueSave.bind( this );
this.onInputFocus = this.onInputFocus.bind( this );
this.onInputBlur = this.onInputBlur.bind( this );
this.onChangeValue = this.onChangeValue.bind( this );
this.onCellPress = this.onCellPress.bind( this );
this.handleChangePixelRatio = this.handleChangePixelRatio.bind( this );

this.onSubmitEditing = this.onSubmitEditing.bind( this );
this.onChangeText = this.onChangeText.bind( this );
const initialValue = this.validateInput(
props.value || props.defaultValue || props.minimumValue
);
const fontScale = this.getFontScale();

this.state = {
accessible: true,
sliderValue: initialValue,
initialValue,
hasFocus: false,
fontScale,
inputValue: initialValue,
sliderValue: initialValue,
};
}

Expand All @@ -55,7 +57,6 @@ class BottomSheetRangeCell extends Component {
}

componentWillUnmount() {
this.handleToggleFocus();
AppState.removeEventListener( 'change', this.handleChangePixelRatio );
}

Expand All @@ -75,29 +76,17 @@ class BottomSheetRangeCell extends Component {
}
}

handleChange( text ) {
text =
typeof text === 'number'
? this.toFixed( text )
: text.replace( ',', '.' );

if ( ! isNaN( Number( text ) ) ) {
this.setState( {
sliderValue: text,
} );
this.announceCurrentValue( text );
}
onInputFocus() {
this.setState( {
hasFocus: true,
} );
}

handleToggleFocus( validateInput = true ) {
const newState = { hasFocus: ! this.state.hasFocus };

if ( validateInput ) {
const sliderValue = this.validateInput( this.state.sliderValue );
this.handleValueSave( this.toFixed( sliderValue ) );
}

this.setState( newState );
onInputBlur() {
this.onChangeText( '' + this.state.sliderValue );
this.setState( {
hasFocus: false,
} );
}

validateInput( text ) {
Expand All @@ -109,30 +98,42 @@ class BottomSheetRangeCell extends Component {
return Math.min( Math.max( text, minimumValue ), maximumValue );
}
return Math.min(
Math.max( text.replace( /[^0-9.]/g, '' ), minimumValue ),
Math.max( this.removeNonDigit( text ), minimumValue ),
maximumValue
);
}

handleValueSave( text ) {
if ( ! isNaN( Number( text ) ) ) {
const value = this.toFixed( text );
this.onChangeValue( value );
this.setState( { sliderValue: value } );
this.announceCurrentValue( value );
}
removeNonDigit( text ) {
const { toFixed } = this.props;
const regex = toFixed > 0 ? /^(\d+\.?(\d+)?)/ : /^([\d]+)/;
const result = text.match( regex );
return result ? result[ 0 ] : '';
}

updateValue( value ) {
const { onChange } = this.props;
const validValue = this.validateInput( value );

this.announceCurrentValue( `${ validValue }` );
onChange( validValue );
}

onChangeValue( initialValue ) {
const { minimumValue, maximumValue, onChange } = this.props;
initialValue = this.toFixed( initialValue );
this.setState( { inputValue: initialValue } );
this.updateValue( initialValue );
}

let sliderValue = initialValue;
if ( sliderValue < minimumValue ) {
sliderValue = minimumValue;
} else if ( sliderValue > maximumValue ) {
sliderValue = maximumValue;
}
onChange( sliderValue );
onChangeText( textValue ) {
const inputValue = this.removeNonDigit( textValue );
textValue = inputValue.replace( ',', '.' );
textValue = this.toFixed( textValue );
const value = this.validateInput( textValue );
this.setState( {
inputValue,
sliderValue: value,
} );
this.updateValue( value );
}

onCellPress() {
Expand All @@ -143,14 +144,26 @@ class BottomSheetRangeCell extends Component {
}
}

onSubmitEditing( { nativeEvent: { text } } ) {
if ( ! isNaN( Number( text ) ) ) {
text = this.toFixed( text.replace( ',', '.' ) );
const validValue = this.validateInput( text );

if ( this.state.inputValue !== validValue ) {
this.setState( { inputValue: validValue } );
this.announceCurrentValue( `${ validValue }` );
this.props.onChange( validValue );
}
}
}

announceCurrentValue( value ) {
/* translators: %s: current cell value. */
const announcement = sprintf( __( 'Current value is %s' ), value );
AccessibilityInfo.announceForAccessibility( announcement );
}

render() {
const isIOS = Platform.OS === 'ios';
const {
value,
defaultValue,
Expand All @@ -171,7 +184,13 @@ class BottomSheetRangeCell extends Component {
...cellProps
} = this.props;

const { hasFocus, sliderValue, accessible, fontScale } = this.state;
const {
hasFocus,
accessible,
fontScale,
inputValue,
sliderValue,
} = this.state;

const accessibilityLabel = sprintf(
/* translators: accessibility text. Inform about current value. %1$s: Control label %2$s: Current value. */
Expand Down Expand Up @@ -225,8 +244,7 @@ class BottomSheetRangeCell extends Component {
minimumTrackTintColor={ minimumTrackTintColor }
maximumTrackTintColor={ maximumTrackTintColor }
thumbTintColor={ thumbTintColor }
onValueChange={ this.handleChange }
onSlidingComplete={ this.handleValueSave }
onValueChange={ this.onChangeValue }
ref={ ( slider ) => {
this.sliderRef = slider;
} }
Expand All @@ -241,12 +259,14 @@ class BottomSheetRangeCell extends Component {
hasFocus && borderStyles.isSelected,
{ width: 40 * fontScale },
] }
onChangeText={ this.handleChange }
onFocus={ this.handleToggleFocus }
onBlur={ this.handleToggleFocus }
onChangeText={ this.onChangeText }
onSubmitEditing={ this.onSubmitEditing }
onFocus={ this.onInputFocus }
onBlur={ this.onInputBlur }
keyboardType="numeric"
returnKeyType="done"
value={ `${ sliderValue }` }
defaultValue={ `${ inputValue }` }
value={ inputValue }
/>
) }
</View>
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-editor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ For each user feature we should also add a importance categorization label to i
-->

## Unreleased
* [**] Reflect changes of slider in block settings immediately.

## 1.35.0

Expand Down

0 comments on commit 1c71b24

Please sign in to comment.