Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Alicante 17' - Writing highly reusable React components

9afcaea1ecdbcf50afb8c99ad77f4a80?s=47 Javier Velasco
October 06, 2017
180

React Alicante 17' - Writing highly reusable React components

9afcaea1ecdbcf50afb8c99ad77f4a80?s=128

Javier Velasco

October 06, 2017
Tweet

Transcript

  1. September 2017 Writing highly reusable React components Javi Velasco

  2. Thanks to our sponsors!

  3. javi velasco @javivelasco audiense

  4. A library of React components implementing Material Design guidelines with

    the power of CSS modules. www.react-toolbox.com React Toolbox
  5. None
  6. abuse of rendering based on props collections “forces” you to

    a no-that-easy setup with webpack customization api based on css modules |> some relevant issues
  7. None
  8. theming and customization what do we understand?

  9. “let’s change the color scheme so all components have a

    different primary color” |> you predict what’s going to be changed theming
  10. “the card title is too small and I don’t care

    about what md says , I want it bigger” |> you can’t predict what’s going to change style customization
  11. “I the date picker but I want to change the

    weekday titles from capital letters to their full names” |> you can’t make everything customizable via declarative api render customization
  12. theming + style customization + render customization |> taking customization

    to the limits, adapt to nearly anything fully flexible component + +
  13. how react faces styling or how can we deal with

    styles in react components.
  14. component(state) => view javascript css css linked through classnames

  15. to get theming you need building and setup what if

    we consider style a function of state? can we handle css as react does with html? |> css is not a first class citizen in react
  16. |>css in js enforcing hate and the js fatigue since

    2015 ® my favorite: styled components |> css-in-js: let’s the building
  17. import styled, { css } from 'styled-components'; const Button =

    styled.a` display: inline-block; border-radius: 3px; padding: 0.5rem 0; margin: 0.5rem 1rem; width: 11rem; background: transparent; color: white; border: 2px solid white; ${props => props.primary && css` background: white; color: palevioletred; `} `; |> simple button with styled-components
  18. import styled, { css } from 'styled-components'; const Button =

    styled.a` display: inline-block; border-radius: 3px; padding: 0.5rem 0; margin: 0.5rem 1rem; width: 11rem; background: transparent; color: white; border: 2px solid white; ${props => props.primary && css` background: white; color: palevioletred; `} `; |> simple button with styled-components
  19. import styled, { css } from 'styled-components'; const Button =

    styled.a` display: inline-block; border-radius: 3px; padding: 0.5rem 0; margin: 0.5rem 1rem; width: 11rem; background: transparent; color: white; border: 2px solid white; ${props => props.primary && css` background: white; color: palevioletred; `} `; |> simple button with styled-components
  20. import styled, { css } from 'styled-components'; const Button =

    styled.a` display: inline-block; border-radius: 3px; padding: 0.5rem 0; margin: 0.5rem 1rem; width: 11rem; background: transparent; color: white; border: 2px solid white; ${props => props.primary && css` background: white; color: palevioletred; `} `; |> simple button with styled-components
  21. render( <Button primary> Button primitive! </Button> ); |> using styled-components

    as primitives
  22. |> using styled-components as primitives styles are bundled with the

    component. you map state to properties (feels natural). the library can define an api for theming. overriding styles relies on javascript and the lib.
  23. const Button = ({ children, primary, ...other }) => (

    <button className={primary ? 'btn primary’ : 'btn'} {…other} > {children} </button> ); |> using react elements as primitives
  24. const Button = ({ children, primary, ...other }) => (

    <button className={primary ? 'btn primary’ : 'btn'} {…other} > {children} </button> ); |> using react elements as primitives
  25. |> using react elements as primitives style is not bundled

    but linked by using classnames. you map state to a combination of classnames. no built-in strategy to get theming. overriding styles relies into selector priority.
  26. solving theming and style customization using but you can use

    anything else!
  27. const Button = styled.button` border: 2px solid ${props => props.theme.main};

    border-radius: 3px; color: ${props => props.theme.main}; font-size: 1em; margin: 1em; padding: 0.25em 1em; `; |>theming with styled-components
  28. const Button = styled.button` border: 2px solid ${props => props.theme.main};

    border-radius: 3px; color: ${props => props.theme.main}; font-size: 1em; margin: 1em; padding: 0.25em 1em; `; |>theming with styled-components
  29. const theme = { main: 'mediumseagreen' }; render( <ThemeProvider theme={theme}>

    <Button>Themed </Button> </ThemeProvider> ) |>theming with styled-components
  30. const theme = { main: 'mediumseagreen' }; render( <ThemeProvider theme={theme}>

    <Button>Themed </Button> </ThemeProvider> ) |>theming with styled-components
  31. const Button = styled.button` border-radius: 3px; font-size: 1em; margin: 1em;

    padding: 0.25em 1em; ${props => props.styles}; `; |> style customization with styled-components
  32. const Button = styled.button` border-radius: 3px; font-size: 1em; margin: 1em;

    padding: 0.25em 1em; ${props => props.styles}; `; |> style customization with styled-components
  33. const styles = css` color: black; border-radius: 50%; background-color: ${props

    => ( props.primary ? ‘aliceblue’ : undefined )}; ` |>style customization with styled-components
  34. const styles = css` color: black; border-radius: 50%; background-color: ${props

    => ( props.primary ? ‘aliceblue’ : undefined )}; ` |>style customization with styled-components
  35. render( <Button styles={styles}> Customized button </Button> ); |>style customization with

    styled-components
  36. const Counter = ({ children, styles }) => ( <Wrapper

    styles={styles.Wrapper}> <Count styles={styles.Count}> {children} </Count> </Wrapper> ); |>style customization with styled-components
  37. const myCounter = { Wrapper: css` background: gray; border: 1px

    solid darkgray; `, Count: css` color: red; text-decoration: underline; ` }; |>style customization with styled-components
  38. render( <Counter styles={myCounter}> 4815162342 </Counter> ); |>style customization with styled-components

  39. solving render customization introducing component injection

  40. import Wrapper from ‘./Wrapper’; import Counter from ‘./Counter’; const Counter

    = ({ children, styles }) => ( <Wrapper styles={styles.Wrapper}> <Count styles={styles.Count}> {children} </Count> </Wrapper> ); |>back to the previous example
  41. const getCounter = ({ Wrapper, Count }) => ( ({

    children, styles }) => ( <Wrapper styles={styles.Wrapper}> <Count styles={styles.Count}> {children} </Count> </Wrapper> ) ); |>extract the node components removing the imports
  42. import styled from ‘styled-components’; const Counter = getCounter({ Wrapper: styled.div`

    background-color: purple; height: 100px; width: 100px; ${props => props.styles}; `, Count: styled.span` color: white; display: block; text-align: center; ${props => props.styles}; ` }) |> create a counter component by injecting fela components
  43. import { createComponent } from ‘react-fela’; const Counter = getCounter({

    Wrapper: createComponent(props => { backgroundColor: purple, height: 100, width: 100, …props.styles, }, ‘div’), Count: createComponent(props => { alignContent: center, color: ‘white’, flex: 1, …props.styles, }, ‘span’), }) |> create a counter component by injecting fela components
  44. import styled from ‘styled-components/native’; const Counter = getCounter({ Wrapper: styled.View`

    background-color: #000; height: 100; width: 100; ${props => props.styles}; `, Count: styled.Text` align-content: center; color: white; flex: 1; ${props => props.styles}; ` }) |> create a counter component by injecting fela components
  45. |> what if I want to have a red background

    when count value is higher than 10?
  46. const getCounter = ({ Wrapper, Count, passthrough }) => (

    ({ children, styles }) => ( <Wrapper styles={styles.Wrapper} {…passthrough(‘Wrapper’, props, this)} > <Count styles={styles.Count} {…passthrough(‘Count’, props, this)} > {children} </Count> </Wrapper> ) ); |> extract the node components removing the imports
  47. const getCounter = ({ Wrapper, Count, passthrough }) => (

    ({ children, styles }) => ( <Wrapper styles={styles.Wrapper} {…passthrough(‘Wrapper’, props, this)} > <Count styles={styles.Count} {…passthrough(‘Count’, props, this)} > {children} </Count> </Wrapper> ) ); |> extract the node components removing the imports
  48. function passthrough(nodeName, props, instance) { switch(nodeName) { case ‘Wrapper’: return

    { counter: props.counter }; default: return {}; } } |> specify how do you want to pass down properties
  49. const Counter = getCounter({ passthrough, Wrapper: styled.div` background-color: ${props =>

    ( props.counter > 10 && ‘red’ )}; height: 100px; width: 100px; `, Count: styled.span` color: white; display: block; text-align: center; `, }) |> use the property to modify the style from its generation
  50. const Counter = getCounter({ passthrough, Wrapper: styled.div` background-color: ${props =>

    ( props.counter > 10 && ‘red’ )}; height: 100px; width: 100px; `, Count: styled.span` color: white; display: block; text-align: center; `, }) |> use the property to modify the style from its generation
  51. None
  52. back to react-toolbox! the road for a final version.

  53. |> a brand new package! react-toolbox-core build your custom react

    ui-kit from a reliable set of agnostic components, hoc and utilities
  54. |> what’s coming with react-toolbox-core? an hoc to make navigable

    components complex components like a date picker an hoc to position elements in the screen
  55. |> react-toolbox v3! react-toolbox v3 delightful material design components that

    will boost your project
  56. |> what’s coming with react-toolbox-core? customize render by injecting nodes

    customize styles without worrying about selectors js theming api powered by styled components powerful children based api
  57. thank you!