Time Series Foundation Models - current state and future directions
BUILDING THE MEDIA BLOCK IN REACT
1. BUILDING THE MEDIA
BLOCK IN REACTJS
the API is an interface that needs to be designed
https://www.flickr.com/photos/darpi/212323100/in/photolist-jLdg7-4zEiwa-nwFCR-cZVtBE-4NHtnv-7daytd-pce3y-4NH3fh-5TLS72-58aMX7-58aMVN-a3826y-gVDVKr-8DRhUB-nEdkNf-6tnApQ-
fqJRqv-4NMHx7-7fUPoM-cNu2W-8etirE-o7PZA-wsB4L-7ABatu-8LyEF5-7iEjwY-3faCd1-9Gn1fF-4qYRms-JUKbE-7B97bb-69Uer5-5DQMzG-f4ZgsG-7TvUJp-5zyhEh-65naZh-nBkNs-5eCcAF-sErjv-4ePHGY-6kV1Q4-
nxWYX-dpGR5-55vgqd-5scyot-5t7uJJ-nLQn5y-9Njbu-79B4aw
13. I <3 HTML, WHY USE
REACT?
❖ html consistency (modal debugging)
❖ smaller api (fewer breaking changes)
❖ don’t need to go everywhere a component
was used to update the dom if it changes
❖ lightning fast dom updates when data
changes
❖ not managing those updates manually
❖ simpler APIs (tabs example)
16. WHAT ARE THE ELEMENTS
OF A REACT INTERFACE
❖ Elements
❖ Attributes
❖ Nested children
❖ Data
Sounds a lot like html, right?
17. HOW DO YOU MAKE A
MEDIA COMPONENT?
in React
Code
var Media = React.createClass({
!
});
18. SO THEN, HOW WOULD
YOU USE IT?
It’s kind of like HTML, it’s called jsx
<Media>
My very first React component!
</Media>
19. BUT, WE NEED TO EXPORT
the Media component, so it can be used in other files
module.exports = {
Media: Media
};
20. DESCRIBE IT WITH A
RENDER FUNCTION
This tells the browser what HTML to render.
var Media = React.createClass({
render: function () {
return (
<p>
{this.props.children}
</p>
);
}
});
just render a paragraph, for now
tell React where to
render children
22. LET’S TRY IT!
Sweet, this is gonna be rad.
<Media>
This text is our component’s children!
</Media>
!
!
!
!
<p>
This text is our component’s children!
</p>
23. LET’S TRY IT!
Sweet, this is gonna be rad.
<Media>
This text is our component’s children!
</Media>
!
!
!
!
<p>
This text is our component’s children!
</p>
When React renders that
component we get this html
24. LET’S TRY IT!
Sweet, this is gonna be rad.
<Media>
This text is our component’s children!
</Media>
!
!
!
!
<p>
This text is our component’s children!
</p>
{this.props.children}
When React renders that
component we get this html
25. NOT VERY USEFUL, RIGHT?
You'd never use react to render a simple paragraph because it
already understands <p> tags, you can just use them!
26. LET’S BUILD AN ACTUAL
MEDIA BLOCK
Step 1:Add the left image
27. SO, WHAT DID WE TRY
FIRST?
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
28. TONS OF ATTRIBUTES
What could go wrong? ;)
https://www.flickr.com/photos/ilo_oli/5856288807/in/photolist-jpnSsc-bp1mTF-iC3JNn-feu2hV-feJdEw-dCsd6V-aQmwUk-qJvwYx-qKHp7N-qKJtpL-pMFnAC-9XxWkr-qKJEV1-q6hte9-qZZXHG-q6hp8d-qKHchA-qKJt8U-bp1mv2-
b6LSWT-bKfSon-kxWCNt-b6LNN8-b8Vpk6-ehScwd-c5CMgq-qKJcqw-r3iaXK-pMieGe-9ZUFNi-aD4zaE-fDwLBF-9Vv1CF-kzarYi-9ovVLy-rVLApS-fDwKki-b5sxAg-fskG7P-bUUme1-bKgdD6-c5CMiW-a1wsSP-4u7U5a-dtv95k-dtvKP6-
dtBtwJ-dtvrRR-dtBm2s-abcAqR
29. CREATE A SOURCE
ATTRIBUTE
We’ll use it in our render function to set the src of the image
<Media leftImageSource='http://placehold.it/50x50'>
Media block content
</Media>
React props are a
lot like HTML
attributes
31. SO, LET’S ADD AN HREF
ATTRIBUTE
<Media
leftImageSource='http://placehold.it/50x50'
leftImageHref='http://www.google.com'>
Media block content
</Media>
Our render function will
make this into a link
wrapper (if it is set)
35. WE NEED AN ALT
ATTRIBUTE
<Media
leftImageSource='http://placehold.it/50x50'
leftImageHref='http://www.google.com'
leftImageAlignment='middle'
leftImageAlt="profile photo">
Media block content
</Media>
Our render function will make
this into an alt attribute on the
<img> tag
37. WE NEED A HEIGHT AND
WIDTH
<Media
leftImageSource='http://placehold.it/50x50'
leftImageHref='http://www.google.com'
leftImageAlignment='middle'
leftImageAlt="profile photo"
leftImageHeight="50px"
leftImageWidth="50px">
Media block content
</Media>
Explicit height and width
allow the browser to do a
single rendering/painting
pass
38. SET THE GUTTER BETWEEN
IMAGE AND CONTENT
with the spacing attribute
<Media
leftImageSource='http://placehold.it/50x50'
leftImageHref='http://www.google.com'
leftImageAlignment='middle'
leftImageAlt="profile photo"
leftImageHeight="50px"
leftImageWidth="50px"
leftImageSpacing="medium">
Media block content
</Media>
For when the 10px default
spacing isn’t right, like a tiny
icon with text
40. FOR EXAMPLE, IT’S
RESPONSIVE
via the stacksize (breakpoint) attribute
<Media
leftImageSource='http://placehold.it/50x50'
leftImageHref='http://www.google.com'
leftImageAlignment='middle'
leftImageAlt="profile photo"
leftImageHeight="50px"
leftImageWidth="50px"
leftImageSpacing="medium"
stackSize='medium'>
Media block content
</Media>
stack size puts the image
above the text at the
breakpoint
41. THIS IS GETTING
OUT OF HAND!
But we forgot something, the media block can have a right
image
42. ADD THE RIGHT IMAGE
PROPERTIES
This is out of control, we are going the wrong way!
<Media
leftImageSource='http://placehold.it/50x50'
leftImageHref='http://www.google.com'
leftImageAlignment='middle'
leftImageAlt="profile photo"
leftImageHeight="50px"
leftImageWidth="50px"
rightImageSource='http://placehold.it/50x50'
rightImageHref='http://www.google.com'
rightImageAlignment='middle'
rightImageAlt="profile photo"
rightImageHeight="50px"
rightImageWidth="50px"
rightImageSpacing="medium"
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
right image
props
43. PROS/CONS
❖ It’s very explicit, we know
what each thing does
What works?
❖ We're basically recreating
html in React, yuck! (we
shouldn’t make a new
different alt attribute!
❖ We have image properties
and media properties all
mixed up
❖ We have too many
properties
What doesn’t work?
44. SO, WHAT DID WE TRY
NEXT?
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
45. JSON ALL THE THINGS
https://www.flickr.com/photos/bike/4797449644/in/photolist-8iWbD3-5HPWhF-QyKg5-eVYyjt-3meRNg-5HPW94-4HwYMz-utah8-3qvXS-aqsJtx-eyQK4T-42P9p1-7Th995-5oKgDS-5mJEJe-9bt9At-4zbwwo-8vDr8Z-7konhy-
BhrJ9-5zHQ7E-bobveq-DmrMg-3qvNs-5HPW1P-qtLJmp-5ZCPcW-9QuNBj-5HUdgS-9thCcq-6FmTKV-7QgAua-6DZyzu-gkukag-apwsgp-8hWccC-4U7EX6-pfaKPb-hvM3q-asXuSH-at18RL-asXuDV-asXuC4-9ys6M7-phFVSp-
dkdPkb-86toqn-dzVg-zVaLA-cDsK7N
47. JSON IN THE MEDIA
passed in as another property
<Media
images={images}
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
48. JSON IN THE MEDIA
passed in as another property
<Media
images={images}
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
{curly braces} mean it’s a JavaScript
variable rather than a string
49. JSON IN THE MEDIA
passed in as another property
<Media
images={images}
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
json goes into the
images attribute
{curly braces} mean it’s a JavaScript
variable rather than a string
50. What works? What doesn’t work?
PROS/CONS
❖ abstraction of passing in
JSON means all the code
isn't in the same place
❖ weird to have JSON in the
middle of what looks like
markup
❖ still reinventing html
attributes of an <img> tag
❖ cleaner separation of
concerns (media takes care
of media stuff, rather than
the properties of its
children)
51. WHAT DID WE DO NEXT?
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
52. PARSING CHILDREN
We decided to try including the images as children
https://www.flickr.com/photos/i-am-mclovin/16535518502/in/photolist-rcbRyA-nshV4n-eAaqTz-bCfUFZ-jH4tBF-pctQQD-qNmfZS-eT3GMZ-bTJsji-N8LkW-iCxgoA-7JDTp2-mPGu7V-dV4m7G-igpkaV-dRobZv-mnUN9i-igoYgJ-bCzBBi-
f9tdxa-oMiWTE-b6LMzz-rcTY6S-dYq12b-qUh6hV-f6oFCx-pmwC9Z-hNLucH-moYnBt-6uGwja-aRrBm4-mPGGDB-igp6YC-f8b3QR-igpkXB-igoY3C-o62zzh-iC3JNn-9217QQ-D3JPG-pcHyUy-pprMfU-igoJAg-hgRxSL-pqomg9-
ahQDpD-4LkbKg-hNLcDy-igoJb8-9STs34
53. PARSING CHILDREN
better, everything is normal html! But, it has a few drawbacks
<Media>
<img src='http://placehold.it/50x50'
href='http://www.google.com' alignment='middle'
alt="profile photo" height="50px" width="50px" >
<p>My media content</p>
<img src='http://placehold.it/50x50'
href='http://www.google.com' alignment='middle'
alt="profile photo" height="50px" width="50px" >
</Media>
54. What works? What doesn’t work?
PROS/CONS
❖ The images and body
content need to be in a very
particular order, it seems
weird to expose that to the
user
❖ Violates the "build
components you can use
without understanding CSS”
principle
❖ Normal HTML
❖ Facebook does it this way
55. WHAT *ELSE* DOESN’T
WORK?
❖ We could loop over children and reorder them, but how do
we tell the difference between content images and media
images?
❖ We were still discovering React, and didn't know how to loop
over children yet
❖ React provides handy error messages and property validations.
We would lose out on that if we made the images children
❖ Facebook's images aren't optional, so it's a different case
56. SO, WHAT DID WE TRY
NEXT?
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
58. FIRST, WE MAKE OUR
IMAGES
var leftImage = <img src='http://placehold.it/
50x50' href='http://www.google.com'
alignment='middle' alt="profile photo"
height="50px" width="50px">;
!
var rightImage = <img src='http://placehold.it/
50x50' href='http://www.google.com'
alignment='middle' alt="profile photo"
height="50px" width=“50px">;
59. NEXT, WE MAKE OUR
MEDIA OBJECT
this looks similar to the JSON example
<Media
leftImage={leftImage}
rightImage={rightImage}
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
60. NEXT, WE MAKE OUR
MEDIA OBJECT
this looks similar to the JSON example
<Media
leftImage={leftImage}
rightImage={rightImage}
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
left and right images are
passed into attributes
61. YOU CAN EVEN WRITE IT
like this if you really want to
<Media
leftImage={<img src='http://placehold.it/50x50'
href='http://www.google.com' alignment='middle'
alt="profile photo" height="50px" width="50px">}
bodyAlignment='middle'
stackSize='medium'>
Media block content
</Media>
image component directly in
the attribute property
62. What works? What doesn’t work?
PROS/CONS
❖ HTML inside an attribute (in
the latter example) is a bit
odd, though it does have
advantages.
❖ React passes default html
attributes in to the resulting
img tag, so we don't have to
do anything special with
height, width, src, aria and alt.
❖ We separate concerns and
the image takes care of it's
own properties
❖ No need to parse content
63. WHAT *ELSE* DOESN’T
WORK?
❖ href will be passed through. So our image will have an href
attribute. I like clean html, and that feels weird to me!
<div class="media">
<a href="styleguide.pivotal.io">
<img href="styleguide.pivotal.io" />
...
Yuck!
64. WE CONSIDERED GOING
BACK TO PROPERTIES…
but decided we should make our own <img> wrapper
<Media leftImageHref="styleguide.pivotal.io">
to property or not to property?
65. SO, WHAT DID WE TRY
NEXT?
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
66. CUSTOM IMAGE
COMPONENT
And another component was born…
https://www.flickr.com/photos/eltonharding/522073772/in/photolist-N8LkW-dLnt39-dsdYRQ-qcf3KQ-rgojpc-dsdWxA-dRxje9-iAgtmB-aaTYBU-mgGFrk-d3TMAf-opZhPw-nbi6ut-gMDt1W-adGAGZ-j8HqHK-gAt6ec-mc944B-
nEMWpG-oQkVQ4-qR9xvi-gSVfC5-oUurRb-9jGTJD-nWUZza-e5NeHJ-aTYLCT-dTTRha-rp3zLC-qn7i8t-hQxDrG-9qcih5-sn5TTi-9aQfXm-nsgfeC-niFxPL-dRxjy7-9Ry7C3-p8VRa4-noA5cx-oovJdV-kLSLxL-dpgFWM-rhZ9Ri-
dRxkm3-9qResk-kGDeJb-bprRNw-oCC5tt-oCX7iY
67. GOAL: OUTPUTS A SIMPLE
<IMG> TAG
but won't pass through attributes
that don't make sense like href
68. STEP 1: CREATE THE IMAGE
COMPONENT
var Image = React.createClass({
!
});
69. STEP 2: EXPORT THE IMAGE
the same way we did the Media component
module.exports = {Image};
70. STEP 3: GET ITS PROPERTIES
and render an image
var Image = React.createClass({
render() {
var {href, src, children, className, ...other} = this.props;
!
var image = <img {...other} src={src} className={classes}>;
!
return href ? <a {...{href}}>{image}</a> : image;
}
});
71. STEP 3: GET ITS PROPERTIES
and render an image
var Image = React.createClass({
render() {
var {href, src, children, className, ...other} = this.props;
!
var image = <img {...other} src={src} className={classes}>;
!
return href ? <a {...{href}}>{image}</a> : image;
}
});
get the properties we need
72. STEP 3: GET ITS PROPERTIES
and render an image
var Image = React.createClass({
render() {
var {href, src, children, className, ...other} = this.props;
!
var image = <img {...other} src={src} className={classes}>;
!
return href ? <a {...{href}}>{image}</a> : image;
}
});
get the properties we need
build the image from our properties
73. STEP 3: GET ITS PROPERTIES
and render an image
var Image = React.createClass({
render() {
var {href, src, children, className, ...other} = this.props;
!
var image = <img {...other} src={src} className={classes}>;
!
return href ? <a {...{href}}>{image}</a> : image;
}
});
get the properties we need
build the image from our properties
if we have a link, wrap the image in an <a> tag
74. STEP 4: MAKE IT
RESPONSIVE
by handling the responsive boolean
var Image = React.createClass({
render() {
var {responsive, href, src, children, className, ...other} = this.props;
!
var image = <img {...other} src={src}>;
return href ? <a {...{href}}>{image}</a> : image;
}
});
75. STEP 4: MAKE IT
RESPONSIVE
by handling the responsive boolean
var Image = React.createClass({
render() {
var {responsive, href, src, children, className, ...other} = this.props;
!
var image = <img {...other} src={src}>;
return href ? <a {...{href}}>{image}</a> : image;
}
});
get the responsive property
76. STEP 4: MAKE IT
RESPONSIVE
and setting the img-responsive class if the boolean is true
var Image = React.createClass({
render() {
var {responsive, href, src, children, className, ...other} = this.props;
!
var classes = classnames({'img-responsive': responsive}, className);
!
!
!
!
!
!
!
var image = <img {...other} src={src} className={classes}>{children}</img>;
return href ? <a {...{href}}>{image}</a> : image;
}
});
77. STEP 4: MAKE IT
RESPONSIVE
and setting the img-responsive class if the boolean is true
var Image = React.createClass({
render() {
var {responsive, href, src, children, className, ...other} = this.props;
!
var classes = classnames({'img-responsive': responsive}, className);
!
!
!
!
!
!
!
var image = <img {...other} src={src} className={classes}>{children}</img>;
return href ? <a {...{href}}>{image}</a> : image;
}
});
add this class
if this evaluates
to true
78. STEP 4: MAKE IT
RESPONSIVE
and setting the img-responsive class if the boolean is true
var Image = React.createClass({
render() {
var {responsive, href, src, children, className, ...other} = this.props;
!
var classes = classnames({'img-responsive': responsive}, className);
!
!
!
!
!
!
!
var image = <img {...other} src={src} className={classes}>{children}</img>;
return href ? <a {...{href}}>{image}</a> : image;
}
});
add this class
if this evaluates
to true
then, put the class
on the image
87. OUR “AH-HA” MOMENT
Users are still needing to specify too many things to get this
component to work, they might as well just write html!
88. SO, WHAT DID WE DO
NEXT?
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
https://www.flickr.com/photos/mstewartphotography/6195718653/in/photolist-aruFip-3Ym2sP-d5ipmU-61ivfM-2SmfSo-eMWyyv-7Tx3yN-p7xVZN-5LExX5-dG1RK2-86LsMW-6TDV5Y-9isMj1-cJuUm-4v2NE-
amKvge-61TfaY-61PcSp-61nGEd-86FasK-qrz8VS-4bGoKp-77DPsN-7NeZKn-botCkn-8vpoEE-oTAKWV-5Sz1Fv-a5oF29-86Hf14-aS9vmZ-a8M5q6-a8Mh8k-7AKzoA-86HcPz-61HM17-7AFRcK-a8LXht-5c5LvE-a8LZXX-61Hb8A-
fJgHuw-86LhDq-86Lmch-3jzdZ-5mYENE-8UMWoM-bx1iUr-p9jsSa-a865Ji
89. ELEMENTS FTW
we can simplify our interface further
https://www.flickr.com/photos/rejik/14681743931/in/photolist-onnLY4-nPYfhm-ed6PWM-bvWmjA-mMGE1V-j88ToM-ngTbpk-nUg38a-9n1hgv-4KZr2Z-nucMef-dd5exw-9eyaqy-8QWK1i-eaTuFL-4RbvFX-7kiwo3-7NqP2a-4R1KYB-
mZEx1J-5iV12q-39v9f8-bqt2rx-7zvWs-9eyamJ-7JKZAh-hiwiDa-poG8fx-ehZRGj-684GeT-pPeQGL-efRP9f-icXKJY-aNxWqT-9niyKk-ouarpw-bmC5SK-7s5DNV-bqt3F8-bqsZ24-mZCLWp-86YqXk-e6ERub-bqtEL8-8K3pJf-
kik4tg-8yYivi-8fi3Ep-dVohpu-fzmggH
https://www.flickr.com/photos/rejik/14681743931/in/photolist-onnLY4-nPYfhm-ed6PWM-bvWmjA-mMGE1V-j88ToM-ngTbpk-nUg38a-9n1hgv-4KZr2Z-nucMef-dd5exw-9eyaqy-8QWK1i-eaTuFL-4RbvFX-7kiwo3-7NqP2a-4R1KYB-
mZEx1J-5iV12q-39v9f8-bqt2rx-7zvWs-9eyamJ-7JKZAh-hiwiDa-poG8fx-ehZRGj-684GeT-pPeQGL-efRP9f-icXKJY-aNxWqT-9niyKk-ouarpw-bmC5SK-7s5DNV-bqt3F8-bqsZ24-mZCLWp-86YqXk-e6ERub-bqtEL8-8K3pJf-
kik4tg-8yYivi-8fi3Ep-dVohpu-fzmggH
90. DESIGNERS ONLY USE 2
KINDS OF ALIGNMENT
❖ Traditional media with everything top aligned
!
!
!
❖ “Flag” component a la Harry Roberts middle aligns
91. WE MADE THESE TWO USE
CASES DEAD SIMPLE
❖ We changed the media component to default to top
alignment if nothing else was specified.
❖ We created the <flag> component
<Flag leftImage={refreshImage}>
refresh
</Flag>
92. What works? What doesn’t work?
PROS/CONS
❖ engineers don't always know
what the flag object is,
documentation and teaching
help
❖ with Flag and Media, we no
longer need to specify
alignment unless we want
something weird
93. ARE ANY OF THESE
WRONG?
No, absolutely not.
https://gist.github.com/stubbornella/e97662e4a197eb9a534a
101. GOOD DESIGN PRINCIPLES
❖ Many drawers -Tom O
❖ Set good defaults
❖ User shouldn’t need to understand CSS to use it
❖ Make tiny components with one job (same as CSS)
❖ Allow flexibility
❖ Prefer a complex implementation over a complex interface
what has worked for us
102. WHO ARE YOUR USERS?
component creators and maintainers, contributors, developers
building features, actual product users
https://www.flickr.com/photos/fabiansociety/16300828766/in/photolist-qQs1tQ-qAa8pJ-pVJmYw-qxNcH4-qAaDuJ-qSHJsr-5SDe5H-josG7R-dxrFDm-e6S4TN-fddCLi-po7JuN-d21PZN-ax7LAK-qBLEie-dEMphp-byfU17-nPjAPc-eZ7ooX-
ctHbf5-g5QFS-naVVhZ-cFgo6s-akEb2Q-qUQi3c-aGJ83i-627cGv-aRFFNx-nSyXpr-dyXFU7-aupkvk-buYgB2-nj7Xyv-jHSXR5-9eAqzK-eNqYdm-a4GaUk-qiFrdF-dy1QsG-bPqzrk-9dEUm7-n7cmgE-gJNeKz-nigszh-mi4QjT-s76Yxa-
103. USE ALL THE TOOLS IN
YOUR TOOLBOX
❖ Elements (built in and custom)
❖ Attributes (simple and objects)
❖ JSON
❖ Children