1 00:00:02,200 --> 00:00:07,750 Let's put the input elements into their own components, for that I'll go into my components folder and there 2 00:00:07,750 --> 00:00:11,010 we have that UI folder which I created a long time ago. 3 00:00:11,310 --> 00:00:14,850 Now in there, I'll create a new subfolder which I'll name input, 4 00:00:14,860 --> 00:00:20,470 you could even create a new subfolder which you named forms where you then create the input subfolder 5 00:00:20,830 --> 00:00:23,260 but I'll go with this approach. In there, 6 00:00:23,260 --> 00:00:29,930 I obviously want to create an input.js file and the input.css file for the styling, 7 00:00:29,930 --> 00:00:34,330 and now let's think about the input component, the input.js file. 8 00:00:34,510 --> 00:00:36,280 I want to use the functional form, 9 00:00:36,280 --> 00:00:43,010 so I'll create an input function which takes some props and which in the end of course will return jsx code. 10 00:00:43,060 --> 00:00:50,050 For that reason as always, we need to import react from the react package and then we'll export this 11 00:00:50,110 --> 00:00:54,340 input function as the default of this file. 12 00:00:54,340 --> 00:00:57,640 Now regarding the jsx code we want to return there, 13 00:00:57,700 --> 00:01:00,150 I actually want to use a div as an input, 14 00:01:00,180 --> 00:01:03,650 now not as the input element itself but as a container for it 15 00:01:03,650 --> 00:01:06,270 because I will have multiple elements in there. 16 00:01:06,490 --> 00:01:11,520 I want to have a label element where of course we set the label from outside, 17 00:01:11,590 --> 00:01:18,450 so I'll add a prop I expect to get on my custom input component which you can name label. 18 00:01:18,720 --> 00:01:21,870 Thereafter, I of course want to have my input element, 19 00:01:21,880 --> 00:01:28,240 now this is not even super flexible because it only allows input elements, if we want to write a more 20 00:01:28,240 --> 00:01:31,180 generic way or more generic method, 21 00:01:31,270 --> 00:01:38,500 we should actually turn this function here which just returns jsx into a function which has a real 22 00:01:38,500 --> 00:01:46,330 function body where we also return jsx of course, but where we also have some check before we do so, where 23 00:01:46,330 --> 00:01:48,870 we check what our input really is. 24 00:01:48,880 --> 00:01:56,920 So we could have a switch statement here where we maybe switch props and then input type or any property 25 00:01:56,920 --> 00:02:05,440 name of your choice and then we could handle cases like input, where we then in the end set our variable 26 00:02:05,440 --> 00:02:15,130 which I create, a variable named input element which is null initially to let's say here input element 27 00:02:15,940 --> 00:02:19,330 equals input, something like that, 28 00:02:19,330 --> 00:02:22,000 we definitely need to add more values there. 29 00:02:22,240 --> 00:02:30,070 So this is a more generic approach we can set up and you can reach any amount of complexity here because 30 00:02:30,070 --> 00:02:35,020 now of course, you also have different attributes per element you might have 31 00:02:35,020 --> 00:02:41,350 so if you also have the case text area, a text area doesn't take the same inputs or the same attributes 32 00:02:41,770 --> 00:02:44,000 as a normal input element does. 33 00:02:44,020 --> 00:02:52,150 So here if we add text area and therefore we set input element equal to text area, 34 00:02:52,150 --> 00:02:55,830 now we all of a sudden might face certain restrictions, 35 00:02:55,960 --> 00:02:59,760 as a side note, a text area is a self-closing element in react. 36 00:02:59,770 --> 00:03:06,880 So this is some complexity we'll have to handle either by creating multiple custom components for the different 37 00:03:06,910 --> 00:03:08,470 input types you might have 38 00:03:08,560 --> 00:03:14,940 so that we basically have a wrapper component for normal inputs, for text areas, whatever 39 00:03:15,100 --> 00:03:19,360 or by simply adding such a switch statement here. 40 00:03:19,360 --> 00:03:25,140 Now go for the switch statement approach and I'll also add a break after this one 41 00:03:25,570 --> 00:03:34,380 and here too and maybe return a default here where we have input element equals input. 42 00:03:34,520 --> 00:03:40,460 And now to handle the case that we also have different attributes, I expect to get the attributes you 43 00:03:40,460 --> 00:03:44,990 want to set on input as props for our input wrapper. 44 00:03:45,200 --> 00:03:49,340 This then allows me to simply distribute them on the input element, 45 00:03:49,340 --> 00:03:53,360 so any default html attributes you want to set on your input, 46 00:03:53,510 --> 00:03:59,420 you only need to set the input type prop and then you pass the normal attributes you would pass to that 47 00:03:59,450 --> 00:04:00,060 type, 48 00:04:00,230 --> 00:04:05,270 so if you have a text area, you simply pass the normal props you want it to pass from outside and 49 00:04:05,300 --> 00:04:11,840 inside of my custom input component, I don't have to worry about which exact type we have. 50 00:04:11,840 --> 00:04:17,880 I rely on you using the wrapper correctly and passing the correct normal html attributes, 51 00:04:17,930 --> 00:04:23,970 this is a way of reducing the complexity here so that I only have to set the right element 52 00:04:24,140 --> 00:04:27,330 and then you take care about the props. 53 00:04:27,350 --> 00:04:32,300 Now we can add more elements here of course, we can add a dropdown, a select element and so on, 54 00:04:32,300 --> 00:04:40,810 for now let's go with this set up and now I want to output my input elements here, so inputElement 55 00:04:40,850 --> 00:04:46,800 this variable where I store either the input or the text area, that's getting output here. 56 00:04:47,150 --> 00:04:48,470 And that's it for now, 57 00:04:48,470 --> 00:04:52,410 we might revisit this later but for now, this is the set up I want to use. 58 00:04:52,700 --> 00:04:55,180 Obviously I also want to style this now, 59 00:04:55,280 --> 00:04:58,160 so I'll now also go to my input.css file 60 00:04:58,250 --> 00:05:01,630 and there, I'll add my custom Input class with a capital I. 61 00:05:01,810 --> 00:05:10,340 Now in here, I first of all want to make sure that the div which I will use to assign this class wraps 62 00:05:10,340 --> 00:05:13,710 the full width of the available space, 63 00:05:13,820 --> 00:05:14,970 so 100%, 64 00:05:14,970 --> 00:05:23,930 let's say. I also in here want to set up some padding let's say 10px, so that we automatically also 65 00:05:23,930 --> 00:05:29,600 have some distance to any element sitting above or beneath my input. 66 00:05:29,600 --> 00:05:38,870 I will also set the box-sizing to border-box thereafter, and with that set up, I can now style the elements 67 00:05:38,960 --> 00:05:39,910 in there. 68 00:05:40,310 --> 00:05:45,280 So here we obviously have the label and then we have an input or a text area, 69 00:05:45,290 --> 00:05:49,830 now I will simply use different classes for that too. 70 00:05:49,880 --> 00:05:58,430 So I'll add a label class here and my label should have a font-weight which is bold, so we'll have a fat 71 00:05:58,520 --> 00:06:02,650 label, my day label should also be of display blocks so 72 00:06:02,690 --> 00:06:10,230 we take the full width to take its own line, its own row in our html document so to say. 73 00:06:10,670 --> 00:06:18,990 I also want to have a little bit of margin to the bottom, so to the input element of let's say 8px 74 00:06:19,130 --> 00:06:21,130 and with that, that's it for my label. 75 00:06:21,410 --> 00:06:29,360 Then I'll add my input element styling here and there, you might need different classes for different 76 00:06:29,360 --> 00:06:31,370 types of input elements of course, 77 00:06:31,370 --> 00:06:33,060 now here I set up a generic one. 78 00:06:33,140 --> 00:06:40,710 I don't want to have an outline so outline none, I want to set the border to 1px solid and this 79 00:06:40,720 --> 00:06:42,020 gray look, 80 00:06:42,020 --> 00:06:45,770 I want to set the background color to white, 81 00:06:45,770 --> 00:06:52,750 I also want to set the font to inherit to use the normal font settings we have for the rest of the application, 82 00:06:53,060 --> 00:06:59,120 I want to set up some padding let's say 6px from top and bottom and 10px from left and right, 83 00:06:59,410 --> 00:07:01,790 and let's also take care about the output element 84 00:07:01,790 --> 00:07:09,380 when we focused it with the focus pseudo selector, there I want to set the outline to none but I want to 85 00:07:09,380 --> 00:07:11,680 set the background color to 86 00:07:11,780 --> 00:07:15,060 let's say this gray-ish look here too. 87 00:07:15,290 --> 00:07:18,040 Now you can of course define way more styles, 88 00:07:18,110 --> 00:07:26,120 you can add a disabled cell or whatever you want to do, I'll simply create a not super complex input 89 00:07:26,150 --> 00:07:27,090 element wrapper, 90 00:07:27,140 --> 00:07:32,340 you can definitely go all in here and create an extremely complex one. 91 00:07:32,360 --> 00:07:40,390 Now with that, I'll assign my created class here to all these elements, so here with class name, I'll assign 92 00:07:40,430 --> 00:07:42,700 the input element class 93 00:07:42,710 --> 00:07:49,160 I just set up and for that of course, I first of all need to import my classes from the css file, so import 94 00:07:49,160 --> 00:07:57,180 classes from ./input.css and then again, add them to all my elements here with classes 95 00:07:57,410 --> 00:08:00,290 and there it was, input element. Of course 96 00:08:00,290 --> 00:08:03,090 now, I also want to assign a class to the div 97 00:08:03,170 --> 00:08:08,500 so class name here is classes.Input whilst the class name 98 00:08:08,630 --> 00:08:10,890 and we defined one forward to label too, 99 00:08:11,030 --> 00:08:14,060 here it should be classes.Label 100 00:08:14,180 --> 00:08:18,430 and now I just realized I forgot something for the input element class, here 101 00:08:18,470 --> 00:08:25,850 the input element should also be display block and just should take the full available width, let's say, so that it 102 00:08:25,910 --> 00:08:28,950 really takes the full width it can take. 103 00:08:29,030 --> 00:08:35,270 Now with that set up, let's go back to our contact data page and let's use our custom input element now. 104 00:08:35,570 --> 00:08:44,870 So here, I will now quickly import input from and then navigate into the components folder and there 105 00:08:44,870 --> 00:08:52,330 into the UI folder and then into the input folder and to take that input element and of course now use that 106 00:08:52,360 --> 00:08:54,250 input. So I'll take it, 107 00:08:54,250 --> 00:08:55,320 go down to my 108 00:08:55,360 --> 00:08:58,700 inputs here and I'll replace input 109 00:08:58,710 --> 00:09:02,850 here in that set up with my own input element. 110 00:09:03,220 --> 00:09:09,700 I can now get rid of my class here of the input class because the input element already has some styling, 111 00:09:09,750 --> 00:09:16,560 the styling we just set up, so I can also get rid of the input styling here in my contact data css 112 00:09:16,620 --> 00:09:17,260 file, 113 00:09:17,290 --> 00:09:20,220 it was only the block type. 114 00:09:20,230 --> 00:09:27,370 But all the other things here, placeholder and so on should really be passed on now because we pass 115 00:09:27,370 --> 00:09:30,640 on props, that is what we define in our input component. 116 00:09:30,670 --> 00:09:34,670 One additional prop we have to pass is the input type now, 117 00:09:34,840 --> 00:09:40,950 so I'll quickly do that, I'll set input type on all these inputs and they should be normal inputs here, 118 00:09:40,990 --> 00:09:44,710 so I'll simply set it to input, like this. 119 00:09:44,710 --> 00:09:48,480 Now let's save this, let's have a look at our running application, 120 00:09:48,520 --> 00:09:54,970 so make sure npm start is running and thereafter if you visit your burger and you create one here, 121 00:09:55,030 --> 00:09:57,770 go to the checkout page and continue, 122 00:09:57,850 --> 00:10:04,380 we got an error here which you can take care about in a second but we see that our styling is applied. 123 00:10:04,400 --> 00:10:06,840 Now there's one extra styling rule we have to add, 124 00:10:06,880 --> 00:10:14,560 just realized, the input element also should receive box-sizing border box so that the width is calculated 125 00:10:14,560 --> 00:10:15,700 correctly. 126 00:10:15,700 --> 00:10:17,560 Now the styling is all right, 127 00:10:17,560 --> 00:10:22,710 we can also see that we can highlight these and put elements but what about this error. 128 00:10:23,040 --> 00:10:31,650 Now this error message is stemming from a change in react 16, it does pass on all props here and input 129 00:10:31,700 --> 00:10:36,670 type due to its casing is not reusable as a default 130 00:10:36,700 --> 00:10:41,760 html prop because html in the dom is case insensitive, 131 00:10:42,010 --> 00:10:46,170 therefore it throws this error. In the past prior to react 16, 132 00:10:46,330 --> 00:10:49,790 it wouldn't have passed on this type prop which it doesn't know. 133 00:10:49,870 --> 00:10:54,810 Now it does and it warns us that this is then invalid because of the casing, 134 00:10:55,000 --> 00:11:01,120 so one way to fix this is to simply change this to input type, 135 00:11:01,390 --> 00:11:05,780 all lowercase, this is a quick and easy fix for this issue 136 00:11:05,830 --> 00:11:10,120 if we use that and of course also use it here when assigning this, 137 00:11:10,270 --> 00:11:12,980 now we should see that we no longer get this error 138 00:11:13,030 --> 00:11:16,680 and you can see that our props like the placeholder are passed on. 139 00:11:16,690 --> 00:11:18,990 So that is our wrapping input element 140 00:11:19,000 --> 00:11:20,080 created, 141 00:11:20,080 --> 00:11:24,480 now let's see how we can handle different types of data with it 142 00:11:24,700 --> 00:11:28,390 and let's create a real form with the data we actually need.