Web Components: It’s about Time | Erin Zimmer

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi I'm I'm Aaron you might remember me from such earlier sessions as the opening keynote and updating your angular app today we're gonna talk about web components I have managed to get some kind of nasty throat infection when I was in America last week so we might need to end this like through interpretive dance or something but well we'll push through and see how we go all right as we mentioned yesterday web components have actually been around for quite a while they were first proposed in 2011 but in 2011 everyone was writing jQuery plugins right nobody cared about components so it was quite a while before they really gained proper browser support it was only last year that Firefox and our support and edge has actually only just getting support as they switch to using blink as their engine but so what's changed since 2011 mostly these days when we're writing code we write it with components right we use frameworks and frameworks are built out of components so everybody's used to add you have components now we all think that there are a pretty good idea the question though is if we've got these frameworks then why do we need native components in the browser we've already got components in our frameworks or to put it another way in framework components and web components with a fight who would win there's a few arguments on both sides so framework components give you a bunch of stuff you don't get from web components for instance they give you an easy way to bind your JavaScript model to your HTML view through things like JSX templates and angular that kind of thing I'm a lot of them give you change detection so for instance angular gives you automatic change detection through zone Jass and view does something similar you native JavaScript get as incentives and they give you things above the level of the component like state management and routing on the other hand web components are a lot more lightweight right all of this stuff that your framework or library I guess in the case of react gives you it doesn't come for free there's a cost to having all of that managed for you whereas web components you're just shipping the JavaScript that you're actually using for your component the other thing is web components are flexible you can mix and match them you can use them with your frameworks or not or with whatever there's actually a website called custom elements everywhere which tells you where you can which like libraries and frameworks you're comparing its web components are going to work with and we look down through the list you'll see it's pretty much all green everything is going well except for that one little remaining ones using this library react yeah if there's a couple of issues there with passing in attributes and handling events but they're working on it you can absolutely still use web components with it the other thing is you can use web components with your CMS so if you don't have a framework but you still want to have reusable components as far as the CMS is concerned they just standard HTML elements so you can use them there so the answer to who would win is that we don't need to find so what kind of situations might you want to use web components in the first is if you don't have a framework right maybe you're building a simple site that just doesn't require a framework but you still want to have reusable components then web components are perfect for that maybe you've got multiple sites that you want to share components between but they're written in different frameworks so maybe you've got a react out and an angular out but they're still under the same brand so you want them to have similar look and feel but you don't want to replicate all that code we've compared it to good for that or you might have a situation where you want a component that's separate from the framework which sounds like a weird thing to do but this is actually how we're using web components where I work for our a B testing when we want to inject a new experiment onto the page we don't have to go through the whole normal build and deploy and release cycle with our free work code so we just build a web component and then we inject it onto the page and then we do our a be testing all right so now you're all 100% convinced that you absolutely want to use web components let's have a look at what they actually involve so web components are actually four separate specs the first one is es modules and I'm sure you're all familiar with that one so we're not going to talk about it second is HTML templates HTML templates give you a way to create like reusable fragments of HTML sort of like you do in a framework component it's super handy but I'm not going to use them today I think gills workshop tomorrow we'll be using them though so if you're interested totally check that out well we're going to look at today is custom elements and shadow Dom so custom elements provide you with a way to create new HTML elements so essentially define your own HTML and shadow Dom provides you with a way to encapsulate that Dom so you can have like CSS inside your shadow Dom that's not going to then leak out and affect everything on the page to do that we're gonna do live coding boo because 5/3 you don't know on the last day of the conference seems like a great time to do that okay we're gonna create a custom element we shut it up we're gonna look at some aspects around styling it we're gonna see how we can pass data into and out of a custom element we can add some behavior and we're going to see how our elements can communicate with each other sweet so the component that we're going to build is this so now that we've Google+ isn't around anymore and Facebook seems to be increasingly getting yourself into trouble I think there's a real opening in the social media market so we're gonna build a social media post so you can see here we've got the users avatar we've got a little bit of content and then at the end here we've got a way to react to the post and we've got the three sort of standard reactions here I copy you can be sad or you can be aerial tramway as you react to it the history of your reactions shows up across the bottom here all right so let's switch to an IDE okay so the thing with this demo is I've got a like a live HTTP reload server running so that it will keep refreshing the page automatically for me but there's no build system right there's no magic nothing up my sleeves no build system no libraries it's all just vanilla JavaScript I do have a little snippet of HTML here to start me off she's just a bit of CSS too because it's pretty ok so we wanted to find a custom element the first thing we're going to do is just use custom elements which is a global object available everywhere that's are fine now we need to pass in a name for our component and the one rule with the name is that it has to have a hyphen in it so you've got no - the browser is gonna think it's a native element if you've got a - it's going to assume it's a custom element we're gonna call ours post the second thing we need to pass in is a cloth that describes the behavior of that element and it needs to extend HTML element the spec allows for extending like children of HTML element like HTML input element but the syntax is a bit enough and it's not supported in Safari and Apple a pretty dead set against it so for now HTML element all right inside our class we need a constructor and inside the constructor the first thing we need to do is call super and that is enough to have a custom element so we can put it on the page now pushed and we go back to our browser you can see in the console here there's our element and in Firefox there's a little link here that will take us to the actual definition of that element so we can see we can see that it's there we can't see it on screen yet though because we haven't put anything in so let's do that now the first thing we want to do is create a shadow root now like I said before this encapsulates our element so it stops the CSS inside it from leaking out but it also provides some in capsulation around how like JavaScript selectors work so this little it's not a touch shudder we need to pass in a configuration object with a single property called mode and we're going to create open and this mode controls whether your shadow root is targetable by javascript so in this case we can now go back to our console and do a bit of a document don't query select maybe we can type greater like duh select it out tweet post and we can get access to the shadow root so you can see the shadow root just here there's nothing in it but it's there whereas if we made this closed and run the same thing we get no we can't um we can't access the shadow root there so do yourselves a favor make your life easier just use open all right once we've got a shadow root we can start adding HTML to it and you can do this any way that you would normally add HTML you can use HTML templates you can use those documents I'll create element and append the children today we are going to use good old inner HTML because it makes it really easy to type stuff okay so in here we're gonna need some we're gonna need a div for the post we're gonna want a div for the avatar the content one for a little reaction button and one for the like the list of the reactions down the bottom and including t'v so now if we look in our browser we can see a post when you see our shadow root there and all about HTML entities we can't see you on the screen still on the window still because we haven't styled it so let's do that now I'm sure you don't want to watch me type all this CSS so here's some I prepared earlier and there through the magic of CSS grid we have our ports a couple of little things with this CSS up here you can see I've used this selector host this basically selects the root element of your like the root of your custom element so it's basically the shadow root itself you can also see here the border is set using a CSS custom property called theme color and that color is actually set up here in a light on so we can for instance change this yellow and our post lot dates yellow so this is the way that you can pass CSS into your custom element is using custom properties they will cross over the shadow boundary I like the blue better though so we're going to stick with that okay cool so now we need to add the content of our post so the first thing we want to do is to add that avatar picture and the way that we want to do that is to allow the user or the person who's using the element to just pass in an attribute called avatar that has the URL of the picture so then we need a way to put that in our HTML so we go into avatar div we can add an image with a source attribute and because this is a template string we can very easily just add some JavaScript in there and we can just do this like the same way you would do with any other HTML element you've got access to the attributes and you can just get access to the value and there is that avatar so the next thing we want to do is add that actual the content of the post and we don't really want to do that via and an attribute because I mean it could be quite long it could be full of characters that aren't valid in an attribute so instead we want to actually make it the body of the of the element here so let me just grab that because we don't want to type it all out you can stick that in there the other advantage of doing this this way is that if the JavaScript is slow to load or whatever this custom element will be on the page with its content so the user will be able to read it still in our case though we can't see it because this element has like we can see the the content here but now it's got like light Dom content and it's got a shadow root and obviously the shadow root wins because the darkside is more powerful or something so we can't see our content so what we need is a way to say hey we want to show the light Dom content inside of our shadow Dom and we can do that using an element called slot the slot basically creates like a tunnel or a sim link between the light DOM and the dark Dom at the doctor the shadow Dom so now we can see our content here and if we look in our dev tools we can see our shadow root and inside our post here we've got a slot and inside the slot it just links to light the light Dom content but look one thing here though is that our link is blue because by default browsers don't inherit the color of a link they set them to blue so we need to fix that problem though is that the link is in the light Dom and our CSS is in the shadow Dom and the shadow Dom can't affect the light zone sorry what we need to do is use a special CSS selector called slotted which will give us access to stuff inside the slots we need to tell it which elements inside the slots we want to affect and in our case it's just all of them and we want to set the color to inherit because inherit is the other thing that will cross the shadow Dom if you said you cut like something to inherit in the shadow Dom it will inherit that value from the light Dom go so there we have our color so the next thing we want to do is add that button that lets us pick an emoji and we're actually going to do that by creating a whole other custom element so this is like two for the price of one it's a good deal all right so just like before we need to custom elements don't define or call it an emerging picker we need a class which extends HTML element we need a constructor I need to call supe we want to this don't touch shudder and again we want that mode to be open and then we want to stop adding out dumb so again I'm just gonna use in HTML this time we're going to want a button and I'm gonna give it a class of selected because it's growing as sure which emojis being selected as the text content once we've selected something content of + and we're gonna want a list of stuff now I cannot for the life of me work out how to type emoji on this computer so we are going to copy/paste we're just gonna ignore all that indenting and then we need to actually add the element to our to our dong so we can do that we can just you can add custom elements inside a custom elements it can be custom elements all the way down there's our mochi pickle on the page looks like though so let's add some styling all right just like before we're using custom CSS properties to set the color of our about emoji picker so this is a good way if you want to like themed things you can just get the theme color passed in so we haven't set that color anywhere so I'm just gonna set it up here the picker color need more dashes it's going to be the same as the color of our post right so everything is nice and muchy so now we've got the nice blue border obviously this isn't how we wanted to start we want that list to start hidden so I I've got some CSS here we can just add a class that will hide it all right now we're ready to add some behavior so the first thing we want to do is when we click the button we want the list to appear now this is just like writing any other HTML basically a JavaScript elements we just stop with a shadow root we can just use query selector and we can grab a reference to the button selected equals that and then we can grab also a reference to the list in this case we can use like a super generic selector like ul because this query selector is only going to run in the context of our shadow zone so even if we had more shadow Dom like a child element inside of here we can still use this super generic selector which is nice and then we just want to add like a normal out of an event listener so this don't selected don't add event listener it's gonna be a click handler and when we click on the button we want to remove that hidden class from the from the list girl so now we click the list appears hooray so the next thing we need to do is when we click one of these buttons we want to hide the list and we want to change the like the the content of the the button to show you that emoji so again we just need to add another event listener so just a list dot out event listener again it's a click event this time I want to get a hold of the event so let's just grab a copy of the the actual emerge-ii that was selected right so that's just gonna grab whichever but emoji was on the button that was clicked then we're gonna want to hide the list and finally we want to set the content of the button to the emoji so this don't selected text content equals this dog value cool so now when we click the button we can select our emergy and it shows up on the button so the last thing that we need to do is then pass that emoji that we've selected back up to the parents like this so that it can add it into the lists down here and we can do that again just using a really standard HTML feature we're going to use an HTML event so every one of this dispatch event in the event we can call it whatever we want say emoji picked we need to pass in a couple of config items the first one we want to pass the actual emerging that we selected which we do via the detail property and has to be called detail you can't just make up anything the other thing we want to do is to make sure our event bubbles upwards so that the parent gets access to it once we've done that we can go back to our parent element which I've lost and add a listener here so we're gonna listen on the shadow root we're gonna add an event listener which is going to listen for our emoji picked event to access the event and then here we can just console.log what have I done I'm outside of the club then we can console dot log say parent and the event dot detail and now if we click we choose an emoji oh no it's not an object oops right because this needs to actually be a custom event I do that like every second time I do this talk all right so now when we click on our thing you can see in the console down the bottom there we've the parent has received the event now in this case the event is only going to bubble off as far as the next shadow dome the shadow root it's not going to pass over the shadowed boundary so for instance if we were to add another event listener window dot add event listener emergy picked and we have the event not with those kind of brackets we don't and we consult log window an event dot detail you can see that when we send the event only the parent receives it it doesn't make it as far as the window and in some cases this is fine but in some cases you're going to want your events to bubble up the whole way to the window you can do that by just adding another property in your event config which is composed I have no idea why it's called composed it is no idea once we do that we can add it and we can see both the parent and the window are getting the event so you can do it either way it depends on what what's going to work for you in our case it really doesn't matter well let's just get rid of that okay so once we've got this event detail we want to add it into our Dom so what we need is a list of emoji that have been selected before and a reference to the particular Dom element element and then every time we receive an emerge we can just push it onto the list and then update the text content of that reactions element to be the list so there's two reactions text content equals list and we just need to join them with an empty string otherwise you'll get commas in between them because that's how JavaScript rolls so now you can see we can choose our emoji and there they are appearing in the parent element cool so this is all well and good but it's probably not how you're going to load a component are you probably going to need to do some kind of API call that's then going to load the content or something like that so let's let's fake that let's just grab a little snippet here which is going to pretend that we've got the component on the page and then we've made some kind of API call that has then filled in the details so we're going to use the set timeout and after two seconds we're going to set the attribute the avatar attribute and we're going to set the contents so let's just get rid of them out of here and if two seconds seems like a long time to get to take to get back this much information just pretend you're on holidays in Australia okay so if we do that we can see that we get an error down in the console here bigger because we're trying to reach avatar attribute and it hasn't been set yet so let's just get rid of that so the error goes away now after two seconds you can see we get the content but obviously you don't get the Avatar anymore because we just got rid of that bit of code so how are you going to do that we need a way to know when the avatar attribute has been updated and then to do our stuff we can do that we need to do two things to make that work the first is that we need to tell our custom element which attributes we want to listen for and we do that by giving it a class property so you can do that using static get observed attributes and it does need to be called observed attributes and this needs to return a list and in our case that list is just going to have one item in it which is the avatar attribute alright once we've done that then we can use a lifecycle func like a callback that watches the attributes and this is just a standard HTML element life cycle callbacks called attribute changed call back and it's gonna get a name it's gonna get the old value and it's going to get the new value and we can just console.log say the name and the new value and then after our two seconds you can see in the console that we've logged the name in the that should be value so once we've done that we can just use that to set the the image source so if name equals avatar this dot shadow root query selector image source equals new value after two seconds we get our avatar back so that's cool but I mean you don't normally do this kind of thing using attributes right you probably want to do it using properties and we can do that as well so for instance if we have here selected our aerial tramway does anybody actually call that an aerial tramway I would call it a cable car but apparently aerial tramway is the official name of the emoji okay so we've got a shadow routes and we do a query select to get access to our G pickup and we can get the value of our Jeep Iike you can see it's aerial tramway because we said that property when we changed the value we can even change the value to something else and if we read it back in the console we can see that the value is updated but nothing's changed on the screen this is one of those things that your framework components give you right that the binding between your data models and your HTML luckily this is actually pretty easy to fix you know web component just need to go into our emoji picker here and add a setter for the value so if we add that setter then whenever the value is changed we run the code that updates it then that will be Margie and this will be emergent should take that to second to layout so now we can set the things normally or we can set the value programmatically and it will still update in the screen unfortunately now we've broken this we can't read it back that's because if you have a set up then you need I guess I'll be able to read it so we can get value and then we need to return like need to store it in a fake private property here so if you're not familiar with this kind of notation the underscore emoji means like the underscore in the variable name means this is supposed to be private please don't look at it but there's nothing actually stopping anybody from looking at it or touching it so it's not like super ideal proper actual private properties are being like are in the process of being added to the browser's there is a standard for it they're just not here wait yep but once we've got that this will be a bit a bit better all right so now we can set aerial tramway we can set whatever we can set a value programmatically and we can read that back as well and this like we can create it's not just the properties that we can set here right we can create a whole API for our web component so if we wanted to allow people to programmatically open and close the list on our on our on our emoji picker we could create a function that is a toggle list which does this dot list class list toggle hidden then I really should get rid of two seconds then any way that you can get programmatic access to the web component you can call the list I know will open and close it so then I mean it's it's pretty handy you've got everything in there that you can do I guess you could do everything you can do in a framework component eventually if you're willing to to write all the code mostly though I think that these are super useful as like the leaf nodes in your component tree so the things right down the bottom the little things at the end obviously that was also a lot of boilerplate a lot of editing HTML templates which is not super great because you don't get all of your code completion the good news is that there are a bunch of libraries available to your help you out with that so we've got hybrids HTML and lit element from Google stencil slim j/s polymer which you might have heard of which is a whole framework built around web components and angular elements which allows you to actually just build normal angular components and turn them into web components and so hopefully that has inspired you to maybe try out web components in your next and your next project I have been Aaron I actually I probably should have said I work in a consultancy in Melbourne could shine and we are hiring so if anybody's looking for a job in Melbourne Australia anybody the slides are available and the the demo code is available line and that demo has got like code comments all through it so it's not just a complete mystery and that's it thank you very much nobody has any questions right one question yes absolutely yeah I was doing that in the console yep absolutely yep yep yep yes they will I won't components will work with you you can build them and then use them in view and then use the same component in your angular app or your Django not change Drupal or whatever you like yep if you are only building view apps I would probably just use view because that's gonna be simpler but if there's any chance you're going to want to reuse them anywhere else then yeah this makes a lot of sense hi I don't think there's a lot of value in building web components if you're just going to be using the one framework all the time how sure are you that you're going to still be using that framework in three years time though I guess is the thing and and again though if you you could build your web components and say hey in case we change frameworks but then all those web components do going to be relevant in three years time so I mean yeah it's gonna it's something you need to work out for yourself yo right at the back sorry an older browser there is a polyfill available so we're working everything except for IE 11 there is a polyfill available I think that the way that the shadow Dom works means that you need to write code specific for that polyfill for the shadow Dom stuff I've not done it myself though yeah we're using angular elements that work so it just takes care of it anybody else um yes I think so unless the library code was available like globally on the page yeah I'm not sure I've not done that yet Oh anybody else yeah sorry oh you just as NPM packages yeah who anybody else no all right let's go to the pub [Applause] [Music]
Info
Channel: International JavaScript Conference
Views: 6,934
Rating: 4.8431373 out of 5
Keywords: international javascript conference, ijs, 2019, ijs 2019, javascript conference, developer talk, videos for developers, ijs london, international javascript conference london, international javascript conference london 2019, javascript, web components 2019, web components frameworks, why should i use web components, custom elements deep dive, shadow dom, custom elements
Id: zZ1YMJydqR0
Channel Id: undefined
Length: 39min 40sec (2380 seconds)
Published: Sat Sep 07 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.