UNPKG

@prosperitainova/dumbo-react-native

Version:
266 lines (264 loc) 7.4 kB
"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