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

Building Loveable UIs

Building Loveable UIs

Some of the good and bad patterns when designing components in React. How to build scalable components keeping the visual consistency and good developer experience.

Presented at React Amsterdam 2016.

http://react.amsterdam

Henrique Alves

April 16, 2016
Tweet

More Decks by Henrique Alves

Other Decks in Programming

Transcript

  1. HTML MARKUP HOLY GRAIL OF 
 WEBMASTER JS UI CSS

    STYLING – THE EARLY DAYS –
  2. const StaticReadingList = () => ( // Let's render only

    one item <ReadingItem headline="The End of Ice" subHeadline="The New Yorker" description={ `A team of scientists hikes to investigate how quickly its ice is melting.` } imageSrc="//cldup.com/1rbk08vtLj.jpg" /> );
  3. const ReadingItem = ({headline, description, imageSrc}) => ( <Box> <Box

    flex="0 0 55%"> <Headline level={2}>{headline}</Headline> <Text element="p">{description}</Text> <Link href="#">Read Article</Link> </Box> <Box flex="1 0 45%"> <Image width="100%" src={imageSrc} /> </Box> </Box> );
  4. LEARN HOW TO ABSTRACT.
 BORROW CONCEPTS.
 — ATOMIC DESIGN —

    CONTENT & DISPLAY PATTERNS — FUNCTIONAL CSS
  5. <Headline level={5} /> // <h5> <Text element="p" /> // <p>

    <Headline level={2} /> // <h2> <Link /> // <a> <ReadingItem headline="Article Title" subHeadline="Site Name" description="Random copy" imageSrc="thumb.jpg" /> <Box element="article" /> // <article>
  6. // layout.js export const Box = ({ element: Element =

    'div', children, ...otherProps }) => ( <Element {...otherProps} style={composeStyle(otherProps)}> {children} </Element> );
  7. // layout.js // compose style object from props function composeStyle({style,

    ...otherProps}) { const bodyStyle = document.body.style; return { ...pickBy((v, k) => bodyStyle.hasOwnProperty(k), otherProps), ...style }; }
  8. NAMING COMPONENTS COOL NOT COOL <Card />
 <Headline /> <Headline

    level={1} />
 <Link /> <ImageCard />
 <StoryTitle /> <MasterHeadline /> <StoryLink />
  9. class ReadingListPage extends Component { constructor(props) { super(props); this.state =

    {data: []}; } componentWillMount() { fetch('http://localhost:8000/reading-list.json') .then((response) => { if (response.status >= 400) { return Promise.reject(new Error('Something went wrong!')); } return response.json(); }) .then((stories) => this.setState({data: stories})); } render() { const {data} = this.state; return <ReadingList data={data} /> } }
  10. const ReadingList = ({data}) => ( <ul> {data.map( (story, key)

    => ( <li key={key}> <ReadingItem headline={story.headline} subHeadline={story.site} description={story.description} imageSrc={story.imageSrc} /> </li> ) )} </ul> );
  11. SHALLOW COMPARE // react-addons-shallow-compare shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps,

    nextState); } // Using immutable objects shouldComponentUpdate(nextProps) { // Avoid object deep comparison return this.props.title !== nextProps.title }
  12. FUNCTIONAL COMPONENTS — NO SIDE EFFECTS
 — GOOD TO BUILD

    ABSTRACTIONS
 — WORKS IN SMALL AND LARGE
  13. const CONTENT_SPACING = 15; const BORDER_RADIUS = 3; const styles

    = { padding: CONTENT_SPACING, borderRadius: BORDER_RADIUS, width: 500, flexDirection: 'row', flexWrap: 'wrap', overflow: 'hidden', backgroundColor: '#fff', boxShadow: 'rgba(0, 0, 0, 0.0470588) 0px 2px 3px 0px' };
  14. const ReadingItem = ({animate, headline, description, imageSrc}) => ( <Animate

    animate={animate}> <Box> <Box flex="0 0 55%"> <Headline level={2}>{headline}</Headline> <Text element="p">{description}</Text> <Link href="#">Read Article</Link> </Box> <Box flex="1 0 45%"> <Image width="100%" src={imageSrc} /> </Box> </Box> </Animate> );
  15. // animate.js const styles = { root: { position: 'relative',

    zIndex: 2, transition: 'all 1s cubic-bezier(.75,.1,.1,1)', transformStyle: 'preserve-3d', transform: 'translateX(-1000px) rotate(30deg) translateY(1000px)', visibility: 'hidden' }, animate: { transform: 'translateZ(0)', visibility: 'visible' } }; const Animate = ({children, animate}) => { const style = Object.assign({}, styles.root, animate && styles.animate ); return <Box style={style}>{children}</Box>; }
  16. REACT-FUTURE * 
 — ANIMATION — GESTURES
 — LAYOUT SYSTEM

    (DEPENDS ON INLINE STYLING) * GITHUB.COM/REACTJS/REACT-FUTURE
  17. LINKS & REFERENCES GITHUB.COM/HENRIQUEA/REACT-AMSTERDAM-2016-TALK GITHUB.COM/REACTJS/REACT-FUTURE GITHUB.COM/RECON-JS/RECON GITHUB.COM/KADIRAHQ/REACT-STORYBOOK GITHUB.COM/SKIDDING/COSMOS GITHUB.COM/SCUP/ATELLIER DANIELMALL.COM/ARTICLES/CONTENT-DISPLAY-PATTERNS

    BRADFROST.COM/BLOG/POST/ATOMIC-WEB-DESIGN PATTERNLAB.IO JON.GOLD/2015/07/FUNCTIONAL-CSS MEDIUM.COM/@DAN_ABRAMOV/SMART-AND-DUMB-COMPONENTS-7CA2F9A7C7D0 JXNBLK.COM/REBASS GITHUB.COM/CHENGLOU/REACT-MOTION GITHUB.COM/JSSTYLES/JSS GITHUB.COM/CSS-MODULES/CSS-MODULES