Declarative Reactive Web Components with Justin Fagnani

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] thanks a lot for coming I'm really happy to have the opportunity to speak here was a little bit last-minute Peter asked me to speak and I got some slides together I've actually wanted to come here for a long time and join you so this is a really good opportunity to do that so like Peter said my name is Justin from yani and I work on the polymer project here at Google and tonight we're gonna dig into building declarative reactive web components with two libraries that my team maintains lit HTML and lip element and this title right here declarative reactive web components with lid HTML in the element it's a bit of a mouthful so we're going to deconstruct this and get into what all that means in just one second first I just want to talk a little bit about our team so we work on this effort called the polymer project and this was created by Chrome in order to help make using new web api's like web components easier and to provide some real-world feedback back into the standards process so we build polyfills that make these things work on older browsers we build libraries to help you write components and we and we build component sets that you can use when you're building an application and our goal is to make using web components in production and at scale practical and productive ok so let's get into what these words mean I said live element declarative reactive web components you know what are we really talking about here and normally I would kind of start at the very beginning of everything and break it down to the core pieces the very foundation of this and define everything and then build back up to where you can finally see it all come together for something cool and I've realized that's probably good for a textbook but I think it might be a little too much delayed gratification for a talk and it doesn't give you a sense right away of where we're going and why you should care so tonight I'm going to try something a little bit different and start in the middle with this ok so this is a basic book complete HelloWorld lit element now this is a short example but it does use a lot of very new or even kind of not yet arrived platform features so I hope even if this is your first time seeing lit element or this is using typescript decorators here or JavaScript classes liddie tml tag template literals all the stuff packed into this small example I hope if you look at this that you can get a sense kind of intuitively of the essence of what we're trying to do here and what this is so this example shows how to make a new web component give it a tag name declare property on it and render some Dom that uses that property and if we walk through the bits here one at a time so you at least know what these are this is a decorator that will register the class as a custom element with the name HelloWorld this is a class declaration we're going to define the hello element class and extend our Litella meant base class this is a decorator on a standard javascript class field and that decorator is going to make this a reactive property for that element and this is a render method which hopefully is familiar to the react developers here this gets called when our element needs to update and it returns a litlle HTML template expression which contains some HTML and an expression in the middle so these are all the parts that come together to make a little MIT and I'm going to be using typescript throughout or more like plain JavaScript with decorators because I think it makes it a little more clear but just so you know what this works with plain JavaScript as well so here's an example where we declare the properties in this separate static property here and we call an API explicitly instead of a decorator to register our element it's okay I wanted to give you some kind of starting point here where you can know like where we're going why we're doing all this so we defined an element and we want to use that element so this is where web components get a little bit different from most frameworks if you want to use a web component you don't actually have to write JavaScript all you have to do is import the definition which registers the component with the browser and then use it in your HTML so this is what an actual main HTML page would look like that uses a web component so and you can see we give us some data there to populate that name field we put in earlier with San Francisco so if we use it like that we're gonna be saying hello to San Francisco it's very easy to use it's all encapsulated this is great and if we change the data we change that attribute there it's going to say hello sfhtml5 hello and yeah so it's easy to use that's how it comes together here we go and I but before we move on and show like how all this is built I want to add one last thing here to make the example a little more realistic and that's some styling so we're gonna add some styles here in this static Styles block and we're gonna give it some typical demo ugly styling with a background of papaya whip because I love the name of that color and some red text there and you see it does what we expect and this looks suspiciously like CSS and JavaScript and it kind of is but this creates a real stylesheet behind the scenes and attaches it to the element and the cool thing here is that because of one of the web components standards called shadow Dom we can style this element we styled a div and if you look at the selector here we just said div this looks like a dangerous thing to do right this normally styles every div in your page but if we go ahead and add some other content here in a div this random content line you can see it doesn't style that so web components and let element give you style encapsulation too and you this works you know without any other things on the page opting into it just happens automatically to your main page content and so things get a lot more powerful and deep than just this right hello world isn't you know never really shows off the full extent of what you can do but I did want to give you some idea of our destinations so we can see you know how all this works and why we're doing this later all right so I mentioned one way that you can use web components by using them from HTML well the really awesome thing about web components is that they are they are HTML and Dom standards and they're implemented by the browser and this means that if you create a component definition with web components it works everywhere HTML works so we've seen this work in the main page but it also oh that's right okay this is what happens when I do slides last minute I wanted to compare this against how you know we used to do component instantiation in the past right so here is like an example done with jQuery style right you'll have some function that you execute that finds all the elements in the page and then kind of upgrades them to your component and you can see a very similar pattern here with react as well so you can define a react component and normally you don't think about how that gets instantiated but at some point you have to attach that to the Dom and you call a very similar API here with react render where you give it a component kind of instance hello wouldn't hello world in this case with the data and then you tell it to attach to a particular element in the Dom um so web components let you do this without any of that boilerplate right you just use the element anywhere in HTML and this also works anywhere else you can use HTML so first of all you get a constructor this is an element it's kind of like calling if you could call a new HTML div element with web components you actually get callable constructors you can also use it from document create element here you pass the tag name the browser knows what class is associated with this and it creates the element for you so you can do this also from inner HTML if you integrate tml anywhere in your page and you have some content that contains elements that were rendered they will render or you can do something more complicated so it's quite common in the guts of frameworks or in some you know custom application code to create a template and then to clone that template when you need it so if you create a template that contains a reference to your element and then you clone it that clone will be upgraded and turned into your element instance by the browser so this is kind of universal and you don't have to tell any other code about your custom element for this to work and this comes in really really handy when you're using frameworks right so for the most part with most frameworks we just integrate extremely well without them even knowing about us right I wanted to show one example here of angular so this is an angular component and we want to use our hello world component in the middle of this angular component now angular doesn't really know anything about customer so just knows how to create Dom but so all we have to do is import our element definition here this is the module that I showed you earlier and that's going to register the element and then we just use the element inside of our template and this will just work as expected and we'll get the style scoping even though the element didn't know about a participate in angular's style scoping system itself so this is great and it works with the vast majority of frameworks out there there's a website that one of the Googlers Rob Dodson made called custom elements everywhere that actually includes a full test suite for every framework that people have contributed here and tests every framework for how well it can do things like set attributes and properties and listen to events on custom elements and we do really well you know in most frameworks react has a little bit of difficulty because it assumes elements can't have properties but basically other than that everything kind of works for the most part okay so that's what we want to do we want to build components that work anywhere and so I talked about lit element there gave you an example let's look at the rest of the terms here and let's start with declarative and reactive so declaratives a funny term I don't think there's a great singular definition for it but essentially what it means to me is that you want to say what you want to do not how to do it and this is where I think that you know the thing we've built here shines pretty well if you look at all the components of this definition here everything here is a what not a how so here we say what do you want to do you want to create an element called hello world how do you you know what do you want to do here what's the base class for it you want to extend live element it's like literally called the class declaration here are the styles this doesn't say how the styles are being applied it just says here's the style declarations for that here's the property declaration you just say I want a property called name this actually creates some accessors under the hood a getter and setter but you don't have to know that it just does it for you and then inside of your render method this is also a method declaration we have the declarative lit HTML template so it's about as declarative as you can get you can of course do imperative things in here but the core of this base he says you describe what you want your element to look like and it makes itself um okay and I wanted to talk one more thing about multiple about reactivity here and how properties work so one of the problems with like very old way of doing Dom manipulation is that you would typically create some Dom grab a reference to elements inside that Dom that you cared about and whenever you detected somehow that your data had updated you would go into the Dom and up that update that data yourself and once the logic for this gets complex enough you run the risk the very real risk of having your data and your Dom get out of sync and so one of the goals here is to make sure that that doesn't happen so you can see here we define multiple properties first name and last name and we use them in the template and then we set them here and lit element takes care of automatically recognizing when the data has changed and rendering your template and in this instance it will also render your template only once because we do batched rendering so even though you set to properties separately here will not render twice so that was a little bit about declarative Ness and reactivity let's talk about web components because that underlies everything we're doing here so what are web components web components are the native component model for the web platform so the web has really evolved from a document platform into an application platform and if you think about it basically every single graphical application platform out there has its own UI component model and it's really time the web did too and that's what web components bring you know you're not expected to bring your own UI framework to iOS or to Android right and you shouldn't have to for the web and you can if you want of course but the web should have some of these capabilities built in because it's such a universal need right in a sense that component model is really just table stakes these days for any application platform right this goes all the way back to the original GUI systems you know coming from original Mac OS and Xerox PARC right um web components also essentially expose existing capabilities that were previously reserved for native code you know the browsers have had these features locked up inside them for years elements like the video element and input they already use shadow Dom and they used HTML to implement it you just didn't have access to that right so you know now we allow user land code developers to do many of the same things that the platform engineers can write in a sense this democratizes the web platform and it you know gives you powers that were previously reserved for the C++ developers you know working at these and these big projects right and you can look at this as a form of archeology right we're trying to discover the you know powerful capabilities that are locked up inside the browser and you can you know look at all the web components features as intent analogy does something that already exists in the platform right like the platform can create elements so we have custom elements and web components the platform has the power of DOM and capsulation and style encapsulation so we have shadow Dom the platform has pseudo elements like placeholder for input so now we have a standard called CSS shadow parts which lets you create your own custom super elements forms forms are pretty magical right like you have inputs that communicate across the Dom tree to the form and are able to understand when the form is being submitted because there's validation events and all this stuff well now there's an API called form participation which is about to ship in chrome which gives web components that ability to same thing with Aria right like a button has a predefined Aria role you don't have to put Aria attributes on a button and so now your web components can do that as well with the accessibility object model or that's that's still being finalized but it's pretty close so really what we're doing here is trying to you know give developers the same powers that the browser has and that brings us to this last point I want to drive home is that the web component api's are actually really low level within the Dom they let you hook into and customize the Dom tree in ways that we never could before right and there's - the two most important web component API is our custom elements which let you define new tags in shadow Dom which gives you encapsulation and they really only give you like a when and aware for your component right the where is where to render right the element instance that appeared in the Dom and its shadow root and the when is the constructor when your elements created and all the lifecycle callbacks and that's really most of it right and because web components are low-level at least currently right it's expected by the people who were you know helping build these specs that developers are going to want to use libraries to help with repeated tasks and to improve the overall organ onyx and the developer experience right you know maybe one day we will have AP eyes that are extremely high level and let you do declarative custom elements but we don't have those yet and so we look to libraries to fill in some of these gaps and so here are the what are the core web component specs originally we're expanding these over time so custom elements let you define new HTML elements they give you life cycle callbacks for when your elements are connected and disconnected to the Dom HTML template element gives you an inert cloneable Dom area if you use the template element and put say an image tag inside of it that image will not load this is really useful for stamping out repeated chunk saddam and shadow dom is an element internal dom area it's private from the rest of the code and the rest of the dom outside of it and it gives you scope Dom and it gives you a way to compose children into your internal Dom okay so I mentioned that you know we don't have everything in web components that make building a component easy so you know we have these gaps there's a lot of things that aren't covered yet right and really there's always gaps in the platform there's things we need to do that the platform doesn't get a support or doesn't support organ amelie and these gaps in the platform they change over time as we add new features to the platform's like web components so as we fill in some gaps some new ones are created or left over in some time so it looks like a gap isn't so much a missing feature it's just an area where the platform doesn't have an opinion or doesn't want to take an opinion and opinions are great and the web development world has a lot of them so we want to allow opinions in this world to and that's where our libraries like lit HTML element come into play they fill some of the remaining gaps they add organ ah mcc's and they take some relatively light opinions on how to build a component so what kind of gaps are we talking about first Dom rendering if you think about it the Dom doesn't have any built-in way to create a large chunk of Dom from some data right this is the essential operation of most templating systems and frameworks really you have some template predefined or some JSX or something and it describes how you want to create Dom from data and the the Dom doesn't have any way to do this currently right you can clone a chunk of Dom but then you have to imperative lis go into it and find the parts that you care about and want to update and it also doesn't have a way to update Dom efficiently right like you can do in our age t ml over some existing Dom and that will be slow because it destroys the Dom you could clone and replace but that's also going to do the same thing and be slow so we want to give a way to you know update Dom efficiently when we fill those gaps also reactivity right the Dom doesn't necessarily have an opinion or even a place to care about like when your data changes there's no Dom API that you give data to generally right it also doesn't really have an opinion on how to sync attributes and properties built-in elements do it sometimes they do it differently but if you're building an element that's something you have to do yourself it doesn't really have a way to share styling across a ton of different elements in the scope styling Reyes now that's something that's kind of unique to web component so we'll get into that in a little bit and it also doesn't have glue like a lot of these api's are imperative in nature when you create a shadow root you have to call a method to create a shadow root right and so if people don't want to use imperative the api's they want to do it declaratively the Dom doesn't do that for you automatically so we built a declarative layer for that and so that brings us back to lit element and it lets us know why we've built lit element in lit HTML and what they're trying to do they're built to fill these gaps in to add ergonomics and to make building high-performance and reliable web components as easy as possible all right so let's look at what lit element gives you so first it gives you reactive properties you can declare these properties with that decorator or with the property block I showed you they will respond to changes it gives you attribute reflection so when you declare a property you're actually declaring an attribute at the same time and it will keep those in sync for you and it does batched updates so if you change a bunch of data at once it will kind of collect that up do an update later on so it can be more efficient and it gives you a declarative rendering with lid HTML so we try to be as on opinionated as possible you have to have a little bit of opinion to put the glue together but really we're just trying to make it possible to use the underlying API as as as easy as we can so it has a fairly minimal feature set what I listed on the previous slide we do have full typescript support like I've shown you we work with plain JavaScript but we think it's pretty important to support the growing typescript community out there and it's fairly small so it's weighing in 6.7 K right now there gzipped and minified and that includes if you bundled lead HTML and so this is a cost that would be shared across all your component definitions in an app and it's also just JavaScript so ignoring if you if you're not using typescript if you're using the plain JavaScript no compiler is necessary you can load these modules directly in your browser directly from a CDN like unpackage and they will just work so I want to get into some specifics now about how to use lit element so I showed you declaring properties before this is the syntax here for using plain JavaScript properties and what we want to move to eventually is having decorators built into the platform so that we can declare properties in this nice syntax here with decorators properties have some options so there's different things you might want to do to your property as it changes so first you might want to declare a type this isn't a type script type this is a number constructor here and what what this does is it converts the attribute to the property using this as a converter here so if you have you know boolean strings complex objects you want to use JSON you can do that here and define a converter for your property you can customize the attribute name with the the attribute option here so you know many attributes have dashes in them and dashes are valid JavaScript syntax so we allow you to define the mapping here and customize it yourself we also allow you to opt in to reflection so not every property in the platform reflects two attributes there's a little bit of a cost if you set a property to update the attribute so we let you opt into it and if you have an element that has a property that reflects this is usually good for things like external styling you want somebody to be able to say style and element when it's selected from the outside so you make sure that the attribute is updated when the property is and we let you customize the change detection on the property so the way we support reactivity is we generate a getter and setter pair for your property and you can customize the setter with this has changed value here and this lets you tell the system when a property has truly changed so that if you don't want to say update the Dom you know maybe you're using like immutable dot J s and you see if it's the same reference or the same hash you don't want to update the Dom so this is a little bit like reaction component update but on a per property basis and so talking about updating the Dom brings us to the update lifecycle so let element lets you declare properties the properties are reactive well what actually happens when it detects that something changed and how does that call all the way through to render so we have what we call the update lifecycle here and it's really based around this core pipeline when something happens that changes your element this method called request update is called now this is done for you in a lot of cases from the setters for properties or from the attribute when attributes change and you can also call it yourself if you know that you want to update the Dom and what that will end up doing is queuing an update task this is a micro task that the browser keeps track of and it can hold a whole queue of different micro tasks and this micro tasks will be updated later after the browser has finished the previous task before it when that update task is run it'll call the update method on the element which by default just calls the render method so this happens every time properties change and this is how you get reactivity into the system so we can look at the inputs into this what will trigger updates by default so first is just connecting an element to the document web components have a lifecycle called connected callback we implement that and when it runs over requests an update so you know this will render your element the first time like I mentioned if you set a property that triggers the system to the setter will call has changed if has changed returns true it'll call request update and you cue an update task same thing with attributes that will go through attribute change callback and this will all basically these are all inputs into your system that cause your element to update and they all share the same update task queue right so if you update multiple properties and attributes and connect to the document all at the same time you're only going to get one render and it'll be very efficient there and that brings me to rendering which is actually asynchronous and this is the kind of nature of using a queue and badged updates for doing the updates here and so this has some interesting properties so first of all async rendering gets us our batching right they kind of go hand-in-hand it's kind of hard to do batching without async and hard to do async without patching but what's interesting about this to me at least is that this allows you to have an object-oriented interface right where you have like individual properties instead of a props bag like a lot of frameworks have but you get functional behavior and what I mean here is that you know you can think of kind of mutating your state imperative lis line after line if that's what you're doing as setting up the arguments for your render function if you will and so this lets you think about your rendering as pure functional rendering and it also means that because all of these elements are async always right that is very easy for us to schedule and prioritize rendering so different elements can render at different times and you can have high priority elements render before low priority elements so I wanted to go back to this example where we have multiple properties here so one of the things that you'll want out of an element like this is to make sure that you don't ever render this element with the first name and last name that disagree right oh sorry so we have two properties here you could also think about these as properties that were constrained together like mathematically like what if you had a point down a circle there's a relationship between those properties that has to hold and so what this async batching does is it lets you go in and set one property and then set another property and then they will only cause one update now most of you probably don't set properties on your components imperative Li like this they're actually going to be set from another template right but this means that the elements don't have to coordinate if you have some container element that's not a let element and it has a template system that's setting these one at a time as it has to you're still going to get batch to coherent rendering without coordination between your different component libraries okay so little make is your reactive properties attribute reflection batched updates let's talk about the declarative rendering and that brings us to lit HTML and that's really the core of the system here and what drives most of this so what is it so it's HTML templates in JavaScript like you've already seen in the render method there they give you a fast first render and a fast incremental update here we go okay so the way it works is that templates are defined in line with components and data right we want to do this inside of JavaScript because your data is inside the JavaScript if people have used polymer before we had that's like the previous system before little element we had templates defined in HTML and that's really nice for some reasons but you have to reinvent a programming language basically there because you have to have a way to access your data from HTML and so we've definitely found for a lot of developers it's easier to you know write their templates where their data is and so this lets you do it conveniently like that so because we're in sighted JavaScript you have the full power of JavaScript the expressions are just JavaScript expressions all the control flow is just normal JavaScript lit HTML itself is very small it's about 3 kgs up to minified right now like I said it renders and updates fast and it's about as easy to use as innerhtml in the simple cases right you can just render some HTML from a string and it will do what you want and then you can supercharge it later and it's also extensible you know we know the template system isn't going to do everything you need out of the box we give you ways to add to it okay so to show you some details on load HTML first it's really based around these two exports out of the lead Shmuel module here HTML which allows you to declare your templates and render which lets you apply them to the DOM and so here's a basic liddie HTML template some of you have seen this syntax that came with es5 tag template literals some of you may have not but to go over real quickly these are like strings except for that they use backticks instead of single quotes and it can be multi-line which is obviously required if you're going to do complex templates you can't put them on the same line or use pluses everywhere that would kill you and they can have expressions in them now these expressions look like string interpolation and a lot of other languages they would be string interpolation every single one of these would be converted to a string first but the really incredible thing about tag about template literals in JavaScript is that they can be tacked and this tag gives it superpowers basically this tag is a function and it is called with the contents of the tag template literal strings and the values from the expressions and it can completely customize how all this is put together right and so you'll notice that this HTML template we have right here this is actually an expression this returns a value right and one question you might have if you're looking closely here is like what kind of value does this return right if we return to string this would be just like using inner HTML and you would have poor performance and you would blow your Dom away all the time right so what does it return it returns a thing that we call a template result and a template result is an incredibly cheap data structure that just records the values that were passed here and a pointer to the template that was used so it's it's basically an array of the values and it's very cheap to make and then we pass that array and the pointer to the template to this render method and the render method has all the smarts that know whether or not that template has been rendered here before and if it has it knows how to find exactly the parts that need to be updated and only update those and and so here you see we render some Dom and it's just going to tank contain whatever title and content were there when we ran this whole section of code so that's not going to be that useful because we usually want to update our Dom so what let HTML tends to look like is that you write these template functions and these are literally functions from state to UI and you'll end up calling this function over and over again with different state so here's an example of that you might call it the first time where you say welcome to polymer that really should say lit HT no there and you might rent it the second time thanks for coming right and as you do that it's only going to update the expressions that were written to the Dom they're not the rest of the HTML okay so those of you who use react might say this is a little bit like react yes and the answer is yes it is in many ways so just to give you an example of how close to react it can look like this is no longer lit HTML I actually removed the late HTML out of here and this is JSX and this would be a react render function right here right and now it's lit Gmail so we just added the backticks and change the expression to limiter so I'll go back again react lid HTML react HTML ok really the only difference here is that instead of using JSX we're using standard JavaScript there's some other important differences too about what we're able to know about this template because we have this structure provided by tag template literals but one of the most important similarities here is the concept of UI equals F of state your UI should be a function of state and the I here the idea here is twofold one is that your UI is a value and you can pass it around right this is a little literally the return value of your render function and this gives you really really powerful composition you know you can combine templates and perform logic over them but the other key idea here is that whatever your state is that you pass to this function should solely determine what the UI looks like right you don't want to have path dependencies we're depending on the sequence of state changes you know gets into your UI into some state that maybe if you played a different sequence that ended up in the same state your UI would actually be different right and so you can help enforce this by literally making your code make you ID be a function of state and so late HTML shares that with react as well and another thing it shares is a minimal Dom updates so I've mentioned a few times that we only update the parts of the Dom that change react does this with a V Dom diff V turns out can be pretty expensive right you have to take your old V Dom tree in your new Dom tree and figure out what changed well the nice thing is that you when you define a template I already tell lid HTML what parts can change and so we just only ever check and change those parts and so to give you an example of this to really drive it home because people ask now I'm gonna do something a little bit dangerous here this is actually running in my slide deck software it's a clock written in lit HTML and I'm you can see it changing and this is just running on a timer and it's you know it looks like it's rerender entire template that's implementing this clock but I'm gonna open up dev tools on my slide deck and I'm gonna go to the elements panel over here and select one of these okay so if you can see there I know the font is kind of small you can see in the elements panel what parts of the Dom are updating and it's only the CSS transform properties for the second and minute hands there so we're only updating a little teeny bit of the Dom this is live and I'm really happy it worked now we can go back to regular slides okay so you can see we really do update just the dynamic parts we don't update the whole template okay but there's some very very important differences that we have here so first like I said there's no video I'm dipping that's expensive that can cause websites you know especially like on low-end mobile phones during rehydration and cause them to eat up a lot of CPU and we just skip that it's also standard JavaScript and because we get these values these template results back that separate the static and dynamic structure of your template we're able to use that for efficiency and lit hTML is designed to have a hundred percent compatibility with custom elements so unless you pass all kinds of different properties into custom elements we'll get into that in a second so I want to show you how it works real quick hopefully I have enough time to do this I'm going to try to go quickly here so little shimmer works differently depending on if you're doing the first render or an update so if you're doing the first render it takes your template literal it grabs the strings out of that template not the values it creates an HTML template element and then it uses that template element to create the Dom and it creates the done without the values it just grabs the strings so it looks like this up top here you'll have an HTML express lid HTML expression we grab just the string parts not the expression in the middle and we turn that into an HTML string and if you see in the middle here we drop in a little comment and that's our expression marker so this lets us know we're a dynamic part is and then we clone this template and we get to the Dom on the bottom and that's the Dom we're going to start with so that's first render and then we have an update and update takes the template result and it grabs only the values not the strings and it updates those placeholders so here we're going to start with the same lid HTML template and instead of getting the begin and end if markers out of there we're just going to get the value and we're going to insert that right before the placeholder don't we put in there and here I changed let me show you again here the name is an and here the name is gone and you're going to see that what we do is because we know where this value is going to flow to in the DOM only update the dominant one location so this is what you saw with the clock demo okay so that's real quick the the basically how late HTML works let's take another real quick look at what you can do with it you can do a lot more than just putting texts into your Dom so first we have the text bindings it's the simple expression there these expressions are just JavaScript and yeah you can have attributes as well right so text and attributes they're kind of the two main locations of things you're going to want to do in Dom but we also have certain attributes that need to be present or not present when you render input checkbox the checked attribute is a good example of this so we have some special syntax here that helps you do this if you put a question mark in front of an attribute name that makes this a boolean attribute and when the values false it just removes it and really importantly we support properties so we can see this here with an HTML input element that sometimes you want to set the value property because if you try to update the value attribute the input itself is not going to update this is also incredibly important with custom elements because you want to be able to support passing complex data between your elements not just strings and you do that with property bindings and then next we have event handlers so we have this special syntax again I think we share this with views binding syntax if you put the @ sign in front of a name it calls add event listener with that name there and then the value is going to be the event handler and we even do a special thing with lit element where we call that event handler with the element as the this value so you don't have to use arrow functions or bind or something like that to be able to get the right this value for your event callbacks so of course because it's JavaScript we support expressions we have the expression in line right here with the template and the expressions can contain some interesting values too so that can contain simple values like strings and numbers but they can also contain other template results so here we've shown nested template results at the top we have a header that has some data in it and we're just going to embed that entire header into an expression inside of another template and that means you can compute over templates when you you know before you embed them so here we're going to use a JavaScript if statement for a conditional but we're going to compute what the message is going to be and then we're going to insert the result of that into our final template we also support a raise so if you put a list we're just going to insert each item in the list individually nothing special on its own but what happens is when you combine lists with nessa templates you you get magic powers not really but it's nice to say and so here's map to race so this is gonna again look a lot like JSX right so here we have a list of items and we want to display a special template for each item in that list and so we're just going to use arrays map method provide a callback which returns some live HTML templates this is going to get turned from a list of items to a list of templates and then lit HTML is going to render each of these allies inside of that UL like you want another thing we support is dom nodes so you can put a dom node directly into an expression here and this is really really great for either doing kind of custom high performance work that you might want to do or for integrating a third-party library so let's say you're using d3 and you want to have it produce a chart that you insert into your template you can just have it make the chart and then just put the element right in your template and it will rerender everything around that and let your library handle what's inside the expression and so if you put all this together you see you can do some very powerful stuff you can do some complex stuff if you want but you can also work in multiple paradigms so up top I'm showing an example of working like in a functional paradigm and so here you're gonna call you know methods like split and map to produce some results in a pure functional mantle here you can also work imperative lis so you can use if statements and for loops and whatnot to compute some content that you're going to insert later and then finally if you want you can work very declaratively and have no control flow constructs at all so you can put it all together like this so it's kind of up to you how you want to use it and finally for lady HTML there's a hidden kind of escape hatch here that'll gives you a lot of power that we use internally to called directives so directives are a special type of value so when a value is put into the system what happens internally is we create this thing called a part so that comment that I showed you earlier that's really owned by a class called a part that lets you manipulate it and it turns out that what you can do is pass a function as the value and let HTML we'll just call that function with the part and then that function can do whatever at once with that little chunk of Dom right there and it can call set value on it to kind of compute a value and produce it put it in there and so all we have to do is tag a function as a directive which let's let HTML know it's special and then we'll be able to do have this function called and do whatever we want and so here's a real quick example of the until directive this is a directive that takes a promise and renders the result of that promise when it's ready so what this directive does is it first sets the part value to the default content like your place holder and then it commits it so flush it to the DOM and then it just waits for the promise and sets that value later so here we've added a synchronicity to our template system that doesn't have a synchronicity built in and so directives end up being a very very powerful concept in Lydda HTML and so we ship with a number of built-in directives repeat does keed update lists so if you reorder the list and remove the Dom around for you efficiently I think I'm running a little short of time so I'm going to skip these but we have a number of directors that kind of help you manipulate Dom and some pretty powerful ways soeul it is a pretty focused API it's only templating it itself is not a framework it doesn't have a component model and it tries to be minimal and then let you add features via these directives and the extensions okay so let's tie it all together now I showed you an example before of hello world how the world is taking a string right like a name if you're building an application you're probably going to pass around complex data so here's an example where we want to have some complex data come in as a property and we're going to use part of that complex data to render some Dom we also want to support rendering some children so this might be a card that displays like some person info and then some arbitrary info that you inject into it later a slot as a shadow Dom concept that lets you take children of your element kind of like react props dot children and render them wherever you want to in your template so slot gives you that location to render okay so here's a person card it's going to display the name and then some other content beneath it you might want to use this in the application this is supposed to be a directory listing right and so we might have here an array of people right and what we want to do is take this array and we're going to use the repeat directive and we're going to iterate over every person in the array with this separate template in here and this template is then going to instantiate a person card for every single person in the listen it's going to pass that complex data on via a literal property binding and then we're going to provide some child content which some other component we got from somewhere else and that's going to be rendered into that slot so altogether lit HTML web components shadow Dom they give you composition primitives encapsulation primitives and you can put this together to build very complex components or even entire apps so we see a lot of people use little--it for design systems we're seeing a lot of design systems come out and people often say web components are good for leaf nodes so are they good for design systems yes they are but if you use the composition primitives to build complex components all the way up to an application you can also build applications with lid element and you can coordinate them together too with standard Dom primitives like events so one of our mantras matches everyone else is out there now these days which is like data down and events up in in the Dom it's literally data down via property bindings here and custom events or something like that up that tell you when something changes you can use Redux oh you can build your own Redux just using events so lastly who's using a little element it's it's been out basically this year for production but we're already seeing a lot of really interesting adoption we're seeing groups from IBM doing designs systems Microsoft integrating with SharePoint a lot of banks and enterprises are using lid element and web components which is an interesting thing because you usually think of enterprises kind of lagging behind the bleeding edge but in this case the enterprises have such a problem with multiple projects and different frameworks that they're kind of leading the way here github is doing some interesting stuff and of course some Google projects like material design and some newer Google projects are starting to use it too and I wanted to highlight a couple of interesting use cases there's some interesting design systems out there that aren't your normal kind of corporate plain buttons and whatnot one of them is called wired elements so this is a set of elements that are actually usable elements you can click on these and open menus and stuff but they're written with this sketchy kind of format so if you're doing prototyping you can use these elements and they work in any framework because they're web components and another one that's been having a lot of success recently is called model viewer this isn't a design system it's a singular complex component and it displays 3d models in your browser using WebGL and it's being picked up by a lot of people like like Shopify just announced that they're using it and it's available to all shops in their in their program and they're able to use this because it's a web component I don't think Shopify is using you know react or angular I'm not sure but whatever framework they're using they can integrate model viewer in easily okay lastly real quick I want to talk about the future so we've been adding new features to the Dom and we're not quite done yet there'll be more so the current specs solve some common problems that we know about we need a component model we want encapsulation we get that from shadow Dom you want cloneable Dom we get that from template we want to be able to extend CSS I didn't talk about CSS custom variables but these let you define your own properties creating custom shadow parts these custom pseudo elements lets you do theming JavaScript modules you know JavaScript modules lets you import your dependencies and you know you can package there's supposed to be a strikethrough here we used to use HTML imports to package everything together and web packaging is a new burgeoning standard that we want to use for that and so we have new proposals that are designed to you know filling some more of the gaps and solve more of these problems I showed you class fields and decorators template instantiation is going to do the guts of this template mechanism that lid HTML uses and other template systems use and build that into the browser we also are trying to push forward CSS and HTML modules so let you import CSS directly into your JavaScript and then everybody out there wants to import modules by name you want to import late HTML not dot slash don't modules slash little HTML whatever and so import Maps is a standard coming along to help you reference modules by name and then finally we want to have scoped custom element registries so you can have different definitions for the same element in different parts of your page ok and that brings me to the end here I might have gone through the Q&A time Peter says no it's fine I have a couple links for you here you can look up web components right on MDN because it's a standard is documented there ledee shimon wood element have their own sites and then also i want to call out this site called open - WC org they're an independent group that creates a lot of tutorial and tooling for web components [Music]
Info
Channel: SFHTML5
Views: 9,606
Rating: 4.9141631 out of 5
Keywords:
Id: 9FB0GSOAESo
Channel Id: undefined
Length: 49min 59sec (2999 seconds)
Published: Sat Jun 22 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.