@prosperitainova/dumbo-react-native
Version:
Dumbo for React Native Library
266 lines (264 loc) • 7.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Slider = void 0;
var _react = _interopRequireDefault(require("react"));
var _reactNative = require("react-native");
var _defaultText = require("../../constants/defaultText");
var _helpers = require("../../helpers");
var _colors = require("../../styles/colors");
var _Text = require("../Text");
var _TextInput = require("../TextInput");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/** Props for Slider component */
/**
* Slider component for rendering a slider between numbers
*
* {@link https://github.com/carbon-design-system/carbon-react-native/blob/main/example/src/Views/Slider.tsx | Example code}
*/
class Slider extends _react.default.Component {
state = {
active: false
};
_panResponder = _reactNative.PanResponder.create({
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderStart: () => this.onStart(),
onPanResponderMove: (_event, gestureState) => this.onMove(gestureState),
onPanResponderEnd: () => this.onEndMove(),
onPanResponderTerminate: () => this.onEndMove()
});
onStart() {
this.setState({
active: true
});
}
onMove(gestureState) {
const {
value
} = this.props;
const newDeltaValue = this.getValueFromOffset(gestureState.dx);
const cappedValue = this.capValueWithinRange(value + newDeltaValue);
gestureState.dx = 0;
this.setState({
active: true
});
this.onSliderValueChanged(cappedValue, true);
}
onEndMove() {
const {
value
} = this.props;
const cappedValue = this.capValueWithinRange(value);
this.setState({
active: false
});
this.onSliderValueChanged(cappedValue, true);
}
capValueWithinRange = value => {
const {
minValue,
maxValue
} = this.props;
const rounded = Math.round(value);
if (rounded < minValue) {
return minValue;
}
if (rounded > maxValue) {
return maxValue;
}
return rounded;
};
getValueFromOffset = offset => {
const {
minValue,
maxValue
} = this.props;
if (this.barWidth === undefined) {
return 0;
}
return (maxValue - minValue) * offset / this.barWidth;
};
getOffsetFromValue = value => {
const {
minValue,
maxValue
} = this.props;
if (this.barWidth === undefined) return 0;
const valueOffset = value - minValue;
const totalRange = maxValue - minValue;
const percentage = valueOffset / totalRange;
return this.barWidth * percentage;
};
onLayout = event => {
const {
width
} = event.nativeEvent.layout;
this.barWidth = width;
this.forceUpdate();
};
onChangeText = inputValue => {
const {
minValue,
maxValue
} = this.props;
let value = Number(inputValue);
if (Number.isNaN(value)) {
value = 0;
}
if (value < minValue) {
value = minValue;
}
if (value > maxValue) {
value = maxValue;
}
this.onSliderValueChanged(value, false);
};
onSliderValueChanged(value, setInputText) {
const {
onChange
} = this.props;
if (typeof onChange === 'function') {
onChange(value);
}
if (setInputText) {
this.setState({
inputValue: value.toString()
});
}
}
get styles() {
const {
disabled
} = this.props;
const {
active
} = this.state;
const currentKnobSize = active ? 20 : 14;
return _reactNative.StyleSheet.create({
wrapper: {
display: 'flex',
flexDirection: 'column'
},
sliderOuterWrapper: {
flexDirection: 'row',
alignItems: 'flex-end'
},
sliderWrapper: {
height: 48,
flex: 1,
flexDirection: 'row',
alignItems: 'center'
},
sliderBar: {
position: 'relative',
flex: 1,
flexDirection: 'row',
alignItems: 'center',
height: 2,
backgroundColor: (0, _colors.getColor)('borderSubtle00'),
marginLeft: 16,
marginRight: 16
},
sliderProgress: {
height: '100%',
backgroundColor: (0, _colors.getColor)(disabled ? 'borderDisabled' : active ? 'interactive' : 'borderInverse')
},
sliderKnob: {
position: 'absolute',
width: currentKnobSize,
height: currentKnobSize,
backgroundColor: (0, _colors.getColor)(disabled ? 'borderDisabled' : active ? 'interactive' : 'iconPrimary'),
borderRadius: currentKnobSize / 2,
marginLeft: -(currentKnobSize / 2),
marginRight: -(currentKnobSize / 2)
},
sliderRangeLabel: {
color: (0, _colors.getColor)(disabled ? 'textDisabled' : 'textPrimary')
},
textInput: {
paddingTop: 0,
marginLeft: 16,
minWidth: 72
},
label: {
color: (0, _colors.getColor)(disabled ? 'textDisabled' : 'textSecondary')
}
});
}
rangeLabel(value) {
const {
hideRangeLabels
} = this.props;
if (hideRangeLabels) {
return null;
}
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, {
style: this.styles.sliderRangeLabel,
type: "code-02",
text: value.toString()
});
}
get slider() {
const {
value,
minValue,
maxValue,
disabled
} = this.props;
const cappedValue = this.capValueWithinRange(value);
const offset = this.getOffsetFromValue(cappedValue);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: this.styles.sliderWrapper,
children: [this.rangeLabel(minValue), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: this.styles.sliderBar,
onLayout: this.onLayout,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [this.styles.sliderProgress, {
width: offset
}]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [this.styles.sliderKnob, {
left: offset
}],
...(!disabled ? this._panResponder.panHandlers : {})
})]
}), this.rangeLabel(maxValue)]
});
}
render() {
const {
label,
disabled,
hideLabel,
hideTextInput,
accessibleText,
style,
value
} = this.props;
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: (0, _helpers.styleReferenceBreaker)(this.styles.wrapper, style),
accessibilityLabel: accessibleText || _defaultText.defaultText.slider,
accessibilityHint: label,
children: [!hideLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.Text, {
style: this.styles.label,
type: "label-01",
text: label
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: this.styles.sliderOuterWrapper,
children: [this.slider, !hideTextInput && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInput.TextInput, {
style: this.styles.textInput,
value: String(value),
disabled: disabled,
onChangeText: this.onChangeText,
componentProps: {
keyboardType: 'number-pad'
}
})]
})]
});
}
}
exports.Slider = Slider;
//# sourceMappingURL=index.js.map