I'm working on a project that uses pre-made TailwindUI component code. If you refer to this gif, you can see that the code on the site is responsive to mobile design and the hamburger menu toggles on button click.
However, the code given for this does not include the necessary JS, so the toggling of the hamburger menu does not work.
I am trying to fix this, this is what i've done so far:
I've wrapped the flyout menu code in a div and gave it an id 'mobile-menu' and a state of 'hidden'. Inside this menu is the X button, which i gave an id 'menu-toggle' since i want this button and the hamburger button to toggle the flyout menu. Below is not the whole code but just the relevant parts
<div class="absolute z-30 top-0 inset-x-0 p-2 transition transform origin-top-right md:hidden">
<div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
<div class="pt-5 pb-6 px-5">
<div class="flex items-center justify-between">
<div>
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow">
</div>
<div class="-mr-2">
<button id="menu-toggle" onclick="" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
<span class="sr-only">Close menu</span>
<!-- Heroicon name: outline/x -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
Outside of this div and elsewhere in the code is the hamburger menu button, which i also gave an id 'menu-toggle'
<div class="-mr-2 -my-2 md:hidden">
<button id="menu-toggle" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-expanded="false">
<span class="sr-only">Open menu</span>
<!-- Heroicon name: outline/menu -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
Finally i've added a script tag to the whole .html file (the file does not contain HTML boilerplate because it is a 'partial' in a Hugo project, similar to a component in React) and that looks like this:
<script>
let menuButton = document.getElementById('menu-toggle');
menuButton.addEventListener('click', function () {
let flyout = document.getElementById('mobile-menu').classList
flyout.toggle('hidden')
flyout.toggle('block')
})
</script>
but this JS doesn't work at all. Looking for insight on how to pull this off properly. Thank you!!
I have written a little code to do the work around. Perhaps it is not the effect you want for your final result, but it is a start. The aproach here is that you can't apply a toggle function for the same button and the same element toggling diferent class, without use some css at least. Besides, there are so many code errors to explain one by one. Here I let you the code that allows to you open with burger button and close with cross button.
If you need to toggle with the same button just use the menuButtonBurger event and add flyout.classlist.toggle('visible), and remove menuButtonCross. Combined with the css I wrote you this must work.
let menuButtonBurger = document.getElementById('menu-toggle-burger');
let menuButtonCross = document.getElementById('menu-toggle-cross');
menuButtonBurger.addEventListener('click', function () {
let flyout = document.getElementById('mobile-menu');
flyout.classList.add('visible');
});
menuButtonCross.addEventListener('click', function () {
let flyout = document.getElementById('mobile-menu');
flyout.classList.remove('visible');
});
#mobile-menu {
display: none;
}
#mobile-menu.visible {
display: block;
}
<div class="mr-2 my-2 d-md-hidden">
<button id="menu-toggle-burger" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-expanded="false">
<span class="sr-only">Open menu</span>
<!-- Heroicon name: outline/menu -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
<div id="mobile-menu"class="absolute z-30 top-0 inset-x-0 p-2 transition transform origin-top-right d-hidden">
<div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
<div class="pt-5 pb-6 px-5">
<div class="flex items-center justify-between">
<div>
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow">
</div>
<div class="-mr-2">
<button id="menu-toggle-cross" onclick="" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
<span class="sr-only">Close menu</span>
<!-- Heroicon name: outline/x -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
Related
I am working on a react project using vite and for css I am using tailwind css. From the component section of tailwind css website I have copied template, and I am unable to get responsive functionality and show/hide menu on click
below is my header code
<nav class="bg-gray-800">
<div class="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
<div class="relative flex h-16 items-center justify-between">
<div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
<button type="button" class="inline-flex items-center justify-center rounded-md p-2 text-gray-400 hover:bg-gray-700 hover:text-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white" aria-controls="mobile-menu" aria-expanded="false">
<span class="sr-only">Open main menu</span>
<svg class="block h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
<svg class="hidden h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start">
<div class="flex flex-shrink-0 items-center">
<img class="block h-8 w-auto lg:hidden" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company" />
<img class="hidden h-8 w-auto lg:block" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=500" alt="Your Company"/>
</div>
<div class="hidden sm:ml-6 sm:block">
<div class="flex space-x-4">
Dashboard
Team
Projects
Calendar
</div>
</div>
</div>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
<button type="button" class="rounded-full bg-gray-800 p-1 text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
<span class="sr-only">View notifications</span>
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0" />
</svg>
</button>
<div class="relative ml-3">
<div>
<button type="button" class="flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800" id="user-menu-button" aria-expanded="false" aria-haspopup="true">
<span class="sr-only">Open user menu</span>
<img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt=""/>
</button>
</div>
<div class="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" role="menu" aria-orientation="vertical" aria-labelledby="user-menu-button" tabindex="-1">
Your Profile
Settings
Sign out
</div>
</div>
</div>
</div>
</div>
<div class="sm:hidden" id="mobile-menu">
<div class="space-y-1 px-2 pt-2 pb-3">
Dashboard
Team
Projects
Calendar
</div>
</div>
</nav>
everything is working fine but by running the above code I am getting only ui and not getting click function on menu bars or other
see the image below
[
let menuMovilButton = document.getElementById('menu-movil-button');
let userMenuButton = document.getElementById('user-menu-button');
let userMenu = document.getElementById('user-menu');
let menuMovil = document.getElementById('menu-movil');
menuMovilButton.addEventListener('click', () =>{
menuMovil.classList.toggle('hidden');
});
userMenuButton.addEventListener('click', () =>{
userMenu.classList.toggle('hidden');
});`
So I am new to Cypress and trying a basic automation test. On the login page, there is an error popping up when the email is not in a valid format and I have to assert it but I am stuck in the test because I cannot get the error message. I cannot write a proper selector with the help of cy.get()
Below is the HTML for the pop-up from the page.
<div data-v-666984d3="" class="modal-overlay flex flex-col z-50 w-1/2" xpath="1">
<div data-v-666984d3="" class="flex flex-col flex-1 mt-[70px]">
<div data-v-666984d3="" class="flex flex-row justify-end">
<div data-v-666984d3="" class="flex justify-between w-2/3 mr-2 p-5 bg-red-500">
<div data-v-666984d3="" class="flex flex-col justify-center w-full">
<span data-v-666984d3="" class="font-normal md:text-md text-center flex-4 text-white">
Email is not in a valid format.</span></div>
<div data-v-666984d3="" class="flex justify-end p-2">
<a data-v-666984d3="" href="#" class="text-white">
<svg data-v-666984d3="" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24
24" stroke="currentColor" class="h-6 w-6 text-white"><path data-v-666984d3="" stroke-
linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</a>
</div>
</div>
</div>
</div>
</div>
The page looks like this Click Here Please
And this is my code so far:
/// <reference types="cypress" />
describe('Negative Login Test Case', () => {
beforeEach(() => {
cy.visit('https://manager.xogo.io')
})
it('.should() - Verify the quick start guide is present', () => {
cy.get('.font-semibold')
.should('have.text', '\n Got questions? Checkout our Quick Start Guide to see how
it all works\n ')
})
it('.type() - type email and password', () => {
cy.get('#email_1')
.type('ss#xogo.io').should('have.value','ss#xogo.io')
cy.get('#password_2')
.type('Balaji2022').should('have.value', 'Balaji2022')
})
it('.contains() - Click on the login button and get the pop-up', () => {
cy.get('button').contains('Login').click()
cy.get('span').should('have.class', 'font-normal md:text-md text-center flex-4 text-
white')
.contains(' Email is not in a valid format.')
})
})
Any tips would be appreciated and an answer would be so good. Thanks my fellow coders for the help... Much appreciated.
I would also suggest to use:
cy.contains('Email is not in a valid format.').should('be.visible')
Also, one more thing try to ask in your team (better with devs) to include some custom attributes like data-testId in your code so you don't have to write complex selectors which over the time gets outdated and makes tests flaky. So your above mentioned code in the end it will look like this:
<div data-v-666984d3="" class="modal-overlay flex flex-col z-50 w-1/2" xpath="1">
<div data-v-666984d3="" class="flex flex-col flex-1 mt-[70px]">
<div data-v-666984d3="" class="flex flex-row justify-end">
<div data-v-666984d3="" class="flex justify-between w-2/3 mr-2 p-5 bg-red-500">
<div data-v-666984d3="" class="flex flex-col justify-center w-full">
<span data-v-666984d3="" data-testId='invalid_credentials_text' class="font-normal md:text-md text-center flex-4 text-white">
Email is not in a valid format.</span></div>
<div data-v-666984d3="" class="flex justify-end p-2">
<a data-v-666984d3="" href="#" class="text-white">
<svg data-v-666984d3="" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24
24" stroke="currentColor" class="h-6 w-6 text-white"><path data-v-666984d3="" stroke-
linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">
</path>
</svg>
</a>
</div>
</div>
</div>
</div>
</div>
Just use
cy.contains('span', 'Email is not in a valid format.').should('be.visible')
Forget about the classes, they are for formatting, will change over time, and will break your test. You just want to assert the error text is showing.
I am using a tailwind cssv3 installed via NPM and I changed my tailwind.config.js to
module.exports = {
content: ["./*html"],
theme: {
colors: {
transparent: 'transparent',
current: 'currentColor',
'myblack': '#ffffff',
'myblack': '#000000',
'myorange': '#FF7E00',
'mygray': '#A8A8A8',
'mywhiteuse1': '#F1EBEB',
'mywhiteuse2': '#E9E9E9',
'myaction': '#B31717',
'myneutral1': '#A8DFBB',
'myneutral2': '#93BF97',
},
},
plugins: [],
}
and I changed this code from
<div class="flex flex-wrap lg:w-4/5 sm:mx-auto sm:mb-2 -mx-2">
<div class="p-2 sm:w-1/2 w-full ">
<div
class="bg-orange-400 rounded flex p-4 h-full items-centertransition ease-in-out delay-150 hover:-translate-y-1 hover:scale-110 duration-300">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
class="text-gray-500 w-6 h-6 flex-shrink-0 mr-4" viewBox="0 0 24 24">
<path d="M22 11.08V12a10 10 0 11-5.93-9.14"></path>
<path d="M22 4L12 14.01l-3-3"></path>
</svg>
<span class="title-font font-medium text-gray-600">Attendance management</span>
</div>
</div>
</div>
to
<div class="flex flex-wrap lg:w-4/5 sm:mx-auto sm:mb-2 -mx-2">
<div class="p-2 sm:w-1/2 w-full ">
<div
class="bg-orange-400 rounded flex p-4 h-full items-centertransition ease-in-out delay-150 hover:-translate-y-1 hover:scale-110 duration-300">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="3" class="text-gray-500 w-6 h-6 flex-shrink-0 mr-4"
viewBox="0 0 24 24">
<path d="M22 11.08V12a10 10 0 11-5.93-9.14"></path>
<path d="M22 4L12 14.01l-3-3"></path>
</svg>
<span class="title-font font-medium text-mywhiteuse1">Attendance management</span>
</div>
</div>
</div>
and the text color is not changing I tried every method in this tailwindcss official documentation link:https://tailwindcss.com/docs/customizing-colors and still no method is working please help me
You can directly use any custom color like this text-[#F1EBEB]
<span class="title-font font-medium text-[#F1EBEB]">Attendance management</span>
This is the complete code
<script src="https://cdn.tailwindcss.com"></script>
<div class="flex flex-wrap lg:w-4/5 sm:mx-auto sm:mb-2 -mx-2">
<div class="p-2 sm:w-1/2 w-full ">
<div
class="bg-orange-400 rounded flex p-4 h-full items-centertransition ease-in-out delay-150 hover:-translate-y-1 hover:scale-110 duration-300">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="3" class="text-gray-500 w-6 h-6 flex-shrink-0 mr-4"
viewBox="0 0 24 24">
<path d="M22 11.08V12a10 10 0 11-5.93-9.14"></path>
<path d="M22 4L12 14.01l-3-3"></path>
</svg>
<span class="title-font font-medium text-[#F1EBEB]">Attendance management</span>
</div>
</div>
</div>
I'm trying to create a Mega Menu that triggers on Hover, using Tailwind CSS and Alpinejs. I kind of having it working, but it's really buggy.
I've tried adding x-on:mouseleave to different elements but it will either flicker constantly or only disappear when moving away from certain areas. So it will either disappear when moving below the menu and not when moving above and vice versa.
Any insight would be much appreciated!
https://codepen.io/kennyk3/pen/yLJmzYJ
<div class="bg-blue-800 hidden md:block">
<div class="max-w-screen-xl mx-auto">
<nav class="flex items-center justify-between flex-wrap">
<div class="w-full block flex-grow md:flex md:items-center md:w-auto">
<div class="font-bold md:flex-grow">
<ul class="flex justify-between">
<li>
LINK
</li>
<li>
LINK
</li>
<li>
LINK
</li>
<li>
LINK
</li>
<li class="group hover:bg-white">
<div x-data="{ resourcesMenu: false }" x-on:mouseover="resourcesMenu = !resourcesMenu" x-on:mouseleave="resourcesMenu = !resourcesMenu">
MEGA MENU
<div x-show="resourcesMenu" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 -translate-y-1" x-transition:enter-end="opacity-100 translate-y-0" x-transition:leave="transition ease-in duration-75" x-transition:leave-start="opacity-100 translate-y-0" x-transition:leave-end="opacity-0 -translate-y-1" class="absolute inset-x-0 transform shadow-lg -mt-1 z-10">
<div class="bg-white">
<div class="max-w-7xl mx-auto grid gap-y-6 px-4 py-6 sm:grid-cols-2 sm:gap-8 sm:px-6 sm:py-8 lg:grid-cols-4 lg:px-8 lg:py-12 xl:py-16">
<a href="#" class="-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50 transition ease-in-out duration-150">
<div class="flex md:h-full lg:flex-col">
<div class="flex-shrink-0">
<div class="inline-flex items-center justify-center h-10 w-10 rounded-md bg-indigo-500 text-white sm:h-12 sm:w-12">
<svg class="h-6 w-6" x-description="Heroicon name: chart-bar" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
</svg>
</div>
</div>
<div class="ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4">
<div>
<p class="text-base font-medium text-gray-900">
Analytics
</p>
<p class="mt-1 text-sm text-gray-500">
Get a better understanding of where your traffic is coming from.
</p>
</div>
<p class="mt-2 text-sm font-medium text-indigo-600 lg:mt-4">Learn more <span aria-hidden="true">→</span></p>
</div>
</div>
</a>
<a href="#" class="-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50 transition ease-in-out duration-150">
<div class="flex md:h-full lg:flex-col">
<div class="flex-shrink-0">
<div class="inline-flex items-center justify-center h-10 w-10 rounded-md bg-indigo-500 text-white sm:h-12 sm:w-12">
<svg class="h-6 w-6" x-description="Heroicon name: cursor-click" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122"></path>
</svg>
</div>
</div>
<div class="ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4">
<div>
<p class="text-base font-medium text-gray-900">
Engagement
</p>
<p class="mt-1 text-sm text-gray-500">
Speak directly to your customers in a more meaningful way.
</p>
</div>
<p class="mt-2 text-sm font-medium text-indigo-600 lg:mt-4">Learn more <span aria-hidden="true">→</span></p>
</div>
</div>
</a>
<a href="#" class="-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50 transition ease-in-out duration-150">
<div class="flex md:h-full lg:flex-col">
<div class="flex-shrink-0">
<div class="inline-flex items-center justify-center h-10 w-10 rounded-md bg-indigo-500 text-white sm:h-12 sm:w-12">
<svg class="h-6 w-6" x-description="Heroicon name: shield-check" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"></path>
</svg>
</div>
</div>
<div class="ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4">
<div>
<p class="text-base font-medium text-gray-900">
Security
</p>
<p class="mt-1 text-sm text-gray-500">
Your customers' data will be safe and secure.
</p>
</div>
<p class="mt-2 text-sm font-medium text-indigo-600 lg:mt-4">Learn more <span aria-hidden="true">→</span></p>
</div>
</div>
</a>
<a href="#" class="-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50 transition ease-in-out duration-150">
<div class="flex md:h-full lg:flex-col">
<div class="flex-shrink-0">
<div class="inline-flex items-center justify-center h-10 w-10 rounded-md bg-indigo-500 text-white sm:h-12 sm:w-12">
<svg class="h-6 w-6" x-description="Heroicon name: view-grid" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"></path>
</svg>
</div>
</div>
<div class="ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4">
<div>
<p class="text-base font-medium text-gray-900">
Integrations
</p>
<p class="mt-1 text-sm text-gray-500">
Connect with third-party tools that you're already using.
</p>
</div>
<p class="mt-2 text-sm font-medium text-indigo-600 lg:mt-4">Learn more <span aria-hidden="true">→</span></p>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</li>
<li>
LINK
</li>
<li class="md:hidden lg:inline-block">
LINK
</li>
<li class="md:hidden">
LINK
</li>
<li>
LINK
</li>
<li class="md:hidden lg:inline-block">
LINK
</li>
</ul>
</div>
</div>
</nav>
</div>
</div>
Change your trigger event from mouseover to mouseenter. The problem you're having is mouseover is triggered for the parent and its child elements.
See: https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseover_event
The mouseover event is fired at an Element when a pointing device (such as a mouse or trackpad) is used to move the cursor onto the element or one of its child elements.
Wheres mouseenter will be triggered once.
I'm using the free example navbar on tailwindui. I wrote some javascript to be able to toggle the menu on mobile and toggle the profile pic tooltip. However the profile pic tooltip doesn't close on clicks outside it.
My current javascript code only toggles the profile pic tooltip on and off when it's clicked. It doesn't hide the tooltip when outside it is clicked.
I tried using a click event listener and toggle the tooltip off when the event listener fired but that didn't work.
Using Javascript, how would you hide the profile pic tooltip on outside clicks?
document.getElementById('togglemebutton').onclick = function () {
document.getElementById("resultnav").classList.toggle("hidden");
}
//document.getElementById('togglemebutton').onclick = function () {
// document.getElementById("toggleme").classList.toggle("hidden");
//}
document.getElementById('toggleprofile').onclick = function () {
document.getElementById("resultprofile").classList.toggle("hidden");
}
<link href="https://unpkg.com/tailwindcss#^1.0/dist/tailwind.min.css" rel="stylesheet">
<nav class="bg-gray-800">
<div class="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8">
<div class="relative flex items-center justify-between h-16">
<div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
<!-- Mobile menu button-->
<button id="togglemebutton" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white transition duration-150 ease-in-out" aria-label="Main menu" aria-expanded="false">
<!-- Icon when menu is closed. -->
<!-- Menu open: "hidden", Menu closed: "block" -->
<svg class="block h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<!-- Icon when menu is open. -->
<!-- Menu open: "block", Menu closed: "hidden" -->
<svg class="hidden h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="flex-1 flex items-center justify-center sm:items-stretch sm:justify-start">
<div class="flex-shrink-0">
<img class="block lg:hidden h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-on-dark.svg" alt="Workflow logo">
<img class="hidden lg:block h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-logo-on-dark.svg" alt="Workflow logo">
</div>
<div class="hidden sm:block sm:ml-6">
<div class="flex">
Dashboard
Team
Projects
Calendar
</div>
</div>
</div>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
<button class="p-1 border-2 border-transparent text-gray-400 rounded-full hover:text-white focus:outline-none focus:text-white focus:bg-gray-700 transition duration-150 ease-in-out" aria-label="Notifications">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
<!-- Profile dropdown -->
<div class="ml-3 relative">
<div>
<button id="toggleprofile" class="flex text-sm border-2 border-transparent rounded-full focus:outline-none focus:border-white transition duration-150 ease-in-out" id="user-menu" aria-label="User menu" aria-haspopup="true">
<img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</button>
</div>
<!--
Profile dropdown panel, show/hide based on dropdown state.
Entering: "transition ease-out duration-100"
From: "transform opacity-0 scale-95"
To: "transform opacity-100 scale-100"
Leaving: "transition ease-in duration-75"
From: "transform opacity-100 scale-100"
To: "transform opacity-0 scale-95"
-->
<div id="resultprofile" class="hidden z-40 origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg">
<div class="py-1 rounded-md bg-white shadow-xs" role="menu" aria-orientation="vertical" aria-labelledby="user-menu">
Your Profile
Settings
Sign out
</div>
</div>
</div>
</div>
</div>
</div>
<!--
Mobile menu, toggle classes based on menu state.
Menu open: "block", Menu closed: "hidden"
-->
<div id="resultnav" class="hidden sm:hidden">
<div class="px-2 pt-2 pb-3">
Dashboard
Team
Projects
Calendar
</div>
</div>
</nav>
I tried using a click event listener and toggle the tooltip off when
the event listener fired but that didn't work.
This is exactly what you need, event listener on all elements:
const toggleprofile = document.getElementById("toggleprofile");
const resultprofile = document.getElementById("resultprofile");
[...document.querySelectorAll('body')].forEach(el => {
//in order to get all elements
el.addEventListener('click', event => {
//add click event to all of them
if (event.target.parentElement.id !== "toggleprofile") {
// if element is not profile picture - parent button has id, easier to target
console.clear();
console.log(event.target.parentElement.id)
resultprofile.classList.add("hidden")
//add class
}else{
resultprofile.classList.toggle("hidden")}
//if it is profile, toggle class
})
})
Keep in mind now you have click event listener on all elements on page, so if you need something else with other element, just expand this.
Working example:
document.getElementById('togglemebutton').onclick = function() {
document.getElementById("resultnav").classList.toggle("hidden");
}
//document.getElementById('togglemebutton').onclick = function () {
// document.getElementById("toggleme").classList.toggle("hidden");
//}
const toggleprofile = document.getElementById("toggleprofile");
const resultprofile = document.getElementById("resultprofile");
[...document.querySelectorAll('body')].forEach(el => {
el.addEventListener('click', event => {
if (event.target.parentElement.id !== "toggleprofile") {
console.clear();
console.log(event.target.parentElement.id)
resultprofile.classList.add("hidden")
}else{
resultprofile.classList.toggle("hidden")}
})
})
body{
height:300px}
<link href="https://unpkg.com/tailwindcss#^1.0/dist/tailwind.min.css" rel="stylesheet">
<nav class="bg-gray-800">
<div class="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8">
<div class="relative flex items-center justify-between h-16">
<div class="absolute inset-y-0 left-0 flex items-center sm:hidden">
<!-- Mobile menu button-->
<button id="togglemebutton" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:bg-gray-700 focus:text-white transition duration-150 ease-in-out" aria-label="Main menu"
aria-expanded="false">
<!-- Icon when menu is closed. -->
<!-- Menu open: "hidden", Menu closed: "block" -->
<svg class="block h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<!-- Icon when menu is open. -->
<!-- Menu open: "block", Menu closed: "hidden" -->
<svg class="hidden h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="flex-1 flex items-center justify-center sm:items-stretch sm:justify-start">
<div class="flex-shrink-0">
<img class="block lg:hidden h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-on-dark.svg" alt="Workflow logo">
<img class="hidden lg:block h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-logo-on-dark.svg" alt="Workflow logo">
</div>
<div class="hidden sm:block sm:ml-6">
<div class="flex">
Dashboard
Team
Projects
Calendar
</div>
</div>
</div>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 sm:static sm:inset-auto sm:ml-6 sm:pr-0">
<button class="p-1 border-2 border-transparent text-gray-400 rounded-full hover:text-white focus:outline-none focus:text-white focus:bg-gray-700 transition duration-150 ease-in-out" aria-label="Notifications">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
<!-- Profile dropdown -->
<div class="ml-3 relative">
<div>
<button id="toggleprofile" class="flex text-sm border-2 border-transparent rounded-full focus:outline-none focus:border-white transition duration-150 ease-in-out" id="user-menu" aria-label="User menu" aria-haspopup="true">
<img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</button>
</div>
<!--
Profile dropdown panel, show/hide based on dropdown state.
Entering: "transition ease-out duration-100"
From: "transform opacity-0 scale-95"
To: "transform opacity-100 scale-100"
Leaving: "transition ease-in duration-75"
From: "transform opacity-100 scale-100"
To: "transform opacity-0 scale-95"
-->
<div id="resultprofile" class="hidden z-40 origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg">
<div class="py-1 rounded-md bg-white shadow-xs" role="menu" aria-orientation="vertical" aria-labelledby="user-menu">
Your Profile
Settings
Sign out
</div>
</div>
</div>
</div>
</div>
</div>
<!--
Mobile menu, toggle classes based on menu state.
Menu open: "block", Menu closed: "hidden"
-->
<div id="resultnav" class="hidden sm:hidden">
<div class="px-2 pt-2 pb-3">
Dashboard
Team
Projects
Calendar
</div>
</div>
</nav>
Or as mentioned in comment:
window.addEventListener('click', event => {
if (event.target.parentElement.id !== "toggleprofile") {
console.clear();
console.log(event.target.parentElement.id);
resultprofile.classList.add("hidden")
} else {
resultprofile.classList.toggle("hidden")
}
})
I'll try to improve this others are requested to do the same