 Hi Today I'm going to talk about ember power select ember power select is an add-on I built recently and Was a source of inspiration for many patterns I discovered It's also a talk about composing components because it's the pattern I Use for building this and the pattern I wanted to enable with this add-on This is going to be a light coding talk most of it, but I have a few slides and besides I have no Plan B. So if I don't I mean everything is going to be done by scratch from scratch I'm going to create a new component within 10 minutes. It has to work My you can find me on Twitter or github under these nicknames And the first question is why why I wanted to build yet another select component and the reason is I look at the Existing at the landscape of existing components for ember set components for ember and I found these problems Most of them if not all were wrappers around jQuery libraries jQuery libraries has been there forever and They have a lot of acquired knowledge So it's valuable to reuse this knowledge But they still you have been limited by the equities the jQuery API surface Which is not very friendly for our for to the declarative way of building UI's and ember So there's they are not idiomatic to use They are tricky when you want to use them with ember data collections because they are not playing a race the mind the ember data collections can mutate and The amount of glue code you need to put in your add-on to wrap your jQuery library happens to be Usually bigger than the amount of code you need to write to build something from scratch and Also, if you want to customize and what's my need? I don't want it to use it needed to customize my selects quite a lot It's just not possible to usually they are what I call monolithic black boxes your add-on. I mean them The jQuery jQuery library is a black box and you need to take take it or leave it pattern I call the large monolithic with an army of options This is a the kind of components where you Have a huge API with a lot of information to move things around or tweak every single detail And you need a 20 pages manual to know how to use something that makes me very sad and We know better when it comes to create components. We have very very good API C number and very with Surface for using the template to compose your UI That's why I build ember power select you can find it on ember power select dot com and I built this add-on with composition So my idea with you for building components is you should take a small fine-grained focus components and build them or put them play level with them So you can build your complex UI from very small and very focused Components so if this is a real example the ember power select with multiple selection is basically a particular case of the power select Power select is built over another add-on of myself called ember basic drop down That is just a trigger that opens a floating box and know who to position this box absolutely over below the trigger And this thing this Automatic positioning is done with ember wormhole. So you can render part of your UI in another Tom element usually on the root of the page And it's also built for composition because I want to allow people to use my add-ons and Compose their own specific version of my add-on for fulfill their needs Because you assume it you cannot fail you cannot prevent or For seeing all the needs of your users. So you need to enable them to modify your component That's an example of how the company is organized if you look at any pie any piece of UI This is an example. You can see that it is chunks of the UI with different Needs and different behaviors in A set component basically you have as the main Areas the trigger which is the box on the top and the list of options and apart from that You also may consider the content of the trigger another component the Theme you may have another Slot before the list because you may want to add a search box there Another below the list in this case is empty, but you could add something there and Each option of the list is also a component or a block you can pass Let's see or I want to demonstrate how to build a Select that allows you to with drag and drop sort the options Within 10 minutes. I have no backup plan. Let's see what how it goes That's it. So let's go into create a new member project. So it's going to be an add-on. So Ember add-on Ember power Select I'm going to call it sortable. I have local npm. Let's see if it works Less, okay There we are installing yet I'm going to do here. This is the application is vs of my add-on because I want to try to use it and And show how I evolve the code the add-on into the final result This is taking a while because it's you know npm Stalling it's big enough Okay, that's the biggest npm chunk. You're going to see the rest is quit fast But And you know Not about npm Sorry SL no Install it back in chess. Oh something went wrong Is Yeah, but let me see less less no What is going on? There Okay, the speaker either it is Get there Let's see, but I don't know is this thing trying to push to get it's just Okay So Uh No, because I was everything was guys in theory, so it should be equally slow Well, yeah me I say 25 minutes probably appear let's try sl that's it That's fantastic I'm going to do that right now Are these people look at this You know npm is the new i it's compiling of the modern era About power that's good. Yes. We have this unless so let's see the Into the folder split the string again First of all, this is going to be an add-on over an add-on. So I need to install the original one Ember install sorry install Ember power Select and I want to install the latest beta. So 0.8 0.0 That's a little seven. I think I like betas. It's good for people not yelling at you because you break things Okay, and now yes embarrass This should be quick localhost Please work There we are. So first of all, I want to use the component. Uh The basic one so I going to do Uh, it's this going well, obviously if you want to sort options, it has to be a multiple select for having more than one So, uh Power select multiple options equals Options why not? selected equals selected And on change, which is the only actions We care about We are going to Do an action That is going only to mutate the selected value. So mute selected This is going to yield each option of the Of the collection. I'm going to call it number or num multiple And in here, we are going to just put the num because it's going to be a string and I don't need to do anything with that Uh, I also want to Ember g controller Uh application because I want to define this data application controller and Options is going to be an array with one two three four and Yeah, seven seven Why not? And Let's see. Okay. We have a multiple select working. That's nothing fancy. Oh, yes. It's very important. Um Oh much better Let's go. Um Oops, you know nobody And so we want to do is basically drag and drop this thing and reorder the options and This component as I show in the presentation has some slots you can personal Customize this one the trigger is the one I customize to add some kind of drag and drop functionality in there So, uh, I'm going to Keep sorry. Um, I'm going to Add that here, uh an option. I'm going to call the trigger component is power select sortable Trigger I'm going to render this component in the slot prepared for that And it's going to replace the default behavior So let's generate this handle this controller this component ember g component Sorry Copy paste there install and Trigger hbs Are you going to do blah and see if it works? No, what's going on? I know what's going on Happens with when you have an addon that has to compile templates. You need to move a hand a html bars To that runtime dependencies Sorry and Package.json So html bar has to be Here There probably need to restart There it's working. Basically it's rendering my component that has some blur test Text text so now I want to Give some functionality to this the first the first thing I can do is check how Ember CLI itself is built. Sorry, Ember CLI itself ember power select is built Because I'm using duck footing. So my component is built on top of my component The bow the multiple version. So if I go to the Templates of the multiple component You see that there is a trigger a custom trigger which is this mark up I want to copy it because mostly of most of it is fine for me I copy it and paste it. That's the markup. I want This fails because there is an action search is not found In the Addon itself if I look for trigger J s the code of the component Not this this You see that there is some logic in this component. So I'm going to inherit from This in Trigger.js Instead of create an editing from ember component. I'm going to import. I'm going to call it ember power select a multiple Trigger from I'm sorry Thanks I'm going to use how to complete. So This run, but it's fine And import different ember power select Addon components power select multiple trigger without the js. I think Let's see if it works From the addon Yes, addon is not needed And see if it works. Yes So for now we have the same thing we did but with our custom component on top So now is when we want to use something else to allow drag and drop There is a very good addon for that by jamie And allows you to allows us to do this kind of drag and nice drag and drop thing and That's I'm going just to copy text to copy the example in the very read me And paste it and see if I can modify things a little So we have a ul. I don't want any any list for it for this. So empty tag name. I don't want any div nothing Uh, I want Twitter over I call it selected And I'm going to call this thing Oops Okay, and I want this class because I want to reuse the class Uh, this is a span. I want to keep the markup model it in group, uh, I don't really need a handle. I want to drag the thing with the entire element And The rest of the component is something I can copy. Let's put it here Uh indent Let's comment out the rest And see if it works Sortable group Oh, because I I never installed the addon. So ember install Ember Sortable There restart and see if this works Okay, let's select one element another element and drag it Oh, I can drag only vertically. That's fine. That's fine Uh, there is an option for that in here because I don't know how this works, but jamie you do and Direction equals X I'm all right See Lex one two seven And drag it. Oh, we're dragging Okay, and if I drop nothing happens because I have no actions for this drop event Let's do it. I don't have a reorder items, but I can add it Action reorder items and if I go to the trigger, uh, I close it trigger.js I'm going to add an action for this action actions reorder item Uh, if I'm right this receive the items in the new order And I just want to call the default behavior. So this I nested component receives An object that contains the public api of the parent component. So I do this dot get The select and action and then I call actions dot Choose this thing Choose and the items So now Sort the other items not There Okay, if I now I select Three items and I drag and drop Whoa, something went wrong You know This thing happens as I said, I have no backup plan. So if you see something fishy, tell me please And if I reorder And items and the fine and the fine. Okay, something is wrong in the template A item is option And I'm pretty confident this is going to work now. So remove this thing reload One two seven and it works It's not done Let's add Another let me go and now I can I'm confident I can remove this thing and In the application sbs. I'm going to add a copy of this thing for reference here here And I don't want to make this one The one below is the new one Sorry They are both bound to the same value Okay, that's working This took like five minutes ten minutes if it wasn't for a for npm So this is still not ideal because if you look in the template if we look in the template There You have this Wide thing because in every single call where you want to call this component You need to specify I want the trigger component to be that this specific component. I have So let's create a new component That wraps this usage and call it sortable And basically I don't want this. I want to be automatic when I use this component. I always use the sortable behavior And Let's create this component mber g component Power select Sortable there I don't think I need this anymore Need this uh Sortable hbs And in here I want From this component render a multiple select With my options. So I want to compose this component On top of mber power select multiple as I did before So I'm going to sorry Here I copy this thing let me undo I want this No, I want This I want here But uh There is more options. So probably I should enumerate every option in that the Original component allows so I can have the very same interface The best way to do that is I go to the original one. I check in the template of the component How I did it select add on templates This one I'm basically copy all of this It's just a list deal with it Where you want to Handle everything this is probably On focus sorry On focus. I don't I bypass everything On open And the only difference is that the trigger component Will be trigger component. That's fine. And I want the trigger component to be this one here so I'm going to copy this thing delete this thing and in the J s I'm just going to specify that The trigger component is always the same value and Tachname. I don't want this to be a hover wrapper tag So if everything is working this should be here. Sorry. Um, I think I did some yes power select multiple this thing Dash and Reload I can drag and drop. Yes, I can drag and drop. So now we have this nice interface That is exactly the same as the original component Except from the name of the component and we have built within a few minutes a component that with a quite complicated behavior Because there is there is in the wild components that they are very good on a specific task meaning being a select or being a Drop drop and drop sortable thing so we are Taking advantage of this for our Our benefit so Let's recap what we did. Why I think composition is awesome First of all We are standing on the shoulders of giants meaning this case jamie because jamie built A very big component for sorting things. I have no idea who he works and I don't care I know that has a very nice declarative api in the template I drag and drop things and my component is very good at being a select that has no idea how to sort things We mix both and we have the desired behavior We don't need to reinvent the wheel because jamie jamie did I did someone else did ember one hole and I'm think I'm very Thank you. Thank you for for that Another advantage of this approach for having very focused components Composed to create big good experiences Is that apart from not reinventing the wheel you don't shift the wheel twice If you are using by example, I think it's ember model You are already using ember one hole So your component is using ember one hole. This other component is using ember one hole You're using the exact same code. So you don't pay the pay the price in the site of the application Saying if you're using any sufficiency sufficiently big application, you're going to have a lot of components being used And some of them may depend on the same package So you don't want this functionality to to be repeated and they go to be twice in your payload And you get more reliable reliable results faster. We made this thing within a few minutes Is as rocket is as Rock solid as ember power select and ember saltable is on a standalone thing combined This is the current structure power select sortable depends on ember power select multiple that depends on Power select that depends on ratio drop down that depends on one hole and also uses ember saltable And I we did this with a few lines But a little effort for very good for very good results within the time So compose start right now create. It's what I call building blocks start creating addons that are very good at something And when you want to create something A complex Mix and match As long as the your addons the addons you are using keep the public api consistent You have Free upgrades with no break it no breaking changes You have the good part every book fix everything for free on your own on your own addon And you need to care about H cases that someone else already covered And that's it Thanks If we are on time if we are on time I like to first of all get at everything DCI Life run ember London Let's see if I can get push Yes GitHub I'm going to deploy the I release this thing live So why not? New repo power select there is a few addons already So a sortable There great repo Copy this thing Oops push this thing Works Reload and ember release Yes, why not? An mpm publish See No, but let me kill This It's my local mpm. I want to set the registry to the original one And publish again cross fingers Deploy