@wordpress/components
Version:
UI components for WordPress.
263 lines (258 loc) • 7.86 kB
JavaScript
/**
* External dependencies
*/
import { Platform, AccessibilityInfo, View } from 'react-native';
import Slider from '@react-native-community/slider';
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { withPreferredColorScheme } from '@wordpress/compose';
/**
* Internal dependencies
*/
import Cell from './cell';
import LockIcon from './lock-icon';
import styles from './range-cell.scss';
import RangeTextInput from './range-text-input';
import { toFixed } from '../utils';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const isIOS = Platform.OS === 'ios';
class BottomSheetRangeCell extends Component {
constructor(props) {
super(props);
this.onSliderChange = this.onSliderChange.bind(this);
this.onCompleteSliderChange = this.onCompleteSliderChange.bind(this);
this.onTextInputChange = this.onTextInputChange.bind(this);
this.a11yIncrementValue = this.a11yIncrementValue.bind(this);
this.a11yDecrementValue = this.a11yDecrementValue.bind(this);
this.a11yUpdateValue = this.a11yUpdateValue.bind(this);
const {
value,
defaultValue,
minimumValue
} = props;
const initialValue = Number(value || defaultValue || minimumValue);
this.state = {
inputValue: initialValue,
sliderValue: initialValue
};
}
componentWillUnmount() {
clearTimeout(this.timeoutAnnounceValue);
}
onSliderChange(initialValue) {
const {
decimalNum,
onChange
} = this.props;
initialValue = toFixed(initialValue, decimalNum);
this.setState({
inputValue: initialValue
});
onChange(initialValue);
}
onTextInputChange(nextValue) {
const {
onChange,
onComplete
} = this.props;
this.setState({
sliderValue: nextValue
});
onChange(nextValue);
if (onComplete) {
onComplete(nextValue);
}
}
onCompleteSliderChange(nextValue) {
const {
decimalNum,
onComplete
} = this.props;
nextValue = toFixed(nextValue, decimalNum);
if (onComplete) {
onComplete(nextValue);
}
}
/*
* Only used with screenreaders like VoiceOver and TalkBack. Increments the
* value of this setting programmatically.
*/
a11yIncrementValue() {
const {
step = 5,
maximumValue,
decimalNum
} = this.props;
const {
inputValue
} = this.state;
const newValue = toFixed(inputValue + step, decimalNum);
if (newValue <= maximumValue || maximumValue === undefined) {
this.a11yUpdateValue(newValue);
}
}
/*
* Only used with screenreaders like VoiceOver and TalkBack. Decrements the
* value of this setting programmatically.
*/
a11yDecrementValue() {
const {
step = 5,
minimumValue,
decimalNum
} = this.props;
const {
sliderValue
} = this.state;
const newValue = toFixed(sliderValue - step, decimalNum);
if (newValue >= minimumValue) {
this.a11yUpdateValue(newValue);
}
}
a11yUpdateValue(newValue) {
const {
onChange,
onComplete
} = this.props;
this.setState({
sliderValue: newValue,
inputValue: newValue
});
onChange(newValue);
if (onComplete) {
onComplete(newValue);
}
this.announceValue(newValue);
}
/*
* Only used with screenreaders like VoiceOver and TalkBack.
*/
announceValue(value) {
const {
label,
unitLabel = ''
} = this.props;
if (isIOS) {
// On Android it triggers the accessibilityLabel with the value change, but
// on iOS we need to do this manually.
clearTimeout(this.timeoutAnnounceValue);
this.timeoutAnnounceValue = setTimeout(() => {
AccessibilityInfo.announceForAccessibility(`${value} ${unitLabel}, ${label}`);
}, 300);
}
}
render() {
const {
value,
defaultValue,
minimumValue = 0,
maximumValue = 10,
disabled,
step = 1,
preferredColorScheme,
minimumTrackTintColor = preferredColorScheme === 'light' ? '#00669b' : '#5198d9',
maximumTrackTintColor = isIOS ? '#e9eff3' : '#909090',
thumbTintColor = !isIOS && '#00669b',
preview,
cellContainerStyle,
shouldDisplayTextInput = true,
unitLabel = '',
settingLabel = 'Value',
openUnitPicker,
children,
decimalNum,
...cellProps
} = this.props;
const {
inputValue,
sliderValue
} = this.state;
const getAccessibilityHint = () => {
return openUnitPicker ? __('double-tap to change unit') : '';
};
const getAccessibilityLabel = () => {
return sprintf(/* translators: accessibility text. Inform about current value. 1: Control label. 2: setting label (example: width). 3: Current value. 4: value measurement unit (example: pixels) */
__('%1$s. %2$s is %3$s %4$s.'), cellProps.label, settingLabel, toFixed(value, decimalNum), unitLabel);
};
const containerStyle = [styles.container, isIOS ? styles.containerIOS : styles.containerAndroid];
return /*#__PURE__*/_jsx(View, {
accessible: true,
accessibilityRole: "adjustable",
accessibilityActions: [{
name: 'increment'
}, {
name: 'decrement'
}, {
name: 'activate'
}],
onAccessibilityAction: event => {
switch (event.nativeEvent.actionName) {
case 'increment':
this.a11yIncrementValue();
break;
case 'decrement':
this.a11yDecrementValue();
break;
case 'activate':
if (openUnitPicker) {
openUnitPicker();
}
break;
}
},
accessibilityLabel: getAccessibilityLabel(),
accessibilityHint: getAccessibilityHint(),
children: /*#__PURE__*/_jsx(View, {
importantForAccessibility: "no-hide-descendants",
children: /*#__PURE__*/_jsx(Cell, {
...cellProps,
cellContainerStyle: [styles.cellContainerStyles, cellContainerStyle],
cellRowContainerStyle: containerStyle,
leftAlign: true,
editable: false,
activeOpacity: 1,
accessible: false,
valueStyle: styles.valueStyle,
disabled: disabled,
showLockIcon: false,
children: /*#__PURE__*/_jsxs(View, {
style: containerStyle,
children: [preview, /*#__PURE__*/_jsx(Slider, {
testID: `Slider ${cellProps.label}`,
value: sliderValue,
defaultValue: defaultValue,
disabled: disabled && !isIOS,
step: step,
minimumValue: minimumValue,
maximumValue: maximumValue,
minimumTrackTintColor: minimumTrackTintColor,
maximumTrackTintColor: maximumTrackTintColor,
thumbTintColor: thumbTintColor,
onValueChange: this.onSliderChange,
onSlidingComplete: this.onCompleteSliderChange,
ref: slider => {
this.sliderRef = slider;
},
style: isIOS ? styles.sliderIOS : styles.sliderAndroid
}), shouldDisplayTextInput && /*#__PURE__*/_jsx(RangeTextInput, {
label: cellProps.label,
onChange: this.onTextInputChange,
defaultValue: `${inputValue}`,
value: inputValue,
min: minimumValue,
max: maximumValue,
step: step,
decimalNum: decimalNum,
children: children
}), disabled && /*#__PURE__*/_jsx(LockIcon, {})]
})
})
})
});
}
}
export default withPreferredColorScheme(BottomSheetRangeCell);
//# sourceMappingURL=range-cell.native.js.map