2018 - The Year of Web Components - Dominik Kundel

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone welcome to 2018 the year of web components before we kick off and I hope this stage really stays because it's shaking and so if you don't see me move much that's mainly because I'm afraid that this stage drops down let's start with a question and I might might see your hands I might not um hopefully so hands up if you at any point in your career had to write front-end code cool that's pretty much everyone I expected that but keep your hands up if at that point you had to write a date picker or custom select box at one point all right that's also pretty much everyone for the people who are watching on the overflow room and you know that's the problem right there like I've done the same thing and in fact if you search on NPM there's over a thousand modules that solve date pickers and there's everything from generic date pickers to date pickers for react and date pickers for view j/s and there's not just one date picker for react but a million date pickers for react and that's just really complicated and you have like a big amount of fragmentation because first of all date picker implement implementing date pickers isn't easy so why don't we have a way to just use a date picker like we use any other element that is native to the browser like a video tag or an input input tag like like a tag textbox and this is pretty much where web components come into play and the ideas that we can use a UI concept like date pickers just like that and over the next hour I would love to talk to you about why I believe that 2018 is sort of where we want to look into web components more and where they're really going to take off and if you've been around the web development community for a while you might have heard the same statement in 2013 or even in 2011 when the web components idea was initially announced however I really think that 2018 is really the moment where we want to start looking at it and hopefully by the end of the talk you're as excited about them as I am but before we get started let me quickly introduce myself I'm Dominic I live in Berlin and I work as a developer evangelist for a company called Twilio where a cloud communications platform so we have different API for developers to sort of different communication problems such as sending SMS making phone calls chat video etc if you want to talk more about that we actually have a booth downstairs so you can come by later ask me any questions about the talk or also about Twitter in general so I've been developing for the web for a while now and at every point in time so if we have the same problem and that was how do we share UI come UI concepts and in general like UI solutions between projects and there were different approaches developed over this time one of them I call the bootstrap approach so that's basically you take a bunch of CSS and HTML script that is typically hosted somewhere on some CDN you blindly copy paste that from the documentation because you're like I think I need all of them even though they say optional but I'm not really sure which ones are optional so I'm just gonna copy all of them and once you have done that then you go back to the documentation you pick out your favorite component you want to take and then you copy paste that code and then the puzzling stores so you want to have an alert box cool your copy paste this but now the question is so which ones of these are styling related which ones are mandatory which ones are optional which ones are semantical which ones help you with accessibility you know like and which ones do I have to keep up-to-date at which point you know is it do I have to have the HR in there or will the entire thing flip a table if I remove it what's mb0 you know like if you don't spend a lot of time with that you have no idea what that does where it's like alert heading that seems sort of reasonable but does that have to be an age for can it be an age five because in that contents their contact context there is already an age four and I don't want to I still want to have semantically HTML so there's a lot of these things that are kind of really unsure and you shouldn't really have to bother with so there's another approach which is more the JavaScript API is DK approach so in this approach we load some global JavaScript and then in this case the Google Maps API and then we specify some way that it B is being triggered so in this case we declare a global function that is automatically being triggered when the script has been fetched and then in there we use a some global SDK where we specify a Dom element that has to be already present which sort of acts like a container and then pass some options in and magically the SDK places a bunch of stuff in there that we can configure while this is a cool approach because it abstracts away the things that we don't have to care about there's a lot of things going on here that are not really compatible with modern web development how we do it so first of all this requires Dom access that's something that libraries like react or angular really don't encourage you to do because this will be very difficult with server-side rendering for example the other thing is global functions we shouldn't really use that and all of these concepts really don't create a nice user experience here and then there's another alternative approach which is sort of like the share button approach from Facebook and it's a mixture of loading some global JavaScript and this just looks really confusing because they do asynchronous JavaScript loading without using the async and the defer attribute but I kind of like just injecting the script manually and one that once that actually happened then you have to play somewhere on your page some HTML that has to have a specific shape so similar to the bootstrap one by having a class in this case FB share buttons so the SDK knows what to look for and then you specify a bunch of data attributes that then will be read by the SDK and magically place in this button the cool thing about this is that we can have a fallback in this case so if the SDK isn't being loaded in this case we can put an a tag there and that will just work however we also see here that there's at this point we already have duplicate code because we have twice the same URL that we need to keep in sync and it's very easy kind of like overlook this so overall all of these approaches what pretty well if you're right playing JavaScript but you quickly end up with a poor developer experience when it comes to combining this with frameworks like angular react view pretty much all of them because it requires you to access the Dom in a lot of cases which is actively discouraged and/or it requires you to load in a bunch of copy-paste a bunch of stuff so we quickly hand up writing wrapper components around these things however these wrapper components are always kind of bound to the respective framework where we want to use them and that quickly kind of creates a fragmentation in the way that we have things that are out of sync different features are in different different wrapper components so if we look at something like MDL which is material design light so you can imagine that like the bootstrap equivalent for a material design so it has some global style sheets and it has a global JavaScript and people wrote wrapper components around this and there's one for pre-act there's one for react but for some of these two even though they're relying on the same boots like bootstrap style library they have completely different features they have not only different syntax but like they have completely different feature coverage same time for view and stuff and what if they kind of go out of sync because like one of them is keeping up to date with these security patches the other one is not being used anymore because it's driven by someone from the community and they don't really care about this anymore because they moved on to another project so all of these kind of really create a port developer experience so what if we could instead use custom like use elements and components as if they are just native to the browser you know what if we can actually extend them from the built-in HTML element and this is where web components come into play and web components contrary choose like a popular belief it's just it's not just one spec it's actually a serious of specs so it's a series of four specs the first one is called custom elements and it's probably the thing that most people associate with web component so custom elements is this concept of allowing you to extend the eight built-in HTML element to declare your own elements on HTML tags and when I'm talking about extending the HTML element I might I mean that quite literally so you would define a new years 2015 class it has to be an es 2015 class you can't do the prototypal inheritance with functions here and then inside the constructor you can then kind of make your own magic and kind of place things into that attribute and start rendering things and then later you just call custom elements that define specify a tag name and specify this class and the browser will register this for you so you can use it the cool thing is you can also extend other built-in elements so if you would want to extend the input element instead you could do that you would instead extend from that class and then you would specify an attribute called extends input to the custom elements and both of these can be used the same way you can use them as declarative as you're used to via HTML so you just use either if it's a normal web normal custom element you just use the HTML tag that you define and otherwise if it's an extending one you use that base tag and you write is equals and then the name that you defined and then you can also use them imperative leave via JavaScript so you can just use document or create element and this is really cool because things like the video memory act and pre act like just called document or create element under the hood and all of these sort of libraries do so because they anyways have to deal with things like input and video and stuff like that so there is no additional magic here that it just works if we talk about custom elements one thing you should keep in mind when you're building them is a difference between attributes and properties if you're not familiar with the difference basically an attribute in HT is the ones that you define in HTML and these can allow you to pass information into a component but they only support simple data so that means we can pass on some things like string or we can check if the property is generally available we could sort of stringify data and then place it in but since we would constantly have to parse it that's not really performance so typically you rely on basic data here and then there is properties and properties are really the properties on an instance of this class so for example the value here the equivalent would be a proper the equivalent property would just be like we grab out the element out of the Dom and then call it value similarly for like disabled but we could also pass more complex data like an array for example and the thing here is that these two are not directly connected we can connect them and we can make these reflect reflect these changes and that's what you would typically see with built-in built-in elements but you have to do it manually so it would look similar to this where you would define instead of just a plain property you would define a setter and getter and then these would sort of take care of reflecting that change back into the attribute there's also lifecycle hooks in the HTML element base class like attribute changed callback so you can have listen on when attributes changed and then have reflect that back into properties or handle events on this and stuff like that the next spec is HTML templates so that allows you to create HTML that is very easily easily and very performant Lea duplicatable so you would use the HTML template tag and then inside there you can specify a bunch of different HTML and CSS and things and they won't be rendered so you don't have to worry about that but the nice thing is you can grab this by the query selector or document or get element by ID and then you can clone these nodes very efficiently so we do that by grabbing the content and then calling clone node on this and in this case we're doing a deep clone and then we can kind of really easily stamp out new instances in a very performant manner this is the most performant way to duplicate the same thing again and again into the into the Dom because it's directly powered by the browser and one thing you see here is a slot attribute and we'll cover that later but this is one thing that you can use in templates as well so then there's the shadow Dom and the shadow Dom is allows you to hide underlying implementation of your custom element for example and scope styling so a good example for this will be the HTML video tag or really like any of the built-in elements that are not that are doing some styling to it right because we want to make sure that for example if you're overriding the styles for every button the play button on a video at the video player shouldn't directly be influenced by this and this is what the shadow Dom kind of ensures the way you use it is you use it in the constructor of a of your custom element and you just call this dot attach shadow you in this case we're using the open mode and you will see later how that looks like and then we append just the content in this case from the from the template that we grabbed earlier we just then clone that into the into the shadow root and then that sort of appears like this on in in the dev tools so the top one is how we would write in a code we'll create a date picker we could pass in some child component and then once that's rendered we actually have these like the content that we pass in as a child appear in the slot and it's not going to be actually placed in there but it's gonna appear at that position and we again we're gonna see later in an example how this looks like in case this is a bit too abstract for you right now and then there's the fourth one and that's HTML imports and that's the one I'm not really gonna dive into because it's essentially declared dead the idea here was to find a way to include all of these things like HTML HTML templates and and JavaScript and stuff like that and and CSS all of that into into another web site in an easy way and the idea was well HTML already understands all of these things so why don't we just do a way to import HTML in the meantime we didn't really see adoption for that in the community so as a result the team working on it kind of like declared it dead and instead right now everyone is focusing on JavaScript modules there is the discussion around HTML modules but they're still in a very early stage so we're not going to cover those so how does the support look like so the support is pretty good if you use polyfill so most of the things that I talked about like HTML templates and yes modules are actually in every evergreen browser these days custom elements can be actually really well polyfilled shadow Dom is the more tricky one so there is a polyfill called shady CSS which will kind of try to do this scoping of the styles but it there there's just certain things that are just not polyfill abble there so you still have to kind of write very good CSS there until until shadow Dom support is there however the polyfill certainly help you to on board this quickly so that once the browser's finish the implementation your component just works so why should you care why should I care why should anyone really care about this so if you develop a UI component web components is definitely the best way for you to get larger adoption if you're writing your component for react only you're excluding a large user base of view and angular users and really anyone who builds a static website there are still a lot of use cases for static websites especially in things like marketing etc and even if you don't write UI components for the world out there it allows you to provide share the same tools the same components among your teams in your company so if if you're working on sort of like the brand guidelines and stuff like I used to work at Microsoft and everyone in the office org kind of implemented their own version of the very same button and this is sort of a lot of redundant code and you kind of continue doing that again and again every time there's new brand can the guidelines like on every department sort of use the same button and even if you don't fall in that category like other people developing web components and onboarding to web components just creates a better development experience for you as well because every framework knows how to handle native elements and therefore that's always something that has a good developer experience in every framework to show you a good example of web components I want to talk about a frame so if you're not familiar with a frame I'm not sure how many of you heard of a frame all right that's not too many so a frame is an abstraction layer around three json WebGL and it's there to enable you to build really easily web VR experiences using simple HTML markup hmm I'm gonna quickly show you a demo here to show you where why this is really useful so this is this is an A Frame example it's some glitch and the link is in the slide so I'm gonna share that later if you want to play around with us but we can do these things like walk around and stuff and it's really cool but writing this code in WebGL would be incredibly complex writing this code in three.js is still a lot of code and very complex however we looked at the code here we see already there's a license file a readme file and then just an index.html there's no JavaScript there's no package JSON there's no build pipeline there's nothing like that this is all the code for what we see and it's readable like I can even if I'm not an expert on what VR I know how to use this and I can go like all right there's like Hello a frame here so if I look back here it says it there so I should be able to just go here and say hello let me see Oslo and we can change the color here some let's I don't know make this bright green so stays like this and up loading Oh anyways let's just keep this there we go oh it was there Internet it's loading so it has to fetch the the other resources let's try this again anyways but it's it's really easy to to kind of understand how how all of these things play into each other and even if you're not an expert on this you're able to play around with this another thing another good example is a web component my colleague Phil Nash Road which is about the web share API and it's a progressive component and I think in highlights and really nice concept so this is how you would use his web component and it uses the web share API which is an API designed to make sharing things on the web easier especially if you're on mobile and things like that so you can just click a button it opens the have shared dialogue that you're used to from from native apps and you can specify a bunch of properties here but then he also allows you to specify child components and in case web components are not supported at all it will just drop back to those child components because the browser will just treat the web component as a as a div as a div tag so it's gonna ignore all of that but if it does support web components and it does support the web share API then we will get an even better experience for the user because they can actually get the native share dialog so if web components are great why why and we've been talking about them so long why didn't they take off yet and there are multiple reasons first of all browser support so it took a long time until the spec was sort of finalized and then the browser started implementing it but it took a very long time like the v-0 spec was around for a long time and now we finally have a V once Baghdatis be implemented by more browsers than just chrome and then the other thing is it's a very low level API similar to WebGL those were API that typically you wouldn't want to write have the code manually for because like I showed you the example of how to keep attributes and properties and sync and that's just for one imagine you have to write this for every other property of your web component but the reason why we have a low-level API has to do with something called the extensible web manifesto and that's a manifesto that is was created by the all the browser vendors to kind of agree on how they spec new features for the browser and there are two particular things in there that explain why we work with low-level API so these days the first thing is that they agree on that they should focus on adding new late low-level capabilities so that they can create secure and efficient api's because if they would focus on backing a date picker and then ship that date picker everyone would just complain about like that's not the date picker we want it to have you know like if you like a good examples of select box how many of you try to style the actual build and select box it's not that easy it's not what we wanted so instead we end up writing our own anyways and then these low-level low-level capability should explain an existing feature such as HTML or CSS and they should allow the authors to understand and replicate them and that's exactly what we see with specs like WebGL which basically it was like the accessing access to the renderer or things like the the web components API is which literally just explain how every custom how every native element is built like it's the same way as how input tags how video tags are built is how web components are being built if you want to learn more about that and why II like the specs of the web components took so long that's an entire talk by Monica that is really great it's called how the web sausage gets made so I highly recommend you check that one out because I don't have time to cover all of that and she did a way better job that so if it's a low-level API we want to have great tooling because there's a reason why we write tools around things like WebGL so there should be great tools around web components as well and in the past this your options look pretty much like this you wrote native web components or you use polymer and that was pretty much it a polymer was the only thing really driving for the adoption of web components but the landscape these days looks completely different so those are just a few options and only some of the options that actually have logos so this is you can pick between things like web components and polymer still polymer is now in version 3 and drastically changed from what they look like in version 1 and 2 and there their goal is to be redundant at one point they just want to drive the adoption of web components so don't get confused something there they just really want you to drive for getting like building all your apps on polymer they just really want you to build web components but you can also use things like glimmer which is the rendering engine inside Ember so that's the logo on the top right you can use something like skate which is the bottom left one it supports different rendering engines from pre-act to hyper HTML etc you can take your since the latest version of angular you can start experimenting with taking an angular module and then turning that into a web component so you can take multiple of your angular components stack them together and then expose that as a custom element view does the same thing there projects for react pre-act and stuff looking into this there's also the new kit around the block called stencil which kind of made a lot of fuzz it's built by the ionic team and there's a bunch of these things and the the goal here really is to allow you to pick your favorite way of writing these things and then sharing them with others so that they can pick their favorite tools this is not meant to replace angular and react and view and stuff like that they all have their use cases and they're made for you to build complex applications but they're not really designed to share UI concepts with others and that's really where web components come into play and with that let's stop talking theory and actually start building the last date picker here on stage to write a bit of history or if I look at my time we might actually not have enough time for that so instead let's build a rating component because I feel confident enough to do that right now and before we start I need to give you a bit of background if you if you've seen my Twitter profile you might have seen this picture so I'm part of a group called one zjs we're just a bunch of JavaScript developers who love the community and also love wearing onesies at events I didn't bring mine this time but I'm typically wearing a panda onesie so I figured I want to get your feedback about the talk later so we're gonna build a rating component that you can rage how many pandas were worth was this talk and or pretty much any emoji so we're gonna call it emoji rating and in order to build this we're gonna use a tool called lit element so little element is still pretty new around the blog and is still in active development but it's written by the polymer team and it's just a simple base class for for creating custom elements that is powered by ledee HTML and I'm gonna talk about that in a second but it's one of these things that the polymer team is working on to make the adoption of web components easier without actually having to dive into polymer it uses web standards which means we don't have to compile anything we will use module bundling but that's simply because we're using we're using base where you say I forgot how they're called but the normal module syntax that you used to use to from note and things like that instead of actually specifying fall paths if you're not familiar with lid HTML it's powered by tag templates so string templates from JavaScript and it's powered using HTML templates so that means it's very efficient in re rendering and creating multiple instances if you want to check it out that's the github repository and again I'm sharing the slides later so you can check out all of these things but that's actually start building this thing instead all right by the way just load it again but reset the code um so let's ignore this ah cool so that's the wrong project nope it's also not the one this is the one so I already have some code but it's it's very much boilerplate code so what I what I installed is I I created a basic HTML here and what I'm loading in here is the web components jeaious bundle which is just all the polyfills that we might need and then a side of that I don't have anything in here yet and I'm using partial to kind of to bundle this during development so we can easily test this so if I run NPM start here it's gonna kick off parcel as you can see here and start a development server so we can click on this I'll click there we go and there's nothing on there yet because we didn't create anything so if you develop with parcel before or if you've watched Stefan's talk yesterday you will know that you can simply load any script here and it's going to start the bundling for this so that's what we're gonna do and if we look into emoji rating it's been completely empty files so let's start with actually creating a class so we're gonna create one called emoji rating and we need to extend this from something since I said we're not using HTML element directly but we're using lit HTML I'm gonna import this from the polymer lit element module that I already installed because I didn't want to rely on the internet for this and then we simply extend this from that and the lead element expo has a sort of interface you want to implement and one of these is the underscore render function so anything that's with underscore in an inlet element will be internal kind of functions and everything that you add as without an underscore will actually turn into a method on the custom element later and in here we're gonna return lit HTML templates so the way that works is we just write HTML here I'm gonna import that from the tellement and then in here we just write HTML and I actually have a visual studio code extension installed so I get full autocomplete here and everything so you don't have to worry about that but the difference compared to JSX is that there's nothing here that needs to be converted later this would just run if I would specify here instead the path to the actual bundle I wouldn't even have to bundle this it would just run because it's using web technology so I said we're creating a rating so we're gonna create a roll range here let's add a class called rating and for now let's just write something like hello here to see if it works and then we go back into the index.html and we can start using this so emoji rating safe this switch back and oh so I created the class but obviously I didn't tell like you tell the browser about this so we want to do custom elements that define specify that it's called emoji rating and then pass in which class should be instantiated and now we have two hello here so far so good now we want to have some properties so we can customize this and the nice thing about little iment and one reason why i like using it is because that element does the connection between attributes and and properties for you automatically and all you have to do is define a setter called a getter called properties and return an object here that specifies which values of available in what type they are so we want to have a min value a max value want to have a value and then an emoji would be nice so we can modify which emoji it is so that's of type string and we want to have some default values and that's what we do in the constructor so we create a constructor here need to call su persons we're inheriting and then all I do here is really set this to men there's max choose five value to zero and because we're gonna use pandas by default it's panda here and now we have all of these available in the render or we could just call this dot on them but the render method is also nice enough to pass all of these in here so we can just grab them and for now what we get just gonna do here is put in the emoji here so we're just using string interpolation like any other string template would do in JavaScript and now we have the Panda emoji here so if we go back actually change that here so if we open the dev tools and we click on this this is how it looks like right now so we see here the shadow root because we're using the shadow DOM and then in here is the HTML we wrote and we see the Panda here if I select this and I open the console down here we have access to that so let's store that as dollar zero and then we can set the emoji for example two hard toys for example and that updates automatically you can see it doesn't actually set it as an attribute because right now it's only doing the reflection in one way because that's typically what you wanted to anyways but you can kind of enable that as well if you want to cool so we have that let's actually built this as a rating tool so one thing we need is we need a list of emojis and I'm just going to do a small trick here so this way we just get a the exact number of emojis that we want and then I'm using since we're using lit HTML it has a couple of helper library helper tools that we can use one of them is called repeat which is just really good and officially re-rendering a list and we can pull that in from the lead HTML module it's actually in its own path so that you're like they really want to make sure it's a like small memory footprint so you need to manually pull these things in and then we're gonna repeat here over the emoji list and we're gonna have to declare a function here that works similar to if you develop with react the keys for example since ours is anyway it's just a list that doesn't have like any good property that we can figure out on which values changed just gonna listen on the index and then I'm gonna pass in a function here to render emoji I'm gonna bind to this and then we need to define this so call render emoji I'm just gonna get an emoji and an index and then in here we can return again some HTML template here we're gonna call it emoji put an emoji in here save this and now we should have what did I break see to open this nothing here oh yeah you should repeat max and not value because will you zero there we go now we have five pandas but we want to obviously make this a proper rating component so one thing we need is a style just like a CSS class active and what we're doing here is if the index is less than the value then we're gonna do the active otherwise we're just going to keep our class and we can just use here string interpolation again and we're just going to write active and we're also going to keep the index property here for later and if we refresh this we see that right now they all have only emoji because none of them is active but let's actually start having some style here so I'm not gonna write that and CSS right now format this and this looks already way more like a rating component if we select this and we now do something like value for exam we can set it to four and we see we have four for pandas but you don't want to ask your users to open the dev tools and play around with this to want to listen on click events and the way we do that is by and this is again similar to things like react and stuff we can just listen on the on click and then we do a template here and in here we just write like this and click we're gonna bind it again and then we need to implement it and we're going to get an event here and our new value is going to be parsing the event or target data set index which is exactly the value we're setting here and then we're just going to to it and one thing I just want to do for simplicity so you can also give me zero Pender's if you want to I would be sad about that but I want to give you the option if it's the same value I'm just gonna set value to zero and otherwise I'm gonna set the value to value save this refresh and now we can start clicking here and all of that works the thing though is that you also want it like in a normal input element you would be able to listen on something like one change so ideally we should be able to go here create a script tag and say hey I want to grab the emoji rating and then I want to add an event listener for change and what I want to do here is I'm grabbing the event and in console logging event or target value so this will work with an input element so why shouldn't work with our rating component so how do we implement that all we have to do is I'm gonna turn this into an async function because I want to wait until the component has been rear-ended and lit element actually gives you render complete promise that always resumes when the rendering has full is always fulfilled when the rendering has been finished and then afterwards I'm gonna dispatch an event I'm gonna just use a built in custom event called change and then I need to specify some detail and that's just gonna be our value and I always put a semicolon there for whatever reason we refresh this and now we see it's actually console logging the values that we specify whenever we click here and the nice thing here now is with this component we can for example specify all the additional how are your tags for example to make this properly accessible and then the people who use it never actually have to worry about this like adding accessibility to it it just works out of the just like and first on one input element would work out of the box what if I want to style this so I'm using in here the CSS custom properties or you might know them as CSS variables and this allows me to define a very clear set of things that I should I like an API almost that I allow the user to modify like I don't want you to modify the entire alignment and stuff like that I just want to be able to allow you to modify how this background looks like so we could for something to give us a class called red and then in here we can create a red and all we do is we set emoji rating unselected color that's the name I gave it to rent we save this and now you can see it's actually red for all the emojis that are unselected and therefore therefore we can expose kind of like a direct thing and this is really nice for teams like a brand team that maybe maybe you want to expose how big a botanist but you just want to do that via CSS and instead of like specifying it in in the HTML or you want to just allow you to like change the color but nothing else this will allow you to do that cool so we have this I actually rolled this up and published it to NPM so we can use it later in an example but I want to talk about something else that a lot of people always keep on asking questions what about stencil so if you're not familiar with stands were never heard of it Stenson was written by the ionic team and the ionic team basically creates a bunch of UI tools for building hybrid apps and they build stencil as a compiler that generates web components so that means contrary to what I just showed you a little element they have their own syntax they have their own bill tool that you need to run this through but then it will generate web components and it's built by the ionic team to bring ionic to more than just the angular because that was their initial vision and then they started building everything in angular and kind of got stuck in there and now they want to bet on web components to allow you to build a hybrid app and to react to and still use their tools for example and it's heavily inspired by things from different frameworks you know they took some things from angular they like they took some things from react like JSX that they liked and therefore it uses typescript it uses decorators it uses JSX if you want to check it out go to stencil J's calm but I figured I'm also just gonna give you a quick demo here so we're going back close these two so what I did is I literally just followed the getting started instructions which is get clone the following project and remove the thing and then let's close the disc for derp and then this is how you how your structure looks like so you get a default component here get an index and HTML we're gonna NPM start this to start the dev server it's gonna do the first build and this is what we see and if we look at the index.html from this this is this is the component we're using and the values and if we inspect the component this is how a component in stencil would look like we have decorators which are still being expect but they're heavily used by things like angular and stencil and stuff so they likely gonna not change too much anymore and then down here we have a render function so similar to what we did with lit lit element but here we're returning JSX so it's a slightly different syntax so let's turn this actually into my alert box because we were talking about alert boxes earlier we're gonna again do be a nice citizen here of the web and actually specify the role of this and we're gonna create a title here you know have an alert title we can give it a default value like alert and then pass it in here and then I'm gonna use the because we're using the shadow Dom here we can use the slot attribute I'm gonna keep this and let's add a paragraph before saying something like hey something went wrong and also add a footer like let's solve this and then you'll be able to kind of prove whenever you use this component you'll be able to provide the details in between these two if we go back into the index.html we obviously need to change this completely it's called my alert now and then in here we can now give information so we could put a div tag in here and then inside we could put a paragraph and say or let's do this like a detail and then we write like Hello here save this now we actually have this details thing here and then in there we have the hello and so far so good but how does this look like now if we inspect this we see the shadow root here and we see the details thing that we used right underneath it but then if we open this entire thing we see the slot and if we open the slot we see it actually refers back to this property here so why why is the browser showing it this way why doesn't it just throw this in there that's the way the shadow Dom works and the reason why this works that is that way is if we create now a global style here and we say for example we want to use cursive font and we safe this will see that the paragraph that we wrote in our own page suddenly has this cursive fond but everything else stays the same it's not being touched and this works the other way around as well so if we go into the my components CSS and we say here as like hey every paragraph should really be a fun weight of 800 it should be of color orange and we save this we see again the other thing is not being touched either so we have a full encapsulation of the styles here and that's that's the really powerful part of the shadow Dom meaning you can provide as a an author of a component you can provide like these are the places that you can play around with everything else I'm controlling so you can have multiple slots and name them so that people can get a better idea of like hey this is where I'm placing whatever and therefore we then therefore not rely on like oh I have to put the things in the right order and things like that cool so we have that one thing I wanted wanted to show you is similar to lead element there's a way to reflect back the attributes so we can do here true and now what this will do is it will not only reflect attributes to properties that will also do it the other way around so if we grab the component here and then do alert title to like something oh no we actually see that it's been updated here as well instead of just in the Dom cool that was the that was the stencil demo now as a last thing I figure we should actually use a web component and in order to use it I built this thing to vote on my talk later and it's not fully done so this is the deployed version but it doesn't actually allow you to deploy it like vote actually on my talk so we're going to change that so the project is written in angular it's just a default out of the box ng CLI project so I didn't do any magic there I will show you two things that I did did you so this is the project we're gonna start it off in the meantime so I can start compiling two things I did on the one hand I went into the TS config where is it and I changed the target to es2015 and the reason for that is that types that web components require you to do es2015 class inheritance you can't you can't do prototypal inheritance you have to do this because those are built in native classes and not functions and therefore you have to do this there is an adapter if you actually still rely on down transpiring to es5 there is a an adapter that you can use but I wanted to show you the like proper way that ideally we can start doing this and then the other thing that I did is in the index.html I'm including again the polyfill and I npm installed my component that I used that I published which is the same code like you can check it out on github if you don't believe me it's the same it's the same code so if we go into app component module this is where we want to do the first changes so its first look if the app deployed so here we go and open the dev tools and enjoy dancing panda yeah so the first thing we need to do is we need to tell angular hey there's custom elements around because angular will try to verify that every component you're using is indeed a component that exists so for that they use custom they use schemas so we can import the custom elements schema which comes with a core library of angular and then we just say hey actually use this so from that point on angular is not gonna bother trying to verify that every component is an angular component they might see like hey there's one I don't know so I believe that's a web component and then the other thing we need to do in this file or we could do it at any point really but I'm gonna do it in this is I'm just going to import the emoji rating and that's all we have to do here so now we can go into the app component HTML and we can load in our emoji rating here save it and if there's refresh is we now have the component here all right works and refreshes changes but if we look into the app component TS we actually already have a current value property so we want to bind to that especially because I want to set the default value to three here so you're hopefully more likely to upload my talk so what we do is we do it like every other component in H in angular works we just say hey find this value to the current value and this is how you do it in angular to do the same thing in view for example and now we see that the Panda by default has three now if we change it it's not reflecting actually down here so it's clearly not updating for that we can listen on the change event and this is how you do it in angular and we're going to create a handle change function that we're just gonna pass on the event - and that one doesn't exist yet so we're gonna write it and in here we grab the event and then again grab the value this on a event or target value similar how we did it earlier with with a native kind of add event listener and then we set the current value to value one thing we have to do here because some browsers based on the polyfill the angular change detection is still breaking but that's not a problem with web components that's a problem with a polyfill right now and there's an open github issue too for that so that's hopefully going to change but in the meantime we actually need to manually trigger the change detection so I'm going to import this here and then just say hey change detection detect changes save this go back and now we see if we reload this hmm oh thank you it's nothing like crowd debugging so now we can see it actually have keeps it up to date down there as well so let's go here remove these two checks save it [Music] commit this someone else just push this and cool so this is gonna trigger off the deployment on net Levi's and hopefully we have that by the end of the talk in the meantime let's wrap this up so I want you to think about web components whenever you've realized you have to share UI with other with other teams with other projects sub projects and stuff that's when you want to start like hey thinking about hey is it worth building this as a web component because web components are not there to limit your framework choices they are not there to kill react or angular or anything that's not the purpose of web components it's just solving this problem of actually sharing UI between projects so we stopped writing redundant code and actually can focus on quality event quality things because ultimately the goal is that you can pick your favorite tools and let others pick their favorite tools that's really the goal of web components and hopefully to write over one date picker to rule them all so we can stop writing these at least have one material design one or one with another design philosophy and ideally one that we can just style ourselves but instead of having a thousand over a thousand date Pickers if you want to learn more about web components and see some examples web components on Orcas grade most of those actually still use HTML imports but it's still a good view of like looking at a couple of existing web components custom elements that everywhere is a great website if you know curious of using web components but you're not sure how the support in your in your framework of choice is because angular and view actually have perfect support however things that react pre-act still have a couple of issues depending on what you're trying to do with your web components but the nice thing is this runs against a bunch of different popular frameworks it runs tests against them and it also keeps track of all the related issues so if you if you see something doesn't work with it there's likely to get up it should already existing you can check what's the status there and have Kievan keep up to date with that if you want to compare different implementations of web components there's a web component to do that has versions for sketches for stencil for view for angular elements on a bunch of other things polymer so you can look at like how the code changes which one seems like the nicest philosophy for you so there's a bunch of resources I'm gonna I wrote a blog post how you can get started and even publish to get an urge NPM a web component with stencil the slides gonna be on this URL and I'm gonna tweet out all the URLs after this talk the emoji rating code is here web component org is our great resource and custom elements everywhere and there's the URL for web components and now let's hope this actually deployed its refresh yay so cool so yeah you can go to go to this URL and vote for it there or you can just throw in a Greens green piece of paper and with that I would like to thank you all for your attention if you have any questions I'll be down at the between booth most of the time so just come by there have some ask me some questions or ping me on Twitter my DMS are open or shoot me an email whatever you prefer and I'm happy to help you out and answer your questions thank you all [Applause]
Info
Channel: NDC Conferences
Views: 16,228
Rating: 4.8801498 out of 5
Keywords: NDC, NDC Oslo, 2018, Dominik Kundel, JavaScript, UI, Web, React Component, Angular Developer, Vue Components, Preact
Id: SgnE3p1qF-c
Channel Id: undefined
Length: 58min 48sec (3528 seconds)
Published: Tue Aug 07 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.