From 029d5d6834767baa1c8e16fb85093180f115b06f Mon Sep 17 00:00:00 2001 From: lukewalczak Date: Thu, 10 Jan 2019 13:02:38 +0100 Subject: [PATCH] refactor: extract slider parts to separate component --- src/Slider/Slider.js | 98 +++------------------------ src/Slider/Slider.stories.js | 60 ++++++++-------- src/Slider/SliderParts.js | 128 +++++++++++++++++++++++++++++++++++ yarn.lock | 4 +- 4 files changed, 170 insertions(+), 120 deletions(-) create mode 100644 src/Slider/SliderParts.js diff --git a/src/Slider/Slider.js b/src/Slider/Slider.js index c58006e..aa53638 100644 --- a/src/Slider/Slider.js +++ b/src/Slider/Slider.js @@ -6,10 +6,10 @@ import { View } from 'react-native'; import MultiSlider from 'react-native-multi-slider'; import Marker from './Marker'; +import SliderParts from './SliderParts'; import { Text } from '../Text'; import { StyleSheet } from '../PlatformStyleSheet'; -const LABEL_LENGTH = 200; const TRACK_HEIGHT = 4; type Props = {| @@ -79,46 +79,6 @@ export default class Slider extends React.Component { onValuesChange && onValuesChange(); }; - calculateOffset = (value: number) => { - const { minValue, maxValue } = this.props; - const { width } = this.state; - return (value * width) / (maxValue - minValue) - LABEL_LENGTH / 2; - }; - - createParts = () => { - const { numOfParts = 1, minValue, maxValue } = this.props; - const step = (maxValue - minValue) / numOfParts; - - const parts = []; - let i; - - if (numOfParts != null && numOfParts < 1) { - console.error('numOfParts cannot be lower than 1'); - } - - for (i = 0; i <= numOfParts; i++) { - const valuePerStep = Math.floor(step * i); - - parts.push( - - - - {valuePerStep + minValue} - - - ); - } - return parts; - }; - onLayout = ({ nativeEvent }: OnLayout) => { const { sliderLength } = this.props; this.setState({ @@ -137,14 +97,10 @@ export default class Slider extends React.Component { customMarker, onValuesChangeFinish, onValuesChangeStart, + numOfParts, } = this.props; const { multiSliderValues, width, singleSliderValue } = this.state; - const typeLineStyle = - type === 'single' && singleSliderValue[0] >= minValue - ? styles.selected - : styles.unselected; - const labelValue = type === 'multi' ? `${multiSliderValues[0]} - ${multiSliderValues[1]}` @@ -174,26 +130,13 @@ export default class Slider extends React.Component { - {this.createParts()} - - { - const minValue = number('Min value', 0); - const maxValue = number('Max value', 10000); - const startValue = number('Start value', 2000); - const endValue = number('End value', 8000); - const label = text('Label', 'Price'); - const type = select('Type', ['multi', 'single'], 'single'); - const snapped = boolean('Snapped', false); - const numOfParts = number('Number of parts', 5); - const sliderLength = number('Slider length', 315); - - return ( - - ); - }) .add('Default', () => ( - )); + )) + .add('Playground', () => { + const minValue = number('Min value', 0); + const maxValue = number('Max value', 10000); + const startValue = number('Start value', 2000); + const endValue = number('End value', 8000); + const label = text('Label', 'Price'); + const type = select('Type', ['multi', 'single'], 'single'); + const snapped = boolean('Snapped', false); + const numOfParts = number('Number of parts', 5); + const sliderLength = number('Slider length', 315); + const step = number('Step', 1000); + + return ( + + ); + }); diff --git a/src/Slider/SliderParts.js b/src/Slider/SliderParts.js new file mode 100644 index 0000000..878e9c2 --- /dev/null +++ b/src/Slider/SliderParts.js @@ -0,0 +1,128 @@ +// @flow + +import * as React from 'react'; +import { defaultTokens } from '@kiwicom/orbit-design-tokens'; +import { View } from 'react-native'; + +import { Text } from '../Text'; +import { StyleSheet } from '../PlatformStyleSheet'; + +const LABEL_LENGTH = 200; +const TRACK_HEIGHT = 4; + +type Props = {| + +type: 'multi' | 'single', + +minValue: number, + +maxValue: number, + +numOfParts?: number, + +singleSliderValue: Array, + +width: number, +|}; + +export default function SliderParts({ + minValue, + maxValue, + width, + numOfParts = 1, + singleSliderValue, + type, +}: Props) { + const calculateOffset = (value: number) => + (value * width) / (maxValue - minValue) - LABEL_LENGTH / 2; + + const createParts = () => { + const step = (maxValue - minValue) / numOfParts; + + const parts = []; + let i; + + if (numOfParts != null && numOfParts < 1) { + console.error('numOfParts cannot be lower than 1'); + } + + for (i = 0; i <= numOfParts; i++) { + const valuePerStep = Math.floor(step * i); + + parts.push( + + + + {valuePerStep + minValue} + + + ); + } + return parts; + }; + + const typeLineStyle = + type === 'single' && singleSliderValue[0] >= minValue + ? styles.selected + : styles.unselected; + + return ( + + {createParts()} + + + + ); +} + +const styles = StyleSheet.create({ + selected: { + backgroundColor: defaultTokens.paletteBlueNormal, + }, + unselected: { + backgroundColor: defaultTokens.paletteInkLighter, + }, + trackLine: { + borderRadius: 5, + height: TRACK_HEIGHT, + position: 'absolute', + top: 25 - TRACK_HEIGHT / 2, + alignSelf: 'center', + }, + partStyle: { + position: 'absolute', + width: LABEL_LENGTH, + alignItems: 'center', + }, + partBorder: { + position: 'absolute', + borderStartWidth: 2, + borderStartColor: defaultTokens.paletteCloudLightHover, + height: 34, + top: 8, + }, + labelText: { + top: 50, + position: 'absolute', + }, +}); diff --git a/yarn.lock b/yarn.lock index 8e94309..b740d55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9996,8 +9996,8 @@ react-native-modal@^5.4.0: react-native-animatable "^1.2.4" "react-native-multi-slider@https://github.com/lukewalczak/react-native-multi-slider.git#feat/block-overlap": - version "2.0.0" - resolved "https://github.com/lukewalczak/react-native-multi-slider.git#920046a4a6ab49f7f163d0e00ae34993b9778807" + version "2.0.1" + resolved "https://github.com/lukewalczak/react-native-multi-slider.git#9b42c1e1bc8759e146b9d0aa097e47f4e9a1c0be" react-native-status-bar-height@^2.2.0: version "2.2.0"