From 2f4f4a2acd58f9da733b2d27d578715107128ac4 Mon Sep 17 00:00:00 2001 From: Gejsi Date: Tue, 3 Oct 2017 21:44:18 +0200 Subject: [PATCH 1/8] :sparkles: Added the step prop to the slider --- packages/Slider/src/index.js | 34 +++++++++++++++++++++++++------- packages/Slider/src/indicator.js | 4 ++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index b4f5459..6659adc 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -17,20 +17,20 @@ const Container = styled.div` opacity: ${props => props.disabled ? '.3' : '1'}; pointer-events: ${props => props.disabled ? 'none' : 'auto'}; &:focus { - div:nth-child(2) { + div:nth-child(3) { width: ${props => props.discrete ? '0' : '14px'}; height: ${props => props.discrete ? '0' : '14px'}; box-shadow: ${props => props.focus - ? 'none' + ? 'none' : props.value == 0 && !props.discrete ? '0 0 0 14px rgba(0, 0, 0, .1)' :props.discrete ? 'none' - : `0 0 0 14px ${rgba(props.theme.primary || lightTheme.primary, .1)}` + : `0 0 0 14px ${rgba(props.theme.secondary || lightTheme.secondary, .1)}` }; } - div:nth-child(4) { + div:nth-child(5) { transition: transform 300ms cubic-bezier(0.4, 0.0, 0.2, 1); transform: ${props => props.discrete ? 'translateX(-50%) scale(1)' @@ -62,7 +62,7 @@ const Thumb = styled.div` ? props.theme.text || lightTheme.text /* Not disabled, discrete but still at beginning */ : props.value == 0 ? props.theme.background || lightTheme.background /* At the beginning */ - : props.theme.primary || lightTheme.primary /* Moved */ + : props.theme.secondary || lightTheme.secondary /* Moved */ }; border: ${props => props.disabled && props.value == 0 ? `2px solid ${props.theme.text || lightTheme.text}` @@ -83,11 +83,26 @@ const Track = styled.div` position: absolute; background: ${props => props.disabled ? 'transparent' - : props.theme.primary || lightTheme.primary + : props.theme.secondary || lightTheme.secondary }; z-index: 1; ` +const Dots = styled.div` + display: ${props => props.discrete ? 'initial' : 'none'}; + height: 3px; + width: 100%; + position: absolute; + z-index: 2; +` + +const Dot = styled.div` + height: 3px; + width: 3px; + position: absolute; + background: ${props => props.theme.text || lightTheme.text}; +` + export class Slider extends Component { state = { focus: false, @@ -101,7 +116,7 @@ export class Slider extends Component { capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1) - getPercentage = (max) => max / 100 + getPercentage = (max) => max / (this.props.step || this.props.max) componentWillMount() { document.body.addEventListener( @@ -227,6 +242,11 @@ export class Slider extends Component { tabIndex={props.disabled ? -1 : 0} focus={focus} > + + + + + {/*Main Line*/} diff --git a/packages/Slider/src/indicator.js b/packages/Slider/src/indicator.js index 6f08c15..fe1f9b6 100644 --- a/packages/Slider/src/indicator.js +++ b/packages/Slider/src/indicator.js @@ -12,7 +12,7 @@ const Discrete = styled.div` opacity: ${props => props.value == 0 ? '.3' : '1'}; background: ${props => props.value == 0 ? props.theme.text || lightTheme.text - : props.theme.primary || lightTheme.primary + : props.theme.secondary || lightTheme.secondary }; color: ${props => props.value == 0 ? props.theme.background || lightTheme.background @@ -36,7 +36,7 @@ const Discrete = styled.div` border-right: 10px solid transparent; border-top: 10px solid ${props => props.value == 0 ? props.theme.text || lightTheme.text - : props.theme.primary || lightTheme.primary + : props.theme.secondary || lightTheme.secondary }; } ` From 5d10566cfce87cf9893f87c5340e53e521566474 Mon Sep 17 00:00:00 2001 From: Gejsi Date: Wed, 4 Oct 2017 21:49:56 +0200 Subject: [PATCH 2/8] :shit: Dots needs to be set dynamically --- packages/Slider/src/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index 6659adc..f1819b3 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -244,7 +244,9 @@ export class Slider extends Component { > - + {[0, 1, 2].map(() => { + return + })} {/*Main Line*/} From 734345376a6d4fd96bf2a628e9cc1a5c692042aa Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 4 Oct 2017 22:25:24 +0200 Subject: [PATCH 3/8] :lipstick: --- packages/Slider/src/index.js | 107 +++-------------------------------- packages/Slider/src/parts.js | 87 ++++++++++++++++++++++++++++ packages/Slider/src/steps.js | 18 ++++++ src/pages/home.js | 2 + 4 files changed, 115 insertions(+), 99 deletions(-) create mode 100644 packages/Slider/src/parts.js create mode 100644 packages/Slider/src/steps.js diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index f1819b3..19f1b44 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -4,104 +4,13 @@ import styled from 'styled-components' import { bind } from 'decko' import { Indicator } from './indicator' -import { lightTheme } from '@slup/theming' -import { rgba } from 'polished' - -const Container = styled.div` - height: 38px; - width: 100%; - position: relative; - display: flex; - align-items: center; - outline: none; - opacity: ${props => props.disabled ? '.3' : '1'}; - pointer-events: ${props => props.disabled ? 'none' : 'auto'}; - &:focus { - div:nth-child(3) { - width: ${props => props.discrete ? '0' : '14px'}; - height: ${props => props.discrete ? '0' : '14px'}; - box-shadow: ${props => props.focus - ? 'none' - : props.value == 0 && !props.discrete - ? '0 0 0 14px rgba(0, 0, 0, .1)' - :props.discrete - ? 'none' - : `0 0 0 14px ${rgba(props.theme.secondary || lightTheme.secondary, .1)}` - }; - } - - div:nth-child(5) { - transition: transform 300ms cubic-bezier(0.4, 0.0, 0.2, 1); - transform: ${props => props.discrete - ? 'translateX(-50%) scale(1)' - : 'translateX(-50%) scale(0)' - }; - } - } -` - -const Line = styled.div` - height: 3px; - width: 100%; - position: absolute; - background: ${props => props.theme.text || lightTheme.text}; - opacity: ${props => props.disabled ? '1' : '.3'}; - z-index: 1; -` - -const Thumb = styled.div` - transition: height 300ms, width 300ms, box-shadow 300ms, background 150ms; - width: ${props => props.focus ? '14px' : '10px'}; - height: ${props => props.focus ? '14px' : '10px'}; - border-radius: 50%; - background: ${props => props.disabled && props.value == 0 - ? props.theme.background || lightTheme.background /* Disabled or = to 0(at the beginning) */ - : props.disabled - ? props.theme.text || lightTheme.text /* Disabled */ - : props.discrete && props.value == 0 - ? props.theme.text || lightTheme.text /* Not disabled, discrete but still at beginning */ - : props.value == 0 - ? props.theme.background || lightTheme.background /* At the beginning */ - : props.theme.secondary || lightTheme.secondary /* Moved */ - }; - border: ${props => props.disabled && props.value == 0 - ? `2px solid ${props.theme.text || lightTheme.text}` - : props.disabled - ? `2px solid ${props.theme.background || lightTheme.background}` - : props.value == 0 && !props.discrete - ? `2px solid ${rgba(props.theme.text || lightTheme.text, .3)}` - : 'none' - }; - position: absolute; - transform: translateX(-50%); - box-shadow: none; - z-index: 2; -` - -const Track = styled.div` - height: 3px; - position: absolute; - background: ${props => props.disabled - ? 'transparent' - : props.theme.secondary || lightTheme.secondary - }; - z-index: 1; -` - -const Dots = styled.div` - display: ${props => props.discrete ? 'initial' : 'none'}; - height: 3px; - width: 100%; - position: absolute; - z-index: 2; -` - -const Dot = styled.div` - height: 3px; - width: 3px; - position: absolute; - background: ${props => props.theme.text || lightTheme.text}; -` +import { Dots, Dot } from './steps' +import { + Container, + Line, + Thumb, + Track +} from './parts' export class Slider extends Component { state = { @@ -221,7 +130,7 @@ export class Slider extends Component { } } - render(props) { + render({ steps, ...props}) { const { handleMouseDown, handleMouseUp, diff --git a/packages/Slider/src/parts.js b/packages/Slider/src/parts.js new file mode 100644 index 0000000..20d8e8d --- /dev/null +++ b/packages/Slider/src/parts.js @@ -0,0 +1,87 @@ +import styled from 'styled-components' +import { rgba } from 'polished' + +import { lightTheme } from '@slup/theming' + + +export const Container = styled.div` + height: 38px; + width: 100%; + position: relative; + display: flex; + align-items: center; + outline: none; + opacity: ${props => props.disabled ? '.3' : '1'}; + pointer-events: ${props => props.disabled ? 'none' : 'auto'}; + + &:focus { + div:nth-child(3) { + width: ${props => props.discrete ? '0' : '14px'}; + height: ${props => props.discrete ? '0' : '14px'}; + box-shadow: ${props => props.focus + ? 'none' + : props.value == 0 && !props.discrete + ? '0 0 0 14px rgba(0, 0, 0, .1)' + : props.discrete + ? 'none' + : `0 0 0 14px ${rgba(props.theme.secondary || lightTheme.secondary, .1)}` + }; + } + + div:nth-child(5) { + transition: transform 300ms cubic-bezier(0.4, 0.0, 0.2, 1); + transform: ${props => props.discrete + ? 'translateX(-50%) scale(1)' + : 'translateX(-50%) scale(0)' + }; + } + } +` + +export const Line = styled.div` + height: 3px; + width: 100%; + position: absolute; + background: ${props => props.theme.text || lightTheme.text}; + opacity: ${props => props.disabled ? '1' : '.3'}; + z-index: 1; +` + +export const Thumb = styled.div` + transition: height 300ms, width 300ms, box-shadow 300ms, background 150ms; + width: ${props => props.focus ? '14px' : '10px'}; + height: ${props => props.focus ? '14px' : '10px'}; + border-radius: 50%; + background: ${props => props.disabled && props.value == 0 + ? props.theme.background || lightTheme.background /* Disabled or = to 0(at the beginning) */ + : props.disabled + ? props.theme.text || lightTheme.text /* Disabled */ + : props.discrete && props.value == 0 + ? props.theme.text || lightTheme.text /* Not disabled, discrete but still at beginning */ + : props.value == 0 + ? props.theme.background || lightTheme.background /* At the beginning */ + : props.theme.secondary || lightTheme.secondary /* Moved */ + }; + border: ${props => props.disabled && props.value == 0 + ? `2px solid ${props.theme.text || lightTheme.text}` + : props.disabled + ? `2px solid ${props.theme.background || lightTheme.background}` + : props.value == 0 && !props.discrete + ? `2px solid ${rgba(props.theme.text || lightTheme.text, .3)}` + : 'none' + }; + position: absolute; + transform: translateX(-50%); + box-shadow: none; + z-index: 2; +` + +export const Track = styled.div` + height: 3px; + position: absolute; + background: ${props => props.disabled + ? 'transparent' + : props.theme.secondary || lightTheme.secondary + }; + z-index: 1; +` diff --git a/packages/Slider/src/steps.js b/packages/Slider/src/steps.js new file mode 100644 index 0000000..da982a6 --- /dev/null +++ b/packages/Slider/src/steps.js @@ -0,0 +1,18 @@ +import styled from 'styled-components' + +import { lightTheme } from '@slup/theming' + +export const Dots = styled.div` + display: ${props => props.discrete ? 'initial' : 'none'}; + height: 3px; + width: 100%; + position: absolute; + z-index: 2; +` + +export const Dot = styled.div` + height: 3px; + width: 3px; + position: absolute; + background: ${props => props.theme.text || lightTheme.text}; +` \ No newline at end of file diff --git a/src/pages/home.js b/src/pages/home.js index 9e56e4b..748b521 100644 --- a/src/pages/home.js +++ b/src/pages/home.js @@ -4,6 +4,7 @@ import styled from 'styled-components' import { bind, debounce } from 'decko' import { RaisedButton } from '@slup/buttons' +import { Slider } from '@slup/slider' import { Logo } from '../components/logo' const LogoContainer = styled.div` @@ -27,6 +28,7 @@ export class Home extends Component { {Logo} Get started + ) } From 16438e2eebfe5d7c07dee5c5fba7a7451999883f Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 4 Oct 2017 22:35:52 +0200 Subject: [PATCH 4/8] :sparkles: Steps --- packages/Slider/src/index.js | 24 +++++++++++++++++------- packages/Slider/src/parts.js | 2 ++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index 19f1b44..be13cdc 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -27,6 +27,8 @@ export class Slider extends Component { getPercentage = (max) => max / (this.props.step || this.props.max) + split = (max, parts) => max / parts + componentWillMount() { document.body.addEventListener( 'mousemove', @@ -53,7 +55,6 @@ export class Slider extends Component { ) } - @bind moveSlider({ clientX }) { const { offsetLeft, clientWidth } = this.slider @@ -138,8 +139,16 @@ export class Slider extends Component { handleKeyDown, handleFocus } = this - const { focus, keyFocus } = this.state + const dots = [] + + if(steps) { + const stepValue = this.split(props.max, steps) + + for (let i = 0; i < steps; i++) { + dots.push() + } + } return( - - {[0, 1, 2].map(() => { - return - })} - + {/** Dots for stepped slider */} + {steps && props.discrete && + + {dots} + + } {/*Main Line*/} diff --git a/packages/Slider/src/parts.js b/packages/Slider/src/parts.js index 20d8e8d..12f8b12 100644 --- a/packages/Slider/src/parts.js +++ b/packages/Slider/src/parts.js @@ -52,6 +52,7 @@ export const Thumb = styled.div` width: ${props => props.focus ? '14px' : '10px'}; height: ${props => props.focus ? '14px' : '10px'}; border-radius: 50%; + background: ${props => props.disabled && props.value == 0 ? props.theme.background || lightTheme.background /* Disabled or = to 0(at the beginning) */ : props.disabled @@ -62,6 +63,7 @@ export const Thumb = styled.div` ? props.theme.background || lightTheme.background /* At the beginning */ : props.theme.secondary || lightTheme.secondary /* Moved */ }; + border: ${props => props.disabled && props.value == 0 ? `2px solid ${props.theme.text || lightTheme.text}` : props.disabled From a2fe12ec993c32ccb384c9f7c1a7b4aef78079f8 Mon Sep 17 00:00:00 2001 From: Gejsi Date: Thu, 5 Oct 2017 20:02:27 +0200 Subject: [PATCH 5/8] :bug: Fixed styling issues --- packages/Slider/src/index.js | 40 +++++++++++++++++------------------- packages/Slider/src/parts.js | 24 +++++++++++----------- packages/Slider/src/steps.js | 13 ++++++++++-- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index be13cdc..831701f 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -5,11 +5,11 @@ import { bind } from 'decko' import { Indicator } from './indicator' import { Dots, Dot } from './steps' -import { - Container, - Line, - Thumb, - Track +import { + Container, + Line, + Thumb, + Track } from './parts' export class Slider extends Component { @@ -161,34 +161,32 @@ export class Slider extends Component { focus={focus} > + {/* Thumb */} + + {/** Dots for stepped slider */} {steps && props.discrete && {dots} + } {/*Main Line*/} - {/* Thumb */} - - {/* Track */} - - - {props.discrete - ? - : null - } + + ) } diff --git a/packages/Slider/src/parts.js b/packages/Slider/src/parts.js index 12f8b12..4a2dea6 100644 --- a/packages/Slider/src/parts.js +++ b/packages/Slider/src/parts.js @@ -15,25 +15,25 @@ export const Container = styled.div` pointer-events: ${props => props.disabled ? 'none' : 'auto'}; &:focus { - div:nth-child(3) { + div:first-child { width: ${props => props.discrete ? '0' : '14px'}; height: ${props => props.discrete ? '0' : '14px'}; box-shadow: ${props => props.focus - ? 'none' - : props.value == 0 && !props.discrete - ? '0 0 0 14px rgba(0, 0, 0, .1)' - : props.discrete ? 'none' - : `0 0 0 14px ${rgba(props.theme.secondary || lightTheme.secondary, .1)}` - }; + : props.value == 0 && !props.discrete + ? '0 0 0 14px rgba(0, 0, 0, .1)' + : props.discrete + ? 'none' + : `0 0 0 14px ${rgba(props.theme.secondary || lightTheme.secondary, .1)}` + }; } - div:nth-child(5) { + div:last-child { transition: transform 300ms cubic-bezier(0.4, 0.0, 0.2, 1); transform: ${props => props.discrete - ? 'translateX(-50%) scale(1)' - : 'translateX(-50%) scale(0)' - }; + ? 'translateX(-50%) scale(1)' + : 'translateX(-50%) scale(0)' + }; } } ` @@ -63,7 +63,7 @@ export const Thumb = styled.div` ? props.theme.background || lightTheme.background /* At the beginning */ : props.theme.secondary || lightTheme.secondary /* Moved */ }; - + border: ${props => props.disabled && props.value == 0 ? `2px solid ${props.theme.text || lightTheme.text}` : props.disabled diff --git a/packages/Slider/src/steps.js b/packages/Slider/src/steps.js index da982a6..4a74ff7 100644 --- a/packages/Slider/src/steps.js +++ b/packages/Slider/src/steps.js @@ -2,17 +2,26 @@ import styled from 'styled-components' import { lightTheme } from '@slup/theming' +import { Container } from './parts' + export const Dots = styled.div` - display: ${props => props.discrete ? 'initial' : 'none'}; + display: ${props => props.disabled ? 'none' : 'initial'}; height: 3px; width: 100%; position: absolute; z-index: 2; + ${Container}:focus & { + div:first-child { + width: 3px; + height: 3px; + } + } ` export const Dot = styled.div` height: 3px; width: 3px; + border-radius: 50%; position: absolute; background: ${props => props.theme.text || lightTheme.text}; -` \ No newline at end of file +` From e48989f11ec48dd9972115387be7e8e3f671acb9 Mon Sep 17 00:00:00 2001 From: Gejsi Date: Thu, 5 Oct 2017 20:52:06 +0200 Subject: [PATCH 6/8] :bug: Fixed step progress with keyboard events --- packages/Slider/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index 831701f..e5d0c5e 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -25,7 +25,7 @@ export class Slider extends Component { capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1) - getPercentage = (max) => max / (this.props.step || this.props.max) + getPercentage = (max) => max / (this.props.steps || this.props.max) split = (max, parts) => max / parts From 2f01c689cc038037ced0d7caf349942a3839ffed Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 6 Oct 2017 15:03:45 +0200 Subject: [PATCH 7/8] :sparkles: --- src/pages/home.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/pages/home.js b/src/pages/home.js index 748b521..f3b3500 100644 --- a/src/pages/home.js +++ b/src/pages/home.js @@ -17,6 +17,24 @@ const LogoContainer = styled.div` ` export class Home extends Component { + state = { value: 0, focus: false } + + @bind + onChange(value) { + this.setState({ value }) + } + + @bind + onFocus() { + this.setState({ focus: true }) + } + + @bind + onBlur() { + console.log('called') + this.setState({ focus: false }) + } + @bind @debounce(300) handleClick() { @@ -28,7 +46,16 @@ export class Home extends Component { {Logo} Get started - + ) } From 084f9cd45843b16578bf116e91d536ec25d44a01 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 7 Oct 2017 16:32:56 +0200 Subject: [PATCH 8/8] :sparkles: Steps :tada: --- packages/Slider/src/index.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/Slider/src/index.js b/packages/Slider/src/index.js index e5d0c5e..fbae92d 100644 --- a/packages/Slider/src/index.js +++ b/packages/Slider/src/index.js @@ -56,14 +56,13 @@ export class Slider extends Component { } @bind - moveSlider({ clientX }) { + progressFromEvent({ clientX }) { const { offsetLeft, clientWidth } = this.slider const { max } = this.props const percentage = (clientX - offsetLeft) / clientWidth - const progress = this.vise(0, percentage, 1) * max + return this.vise(0, percentage, 1) * max - this.emit('change', progress) } emit(type, value) { @@ -79,7 +78,7 @@ export class Slider extends Component { this.setState({ focus: true }) this.emit('focus') - this.moveSlider(e) + this.handleMouseMove(e) } @bind @@ -91,7 +90,19 @@ export class Slider extends Component { @bind handleMouseMove(e) { - if(this.state.focus) this.moveSlider(e) + /** Ignore moves when unfocused */ + if (!this.state.focus) return + + if (this.props.steps && this.props.discrete) { + const perc = this.progressFromEvent(e) + const spl = this.split(this.props.max, this.props.steps) + const index = Math.round(perc / spl) + + + this.emit('change', index * spl) + } + + else this.emit('change', this.progressFromEvent(e)) } @bind