Now that we have a machine defined we need to send it events with the relevant data from the UI. To do this we'll need to install the useMachine hook from @zag-js/react
. From there we'll wire up the actions that we need to send on the input element (e.g. onChange, onFocus, onBlur, and onKeyDown).
Segun Adebayo: [0:01] Now that we've modeled the logic of the PinInput component, let's connect it over to the UI we see here on the right. The first thing I'm going to do is to export the machine from here, and we head over to the UI here.
[0:16] Before we start to connect the logic, let's refactor the Inputs here. You see we're rendering four different Inputs. Let's refactor this to an array and map through that.
[0:25] I'll create a variable called Inputs, and I would create an array from length. Since we have four Inputs there, we put a length of four and grab all the keys, which gives us an array of all of the index or indices of the Inputs.
[0:45] Here, we're going to map through the Inputs, grab the index from there, and then render the Input like so. Because we are using an array here, we just put in a key and put the index in there.
[0:58] Now, there are a couple of attributes that we need from the Input component to bind that to the machine.
[1:04] To consume the machine within React, we need to install @zag.js/react. When we run that code now, we install @zag.js/react, which gives us the binding that we need to connect the machine to the React application.
[1:18] From @zag.js/react, I'm going to import the useMachine hook, and in here, we're going to grab the state and the send from the useMachine hook and put it in the machine we just created. The useMachine hook returns two array parameters.
[1:38] The first one is State, which represents the current state of the machine. The second one is Send, which we can use to dispatch events to the machine.
[1:47] From the State, we're going to destructure out the value and the focus index we created earlier. Currently, that lives in context. Then what we're going to do here, we're literally going to set up a pre-tag, which we can do a JSON.stringify() of the value and the focus index.
[2:07] Now, with that in place, we are pretty much ready to sync up the Inputs UI and the machine itself. I'll start with the Input here.
[2:17] Let's set the value of the Input here. Because we are within a loop here, we can sync to the value and grab the index, the value at the specific index we care about. The value here is a string array, basically just grabbing the index that matches that one there.
[2:34] The next thing is we're going to create the onchange event, which is the event that gets triggered when the nput event fires when you try to type within the Input itself.
[2:45] We can rename this to event here and then we can grab the value from that, which is the event.target. Then from here, we can send the Input event to the machine, passing in the index as well as the value.
[3:07] This way, the machine now has access to the value, the index and knows which event you're currently syncing with within the machine itself.
[3:17] The next thing is onfocus. Here, for the focus event, we're basically going to send in an event type of focus and then we also pass in the index. That means, we really don't need the event from here. We're just going to send the focus. Then onblur, we're also going to just send in a type of blur.
[3:46] Now, if we double-check with the machine itself and look through all the state transitions, we definitely have one more here which is the backspace event and also the paste event. Let's sync up the backspace event.
[4:00] The backspace event is fired on key down here. Let's just put on key down. Grab the event from there. Then we do a quick check on the event's key. Then we can check that if the event key is equal to escape, with that in place, we can send the event to the machine backspace, and also passing in the index as well.
[4:29] The next event we care about is the paste event. We see here when the paste event is triggered, we want to send...First of all, let's try to get the pasted value. The pasted value currently lives in event.clipboarddata.getdata and we can put in here text.
[4:48] This way, we actually have the text version of the pasted information, and we can then send in the event type of paste and then forward in the value and as well as the index. Now we have all the different paths we need.
[5:06] To verify that this works correctly, let's just structure out the event from the state. From the state event, we're going to grab the type of the event. Then within here, we're also going to log out event and map that in there.
[5:25] If we switch over to the UI, we see that there is the event property there. Now, the initial event is machine.init when the machine starts. If I focus on this, you can see that there is now an event called focus, and if we click out, the blur event is sent to the machine.
[5:44] This verifies that everything works as expected. Now, we can go ahead to write the implementations for all of the different logic you have in place.