Build a React tooltip from scratch

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
oh bye greetings fellow developers also it is a tooltip we are developing in this tutorial you will be surprised to know that such tutorial done right adopt many react and general programming concept such as react clone element react portals react use ref for mutable object reducing problem with divide and conquer strategy and recursive functions get ready for a wild ride in react and javascript programming let's get started now now let's get started here in building this tooltip first i will create a component called tooltip i'll place it in the ui folder so here which will be a functional component of course it need a text prop and we receive the other prop in the let's name it props now this will return the children which will get it by destructuring the props object i will export the component now the ideas for this tooltip component is to create a tooltip that is placed outside of our application container at the bottom of the body enable to do this in react we need to rely on the portal class portals allow us to place a react component anywhere in the dom document in our case we want to place the tooltip element at the end of the body element you know now in order to use the portal class of react first we need to create a new element that return this portal as a react element so here i'll create a new component i'll name it portal.js that we'll need first to import react dom from from react dom and we'll create the functional component portal with the props now we return the react dom dot create portal which is a function that allow us to place an element inside any dom element that we specify here as a parameter so the first parameter will be the react element which here is the props dot children and the second parameter will be the dom element we can retrieve a dom element using the get element by id or here in our case we need to specify the body because we need to append the created element here the tooltip element in the body so i'll specify the document dot body then at the end i'll export the component now in my tooltip i'll import the portal and i'll use it as a component here giving it my tooltip element that i will create now with a span and put inside of it the provided text by the user so now let's test this component so in my home dot js i need to import the tooltip but before doing that i want to export the tooltip from the index.js general file in my ui folder so here i'll add tooltip so first here i'll import the tooltip and export it with the other object this way i can import both tooltip and the button element from my ui folder i wrote a button with it with the tooltip so first i'll create the button which will contain a getting started label then i rub this button with it with the tooltip now the tooltip need a text which is required here it seem i made a mistake it notified with all capital letters for the dom so now here in my browser as you can see this is the button of course now the tooltip won't work but if i inspect my page in the at the end of the page at the end of the body element i can see that there is a span with lorem ipsum so this is our tooltip generated outside of our application now the next thing i need to do is to add the mouse event to the getting started button so we need to add a mouse over and the mouse out to show and hide the tooltip so here i have the children which is the button here or any element that we specify that we rope with the tooltip component now for this element the children i want to add the two event to be able to do this i can rely on react clone element this function api of react allow me to add a props to an element by cloning it the cloned element will be identical to the original element we are just adding two new behavior the mouse over and mouse out so we'll import first react and we'll use here's the react dot clone element we'll provide it as the first parameter the children then we provide any additional a prop that we need to add or to append to the element current props so here we need the on mouse over which will be a function we'll name it handle m for mouse over then we need on mouse out to have the function handle m out next we'll create these two functions these two functions need to set a state that is responsible in showing or hiding the tooltip so we'll create that state first we'll import this the used state hook from react and we create here a new state we call the state show and set show so constant show set show which will be equal to use state by default it will be 0 0 mean the tooltip is hidden now i will create the function which will change the set show to one and the handle mouse out which will set again the show to zero so now we'll rely on the show state to whether show or hide the tooltip i need to set the opacity of the tooltip to zero or one depend on the show so i let with some style first i'll import my style component library and i'll create a constant called a component called styled tooltip i'll set the position to fixed the top end button will be now some values so we can be able to see it on the screen we later work on the positioning of the tooltip we'll adjust the font to be a small size and the weight will be bold and we'll add some tiny letter spacing the background color will be a transparent black for now the text color will be white and some styles for the to disable the pointer events so it won't have any interaction with the mouse or keyboard plus we're adding padding to the top button left right then a border radius of 4 pixel the z index will be the highest so it will not be masked by any component on the screen in our application the display will be inline block and the white space will set it to no rope so it won't drop the text unless the user specify using a an html element like brake line br now for the opacity which we want to control depend on the mouse hover of the children of this component so we'll set opacity to be which is the props send to style tooltip now we'll need to send the p dot show the show variable will be either one or zero if it's a true it will be one so we only need to return return it as it is for the opacity which also accept a one or zero as values so it worked great in our case here all right this is it oh i made here a mistake i put these two functions outside of the component tooltip they need to be inside because they rely on the state to be available for them to change it now we'll use style tooltip component instead of our hard coded span here all right and we'll pass it the prop show all right so let's try it in our browser now if i over the getting started i see the tooltip here somewhat it is positioned oh i specified the button in instead of the left i wanted the left so it is our element now for the positioning we'll work on it very shortly but now we have successfully set up the events we have also set the placement of the tooltip on properly on the dom all of this has been handled programmatically by our component the user doesn't have to know about this he only need to rob any element in his html page with the tooltip component and provide the text for the tooltip now let's fix the placement of the tooltip and give the user the option to choose one of four placement button top left and right so here so concerning the placement we need to specify the top and left so we have a point of x y so first we'll create an object here let's name it pause which will be x by default 0 and y by default 0 now this is a mutable object we will change it and once we finish changing this object to adapt the position of the tooltip as desired we'll pass it to the styled tooltip so this will be a meetable object it will be sent by reference to the styled tooltip so it will change its position every time the handle mouseover function is fired we will manipulate this object and this x and y will set the top and left of our component here so we don't want to render the this component each time the x or y change there's no need to render the component all we need to do is change the styles of the component so we can keep it like this in an object but there is a better solution provided by react which is usedrev by importing now the userf we can benefit from it to set this mutable object using use ref and give it the default value in the parameter for the user f now here i'll change the name to pause f now what is exactly the difference here user f will create a mutable object as we were creating it directly in a constant but the difference is each time the component render the object will stay the same it won't rebuild the object so this is the advantage while if we were not using usedrav we're directly assigning the object to a constant every time the component render the object will be rebuilt again now we have the pause ref we will send it to our styled tooltip component as a pause ref and in our style tooltip style component we will use this positive to set the top and left so here instead of 100 pixel i will use the p for props dot pause ref dot current dot x for the top note dot y append to it the pixel the same for the left i'll use now the x all right now if we quickly check our browser we can see that now it is positioned to 0 0 as we have specified here by default now in the handle over function we will work on the element position to define the element position of course we need a placement variable that is set by the user this placement could be bottom top left or right and we'll by default we'll set it set it to bottom now here to position the element i need to have a reference to the element drop by the tooltip and i need a reference to the tooltip plus i need the variable placement to define where it should be placed in relation to the child element so first i will get a reference to the tooltip i will name it tooltip ref which will be equal to use ref and we'll set it to reference the styled tooltip component by assigning zref to tooltip tooltipref now the tooltip contain a reference for the underlying dom element 2 styled tooltip next we need to have a reference to the children element to get the reference to the child element we can rely on the event here which we can use z dot current target to get this element now we will create a function that will return a point the x and y property in an object and we assign this return point to the pause ref dot current so pause ref dot current will be the result of calling a function that we were created in just a moment we will name it get point this get point need as parameter in order to be able to do its job the children element reference so e dot current target then we'll need the reference for the tooltip tooltip ref and finally we need the placement that is defined by the user in order to determine the position of the tooltip plus we'll add a space variable that will create space between the tooltip and the element so it won't be sticked to the children element so now for the space we can also allow the user to define it here by getting it in the probes and by default we'll set it to 15. now all we have to do is create this function it will be outside of the tooltip component so we'll create a constant get point which will receive the element the tooltip i'll name it as a tt and the placement plus the space so the main responsibility of this function is to calculate the x and y and return the final result as an object with an x now we put it as zero and a y will by default it will be zero so let's override zero zero two let's say 50 pixel sorry 50 and 50 just to see it on the screen so now if i go to my application and hover is getting started now the placement has been changed to 5050 next we need to start with the calculation of the x and y in relation to the chosen placement by the user and in relation to the child element that is robbed by the tooltip component now in order to determine the position of the tooltip we follow a simple calculation so i have an illustration here to explain to you how we will do it first we have the button here's the black one and we have the tooltip here the green one so if we want to play to place the tooltip from the bottom of the element first we need to get the element bottom then we'll add to it the space which is default to 15 pixel this way we get the y of the tooltip for the x we can easily get the left of the button now with the left we can set the tooltip here like this adjacent to the left of the button but what we need to do is place it at the center of the button now to be able to center this tooltip we need to add value to the left so what is the value that we need to add that will make this button centered we need to determine the space here the width of the button minus the width of the tooltip which gives us here the space the difference between the with this so we'll get the space here and we'll divide it by 2 and we'll add it to the value of the left of the button which we'll set it to y and will push the tooltip like this for it to be centered to the button so let's make this happen so here we need a point which will be x by default zero and zy by default zero we'll work on this object and we at the end will return it next we need to get the top left right and the bottom of the element we can get it using the get bounding client rec function of javascript so we create here a local constant we'll name it dx for box and we'll assign to it the result of get bounding client rect it's a javascript function that returns the top left right and bottom actually i'll name zbx to l rec so it is clearer now we'll create a switch on the placement now we'll have a case for the top and a case for the left and a case for the right and the default will be for the button now we'll work on the default to place the element at the bottom we need to set the x to the l rect dot bottom plus as i explained to you we need to subtract the width of the of the element minus the width of the tooltip ztt so l dot offset widths minus dt for the tooltip dot offset widths divided by 2. this will give us the x we need for the tooltip to be centered in relation to the element now for z y it will be l red dot bottom plus the space which is by default 15 pixel all right now this point as we here are doing the return value of the function get point is assigned to our pause ref dot current here it needs to be dot current for the tooltip ref it's a it's a mistake oh i need to declare zpt using the keyword constant or var now here i made a mistake the x this is the y and this is the actually the x so let me arrange them properly all right and let's try it in our browser all right this is placed properly at the bottom now let's create for the other values starting with z with the left now for the left to get the the y of to get the i mean the x for the tooltip we get the right of the button then we subtract from it the width of the tooltip which place it here concerning the x-axis then we'll add the spacer which add a space between the button and the tooltip so l rect dot left plus i mean minus z tooltip dot offset width plus z space now for the y to get the y first we get the top of the button which will place it like this then we subtract from this value the difference of the widths of the button minus the width of the tooltip divided by two so it will center it exactly so here we'll get the l direct dot dot plus the l dot offset widths minus ztt dot offset width divided by two so if we test the left he will add the we'll set the placement to the left and we need to break of course to stop from running the other cases the default one so now if we test the left alright so we made here a mistake it's not the width for the left we need to use the of course the height and here it is centered perfectly next we'll set the right position now for the right for the x we'll get the element track right then we'll add to it the offset width of the tooltip then we'll add the space now for the y the same value as for the left let's give it a try we made a mistake yes sure we made a mistake we don't need to the width i'm sorry we set we set it to the right which we are setting here the left of the tooltip to the right of the button then we'll add the spacer in that case you don't need the widths so again here it is working perfectly now for the bottom oh i mean for the top we already did the bottom here which is the default case for the top which should be here for the position x it will be the same as the position button we need to center it horizontally so we'll copy the x of the bottom and we'll pass it to z and we'll assign it to the x of the top now for z y l rec dot dot plus z t offset height or minus minus z dt offset height plus the space this will put it on top of the button and add with a space so it won't be stacked to the button now let's give it a try by setting the placement to top on the getting started button on the home page so now this is working as perfect as it can be which is good now we have successfully positioned the tooltip in relation to the button while giving the user four possible placement to choose from next we have two additional requirements first the tooltip shouldn't overflow the screen second the tooltip shouldn't mask the button so it should not be on top of the button like this or this so let's start with the first requirement here we have a rectangle possibly the screen and a point which is the top left of the tooltip so here is the point so what we need is to restrict that point to a rectangular area and here it's possibly this green so first thing let's remove the button from the equation since we don't have any role in the first requirement and work with the tooltip and the screen so it seems like our rectangle here is the screen but let's make sure this assumption is true by testing for the worst case scenarios and see how it holds so worst case scenario will be if the point is on the edge like this so if we put it here we see that the tooltip is overflowing this screen so it's negative so it's not accepted here neither here neither here now here it could be here but we need to add some space between the tooltip and the edge of the screen a space with default of 15 pixels so we push it a 15 pixel here so this is this point here is acceptable and any other point from this side to the left side so we'll put here a ruler so this is after this rule it is a restrictive area it is the right of the screen minus the width of the button and minus the spacer that is by default 15 pixel or whatever the user defined same for the button all right for the button we can't put the point here it need to be here so we'll subtract from the bottom position of the window the height of the tooltip and minus also the spacer so we have a new restrictive boundary here now for the left and top we only need to subtract the 15 pixel so here we have the rectangular area that that represent our restriction so let's mark it by a box a gray box now after defining the rectangular area the problem becomes easy all we need to do is compare the coordinate x of the point to the left and right of the rectangle and if it's outside of one of the edges we'll set its value to that edge so if it's here we'll set it to the edge here if it's from this edge we'll set it to so we set its value to this edge now this is concerning the x now for the y the same thing against the top and bottom this solves the first requirement now for the second requirement all right here let's get the button back to the equation so here if the button was here if we can't push it then we'll flip it so it will stay on the same axis this way we preserve the orientation the user intended for which makes the most sense now we need to check what is the direction of the tooltip placement whether it is on a horizontal axis like right or left or on a vertical axis top or bottom so if it's on the horizontal axis then we check the coordinate x of the point against the left and right edges of the rectangle so if the user choose for example to put it on the left okay the left is on the horizontal axis in this case we check for the x if the x is lesser than z left of the rectangle which is true then we'll flip this is the main procedure that we will follow to solve the flipping problem the same for the horizontal axis against the top and bottom so always when we flip we change the placement to the opposite one so if it's left we change it to right if it's bottom we'll change it to top now it makes sense to apply the flipping first so we check if there's a flipping case will flip then we run the restrictive boundaries so in other way if we need to flip we flip first but if the item is still overflowing any edge of the rectangle we'll just push it inside and done problem solved after clearing things it's easy to translate our solution into code so let's make it happen so first we'll create the rectangle boundaries the main one so i will name it constant bdys for boundaries which will be equal to an object that has the left which will be equal to z space and then z top which also be equal to the space see 15 pixel by default then we have the right all right which will be equal to the window widths minus the tooltip widths minus the space now here we need to get the body widths to account for the scroll bar in case the page has scroll bar by getting the document client widths or the body client widths we are restricting from it the scroll bar so document dot body dot client widths minus the tooltip dot client widths minus the space for the bottom you can use the window dot inner height because however the document is tall we only need to get the height of the screen here so window.inner height minus the same calculation here minus now here's the height of z of the tooltip then minus the space so this is our restriction box defined and ready to be used so first we'll check whether the element need to be flipped or not here we'll add an if with a couple of condition so if the position or the placement if you name it placement is equal equal equal to two left or the placement is equal to right then here in this case we're talking about the horizontal axis and and then we need to check z the point dot x so we need to check the x if it's lesser than the bdy the main box restriction dby.left or if it's larger than bdys dot right this is the case where we have a flip the other case is for the vertical axis if the placement is top or bottom now we check for the y if the y is lesser than the body dot top or z y is larger than the body dot bottom this is also a flip case we have here what we'll do here is call again the function so we'll call the get point again with the same parameters but instead of the current placement so we'll flip the placement now here as you can see we're working a lot with with placement here now we are checking if it's placed horizontally and vertically and now we need to negate the replacement what i will do is create an object to handle this operation so at the top here i will create an object called position which will be equal to a function we can we send this function z position as p all right and it will return directly an object now this object has some property a current property which will be set to b so you can get the current defined position then we have another property that will negate the the current p so here we'll add some ifs so we check if this dot current is equal to left we return right so this function will return the negative of the current position if it's right it will return z left now if it's top it'll return z button and if it's bottom it will return the top this will allow us to easily negate a position next we'll add a function is horizontal which will return true if this dot current is equal to left or this dot current is equal to right another one which we'll call it is vertical which will return true if it's top or bottom right now we can use this position to help us make the code more readable so here we can create the object we can create a constant we'll name it pause which will be equal to position with a parameter of the position of the placement now we can use here the pause dot current to get the current position hand switch against it now here to check horizontally we'll use pause dot horizontal which is a function and below we'll use for the vertical pause dot is vertical now here to negate we use pose dot negate which will return the opposite placement as a string all right this will rerun the function now with a new placement the opposite placement and will regenerate the posit the pause object with the new placement now the get point is the check on the next iteration pass so it will return the point all right here it will return the point so we need to get the point and assign it to to our current point all right this is how the cursivity work always when you're working with recursive function you need to have a condition that give the recursive function a way to stop here in our case after flipping the placement of z tooltip it will iterate one more time and most probably this will be enough now if it's not enough we will add a condition to stop this function at the third iteration this will do it next but now we will check if this is working as expected all right we have zpt it is constant so we need to make it into not a constant a normal variable so let's go to our browser and give it a try first i'll make sure the placement is let's say button so here in my browser first everything is working as expected now if there's no space at the bottom currently nothing is happening for some reason let me verify our code first while checking the code i noticed here it need to be positive oh here and also i made a mistake it need to be and and and we need to combine both of the each condition so here it needs to be or all right so either this or this we have a flip case now if i go to my browser and here if there is no space at the bottom and the position is placed by the user to be bottom it will flip to the top all right if not it will show at the bottom as expected else it will show at the top all right now to test left and right what we will do we will add here tooltips for our menu so if i go now to my menu to the nav link i can quickly here drop it in a tooltip and add the text to the label of the link and i can position it to the right or sorry i will place it to the left to show you that it will be placed automatically to the right in this case because the left is there's no space in the left sorry i mean again left so now i position the tooltip to show on the left but since the left has no space it will show automatically to the right all right now i'll put it again to the right all right now this is for flipping as you can see here it is done not done sorry concerning concerning the the recursivity of the function we have here a small issue now we're iterating the wall function so we're rebuilding the point we are rebuilding the boundaries here which and also the rectangle here this we don't need to rebuild them again they will stay the same and used by the recursive function the recursive function only need to be consist with here the positioning and the check here plus we need to add to limit the function to only three iteration at maximum so let's do this now so we'll create another function inside of this function which will be named recursive will accept a parameter of replacement or more correctly it required a placement parameter now we need to immediately call this function with the current placement parameter and we need to return it all right so this will be our recursive function now inside of it we will need the position object next we need the z switch then we need here the check and here we need to return inside of hcpt now for the point here since it is an object that define a point with x and y what i will do is create it separately i will create a constant point which will be equal to a function that return an object inside of it there will be the x i will make it at the beginning as null the y as null 2 so this way we can detect if it's defined or not now i created this object to add a function to it or a method if you want reset which will take a point and it will reset the x and y to the new point so this dot x will be equal to p dot x and this dot y will be equal to p dot y this will allow us to create a cleaner code so here where i'm defining the point it will be now a new point object and this point object will be used as we are using it which it has the x and y but here instead of now we can make it constant because we have the reset function so instead of assigning it a new object we use the reset giving it the new object returned by get point now we call the recursive here all right which need only z z position this is reset now here is our recursive function which once it is called it will determine the x and y and then check that the point is inside the restrictive rectangle now if all is good it will return pt now if not it will it will run this line here so to illustrate this here is an illustration that i made to show you how this process will work first we call this function the recursive function first time we'll run the recursive function it will reach this line here which is another call to itself which result in pausing the execution of this the first function and creating a new stack for another call for the same function now the another call will reach also this line then we'll call another time the function itself now this function also is paused at this line so it will stop here the execution for now we're waiting for the return of this function same as the previous one that is awaiting the return of this one and now this one is awaiting the return of the new call which is in a separate stack now now it will keep on doing this forever which will result in an error but here in our case we have a condition this so we are not calling it without any condition so this condition if was false in that case it won't call the recursive function it continues the execution and return the point so once it returns the point this resumes execution and and send the point as a parameter to reset which will reset our point then it will return the point once it returns the point we'll exit the function so after exiting this function and returning the point the same for this one we return the point and we'll exit this function now we are not in the recursive function we have exited there accuracy function which return the point now we're at the get point function which also which now return the result of this recursive function which has returned the point now once we return from the getpoint function we'll exit the getpoint function all right so always when you create a recursive call you should have a condition and this condition should at a certain time stop the execution and after a number of iterations so make sure the condition is valid for a recursive function so here in my case all right it is working so there is one iteration so the user has defined the tooltips to show as the button but the button there is no space so it will show at the top this is a one iteration and we exit the recursive function all together now there is one case here that we haven't covered in our solution imagine the button has a height of let's say 140 some large height and there's no space on both sides the button and the top all right so what will happen here it will the user has specified the tooltip to show at the button there is no space now the application change the position to the top again top there's no space it will negate the position now it is bottoms so we here we're here in a endless iteration so what will happen we'll get an error we get a stack reach the maximum capacity so if i try it now all right maximum call stack size exceeded so this is what happened if you have a condition that is not available condition for recursive functions so what we want to do here if on the second iteration we need to stop the execution so we need to add a counter to limit this function from iterating endlessly in case where there is no space on both sides what we need to do is create a counter and count for each iteration so if there is one iteration it's okay second iteration it's okay which negates the position back to the user choice once we reach the third iteration there's no check there's no place for another iteration it just returned so to add this check we'll create a variable here we name it correctly count which will be initially to zero then in the recursive function we'll increment this variable each time we do an iteration and here in the condition where it run an iteration we'll add another condition on top of it which check the recure counter if it's larger than 2 sorry if it's lesser than two if it's lesser than two proceed with z check else proceed to return the point immediately oh if this is lesser than two here if the key count is lesser than 2 we'll proceed here with the check now if it's larger than 2 we'll skip the check and return zpt which exit the function without any further iterations so let's check it in our browser first here i have the getting started button which have a placement button for the tooltip all right all is working good now if there's no space at the bottom it will show at the top now in case the bottom is very large let's set it the height to 140 pixels or even more all right and we tighten the width of the windows so the button now has don't have any space from the bottom side or the top side for showing the tooltip we see that the recursive function doesn't iterate forever and return another so here it is stopping at the top but if we increase the counter to one iteration that way it will favor if there is no top and bottom available space for the tooltip to be placed it will favor the position of the user so now it is showing at the bottom next what once we do the boundary restriction you will see that c tooltip now will be pushed to the top in this specific case so it will be visible under the the getting started button here somewhere leaving a 15 pixel from the bottom now let's work on this code for example here the sign out is on the far edge now this is not a case of flipping the tooltip this is a case of pushing the tooltip inside of the allowed boundary so this will apply also to this case here the after we have tried to solve this situation by flipping the tooltip the tooltip still is outside of the boundary because both sides have no space in that case the restrictive boundary will kick in and push this tooltip inside the window in any case so let's do it now now here after flipping the point and before returning it i'll add another check for the restrictive boundary all right so here will be the code that will restrict at the end the element it will push it inside the boundary whatever the final result was after flipping it so how we will do this we will create a function in the pt object which is called restrict rect this will restrict the point to a rectangle that we need to send in the parameter so we'll send the bdy s which is our main restriction so in my point object here the point object i'll add another function restrict rect here we get the erect now we'll add a couple of f's actually four we'll check first for the pt.x if pt.x is less than the rect dot left in that case we'll set the pt.x to the rect dot left if zpt.x is larger than rect dot write then we'll set zpt.x to rect dot r so here it need to be else if this is the horizontal restriction now for the vertical again if pt dot y is lesser than rect.top then we'll set the pt.y to rect.top else if pt dot y is larger than rect.button we'll set the pt dot y to rect dot button now i made here a mistake the pt to access dpt inside the function we'll add the this so now if we check as you can see now it break out the centering position of the tooltip against the button in favor of showing the wall tooltip all right this is for the sign out now here in our case the getting started button which at first try to solve its problem by flipping it no success then it will revert it back to the bottom position now after adding the boundaries if we hover this button we see that the tooltip now is visually accessible at the end it hovers the element from the bottom where the user originally wanted to be visible so this is in my opinion the best possible solution for this situation now we have our tooltip whatever happened always accessible now i need to add another option for the tooltips that is specified by the user this is the disabled option so okay so the user can activate and deactivate the tooltip depend on his situation for example here in our menu we don't want to show the tooltip when the menu is expanded we only want to show it when the menu is collapsed let's add now this option we'll add another prop to the tooltip which is disabled by default will be zero zero mean it's enabled so we add then a check here so this is where we are generating the tooltip and place it in the in the dom inside the body here we'll check if it's disabled we won't generate at all z tooltip so disabled or portal so if disabled is true all right return disabled but if it's false false then run this component here the same for the react clone element we don't need to clone the element if the tooltip is disabled so we will check for disabled all right if disabled is true we return the children without modifying it if not we'll clone the element adding to mouse event on it so let's test this new option here in our nav link where we are creating the tooltip we can add the disabled option and set it to whether the tooltip is compact or not now we have the compact in here in the rest which we are using here so we'll add a check to dot rest.com if compact is one which means it is compact we will not disable the tooltip if compact is zero it which means the navbar is expanded we want then to disable the tooltip so if i go to my browser now and check no tooltip when the navbar is expanded but if it's collapsed the tooltip will be activated which is great now we can test also when the tooltip is on scroll plus as you can see now the tooltip is fixed on the screen the tooltips still work because it is positioned in relation to the window screen not the document concerning the height next we need to add a color option for the tooltip so in our tooltip.js component we add another prop which we'll name it bg now since we are not using the props i can get rid of it so zbg will we'll need to send it to the style tooltip which will be used for styling the background color and the color here our background color currently is set to transparent black what we need to do is is instead of specifying here directly the code we need to make a check p dot bg here we return zp.bg and we'll add with the rgb so it must be an rgb remember here in our theme we have followed some for format so the each color contain rgb so the primary has an rgb z secondary also has an rgb for example if we want to use the dark we need to then add an rgb same for the light so the colors that don't have rgb we add a default color so this need to be first in a var dash dash here it's color dash the name of the color could be primary could be secondary or dark or light then we'll add to it here we'll append to it the rgb which give us the rgb format of the color now in case this color doesn't have an rgb we can add a default value with css for the var function so the var check if there's no rbg then we'll use the black color all right so the var take two parameters the first one if it's available as a variable will be used if not the second one will be the default now this is for the background color now for the text color use the var dash dash color and we get the colors specified by the user which is nzbg then we'll append to it this time z contrast all right z contrast also following our theme strategy each color has a contrast so the contrast is a color that you can use it for text or some elements that are on top of the color and we'll also add the default which will be f two five five two five five two five five which will be pure white now for my global style here i'll quickly update the dark to add towards the rgb the same for the light in case the user want to use dark or light colors and the dark i'll make it darker with 444 hexadecimal all right back to our tooltip.js i think i think here we are done with the color of the tooltip so now if i go to my let's say header and choose a color with bg using the secondary for example color color so this is the button on the header now if i go to my application and hover the sign out it will be blue but the color is still black here i forget to add the dash so it's color dash secondary dash contrast so now if i check again it will be white now for the animation we'll add some transition and some transformation i have already in my clipboard the properties needed so here we are adding transition for the transform and opacity property then we are adding transition duration of 0 0.06 second so it will be very minimal the animation the transition timing function is this cubic bit bezier which we are using on our application here in the nav bar then we are adding the transition delay which is specified here by the user all right so to to let the user specify this delay we'll add here a prop delay in our tooltip function and we'll send it to our styled tooltip so we'll add delay which will be equal to delay now we can use it in our styled component css as we are doing here so for the delay we have a condition for the delay if the tooltip need to be visible we use the user defined number for the delay if not we'll use a very quick and tiny delay for it to be quickly hidden once the user mouse moves the mouse out of the trigger then we transform on the scale will scales you to the tooltip so it will have a zoom effect and we control the origin of the transformation with the user provided placement so if the user place the tooltip at the bottom the origin of the transformation will be top that's why we are negating it all right now i'm using the bg and the delays props here but these two are optional so what i will do here is set some default value for this attribute so i will add the editor which will take a function that gets the props as a parameter here i'll set zbg to p.b g if not or i'll set it to dark and remember dark is a color in our theme it's defined next for the delay it will be p dot delay or if not if it's not defined here we need to return this object we can drop it with parenthesis or 0.01 a very small delay which is neglectable but is there so if we did everything correctly and there's no typo in our code everything should work as expected so let us try it all right did you see the animation here and here now let's try it on the nav bar all right did you see how the origin of the animation is on the right of the tooltip so it zoom in from the right now we have reached the end of the tooltip project now we have some clean up to do from our previous video in our previous video we have worked on the nav bar which is and everything is working fine but there are some small glitches for example here check the arrow button here so if i now resize my window as you can see the arrow will is resizing with the flex layout so the flex is controlling its size so to force this button to have a fixed height we need in the nav toggle instead of setting the height we'll set the min height this will force the height always to be 42 and removes the control from the flex layout so as you can see it is now always 42 no resizing of z button next if you reduce a little bit the speed of the animation you can see that here z2 these two links are overflowing z bar slightly all right now it is quick difficult to detect it but to solve this situation we can add an overflow hidden for the main bar main dropper of the bar this this will prevent any element from overflowing the bar all right now this also has another impact on our navigation here as you can see if i hover outside of the button the hover still is activated so this is a also one of the problem that will be fixed once we set the overflow hidden for the main nav bar so if i go to my nav bar here and set the overflow to hidden all right now we have solved this problem and as you can see the our tooltip work as expected even so we have added overflow hidden to the nav bar but remember the tooltip is displayed in the bottom of the page outside of our application container all right so this is the end of our react video tutorial i hope you enjoy it if you do subscribe to my channel for more of this kind of tutorials and give this video a thumb up which i very appreciate and see you hopefully in the next tutorial
Info
Channel: Web Steps
Views: 7,559
Rating: undefined out of 5
Keywords: React, React JS, Reactjs, Javascript, React tooltip, react cloneelement(), react clone element, react clone component, react portals, react createPortal, react-dom, react-dom portals, react useRef, react useref tutorial, react tooltip tutorial, react advance tutorial, recursive function, recursive function javascript, react portals tutorial, react-dom tutorial
Id: bnuw7pqWUGA
Channel Id: undefined
Length: 71min 53sec (4313 seconds)
Published: Fri Feb 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.