In this chapter we're going to focus on creating the fragment view component and this entire chapter is pretty straightforward. We just have to create an ability to view that E2B sandbox URL. So let's go ahead and do that. As always ensure that you're on your main branch and synchronize changes to make sure everything is up to date. The last chapter was chapter 11.
So now let's go ahead inside of source and basically just find project view. There we go. Inside of this project view go inside of your second resizable panel and in here render the fragment web component. We're only going to render this if we have an active fragment. So if you have an active fragment, only then render the fragment web.
And pass in the data to be active fragment. As simple as that. And you can turn this into a boolean like this. Perfect. Now, let's go ahead and let's go instead of components, fragment web.tsx.
Now in here, let's create an interface props with fragment from generated Prisma. Now let's go ahead and let's add a couple of more things. Use state from React, external link icon and refresh a CCW icon. And then we're going to use the Button component from components UI button. Now in here let's go ahead and export function FragmentWeb which accepts data and props.
And in here let's go ahead and start by doing a div with a class name flex, flex column, full width, full height. And then Inside of here, we're going to do an iframe. And we're going to add key. Actually, we can't do this yet. My apologies.
So for now, just do a class name, heightFull, widthFull, sandbox, allowForms, allowScripts, and allow sameOrigin. Full sandbox allow forms allow scripts and allow same origin and then loading will be lazy and source will be data sandbox URL like this and then let's go ahead and import this from components fragment web and I think that now when you click here you should be seeing a big error saying that sandbox was not found but try creating a new prompt so build a landing page let's go ahead and do that and let's wait for this to generate And once you get a response you can click on the new fragment and in here you are now able to preview inside of the iframe the new landing page which was just created. Amazing, amazing job! So you are pretty much halfway there, right? Great, so now let's add some features to make this seem like a little browser.
So inside of this fragment web, we're now going to add a couple of things. Above the iframe, add a div and give this div a class name padding2 border-bottom-background-color-sidebar-flex-items-center-gapx2 So now just above here you have a little bar. Then in here add a button component and inside a refresh CCW icon. Give this a size of small, a side of bottom. Oh, my apologies, no, these are completely wrong props.
Variant of outline. And on click for now, just an empty function. And now you have a refresh button here. Perfect. So after that go ahead and copy this button and in here you're going to have the following.
You're going to have a span inside of here, like this, which will render data sandbox URL, It will have a class name of truncate. And now let's go ahead and do the following. Collapse all of these props, like so. And keep the variant and keep the size. Let's just add a class name here to be flex1, justify start, text start and font normal.
So now you have a big, kind of like an address bar, right, showing the current fragment URL. And then let's go ahead and just add disabled prop to be explicitly false. And then after this button, let's add another one, which will have the external link icon and give this one a size of a small a disabled if there is no sandbox URL variant of outline and on click will be an arrow function which checks if there is no data sandbox URL return otherwise call window open data sandbox URL underscore blank as the second argument So it opens in a new tab. There we go. Now let's go ahead and go inside of iframe.
And let's add, I keep doing the key, but I keep forgetting to implement the key. Let's finally do that. So go to the top here and add fragment key and set fragment key and call useState like this. Then let's add copied and set copied, useState false. Let's add on the refresh method.
Set fragment key previous, previous plus one. Ponst handle copy, navigator, clipboard, write text, data, sandbox, URL. Set copied goes to true and set timeout is fired with set copied set to false with a two second timeout. Now that we have these two, let's go ahead and add onRefresh here, like so. And for this one, let's give it an on click to be handle copy and disabled if there is no data sandbox URL or if we just copied something.
And in here, I think it is good enough. So now you should have buttons to open this in an external tab like this. You should have buttons to copy this. So when I paste, there we go. And you should be able to refresh this but looks like the refresh one is not working.
Let me just check. Yes, it's okay if this expires. That's completely fine. It expires very soon because we don't want to spend our free credits on E2B. So I don't think this refresh is working and it's not working because we need to add the fragment E here.
So now when you hit refresh you can see how it blinks, which basically means it is refreshing. Perfect. So let's try build a calculator app. And let's see that and let's see how that displays in something like this. And here we have a calculator app.
Pretty, pretty cool. Amazing. We can now refresh this, and there we go. You have a whole new refreshed page. Perfect.
You can copy this. Amazing. So now what I want to do is I want to develop one simple component called hint. And we're going to store that instead of source components, hint.tsx. So not inside of the UI folder, let me just close it here.
I mean, it doesn't matter if you want to, you can put it inside of the UI folder. And in here, we're going to mark this as use client and we're going to import everything tooltip related from components UI tooltip. You already have this and see it is inside of the UI folder. So import all of these things and then create the following interface hint props, accepting the children, the text, and then optional side and align, which accepts top, right, bottom, or left, and align start, center, and end. And then let's go ahead and export const hint with some predefined props here.
So basically we have the children, the text, the side, which by default will be top, and a line, which by default will be center. And then inside of here, what you're going to do is you're going to add the tooltip provider, you're going to add the tooltip itself. And then you're going to add a tooltip trigger like that, as child property, and the render children inside. And then you're going to add tooltip content, you're going to pass in the side prop, you're going to pass in the align prop, and inside you're going to render a paragraph with a text. Just like that.
That is our hint component. Now let's go back inside of the fragment web. And let's wrap it around a couple of items. Starting with the external link icon. So simply wrap your button in your new hint component.
Like this. And then you can add a text here and say, open in a new tab, and a side of bottom, and then a line of start. Just make sure you have imported the hint from components hint. And now when you hover, it tells you what it does, right? Because just by looking at the icons it might not be clear.
And now let's do that for the rest. So find the copy button and wrap it in a hint like this. Click to copy with a side of bottom. So now when you hover over here you can see that you can click to copy. And then do the same thing for this one to refresh.
There we go. So now we can refresh as well. Amazing, amazing job. In the next chapter what we are going to do is we're going to implement tabs here so we can switch between a code preview and a actual web preview like we are doing now. Great!
So let's go ahead and mark this as completed a very simple chapter but a very powerful and very rewarding chapter, may I say. So let's go ahead and open a pull request. So this is chapter 12. I'm going to close everything. New branch.
12 fragment preview. Is that the name? It is fragment view. Let's add and stage all of my changes. Let me just click here.
There we go, staged changes. 12 fragment view. Let's commit and let's publish the branch. And let's go ahead and open a pull request here. And let's review what we just did.
And here we have the summary. We introduced a reusable tooltip component for displaying contextual contextual hints. We added a web fragment preview component with controls to refresh, copy, and open the preview in a new tab. We enable the live preview of the project fragments directly within the project view, including interactive controls and tooltips. Perfect!
As always, an in-depth walkthrough, as well as a sequence diagram here, and some actionable comments. So yes, navigator.clipboard.writeText is technically a promise, so you can do .then on it and .catch on it. So it is possible that the copy feature fails, so it might be a good idea to add .then and .catch to at least display some kind of error at least internally for you so you know something is going on. This is not a bad idea. And in here it allows improving, it suggests improving accessibility for the iframe by adding the title and area labels.
Great, I'm satisfied with what we have so I'm just going to merge this pull request. And once it is merged I'm going to go back here, main branch, and refetch. And after it refetches, there we go. Fragment view is the last merged one. Amazing!
That marks the end of this chapter, so let's go ahead and mark this as complete and see you in the next one. Amazing, amazing job!