Coding

Stencil | Props, State & Tons of Decorators

  • 00:00:00 welcome to this video in the last video
  • 00:00:03 of this miniseries I introduced you to
  • 00:00:05 stancil a nice compiler which allows you
  • 00:00:08 to easily create your own web components
  • 00:00:11 here's the web component we created in
  • 00:00:13 the last video this little modal which
  • 00:00:15 is always there now in this video I want
  • 00:00:18 to add some logic that we can pass in
  • 00:00:20 some data from the outside then we can
  • 00:00:22 actually open and close it and improve
  • 00:00:25 the styling a little bit so let's get
  • 00:00:26 started with that in this video
  • 00:00:32 we get our mold layer and first of all I
  • 00:00:35 want to make sure that we can actually
  • 00:00:37 open it that's not always there now for
  • 00:00:41 dead you could go to the index.html file
  • 00:00:43 and add a normal button in there a
  • 00:00:46 normal HTML button where I say open
  • 00:00:48 modal just like that not my model just
  • 00:00:52 mold thank you now this is the button
  • 00:00:55 I'll now add some script here
  • 00:00:57 conveniently simply in the index.html
  • 00:01:00 file so that we can have it all on one
  • 00:01:01 screen
  • 00:01:02 and in that script I now want to reach
  • 00:01:05 out to my buttons stored in a variable
  • 00:01:07 so I'll use document query selector here
  • 00:01:10 to select my normal HTML button and I
  • 00:01:14 will now say button add eventlistener
  • 00:01:16 and add a click event listener add a
  • 00:01:20 function here and then this function
  • 00:01:22 won't you open the modal and alright now
  • 00:01:24 we couldn't click the button because the
  • 00:01:26 backdrop is always in front of it so
  • 00:01:27 I'll comment out the backdrop and I
  • 00:01:31 don't want to have the modal opened by
  • 00:01:34 default now to make sure that the model
  • 00:01:37 isn't open by default I'll go to the my
  • 00:01:40 mol/s CSS file and add display non cuit
  • 00:01:44 so now if I save everything we should
  • 00:01:46 have a white page with only the button
  • 00:01:49 in there the rest should be hidden now I
  • 00:01:52 want to make sure I open the Mon when I
  • 00:01:53 click the button one convenient way of
  • 00:01:56 course is to simply reach out to my
  • 00:01:58 modal and store it in a variable – with
  • 00:02:00 queryselector and now my modal and I can
  • 00:02:04 use my own custom element tag here just
  • 00:02:08 like I could use button because it's a
  • 00:02:09 normal HTML element now my custom
  • 00:02:12 element but here to JavaScript in zone
  • 00:02:15 it's like a regular element I can select
  • 00:02:17 it like this and I could set my modal
  • 00:02:19 excuse-me modeless the name of the
  • 00:02:21 variable modal style display to block
  • 00:02:25 because it's non by default block should
  • 00:02:27 show it if I now save everything and I
  • 00:02:30 clicked this button we see the model
  • 00:02:32 without the backdrop because we
  • 00:02:34 commented this out we'll work on this
  • 00:02:36 but this is the modal this is one way of
  • 00:02:39 doing this however there's also another
  • 00:02:42 way which might be more convenient in
  • 00:02:44 average
  • 00:02:44 use cases would it be nice if our modal
  • 00:02:46 just had something like open method we
  • 00:02:49 could call I know it's a HTML element
  • 00:02:53 but still maybe we could execute some
  • 00:02:55 method on that open like we can call
  • 00:02:59 button click on a normal HTML element to
  • 00:03:04 expose such a method you can call from
  • 00:03:06 outside I'll go into the modal and I
  • 00:03:09 will import a new decorator it's called
  • 00:03:13 method and I will use this method inside
  • 00:03:17 of my class with the method decorator
  • 00:03:20 and opening and closing parenthesis and
  • 00:03:21 attach it to a method I add to this
  • 00:03:24 typescript class I'll name it open the
  • 00:03:27 cool thing is I could create a method
  • 00:03:30 like this anyways but by adding the
  • 00:03:32 method decorator to it I make it call
  • 00:03:35 from outside though like I planted you
  • 00:03:39 by simply calling modal open this will
  • 00:03:43 be possible because open is a method
  • 00:03:45 decorated with the method decorator and
  • 00:03:48 hence callable now in there I could
  • 00:03:51 change the style but I need to change
  • 00:03:53 the style of the element itself
  • 00:03:56 conveniently there all this a decorator
  • 00:03:58 for this the element decorator I can
  • 00:04:02 simply use this and assign it to a
  • 00:04:06 normal property which I'll name modal l
  • 00:04:08 but the name is up to you which will be
  • 00:04:10 of type HTML element and I assign no
  • 00:04:13 value the value will be set
  • 00:04:16 automatically by stance or so to say and
  • 00:04:18 it will be the element itself this
  • 00:04:21 allows me to access it here and say
  • 00:04:23 mol/l style display is try it is by his
  • 00:04:27 german equals block will block like this
  • 00:04:32 so with that I got my open method and
  • 00:04:37 now if I reload the page and I click
  • 00:04:40 this button I still open it but now on a
  • 00:04:43 different way I call this open method
  • 00:04:46 which is exposed to the public where I
  • 00:04:48 then changed the style from with it so
  • 00:04:50 these are two new decorators you learn
  • 00:04:52 about element and method now you
  • 00:04:55 probably want to pass some data when
  • 00:04:58 giving this is to go to the index.html
  • 00:05:00 file and maybe you want to set a title
  • 00:05:02 which could be info and some content
  • 00:05:05 which could be this is an important in
  • 00:05:09 formation so we want to set two
  • 00:05:13 attributes on our custom element to pass
  • 00:05:17 in some data now to do this I'll go back
  • 00:05:21 to my model and you saw this earlier
  • 00:05:23 there's never decorated we can use the
  • 00:05:26 prop decorator and I can use this to
  • 00:05:29 attach it to properties of this class
  • 00:05:31 like to the title property which will be
  • 00:05:33 a string and also to the content which
  • 00:05:37 will be a string and this allows me to
  • 00:05:40 then output this here so I'll get rid of
  • 00:05:42 this for now use parentheses to nicely
  • 00:05:45 wrap this and in there I now want to
  • 00:05:48 have a div which wraps this though
  • 00:05:50 theoretically you could always return an
  • 00:05:52 array here
  • 00:05:53 so unlike and react at least prior to
  • 00:05:55 react 16 you can return an array but
  • 00:05:58 I'll still wrap it here and I'll give a
  • 00:06:00 h1 tag where I now use this type of data
  • 00:06:04 binding which you also might know from
  • 00:06:06 react single curly braces and there I
  • 00:06:09 want to output this title and then I'll
  • 00:06:13 add a paragraph where I output this
  • 00:06:16 content and the single quality braces
  • 00:06:19 allow you to mix your JSX code with
  • 00:06:22 references to your CF CSS to your
  • 00:06:25 typescript class if you now save this
  • 00:06:27 and you open the modal you see info this
  • 00:06:30 is an important information now this is
  • 00:06:34 already nice maybe add some padding to
  • 00:06:36 this modal though it's all sitting on
  • 00:06:38 the edge so in the S CSS file I'll add
  • 00:06:40 padding 16 pixels maybe just a little
  • 00:06:43 styling to make this a bit nicer to view
  • 00:06:46 so that's important that's of course
  • 00:06:49 nice what else can we do though well
  • 00:06:52 maybe we want to have a button in there
  • 00:06:53 which allows us to close the modal and
  • 00:06:56 maybe we want to make this super
  • 00:06:58 complicated and have a button which
  • 00:07:00 allows us to show the button which
  • 00:07:02 closes the modal eventually so we could
  • 00:07:05 add let's say a horizontal line in there
  • 00:07:08 and then a button and here we could say
  • 00:07:10 show up
  • 00:07:12 now let's style that button a little bit
  • 00:07:14 so in my Model S CSS file
  • 00:07:16 I'll nest the button selector inside in
  • 00:07:19 my modal selector and there I'll remove
  • 00:07:22 the background color by setting it to
  • 00:07:24 transparent I'll remove the borders by
  • 00:07:27 setting it to non and I will also set
  • 00:07:30 the outline to non I will also set the
  • 00:07:35 font to inherit so to use the ah font we
  • 00:07:40 have up here Arial and so on if we save
  • 00:07:43 all that reload the page
  • 00:07:45 oops make sure to save DT as X file to
  • 00:07:49 here we see show options options look
  • 00:07:51 like it looks like this now we need more
  • 00:07:54 styling we should add cursor:pointer
  • 00:07:56 here to make it look like a pointer when
  • 00:07:58 we hover over it and let's maybe add a
  • 00:08:00 color like this orange color with fa9
  • 00:08:04 q3f as a hex code with that we got the
  • 00:08:09 show options button which doesn't do
  • 00:08:11 anything when we click it now when you
  • 00:08:13 click it as I said I want to show the
  • 00:08:15 options below it so what we can do for
  • 00:08:18 that is we can go to my model tsx and
  • 00:08:20 first of all let's add a normal property
  • 00:08:23 up there so maybe add it at the very top
  • 00:08:26 I'll name this one buttons and shall be
  • 00:08:30 an array where I have two strings like
  • 00:08:32 ok and cancel so that's my array and it
  • 00:08:37 isn't decorated with prop or anything
  • 00:08:39 like that I also want to add a new
  • 00:08:43 property which shall named show options
  • 00:08:46 and this will be set to false initially
  • 00:08:49 now with that I want to listen to a
  • 00:08:51 click on this button and I do this by
  • 00:08:53 adding on click to it now on click takes
  • 00:08:58 these single curly braces and then a
  • 00:09:00 reference to the method you want to
  • 00:09:02 execute so that could be show options
  • 00:09:06 handler and the handler at the end it is
  • 00:09:09 optional it's kind of the convention you
  • 00:09:11 see right now instantly components like
  • 00:09:13 and react that you name the methods
  • 00:09:15 triggered by your own listeners here
  • 00:09:19 with handler at the end now in there I
  • 00:09:23 could set this
  • 00:09:25 show options to true so this property I
  • 00:09:28 created here now all we need to do is
  • 00:09:31 use the property to show more options so
  • 00:09:35 here I could use a horizontal line again
  • 00:09:38 and then I want to output all the
  • 00:09:41 buttons I have here now since I stored
  • 00:09:43 them in a property what I can do is I
  • 00:09:47 can use these single curly braces to
  • 00:09:49 output this buttons and then just like
  • 00:09:52 in react I want to loop through all of
  • 00:09:54 them and basically output an element for
  • 00:09:56 each element in the array
  • 00:09:58 technically what I'll do is I'll map
  • 00:10:01 this array of strings into an array of
  • 00:10:05 HTML elements of JSX
  • 00:10:08 elements to be precise I do this by
  • 00:10:10 calling the map method and there we have
  • 00:10:14 a function which gets executed
  • 00:10:15 automatically it's an arrow function
  • 00:10:17 here but you could use a normal one
  • 00:10:19 which will get executed for each element
  • 00:10:21 in that array and give me that element
  • 00:10:23 in each function call so a single button
  • 00:10:26 so it will loop through all the elements
  • 00:10:29 in this array and button therefore is
  • 00:10:31 just a string so then I'll use
  • 00:10:35 parentheses to structure this over
  • 00:10:36 multiple lines I'll simply output a
  • 00:10:39 button element here and in there I'll
  • 00:10:43 again use single curly braces to output
  • 00:10:45 button which is just string keep this in
  • 00:10:48 mind so this will be the caption of the
  • 00:10:49 button this should only happen if I
  • 00:10:53 click this button here though so there
  • 00:10:56 they call this show options Handler and
  • 00:10:59 just like you might know it from react
  • 00:11:01 again you need to bind this on this
  • 00:11:05 method call otherwise it won't work
  • 00:11:07 because this in show options handler
  • 00:11:11 will not refer to your class here if
  • 00:11:14 this is called at run time if you're not
  • 00:11:17 finding this during development already
  • 00:11:20 so there was a lot of work if we save
  • 00:11:24 this we see that if we reload this and
  • 00:11:28 up the pub modal we immediately see more
  • 00:11:30 options which makes sense because we
  • 00:11:34 have no logic to only conditionally show
  • 00:11:36 them so I want to add this logic now
  • 00:11:39 q at this logic we still use the same
  • 00:11:43 concept use and react
  • 00:11:45 there is no directive like we have an
  • 00:11:47 angler or view there is no ng if instead
  • 00:11:51 since we simply use JavaScript here in
  • 00:11:55 the end in the render method we can
  • 00:11:57 create a variable which will name
  • 00:11:59 options that by default it's null so so
  • 00:12:01 nothing then I will check if this show
  • 00:12:07 options if this is true then I want you
  • 00:12:12 cut the code from down there and set
  • 00:12:15 options equal Q it whips wrapped in
  • 00:12:20 parentheses what this basically means is
  • 00:12:24 that and I know this can can look
  • 00:12:26 strange if Ural looking at this the
  • 00:12:27 first time the PI default this variable
  • 00:12:30 is null but if this show options is true
  • 00:12:33 we said it equal Q it looks like to HTML
  • 00:12:36 but keep in mind that's just a nicer
  • 00:12:38 syntax for JavaScript here so we sent an
  • 00:12:42 equal Q an array of buttons and now we
  • 00:12:45 can simply use this options variable
  • 00:12:48 down there in our JSX code to output it
  • 00:12:52 and it's even now if show options is
  • 00:12:55 false this will never be overwritten and
  • 00:12:57 then we actually don't want to output
  • 00:12:59 anything but if show options is true
  • 00:13:02 options will be an array of buttons and
  • 00:13:05 we will render the buttons now let's
  • 00:13:07 save this file and reload this page and
  • 00:13:10 open the modal and if you click show
  • 00:13:11 options nothing happens this actually is
  • 00:13:16 to be expected stands for by default
  • 00:13:18 isn't watching all your properties for
  • 00:13:21 changes and doesn't rerender the Dom the
  • 00:13:25 element if one of your properties
  • 00:13:27 changes you have to tell it to
  • 00:13:29 explicitly Ted watch one like show
  • 00:13:32 options when show options changes we as
  • 00:13:36 a developer know that this impacts our
  • 00:13:39 template so to say our JSX code because
  • 00:13:42 we use show options to decide what we
  • 00:13:44 want to output buttons or not
  • 00:13:46 so stancil should actually watch show
  • 00:13:50 options we can tell it to do so
  • 00:13:53 by adding another import state and we
  • 00:13:57 decorate show options with at state this
  • 00:14:01 might look similar to you from react
  • 00:14:03 again there you also have state and if
  • 00:14:05 you change state it rear Enders your
  • 00:14:09 code here and react all the re-renders
  • 00:14:12 of one of your props changes and that
  • 00:14:14 would be the case here at you if this
  • 00:14:17 changes set from outside of course it
  • 00:14:19 would also rerender your template so now
  • 00:14:23 since show options now is decorated with
  • 00:14:27 state whenever we change it like this it
  • 00:14:30 will rerender and if you were coming
  • 00:14:32 from react you don't need to call this
  • 00:14:35 set state or anything like that you just
  • 00:14:37 change it like this if we now save this
  • 00:14:39 and we reload the page and open the
  • 00:14:42 model now if I click show options
  • 00:14:44 it shows the options and I can toggle it
  • 00:14:47 there now always there you could of
  • 00:14:49 course alter the code to make this a
  • 00:14:51 toggle functionality and set show
  • 00:14:53 options to true if it's false and the
  • 00:14:55 other way around now with the option set
  • 00:14:58 of course want you close the modal
  • 00:15:00 whenever I click OK or cancel for this I
  • 00:15:04 simply need to add an onclicklistener to
  • 00:15:07 my buttons and there I want to execute a
  • 00:15:11 method which will name closed modal
  • 00:15:14 handler again handler because it's
  • 00:15:16 triggered from inside basically it's not
  • 00:15:18 decorated with method and in there I
  • 00:15:21 simply want to copy that code where I
  • 00:15:23 set it to block and set it to non again
  • 00:15:25 and here I will simply then call this on
  • 00:15:31 excuse me not on closed modal Handler
  • 00:15:35 and find this again and you could use an
  • 00:15:39 arrow function your tool I can react if
  • 00:15:41 you are coming from that background so
  • 00:15:44 with that if we now saved us one more
  • 00:15:46 time and real otis click show options ok
  • 00:15:49 and cancel should both get rid of it and
  • 00:15:52 we always see that if we reopen it
  • 00:15:54 because we never have logic to switch
  • 00:15:56 show options back to false we could of
  • 00:15:59 course do this as part of the close mole
  • 00:16:01 handler we could set this show options
  • 00:16:04 back to false so that the next time we
  • 00:16:07 this model the options aren't there
  • 00:16:10 anymore so whatever doing a lot let's go
  • 00:16:13 back to the modal which were not really
  • 00:16:16 seeing we simply or if you also want to
  • 00:16:19 open the modal well what we can do is we
  • 00:16:22 called modal open here using the
  • 00:16:25 backdrop I want to show the backdrop I
  • 00:16:27 can comment it in again now it's always
  • 00:16:29 there and we can't click the button
  • 00:16:30 anymore so first of all let's go to the
  • 00:16:33 backdrop and we can basically do this
  • 00:16:36 just like we did it with the modal we
  • 00:16:38 can make sure that we implemented we set
  • 00:16:41 the display to non by default add an
  • 00:16:44 open method and call the open method
  • 00:16:46 like we called modal open nothing wrong
  • 00:16:48 with that in the next video I want to
  • 00:16:51 show you how you nest components though
  • 00:16:53 and how you can then let the components
  • 00:16:56 interact with each other