Slide 1

Slide 1 text

September 2017 Writing highly reusable React components Javi Velasco

Slide 2

Slide 2 text

Thanks to our sponsors!

Slide 3

Slide 3 text

javi velasco @javivelasco audiense

Slide 4

Slide 4 text

A library of React components implementing Material Design guidelines with the power of CSS modules. www.react-toolbox.com React Toolbox

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

theming and customization what do we understand?

Slide 9

Slide 9 text

“let’s change the color scheme so all components have a different primary color” |> you predict what’s going to be changed theming

Slide 10

Slide 10 text

“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

Slide 11

Slide 11 text

“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

Slide 12

Slide 12 text

theming + style customization + render customization |> taking customization to the limits, adapt to nearly anything fully flexible component + +

Slide 13

Slide 13 text

how react faces styling or how can we deal with styles in react components.

Slide 14

Slide 14 text

component(state) => view javascript css css linked through classnames

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

|>css in js enforcing hate and the js fatigue since 2015 ® my favorite: styled components |> css-in-js: let’s the building

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

render( Button primitive! ); |> using styled-components as primitives

Slide 22

Slide 22 text

|> 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.

Slide 23

Slide 23 text

const Button = ({ children, primary, ...other }) => ( {children} ); |> using react elements as primitives

Slide 24

Slide 24 text

const Button = ({ children, primary, ...other }) => ( {children} ); |> using react elements as primitives

Slide 25

Slide 25 text

|> 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.

Slide 26

Slide 26 text

solving theming and style customization using but you can use anything else!

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

const theme = { main: 'mediumseagreen' }; render( Themed ) |>theming with styled-components

Slide 30

Slide 30 text

const theme = { main: 'mediumseagreen' }; render( Themed ) |>theming with styled-components

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

render( Customized button ); |>style customization with styled-components

Slide 36

Slide 36 text

const Counter = ({ children, styles }) => ( {children} ); |>style customization with styled-components

Slide 37

Slide 37 text

const myCounter = { Wrapper: css` background: gray; border: 1px solid darkgray; `, Count: css` color: red; text-decoration: underline; ` }; |>style customization with styled-components

Slide 38

Slide 38 text

render( 4815162342 ); |>style customization with styled-components

Slide 39

Slide 39 text

solving render customization introducing component injection

Slide 40

Slide 40 text

import Wrapper from ‘./Wrapper’; import Counter from ‘./Counter’; const Counter = ({ children, styles }) => ( {children} ); |>back to the previous example

Slide 41

Slide 41 text

const getCounter = ({ Wrapper, Count }) => ( ({ children, styles }) => ( {children} ) ); |>extract the node components removing the imports

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

|> what if I want to have a red background when count value is higher than 10?

Slide 46

Slide 46 text

const getCounter = ({ Wrapper, Count, passthrough }) => ( ({ children, styles }) => ( {children} ) ); |> extract the node components removing the imports

Slide 47

Slide 47 text

const getCounter = ({ Wrapper, Count, passthrough }) => ( ({ children, styles }) => ( {children} ) ); |> extract the node components removing the imports

Slide 48

Slide 48 text

function passthrough(nodeName, props, instance) { switch(nodeName) { case ‘Wrapper’: return { counter: props.counter }; default: return {}; } } |> specify how do you want to pass down properties

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

back to react-toolbox! the road for a final version.

Slide 53

Slide 53 text

|> a brand new package! react-toolbox-core build your custom react ui-kit from a reliable set of agnostic components, hoc and utilities

Slide 54

Slide 54 text

|> 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

Slide 55

Slide 55 text

|> react-toolbox v3! react-toolbox v3 delightful material design components that will boost your project

Slide 56

Slide 56 text

|> 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

Slide 57

Slide 57 text

thank you!