 Welcome back to OpenJS World. This is the workshop on Dojo and building your first Dojo-based web component or custom elements. There are three of us leading this workshop. If you attended the Dojo session yesterday, you'll remember me, Dylan Shimon, I'm one of the creators of Dojo. And then we have the two core architects of modern Dojo, Anthony Goebbler and Matthew Gad joining us to lead the workshop. They're staying at Waving and Matt's it's late at night in the UK. So I think he's gonna skip the video, which is a fair thing. And so if you weren't there yesterday, you don't know what Dojo is. I'll just give like a two minute overview and then we'll jump right into the workshop. So modern Dojo is a progressive, reactive TypeScript-first framework. So we try to leverage all the nice ergonomic and accuracy benefits of TypeScript to create a really nice efficient framework that follows reactive principles and aligns with modern standards and gives you all the things that you typically need out of the box to build an application without being really heavyweight and burdensome. So the idea is we can get the benefits of having consistent patterns and knowing that we have features available to us without creating something that is more kitchen sink like Dojo one was back in the day. We start with a custom rendering engine. It's similar in many ways to something like React, but we do a lot of things a little differently because we sort of have this framework level architecture rather than just a view library. And we have a lot of flexibility built in with various middleware and composability patterns and just other patterns you might expect a framework built today to have. So some of the features we're gonna go through, we're gonna talk about how to generate a custom element. That's nice, not that you have to use a custom element with Dojo, but that if you create something with Dojo and then you wanna import it into anything else that recognizes custom elements, you can do that and not sort of have the burden of thinking, oh, I have to create my whole application in Dojo. You could just create a big widget in Dojo if you wanted to. Or similarly, if you created elements or widgets or components or whatever you wanna call them in other frameworks and you wanna pull them into Dojo, you could do that through the custom element approach as well. We provide a really nice test renderer which we'll look at briefly. We use routing or if you're in Europe, you might call that rooting and various other forms of state management through a Dojo store API. We have a nice CLI interface that gives you really good defaults and gives you commands you need to create. Dojo applications, widget libraries, tests and other things. We are able to do a lot of really interesting things because we sort of know the architecture that's there. So for example, we can do really efficient code splitting automatically. We're using Webpack under the scenes, but as a developer of Dojo, you don't care that it's Webpack. You just care that, hey, I've defined my configuration. I've configured some settings and I get a nice small default bundle size so I get a really nice fast application. And we also provide PWA support out of the box. We have this concept of build time rendering where you can generate static sites or you can basically access and execute node modules at build time and then load different things at runtime to create the entire dojo.io website itself is actually created with Dojo. But if you look at the outputted source, you'll see little to no JavaScript. I think the only JavaScript that's there is to run our demos when you need to do that. And we also have something called Dojo Parade which is sort of like a storybook but a little bit different, maybe not as feature rich, but it's a first version of basically a documentation and widget example system. We'll use that as part of the workshop. So we're covering a lot. I'm gonna go ahead and stop sharing my screen and hand things over to Anthony and begin the actual workshop part of this. If you have any questions, just ask in chat and we will answer them as we see them. Hi, hopefully everyone can see my screen. I'll get Dylan to give me the nod that it's sharing, okay. Okay, cool. So as Dylan said, Dojo, you can do like a lot of things but we thought it'd be cool to kind of do a workshop on using Dojo to kind of build out and build a custom element. And so for that, what we're gonna do, I'm just gonna show this one. So what we're gonna get to is we're gonna build out a weather app that uses the open weather API. I'm actually using a proxy so that people don't hit my rate limit but and then build it out as a custom element and put it in a page and this is the deployed version on the cell. So there we go, it worked. That's good. So you can basically check the weather. It's a nice little weather like widget. It's all a custom element and this is what we're gonna try and build out during the workshop. We have some bonus features as well of being able to kind of change the theme of the custom elements and change some variants. So this is kind of a material theme available from Dojo widgets but you can also have a dark theme that's probably very dark and yeah. So that's an overview of what we're gonna start to build and let's go back to VS Code, there we go. Okay, so I have put some links in the chat. I put together a repository that everyone can clone if they want to kind of work along or if they wanna build it or just basically kind of have a look through as I attempt to fumble my way through live coding this. And there are a few checkpoints. I've created some tags that people with they are carrying along and maybe get a bit left behind. I'll let you know what you can do. Well, at what point you can kind of check out what tags. So the first, the initial tag is the Workshop01 tag and what this gives us is, excuse me, it gives us a kind of a skeleton project for building widgets as a library in Dojo. So we have a Dojo CLI and we have various commands available, one of which is actually a command to scaffold a completely fresh new widget library built with Dojo. So this is a slightly adapted version of that for the start. And so if anyone's interested, we can share kind of our links to Dojo IO and some of the documentation on that as we go through. So with that, with the template, there's some, it's got all the tooling already pre-installed that you need in order to build your widgets, build your custom elements, but also to be able to kind of develop your widgets as you go along. And that's, I think Dylan touched on it in the intro, that's a module called Dojo Parade. It's similar if anyone's familiar with Storybook, but not, you know, it's not the same. It gives a nice development environment for you to be able to create examples, generate, automatically generate documentation based off convention and typescript types and also run tests if you have tests within your widget library. So I'll just quickly show you Dojo Parade. Let's see if I can do this. So in order to do that, just gonna run npm, run dev. And this will build your widget library as within Parade and make it available through the default port is 999 on localhost. 99999, four nines on localhost. Let's see, well, that's always good, isn't it? I have an error. Okay, two seconds. That's a great start. I will show you that in a minute. I need to fix something, obviously. So let's just have a quick look, well, we went through the projects. So it's good. I can see it's now everyone's seen as an error and I'm like, great, that's fun times. So for parade, we've got this examples for a directory. It has some basic config which you can configure and define your examples of your widgets and you give it some information where to find the readme's for your widgets if you want to do that code sandbox. If you have kind of a link to code sandbox, path to the examples and path to the widgets. This is pretty a pretty standard configuration and there should be some documentation on the actual app dojo, sorry dojo parade repository on GitHub. And in there, so in the weather, directory we have a basic example which is just rendering our weather widget which at the moment, if you've checked this out is simply the most basic version of a widget for dojo where I'm using TSX, but we do have functional equivalents to TSX but we won't go into that today. So the main thing to do to just to get started is from the VDOM module, you need to import create which is a factory that is a factory that generates you a factory for creating your functional widgets and TSX so that it can recognize and transcribe down your TSX. And so what we're doing here, I've got an empty in space. I'm not sure whether everyone's familiar with TypeScript but dojo is a TypeScript framework. So we'll be working with types. Again, if anyone has any specific questions, please talk in the chat and I'll attempt or someone else might or Dylan will attempt to answer. So the first thing first is defining a factory for creating widgets. You could call this say render, for example, if you don't it's habitual that I call it factory, I don't know why. So we're calling create and then change method which is used to basically stamp the type of the properties that the widget can accept which in this case is nothing. So we then export this widget with a function. We use a named function. So that helps us with in development time so that we can identify the widget's name. And in here we're just returning back. Hello, dojo world. Now, Dylan, could you talk for a little bit? I just need to fix that thing so that I can actually continue the workshop. Sure, we'll just talk about it, I'm just kidding. Anything you want. Anything at all, that's cool. I mean really generally the job of an emcee or a conference organizers to take the distraction off of someone while something isn't working right. So that's totally fine. I think one of the things you were touching on while you do your thing was this sort of shift to a TSX syntax. So in the early days of dojo two and three and four we had, we supported something called hyperscript which is similar to like one of the internal API's React uses that when you're not using JSX. And what we found was that early on it was difficult for us to do some of the things we wanted to do with typescript in terms of defining really good functional APIs. So a lot of our APIs early on used ES6 classes and used this sort of function signature API that is effectively the same as TSX. It's just, it's written out as like a function with three parameters rather than a TSX which is just JSX wrapped in typescript syntax. But as we've evolved, we've found that most of our users and most of our team are finding it more flexible and a bit more powerful and a bit more efficient to write things as TSX. And a lot of that has to do with tooling where it's hard to know if you have an error unless like in what is conceptually markup or parameters for a component if you don't have tooling support to point out where you've made a mistake. And so because typescript has gotten so good at supporting JSX and TSX and then tools like VS code and other things that support the typescript language services have gotten quite good at that. We've decided that most of the time we prefer writing things in this TSX syntax. And also it's a lot more familiar to people who've used React to, hey, I'm just gonna use a very similar syntax to what I'm used to doing with React. So that was kind of the main reason we made that shift. Dojo always supported the TSX syntax from the 2.0 release but it's kind of become our preferred approach as of Dojo version six. Is that enough distraction for you? Or are you still gonna talk to me? I think that might work, so let's see. So now I'm going back to, so I'm gonna build so I'm gonna run a Dojo parade for our basic widget and hopefully this time it doesn't fail. Okay, come on. That's ominous, isn't it? I just built it on my other screen and it worked. So that's weird. Okay, we'll start again. Please hold. So yeah, I mean, so basically a lot of the tooling we have here, we've kind of dog fooded ourselves as much as possible in the Dojo widgets repository and package. So all of the tooling that we've basically using all the tooling available to external users internally in order to build and test and develop and publish our official Dojo widgets library. Yeah, this isn't working. So that's great. It wouldn't be a workshop without technical difficulties. I just thought it'd be me coding rather than... It's really kind of unbelievable when everything just works perfectly. People don't believe you're human. They just think you're a robot, yeah. I have to make it believable. Okay, so I'm gonna just get started with the workshop rather than fuffing around and hopefully I will get this fixed during the workshop as you do. So hopefully that was kind of a brief overview of the initial kind of template. So what we really wanna do is you've seen the end goal. So we're gonna be using a few widgets from the Dojo widgets package, namely the chip type ahead in order to provide a list of capital cities that you can select and view the weather on. And so that's kind of the first thing we're gonna do. And in order to do that, we're going to use a concept in Dojo called resources. Now, resources is a middleware. And let me go back again. A middleware in Dojo is, it's, I suppose you can kind of compare it to like how hooks are used in React. I don't like doing that, but sometimes that's an easy way of doing it if you're familiar with React. But they allow you to provide kind of inject, create composable functionality that you can inject into widgets. And in this case, we have a middleware called resources that you can define a template that will go and fetch data supporting pagination, querying, like dynamic page size, filtering and that kind of thing. From your like external resource, whether that's a RESTful API or another external resource. And basically you can use that within, so the chip type ahead requires a resource so that it doesn't know anything about the actual, the external data. We can transform that into the payload that we need for the type ahead. And the type ahead can deal with that resource agnostic and not actually have any, not need to know anything specific about kind of the type of resource there. So the first thing I'm gonna do is I'm gonna import, I think it's the default create resource middleware. And it's again, another factory. We do like factories because they give us some power to be able to kind of add typings to like stamp typings onto like core dojo kind of modules or functions and that helps us kind of remove typings from the end user as much as possible, rather apart from that in their own widgets. And so let's go middleware resource. Okay, and is that a thing? No, there we go. It was a name. I should know that, right? So the first thing we need to do is to we need to create the middleware and for our usage here, we just need to, we don't need to pass any, we don't need to pass any like a generic. So basically if you pass a type to this middleware factory, it will imprint a property onto your widget so that it tells the consumer that it needs to take a resource in order to function. So for example, our chip type ahead has that and requires a resource to work. So when you create the resource middleware, you have to pass in like the type, a type into this factory as a generic, which is defined by doing, oh, not in there. Okay, like that. And that would apply a resource property onto the widget instead of you having to define it in your, like manually defining yourself that automatically applies once you've passed, once you've applied the middleware to the create factory. So in order to use this resource middleware, we need to pass in an object. So it takes an object of middleware, so you can have multiple middlewares and middlewares can use middlewares and they can be composed up of multiple, like they can be, functionality can be composed together in such a fashion. And what this does is this tells Dojo to inject the actual resource function into your widget so you can use it in your widget. And again, that's passed in as the arguments into your widget and that is using middleware. So it's passed in and middleware and I'm gonna destructure the resource of it like that. So that allows, so this is the actual resource that's injected into our weather widget, which we're going to use when we start using the chip type ahead. Okay, to use a resource, as I said earlier, is a resource is kind of, it leverages effectively, like a static template that a user can define and describe how to fetch data for that particular resource. So I'm gonna create, I'm gonna add that in there. So let's have a look. So I need to do, I need also create resource template and we'll have a look at what we need to do here. So I'm gonna call this capital city, capital city template create resource template like this and that's gonna ever, because I need to actually start, I need to describe how to interact with this template. And that's done, we're passing in an object that has two APIs, a find, which we'll just leave blank for now and a read. And the read is the important one for this because that will describe how we read the page in the page. So the read function itself can be async. So that allows us to use nice things like async await. And I will, there we go. Let's just put in find as well. So hopefully it will stop complaining. So let's just put in find as well. So let's just put in find as well. So hopefully it will stop complaining. We'll do this properly, find it in a minute. There we go. So that fulfills the template API. So every resource needs to have at the moment two APIs, something that we are looking to improve on in Dojo 7. This was the first iteration of resources to provide you, to provide kind of a read, the read-only side of working with external resources. In the next few versions of Dojo, we're hoping to kind of expand that, expand some of the fine-grained control, implement some kind of some operational data, and working with arrows and handling basically more of these scenarios for the complete resource experience. So with the read function, you get a request. And the request is going to explain a minute, but that's basically telling you whatever is calling this resource needs. And that will be, that contains things like queries, pagination details, and the likes like that. And then you get a second argument called controls injected. Let's make it, let's call it controls. And controls allows you to interact with like the backing store behind resources. So resources are global pressure applications. So it meaning that you effectively have, it caches your controls, the caching of your resource throughout the application so that you don't find yourself having to like make, like thousands of requests for the same thing all over your application. So the next thing we need to do is, and so with the controls, the controls you can actually fetch data that already exists in the store if you need, which we don't need to do today, but also the other control, which is important to us is the put. And the put is how the read function or the read function template, basically it's what it store, it's what it puts into the backing store for that particular request. So let's go ahead and build out this read template. I'm going to do, I'm going to destructure. I'm using a quiet keyboard, which means that I'm not very good at it. I'm going to destructure some of the details of request and that's, I think offset, it provides an offset rather than actually page number or an offset, which you can convert to page number if you need to for your API. Size of page, that's the page size and a query, which basically is the, is if you need to filter down. So for example, type ahead, if the user starts typing, it's going to give you the value that it wants to filter down on. And I'm going to have to copy something in a minute because I can't remember this URL at all. Thanks Glitch. So this is the URL. Let me put that in chat, just in case anybody's following along. They might not be, but that's fine too. Okay. Yeah, so that's probably more useful than okay. So I'm going to build up my URL and I've got this pasted. So basically this is my, my proxy server URL and then I'm passing a param of the size and the offset, which I'm going to react to on my server and that's because I need to tell back up a bit with when you're creating a template that generic you passed a generic to define the shape of the resource data. In this case, I've made it value because it matches the tip type. And so I'm now going to do I can do this without gene const await fetch URL I think and I can't spell and then const await and and this is where we use the controls to put the results of that request. Okay. And what that takes is that takes a an object which has the data and the total and the total is optional. So but in this case, I've made my API provide me with that exact exact shape. So that works to me. And then the second, second part of that is the request and that tells resources, you know, what this data is, what request this data is called. So at this point, we've built out our capital city template and we're not actually using the find API, but we do have a default find which we provide, which operates on the data that the resource is aware of rather than the rather than the the restful, the rest API that in this. So that will do for us at the moment. So the capital city template. So now we can actually have to go on time. So now we can actually start to we can import our chip visit chip. Widget from dojo. Widget chip type ahead chip type ahead. And then we can start to use it. So we're going to replace. We're going to replace the contents of this div. And we're going to put in chip type ahead. Now. That's obviously requires some properties. So as I said earlier, we know that it needs a resource property. So we will use resource middleware and we will pass in a read will use the resource middleware and pass in the template, which is the capital city template. And that should be all you need to operate with resources. There are a couple of required properties in chip type ahead. I believe that's on value and value. I think it is. It will stop complaining in a minute. So now we've got there. So this this chip type ahead should should function as soon as I fix it a little bit. And oh, that's right. Sorry. But it also requires a label, which is typed, which is a child using our type children. So our type children can take an object, which in each of the objects can be and return back, you know, varying contracts depending on what the widget requires in this case. It's just it could be it's just a render result, which is any any kind of like div or string or widget. So select capital cities. Okay. So that fixed the complaining. And now the next thing we're going to do is we get so our our widget, our custom element widget is going to be controlled. So it's going to take a property to specify the locations. So if we do this, it's going to take a property of a string array. And it's also going to take a function which is going to pass the values. The it's currently selected values from the type ahead. And that should be enough at the minute and we'll make this optional. So that means what we can do. And so looping back to properties, obviously the properties were defined by passing the API here. And in the same way as the middleware, properties are injected into the widget arguments like this. Properties is a function that you need to that you need to call. So let's call that function and peel off these things. So instead of an empty array, I'm going to pass through locations and instead of doing nothing here, I'm going to pull the on change with the values of the type of the chip type ahead if we have them like this. And just so that we can see, I'm going to put a pre here and I'm going to stringify our locations now so it's pretty ish. Okay, cool. So that's really all we need to do in order to put the type ahead into our widget to leverage resources in order to work with the chip type ahead to interact with our external restful API and then return and basically return our location results that we're going to use later to actually display the weather. So looping back to our examples in parade so obviously I've added a couple of properties here so I need to fulfill those and to do that I'm going to need to use another middleware called icash which enables you to store state across renders in a functional kind of so so I have to add that to my create so that it's available and injected into my example function so now I have an icash so what I'm going to do is I'm going to I'm going to use an API called get all set it takes a key for so a key for the state itself and with get all set you can provide like an initial state so in this case it's just an empty string so I'm going to pass in the locations here and with the on change I'm going to take the values that are passed to me as we've defined in our widget and pass through in our widget and let's go back just a little bit as we've done here and the values from the chip type and I'm going to icash.set again using the same key locations set those values and that's because there we go so now I've updated my example widget I wonder whether or not parade or work let's have a little look aha it might be let's try it's just building again for some reason I'm not sure why this really hasn't worked parade for this unfortunately there we go hopefully I don't know why that's not working so it's just not working okay I give up on parade now I will see if I can fix it I've got to move this okay so we can't look at we're just we're just going to have to guess since hopefully all work he says okay so we've got through to this is there so if anyone is attempting to follow on I do apologize I've probably took quite quickly on account of not really being able to know how people are doing and also talking quickly just generally we are all this is the next stage is workshop over to if you want to catch up and just be somewhere similar and if you want to check out that tag a workshop that show to that is okay so assuming I've got things right which is your big assumption see if that works and we are going to basically now build out the details the weather part of our widget and so for that I'm going to create let me close this because it's really getting in the way going to create a new widget called weather details a new resource template that will interact with the API to get the weather details for a specific location and that's about it from that so I'm going to be using some CSS in this particular case that's already exists here as part the dojo basically supports CSS modules and it creates the type definitions for them so that when you work with the CSS in your widget you should get auto completion but something's really not working with my ID now as well so that's fine I'll show that in a minute okay so getting back to it we're going to build out the details actually the weather for each of the locations so we need to create a new factory that we're going to use I'm going to create it above here so it's going to be up here obviously can't use factory that's going to be weather details factory and it's not being used weather properties it's going to but it is going to use resources so I'll leave that in there we're going to have a new interface which is going to be the weather details properties and that's going to take a location which is one of the locations that we're going to select with our chip type ahead so I pass that in so to understand the widget with the properties and now I'm going to create my weather details weather details weather details factory function weather details so we know we're going to be using resources and properties in this particular case it's not where I wanted come on let's go back and do it properly there we go so I'm going to get those ready and why is that not working someone help me is it that I have messed this up somehow let's start again have I missed something someone I'm going to just crack on we'll fix this in a minute it's probably because I'm reinstalling node modules anyway middleware and we'll take the resources a resource from that so we're going to work with properties and resource resource in the same way not necessarily in the same way but we're going to work with those two things again when we're building out this part of the widget so the first thing we want to do is get our location from our properties and then we're going to return some TSX to describe the weather yay so that's almost certainly going to start with a div let's pretend there we go so in the weather details we're getting the past of the location but we're going to have to build a similar template to be able to leverage resources in order to get the weather for that location so I'm just going to nick this call it weather template and this do you need to do import start as CSS from yeah that's what I do thanks Dylan well I can thank Tom he mentioned it in chat and I just noticed it there you go yeah I would have got there maybe eventually but that's what I was trying to say exactly that's the nice so the autocomplete for your CSS so it helps with not having to one remember your class names to mistyping your class names you know all the benefits of the general autocompletions for in-type script which is call and so I'm still re-installing node modules so that's why that's doing that okay so we're going to build up the weather template in the same way as we built out the capital city template we're going to get in fact the main differences I'm going to copy this is the payload that the actual the resource itself is not just a value it's going to have all the information we need in order to display the weather in this case it's my weather details so it's got a name which is the name of the city the temperature the max temperature the min temperature an array of descriptions and an icon to display and so passing that to the resource template tells anything that uses this template that the actual the resource is of this type so that you have type safety when working with resources within your widgets so this example is slightly different to just passing a resource to all the resource aware widget like we did with the type ahead in this case we're actually going to use a resource just like within our widget and to do that we need to use some of the apis from resource in this case there's create options function that will create us our pagination options that we need that we can share across so basically we'll share across the renders and also get or read which is the main function at the moment which will read the resource for the page for the option details returning undefined if it's already loading or hasn't been loaded yet and then the widget will re-render once the resource page is available okay let's start with this so the first thing I need is my options so I'm going to call create options and for this I need to actually pass in an ID and each widget gets injected in a unique ID that you can use for cases like this so that will be the same for the lifetime of the widget so that will give us the same options back once they're initially created so the next thing is we're going to call get or read with our weather template and we're going to pass in the options and the options is a function that you need to call which will return the current options but that can also take an object of partial of the options so I'm going to set the page number set the page size and also set the query in this case we need to set the query so that we can tell the template which location to look at so I'm going to do that and it looks just like that I think I'm still installing no modules that's why everyone's gone wonky I'm surprised it hasn't killed my and resources return an array of pages because resources can support returning multiple pages so what we're going to do is we're going to take the weather details from here so we're going to destructure the first item from the array we know there's only going to be one page that could be undefined though because obviously it could be in the process of making the requests so we're going to check that that actually is the page if it's not and property is misspelled okay I'll get that thank you just helping that's what autocomplete really is the one for that restart types group I have types again and I have so many modules installed let's see whether or not that runs in the background okay so if we have the weather details then we are going to render our weather widget or the weather part of our widget if we don't then we're just not going to render anything until the weather details have returned so I'm going to start building out the widget and by doing that I mean I'm going to copy the content because I'm sorry I know that's probably a bit of a so as you can see so this is a page and we know we're only going to get one result back so we can do the same again to get the specific details for that location and that's what you can see there is the red squiggles I'm going to do weather detail and then weather details aha look it kind of didn't didn't fail I still need to do my template of course because that's not going to do anything so we're going to build that out in the same in the similar way so we've got a request on our controls so let me I don't know this a euro either it's long so I'm going to paste this in here that is taking the query name from the request details so let's do that so that's what we've passed in to the options here and we are going to do request and conveniently I've made this API also match the API required for the put and to be able to set the response so Jason and then we're going to do the same as we did earlier because we're going to put the results of that this into control control Jason and for the request so that will then should work I'm going to see if I've reinstalled modules I'm going to see if parade will behave would you believe this has been working all day and then I decide to break it let's have a look very cool just checking on the other screen it's not there we're just going to have to build the customer and that's the way we're going to have to check hopefully if anyone's following along they are having better success I'm not sure what's happened here okay so we've built out our worker details it's pretty standard it's some classes to lay out the information we've got the name of the city max temp min temp the description from the open weather API and then the main temperature so let's go ahead and instead of running to render this let's go ahead and actually use the the weather details and for that we're going to use the locations that are passed into the weather widget and we're going to map through the locations and render a weather details widget with this location for each one so this if I could actually get something to demo for you I know this is terrible should be the I'm still trying this it's not terrible things happen it's real it's all good I think it's my internet so something's not quite right I don't know okay so we're going to skip a couple of steps I'm going to actually build this as a custom element so that we can actually see something and see if it works and that's hard to debug if I've got this wrong so with the build tooling for building a widget library with all of our build all of our SEA like commands we have a dogera C where you can specify configuration for everything so slow my clothes we're going to restart this there we go is it I mean it's not lagging on the video is it I mean that's not even opening the S code for me there we go I just see your browser yeah okay yeah I know as long as it's not something that's killing me this is the S code there we go so we have a dogera C configuration file and if I was actually able to to show you parade the dogera C configuration extends a configuration provided by parade in order to build properly but the bit we're interested in right now so we can try and build our custom element is this build widget with a prefix a build widget section and this will this tells the SEA like so the dogera SEA like build widget command which widgets to build and for custom elements you can provide a prefix which would be like dojo-weather in this case so what I need to do is I need to add source what is it SEA is just source weather weather okay and let's also add there's going to be some so when we build this it's going to be put into the output directory so I've just got a index hgml file here which I'm up there here that I'm going to be using in order to like demo the custom element so I'm going to import the CSS that we generate for the custom element for the weather custom element I'm also going to import the JavaScript for the which is the bit down here so that's the JavaScript and then what we're going to do is I think I have a class called container so we're going to create a div and we have class yep container and in that we're going to use our dojo weather widget that's you should remember hopefully remember that the dojo weather widget itself in dojo requires some properties so for example it requires location at least and an on change so what we're going to do is we're going to provide it with some locations and not provide it with an on change so that we can see whether this works see where we've actually got this running let's give this an idea so I can reference it later and you'll notice that the actual type of the locations isn't a primitive like a boolean or a string or a number so with the custom element support in dojo we can support complex properties by passing in a JSON stringified version of the complex property and you'll also notice that I've not done anything in order to kind of tell the build tooling what properties the widget has or requires or what types they are so how does it know that locations is something that it might get passed as a JSON stringified string and that is part of the build tooling where we can look at the properties during build time to determine what the types are of the properties and then deal with them accordingly within the output compiled custom element okay I can never get this right so I'm just going to deal okay so let's go here so I'm going to pass in location here locations and I'm going to pass in JSON stringified version which is is it is it like this do someone stop me if I'm wrong London I think that might be right okay so I'm going to build this custom element and see whether it works this might be the first time we actually get to see something okay it's building right now my computer is really really slow so this is not normal it's very hot as well so if I serve from the root directory I'll just run npm run build which build the custom element I should have done it in this screen but I didn't want to take the risk of it look at that my map is undefined okay and that's because I need to check whether or not it's undefined because it's not necessarily going to have those properties if I've done it wrong so I'm just going to default it just in case and rebuild it's a time 10 past we're looking given all the problems not looking too bad on time not going to have to show you anything though I bet your microlip server is now dead hopefully people have been using it yeah that's good thank you guys and girls and anybody else it's still building so I'm just going to do a quick drink okay let's see if this works again let's go back to this is our local host so I'm serving 5,000 aha and this is our typehead we haven't done the on change so because it's a control component so I need to tell it it obviously hasn't also passed in the the initial value but we can look at that in a second it's probably because I've got the jason stringer I didn't have that to copy well anyone else just use it all the time hopefully I think it's that so let's go back here and I think I've got an extra pair of quotes on now I did okay but what we could obviously as I just said is it's a control component we're meaning that we need to provide the locations but equally we also want to be able to provide the locations when anyone selects the updated locations sorry when anyone selects an option from the typehead or removes an option from the chip typehead so for that what we're going to do is we're going to register an event listener we're so we have custom elements dojo also automatically finds functions that are prefixed with on and converts them into event listeners that you can attach to within your html when you're using the custom element so we're going to create a script and we're going to do weather.ab event listen change you don't need the on so it's the on and the payload of the callback or the property is passed through on the event in the details so I'm going to destructure details from there but you could also equally do event.details if you want to and for this I'm going to and the details is an array of the arguments passed so I'm going to do weather.locations which is the property and I'm going to set it to what the user has selected in the selected in the chip typehead now hopefully at this point we will get some weather if not I might just go to the last tag I've got which should be correct so it's just building at the moment check this out aha something this is our custom element so we're going to add some some nice sugar that is available to dojo widgets which is some theming so we're going to basically add the material theme that's available from dojo widgets and we're going to add the dojo theme as well we're going to also add some buttons to kind of pre-populate the list in this case London so hopefully if I added another one it's details we'll know TypeScript to save me there unfortunately yeah so we're going to add a button to pre-populate the list and we're also going to add an extra bit of functionality to be able to make this read-only so that if you don't want to have the drop-down it won't show the drop-down and it will just populate the specified locations as a read-only kind of widget that did miss mention I don't know if we're not okay don't worry about it no worries okay so let's carry on first things first this is detail that is detail okay so that would work now so what we're going to do is as I said is we can all of our custom elements can basically can take themes so in this case we're going to because we're leveraging the dojo type ahead and we haven't created a theme for our weather widget which we could have done but we didn't really think we had the time and obviously everything's gone so well so it's probably good we didn't so we're going to create the we're going to add in the CSS and specify the theme and we're going to use a couple of other dojo widgets that we distribute as custom elements that you could just use in your page so let's just do that I'm going to just steal the imports if you don't mind so we're going to add we're going to use some buttons from dojo at dojo widgets we're going to use the material theme and the dojo theme so we just need this the CSS so that's the CSS so I move as part of the build I'm moving this into my output this folder so I can reference it so this is the dojo theme and the material theme and then the CSS for the dojo dojo button custom element that was a mouthful and also we're going to take the JavaScript so and that goes under the body so we're going to add this JavaScript each of the themes have a small wrapper to be able to basically set the available themes for custom elements so in this case the dojo JavaScript the material JavaScript and obviously the button JavaScript that we need for the custom element itself so if I build this again while we do some other stuff I'm really glad this is being recorded I'm never going to want to watch it again I mean the beautiful thing of things not going perfectly ant is that when people struggle they can just remember that it's okay it just happens and normally on a day like this you'd be like alright I'm going to go take a walk for a few minutes everything will work fine when I get back but you don't have that luxury because we're live so it's all good don't beat yourself up I'm not I'm just making fun of myself really the best way to do it and I've just rebuilt the I'm going to start doing that in the in the terminal in VS Code so you can see but I've just rebuilt so hopefully so what we did there is we used so internally in our widget we're using the dojo typehead so that means that it will if you set the theme to be the material theme for all the dojo team pass down and propagate it through to any themeable widgets that you're using in your customer so in this case we've got the material theme which is this here and we now have a material themes typehead that looks a lot nicer I think but I mean bear in mind I haven't been able to run Parade and check this I'm suitably impressed moderate rain in and or okay cool right so let's have a look at what we need to do so as well as as well as theming as of dojo 7 we introduced a concept of well we introduced a concept of variants that could be switched at run time so that supported for all of our I believe all of the widgets out of dojo widgets so we have a dojo theme and a material theme but we also have light and dark variants the light is the default which will be used as you can see here by default so first things first I guess what we should do is add a button so we can change the theme that would be nice from it so we can go from dojo to material and back so that was very hand-waving so we use the dojo button custom element and I'm going to call it toggle theme and I'm going to create an ID of so I can click on and what did I do there so obviously it's a button so if we look at so I can actually show you let's have a look this is dojo parade for dojo widgets so this is what it should be I would only have one widget for the for the example but you can see here this is the main landing page gives a brief overview of how to install dojo widgets how to use dojo widgets and the button and some features around dojo widgets and then down the side here we have each of our widgets we have available within the suite so for example let's have a look at the type ahead because that's what we're using so there's a landing page with some extra information on the chip type ahead an example which is normally just a very basic example on the homepage so in parade it will output the so we introspect not only the properties of the widget itself but also the example so that people so you can see how the example was put together so in this case this should be this is quite familiar as we've got a chip type ahead resource we've passed a label there's slightly different uses for resource because it is using an array of data rather than an external resource and then all the properties for the resource so and as well as that the children that can be passed to the resource also any themeable so if on dojo.io learn there's some sections about styling and theming so you can create themes for any of these widgets if you don't like the dojo one or if you just want to enhance it in some way and these are all the themeable classes that you need to need to use so this is kind of an overview of all the different information and documentation for the widget this is effectively the public API being the properties and then we have so so also in Parade you can change the theme there's a number of themes you can have multiple different examples so for example this is a disabled this is disabled so I can't do anything you can have free text hello I'm sorry about this let's see if that works there you go yeah so this is all of the different widgets so please check out widgets.dojo.io it's pretty it's new Parade was released a month or two ago and so beforehand we actually manually kind of maintained all the documentation so we're moving away from that so please feel free to give feedback and that would be great but this is what we wanted to show you earlier with the weather widget cool so what we're going to do sorry I don't know why I went on a big tangent there but that's why because I was going to show you the button and so from this documentation you can see the property so you've got a long click and you've got all the other events that you might need and so type you know some area so you can pass into your accessibility if you need and things like that okay okay so let's do a thing so we're going to use the idea again and we're going to add an event listener for the click so when the button is clicked and what we're going to do and this is so at the moment we have custom elements when you load in the JavaScript it registers themes on a global called dojo-ce which is what you can use in order to set and change and inspect the available themes so in this case what we're going to do is we're going to do if just double check what I did here that looks good if dojo-ce.theme equals dojo then I'm going to set it to be dojo-ce.theme to equal material I'm going to set the theme to be dojo that seems okay so now we should have a button and and it should toggle our theme so let's have a look that's the wrong one that's paraded it's never going to work aha so yeah so we're now changing the theme for our custom element so in this case we don't have a theme for our weather widget but we do have a theme we are changing the theme for the dojo chip type ahead and you can also see obviously that changes the theme for the button as well so we move from a toggle theme to toggle theme so the next thing we can do is we can toggle between a light and a dark variant of each of these themes so let's add in another button and let's call it toggle variant let's call the id variant let's take this and it's very similar so a variant and basically in the same way as we have a theme we have theme available from the dojo-rc global we also have variants and in this case I think I started with dark that's right so if it's dark I set it to light or default default and if it's not dark then we set it to dark now the variants for for material require kind of the body to have a dark background so we're just going to put a style on when we do this switch for dark so that sets the background to a dark color and let's just set it to a nothing color let's have a look so hopefully and now see we are now toggling the variant of the theme that is applied to all of the custom elements the dojo custom elements the dojo theme the dojo theme and we can toggle it back again and we can add some more so I've already got London so let's do this one I can't pronounce that, long year buy-in maybe okay so you can pre-select and do that so the next thing I mean we just so let's add a button to do to pre-populate these styles so we don't need to pass in location here we don't need to have one like this but we can add a little bit let's add the other functionality we have populate locations populate and what we're going to do there is when that's clicked we're going to set the locations to just a default set so let's do populate dot event listener click this is what I have to remember my capital cities so weather dot locations and we can say London Paris Rome yeah we'll do I think and so quickly we added our second looking last until we had defined a bit of functionality for a read-only weather widget and we populate our locations and look I didn't push the bow out and trying to guess capital cities thankfully so then you can continue to use the type of head functionality I don't know why that's happening that's annoying okay next things so that brings us like right nearly to the end of the custom element workshop we have I've struggled but I've got to have built a we've built a custom element in dojo that leverages kind of the new resource concept that is the way to interact with external resources and to make widgets data are where generally you know from version 7 we've used you know the dojo widgets chip type of head to provide us kind of nice functionality and we've also like created our weather widget and we've configured the project to build as a custom element that we could then distribute out and people could use obviously this is using my proxy but you know in real life you could replace this with the real APIs for say open API and you could take an API key for the for the property and you could use that API key within your resources and so therefore it would work for anybody who wants to you know if you publish this on you know MPM or whatever people could use this as they needed so we but we don't need to do that because we're not using the real API so but that's you know you can and there's lots more you can do with well with any API but specifically for weather you know you could you have a five day forecast three day one day forecast three day forecast you could provide all sorts of you could have all sorts of properties to kind of control that configuration if you wanted to extend out this widget to provide more information the last thing we're going to do we are going to add a new property it's going to be called read only it's going to be optional it's going to be a Boolean and we're going to set that to false by default and we're not going to show the chip type ahead if it's false yeah we're only going to show it we're only going to show this false yeah sorry my bad so if it's read only then it won't show the chip type add if it's not read only then it will show the chip type add and by default the chip type add so let's we're going to have to build this again so let's see if it will build in my terminal here and while that's happening we can add a nice button to kind of set that read only toggle read only toggle read only and obviously button again probably should have used maybe one different dojo custom element so we could have explored a little bit more but I've had enough excitement for one day let's now click so we're going to set the read only to be the opposite of what it currently is let's start building let's see how slow that is that's just in like a copy okay and there we go so we're not showing the so if we toggle the read only we don't show the excuse me the chip type add or the the city selection but we can still populate locations so if we were to let's go back here so if we were to go start off with locations like we did earlier which would be let's say London Paris Rome like we've got so and then we can also if we set the read only initially to true sorry so you have a read only so you could have it as a widget that a user doesn't interact with so maybe they're preferred time zones or preferred cities or locations and obviously I can now toggle it back on and off because I've got these buttons one thing I guess I didn't really show because I didn't have the opportunity in parade but with the resources on the type ahead you're working with paginated requests we the type ahead itself or resources will fetch a page at a time and we'll fetch the pages as the user scrolls so you can add lots more so I think there's like 250 here well once they're obviously loaded they're loaded and cash so it doesn't need to make a request again look at that it's 25 25 and that is is there any questions I don't know whether or not can I see the chat there was no questions in chat did anyone join well I'm not sure about that but I'm going to give parade one more shot before I throw my machine away and I'll do that over there I mean we got there in the end it's a shame that I couldn't get parade to work and it was working all day and I think it's just my machine is pretty much on fire due to lots of different things they don't do well when the room is warm that is true it's very warm I don't know where everyone else is but in England it's unusually warm for us apparently it's 30 Celsius according to your screen so yeah there you go only we had a weather widget yeah the only reason I did this let's see whether it works this doesn't work I mean it didn't help I had to reinstall my modules wow cool no thanks guys it worked so this is what I wanted to show earlier let's see if actually there we go so let me close there we go this is what you get out of the box when you use it's for some reason a bit rebuilt but it's what you get out of the box you get all the niceties of the documentation so you can see here and add any documentation it is there on my main branch I just was lazy during this when I was doing the workshop so if you see I didn't actually deploy this out I don't know why that's happening so this comes out of the box of CLI build widgets sorry CLI create widget which is the command you can use with the dojo CLI which is a tool at dojo CLI from npm in order to create your own widget library and start building out your widgets I hope we see some it would be great to see some innovation from people who have fancy ideas much better ideas than say a well widget but I hope that gives some kind of insight into what you can do with dojo and I appreciate your patience putting up with the problems but we got there in the end and we have a widget there oh I think that's it if there's no questions on chat or anything just remember there's about a 30 second lag between you asking that and the audience typing so we'll just give people a minute or two and we can see them looking at Slack I mean I mean I think the problems made that take longer so maybe that was a good thing sometimes the problems slow things down enough that people can follow what people are doing so it's good yeah if anyone has any feedback just generally if they want to we have a discord channel if only I could remember the invite code for it Dylan could you put that do you know the I think if you just go to the dojo.io website it's there is it yeah yeah so it's the dojo.io website is kind of our home for all of the information blogs roadmap which hands up we need to kind of go a bit better updating a link to the documentation on the other page you'll find the discord see there under community that makes sense let's get this invite so if you want to chat or have any questions around dojo in any way shape or form we're generally online on discord please feel free to kind of hop in if you have any kind of ideas for dojo going forward probably the best repository to raise an issue on would be the main framework issue we can move that around however we want however we need I think that's I think that's about it do you have any anything else Dylan Matt I think at this point also we'd love feedback just as you start playing with dojo do you have any suggestions for what we're missing or whatever let us know what we're missing or things we should focus on and that really helps us frame what to do for our next release and so forth yeah and any suggestions on a better workshop but from obviously not having all the problems is there anything in particular that people want to like new to dojo talk about for an hour or so we're interested in hearing what people need what they want to kind of find out keep an eye out for new blogs there's a few blogs we're going to start publishing one of them is actually about resources as well which is pretty cool yeah and I think we didn't touch on it much at all but the whole build time rendering thing is pretty cool we've actually done workshops before almost exclusively on like how to build a static site with dojo if you and again if you look at the dojo website itself it's built from a bunch of markdown files and resources dojo and you know the dojo build time rendering and dojo blocks and other features and if you ever the other thing we didn't really look at is the light house score of what we just built or the light house score of dojo.io or really any of the out-of-the-box dojo stuff we do pretty well from a performance perspective and a lot of that is down to sort of how we do default bundling and code splitting or for a static site we're really just generating mostly html and css but we're really good about just getting that bundle size as small as we possibly can while giving you all the features we think you need to really help you build fast performant applications and that's a really big focus for us as a project Yeah for sure I mean I didn't touch it earlier I won't talk too long again but dojo.io is built with dojo so you get like you get the nice kind of components or widget kind of widgets from dojo to be able to build your site in and build time rendering and some dojo blocks that I'm hoping to kind of maybe write a blog on at some point if I ever get around to it will provide you kind of a static site generation experience without like a huge amount of configuration you fundamentally kind of work with widgets still and middleware for actually producing and creating the content so yeah I just double check the questions and then I guess we can call it a day at 21.43 Yeah and thank you for your patience if people are watching