Skip to content

Instantly share code, notes, and snippets.

@MoOx
Created October 21, 2016 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MoOx/e6287b36168b1eeb49d8467fea0933a4 to your computer and use it in GitHub Desktop.
Save MoOx/e6287b36168b1eeb49d8467fea0933a4 to your computer and use it in GitHub Desktop.
Stylable component that works well with React inline styles
// @flow
import React from "react"
import Hoverable from "../../modules/Hoverable"
import Focusable from "../../modules/Focusable"
import Touchable from "../../modules/Touchable"
type PropsType = {
children?: React$Element<any>,
// hoc
hovered: boolean,
focused: boolean,
touched: boolean,
// users
component: Class<React$Component<*,*,*>>,
style?: any,
hoveredStyle?: any,
focusedStyle?: any,
touchedStyle?: any,
hoveredOrFocusedStyle?: any,
}
const Stylable = (props: PropsType): React$Element<any> => {
const {
component: Component,
hovered,
focused,
touched,
style,
hoveredStyle,
focusedStyle,
touchedStyle,
hoveredOrFocusedStyle,
children,
...othersProps,
} = props
return (
<Component
{ ...othersProps }
style={ [
style,
hovered && hoveredStyle,
focused && focusedStyle,
(hovered || focused) && hoveredOrFocusedStyle,
touched && touchedStyle,
] }
>
{ children }
</Component>
)
}
export default Hoverable(Focusable(Touchable(Stylable)))
@MoOx
Copy link
Author

MoOx commented Oct 21, 2016

Usage

<Stylable
  component={ Text }
  style={ [
    styles.text,
    isActive &&
      styles.textActive,
  ] }
  hoveredOrFocusedStyle={
    styles.textHovered
  }
>
  { value }
</Stylable>

@renatorib
Copy link

renatorib commented Jan 24, 2017

Change component prop to receive by children, and use React.cloneElement to add the new props you want to pass.
This is more intuitive and readable.

const {
  children,
  style,
  hovered,
  hoveredStyle,
  ...
} = this.props;

// children from children are cloned too, don't worry
return React.cloneElement(children, {
  style: {
    style,
    hovered && hoveredStyle,
    ...
  }
);

Usage:

<Stylable style={...} hoveredStyle={...}>
  <Text>Hello World</Text>
</Stylable>

Intuitive!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment