Let's put the input elements into their own components, for that I'll go into my components folder and there
we have that UI folder which I created a long time ago.
Now in there, I'll create a new subfolder which I'll name input,
you could even create a new subfolder which you named forms where you then create the input subfolder
but I'll go with this approach. In there,
I obviously want to create an input.js file and the input.css file for the styling,
and now let's think about the input component, the input.js file.
I want to use the functional form,
so I'll create an input function which takes some props and which in the end of course will return jsx code.
For that reason as always, we need to import react from the react package and then we'll export this
input function as the default of this file.
Now regarding the jsx code we want to return there,
I actually want to use a div as an input,
now not as the input element itself but as a container for it
because I will have multiple elements in there.
I want to have a label element where of course we set the label from outside,
so I'll add a prop I expect to get on my custom input component which you can name label.
Thereafter, I of course want to have my input element,
now this is not even super flexible because it only allows input elements, if we want to write a more
generic way or more generic method,
we should actually turn this function here which just returns jsx into a function which has a real
function body where we also return jsx of course, but where we also have some check before we do so, where
we check what our input really is.
So we could have a switch statement here where we maybe switch props and then input type or any property
name of your choice and then we could handle cases like input, where we then in the end set our variable
which I create, a variable named input element which is null initially to let's say here input element
equals input, something like that,
we definitely need to add more values there.
So this is a more generic approach we can set up and you can reach any amount of complexity here because
now of course, you also have different attributes per element you might have
so if you also have the case text area, a text area doesn't take the same inputs or the same attributes
as a normal input element does.
So here if we add text area and therefore we set input element equal to text area,
now we all of a sudden might face certain restrictions,
as a side note, a text area is a self-closing element in react.
So this is some complexity we'll have to handle either by creating multiple custom components for the different
input types you might have
so that we basically have a wrapper component for normal inputs, for text areas, whatever
or by simply adding such a switch statement here.
Now go for the switch statement approach and I'll also add a break after this one
and here too and maybe return a default here where we have input element equals input.
And now to handle the case that we also have different attributes, I expect to get the attributes you
want to set on input as props for our input wrapper.
This then allows me to simply distribute them on the input element,
so any default html attributes you want to set on your input,
you only need to set the input type prop and then you pass the normal attributes you would pass to that
type,
so if you have a text area, you simply pass the normal props you want it to pass from outside and
inside of my custom input component, I don't have to worry about which exact type we have.
I rely on you using the wrapper correctly and passing the correct normal html attributes,
this is a way of reducing the complexity here so that I only have to set the right element
and then you take care about the props.
Now we can add more elements here of course, we can add a dropdown, a select element and so on,
for now let's go with this set up and now I want to output my input elements here, so inputElement
this variable where I store either the input or the text area, that's getting output here.
And that's it for now,
we might revisit this later but for now, this is the set up I want to use.
Obviously I also want to style this now,
so I'll now also go to my input.css file
and there, I'll add my custom Input class with a capital I.
Now in here, I first of all want to make sure that the div which I will use to assign this class wraps
the full width of the available space,
so 100%,
let's say. I also in here want to set up some padding let's say 10px, so that we automatically also
have some distance to any element sitting above or beneath my input.
I will also set the box-sizing to border-box thereafter, and with that set up, I can now style the elements
in there.
So here we obviously have the label and then we have an input or a text area,
now I will simply use different classes for that too.
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
label, my day label should also be of display blocks so
we take the full width to take its own line, its own row in our html document so to say.
I also want to have a little bit of margin to the bottom, so to the input element of let's say 8px
and with that, that's it for my label.
Then I'll add my input element styling here and there, you might need different classes for different
types of input elements of course,
now here I set up a generic one.
I don't want to have an outline so outline none, I want to set the border to 1px solid and this
gray look,
I want to set the background color to white,
I also want to set the font to inherit to use the normal font settings we have for the rest of the application,
I want to set up some padding let's say 6px from top and bottom and 10px from left and right,
and let's also take care about the output element
when we focused it with the focus pseudo selector, there I want to set the outline to none but I want to
set the background color to
let's say this gray-ish look here too.
Now you can of course define way more styles,
you can add a disabled cell or whatever you want to do, I'll simply create a not super complex input
element wrapper,
you can definitely go all in here and create an extremely complex one.
Now with that, I'll assign my created class here to all these elements, so here with class name, I'll assign
the input element class
I just set up and for that of course, I first of all need to import my classes from the css file, so import
classes from ./input.css and then again, add them to all my elements here with classes
and there it was, input element. Of course
now, I also want to assign a class to the div
so class name here is classes.Input whilst the class name
and we defined one forward to label too,
here it should be classes.Label
and now I just realized I forgot something for the input element class, here
the input element should also be display block and just should take the full available width, let's say, so that it
really takes the full width it can take.
Now with that set up, let's go back to our contact data page and let's use our custom input element now.
So here, I will now quickly import input from and then navigate into the components folder and there
into the UI folder and then into the input folder and to take that input element and of course now use that
input. So I'll take it,
go down to my
inputs here and I'll replace input
here in that set up with my own input element.
I can now get rid of my class here of the input class because the input element already has some styling,
the styling we just set up, so I can also get rid of the input styling here in my contact data css
file,
it was only the block type.
But all the other things here, placeholder and so on should really be passed on now because we pass
on props, that is what we define in our input component.
One additional prop we have to pass is the input type now,
so I'll quickly do that, I'll set input type on all these inputs and they should be normal inputs here,
so I'll simply set it to input, like this.
Now let's save this, let's have a look at our running application,
so make sure npm start is running and thereafter if you visit your burger and you create one here,
go to the checkout page and continue,
we got an error here which you can take care about in a second but we see that our styling is applied.
Now there's one extra styling rule we have to add,
just realized, the input element also should receive box-sizing border box so that the width is calculated
correctly.
Now the styling is all right,
we can also see that we can highlight these and put elements but what about this error.
Now this error message is stemming from a change in react 16, it does pass on all props here and input
type due to its casing is not reusable as a default
html prop because html in the dom is case insensitive,
therefore it throws this error. In the past prior to react 16,
it wouldn't have passed on this type prop which it doesn't know.
Now it does and it warns us that this is then invalid because of the casing,
so one way to fix this is to simply change this to input type,
all lowercase, this is a quick and easy fix for this issue
if we use that and of course also use it here when assigning this,
now we should see that we no longer get this error
and you can see that our props like the placeholder are passed on.
So that is our wrapping input element
created,
now let's see how we can handle different types of data with it
and let's create a real form with the data we actually need.