Last active
January 11, 2017 15:08
-
-
Save xcoderzach/4a77f87b9eb0eced72f85c53525ad8fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ThemeProvider } from 'styled-components' | |
export default const ComponentProvider = (namespace, defaultTheme) => (props) => { | |
const theme = (parentTheme = {}) => { | |
//If we've never seen a theme object in our namespace before, use the defaultTheme | |
parentTheme = parentTheme[namespace] || defaultTheme | |
// If a library consumer passes a function as their theme, | |
// give them the parentTheme (or defaultTheme) as an argument so they can 🎨decorate🎨. | |
const userTheme = (typeof props.theme === 'function') ? props.theme(parentTheme) : props.theme | |
return { | |
[namespace]: Object.assign({}, parentTheme, userTheme) | |
} | |
} | |
return <ThemeProvider theme={theme}> | |
{props.children} | |
</ThemeProvider> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ComponentProvider from './provider' | |
// I'm doing the interpolation here, because | |
// the range is a visual concern (pixels). | |
// The visual part of your code shouldn't be | |
// logicless, it should only have logic related | |
// to visuals. | |
function interp(domain, range, value) { | |
let domainSize = domain[1] - domain[0] | |
, rangeSize = range[1] - range[0] | |
, offset = value - domain[0] | |
, percentOffset = domainSize * offset | |
return range[0] + rangeSize * percentOffset | |
} | |
const width = 400; | |
const SliderContainer = styled.div` | |
width: ${width}px; | |
` | |
const SliderBar = styled.div` | |
width: ${width}px; | |
height: 5px; | |
background-color: tomato; | |
position: relative; | |
` | |
const SliderHandleUI = styled.div` | |
height: 30px; | |
width: 30px; | |
transform: translate(-15px -30px); | |
background-color: tomato; | |
position: absolute; | |
left: ${({ domain, value }) => interp(domain, [0, innerWidth], value)}px; | |
` | |
const SliderHandle({ ...props, onChange }) => ( | |
<SliderHandleUI | |
{...props} | |
onDrag={({ movementX }) => { | |
let newValue = props.value + interp([0, 360], props.domain, movementX) | |
this.props.onChange(newValue) | |
} | |
/> | |
) | |
export default ComponentProvider("simpleSlider", { | |
SliderHandle, | |
SliderContainer, | |
SliderBar | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
/* | |
This is the Semantic Component, notice there is nothing about | |
the display of the component defined here. 👍Yay SoC👍. | |
There's nothing preventing this component from being used with | |
react native, or as part of an svg, because it only describes | |
the semantics of the slider. | |
Obviously a full featured slider would probably need to do a lot | |
more. | |
*/ | |
export default ({ startValue, stopValue, domain, onStartChange, onStopChange, | |
theme: { | |
SliderHandle, | |
SliderBar, | |
SliderContainer | |
} | |
}) => | |
return ( | |
<SliderContainer> | |
<SliderBar | |
onStartChange={props.onStartChange} | |
onStopChange={props.onStopChange} | |
domain={domain} | |
start={startValue} | |
stop={stopValue} | |
> | |
<SliderHandle | |
position="start" | |
domain={domain} | |
value={startValue} | |
onChange={props.onStartChange} | |
/> | |
<SliderHandle | |
position="stop" | |
domain={domain} | |
value={stopValue} | |
onChange={props.onStopChange} | |
/> | |
</SliderBar> | |
</SliderContainer> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment