Wednesday, June 5, 2024
 Popular · Latest · Hot · Upcoming
21
rated 0 times [  23] [ 2]  / answers: 1 / hits: 9307  / 2 Years ago, sun, february 6, 2022, 12:00:00

Headless UI provides an example for a dropdown menu, where when you click the button, the dropdown opens below.


enter


The code for this is here:


import { Menu, Transition } from '@headlessui/react'
import { Fragment, useEffect, useRef, useState } from 'react'
import { ChevronDownIcon } from '@heroicons/react/solid'

export default function Example() {
return (
<div className="w-56 text-right fixed top-16">
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="inline-flex justify-center w-full px-4 py-2 text-sm font-medium text-white bg-black rounded-md bg-opacity-20 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
Options
<ChevronDownIcon
className="w-5 h-5 ml-2 -mr-1 text-violet-200 hover:text-violet-100"
aria-hidden="true"
/>
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 w-56 mt-2 origin-top-right bg-white divide-y divide-gray-100 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="px-1 py-1 ">
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<EditActiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
) : (
<EditInactiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
)}
Edit
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<DuplicateActiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
) : (
<DuplicateInactiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
)}
Duplicate
</button>
)}
</Menu.Item>
</div>
<div className="px-1 py-1">
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<ArchiveActiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
) : (
<ArchiveInactiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
)}
Archive
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<MoveActiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
) : (
<MoveInactiveIcon
className="w-5 h-5 mr-2"
aria-hidden="true"
/>
)}
Move
</button>
)}
</Menu.Item>
</div>
<div className="px-1 py-1">
<Menu.Item>
{({ active }) => (
<button
className={`${
active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<DeleteActiveIcon
className="w-5 h-5 mr-2 text-violet-400"
aria-hidden="true"
/>
) : (
<DeleteInactiveIcon
className="w-5 h-5 mr-2 text-violet-400"
aria-hidden="true"
/>
)}
Delete
</button>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</Menu>
</div>
)
}

function EditInactiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 13V16H7L16 7L13 4L4 13Z"
fill="#EDE9FE"
stroke="#A78BFA"
strokeWidth="2"
/>
</svg>
)
}

function EditActiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 13V16H7L16 7L13 4L4 13Z"
fill="#8B5CF6"
stroke="#C4B5FD"
strokeWidth="2"
/>
</svg>
)
}

function DuplicateInactiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 4H12V12H4V4Z"
fill="#EDE9FE"
stroke="#A78BFA"
strokeWidth="2"
/>
<path
d="M8 8H16V16H8V8Z"
fill="#EDE9FE"
stroke="#A78BFA"
strokeWidth="2"
/>
</svg>
)
}

function DuplicateActiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4 4H12V12H4V4Z"
fill="#8B5CF6"
stroke="#C4B5FD"
strokeWidth="2"
/>
<path
d="M8 8H16V16H8V8Z"
fill="#8B5CF6"
stroke="#C4B5FD"
strokeWidth="2"
/>
</svg>
)
}

function ArchiveInactiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="5"
y="8"
width="10"
height="8"
fill="#EDE9FE"
stroke="#A78BFA"
strokeWidth="2"
/>
<rect
x="4"
y="4"
width="12"
height="4"
fill="#EDE9FE"
stroke="#A78BFA"
strokeWidth="2"
/>
<path d="M8 12H12" stroke="#A78BFA" strokeWidth="2" />
</svg>
)
}

function ArchiveActiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="5"
y="8"
width="10"
height="8"
fill="#8B5CF6"
stroke="#C4B5FD"
strokeWidth="2"
/>
<rect
x="4"
y="4"
width="12"
height="4"
fill="#8B5CF6"
stroke="#C4B5FD"
strokeWidth="2"
/>
<path d="M8 12H12" stroke="#A78BFA" strokeWidth="2" />
</svg>
)
}

function MoveInactiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M10 4H16V10" stroke="#A78BFA" strokeWidth="2" />
<path d="M16 4L8 12" stroke="#A78BFA" strokeWidth="2" />
<path d="M8 6H4V16H14V12" stroke="#A78BFA" strokeWidth="2" />
</svg>
)
}

function MoveActiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M10 4H16V10" stroke="#C4B5FD" strokeWidth="2" />
<path d="M16 4L8 12" stroke="#C4B5FD" strokeWidth="2" />
<path d="M8 6H4V16H14V12" stroke="#C4B5FD" strokeWidth="2" />
</svg>
)
}

function DeleteInactiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="5"
y="6"
width="10"
height="10"
fill="#EDE9FE"
stroke="#A78BFA"
strokeWidth="2"
/>
<path d="M3 6H17" stroke="#A78BFA" strokeWidth="2" />
<path d="M8 6V4H12V6" stroke="#A78BFA" strokeWidth="2" />
</svg>
)
}

function DeleteActiveIcon(props) {
return (
<svg
{...props}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect
x="5"
y="6"
width="10"
height="10"
fill="#8B5CF6"
stroke="#C4B5FD"
strokeWidth="2"
/>
<path d="M3 6H17" stroke="#C4B5FD" strokeWidth="2" />
<path d="M8 6V4H12V6" stroke="#C4B5FD" strokeWidth="2" />
</svg>
)
}

What I need to do is to have the dropdown menu open above the button instead of below. Something like below:


enter


Can anyone please help me figure out the correct styling to achieve this? It uses TailwindCSS styles.


More From » reactjs

 Answers
1



<script src=https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js></script>


import { Menu, Transition } from '@headlessui/react'
import { Fragment, useEffect, useRef, useState } from 'react'
import { ChevronDownIcon } from '@heroicons/react/solid'

export default function Example() {
return (

<div className=w-56 text-right fixed top-16>
<Menu as=div className=relative inline-block text-left>
<div>
<Menu.Button className=inline-flex justify-center w-full px-4 py-2 text-sm font-medium text-white bg-black rounded-md bg-opacity-20 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75>
Options
<ChevronDownIcon
className=w-5 h-5 ml-2 -mr-1 text-violet-200 hover:text-violet-100
aria-hidden=true
/>
</Menu.Button>
</div>
<Transition
as={Fragment}
enter=transition ease-out duration-100
enterFrom=transform opacity-0 scale-95
enterTo=transform opacity-100 scale-100
leave=transition ease-in duration-75
leaveFrom=transform opacity-100 scale-100
leaveTo=transform opacity-0 scale-95
>
<Menu.Items className=-top-2 transform -translate-y-full absolute right-0 w-56 origin-top-right bg-white divide-y divide-gray-100 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none>
<div className=px-1 py-1 >
<Menu.Item>
{({ active }) => (
<button
className={`${active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<EditActiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
) : (
<EditInactiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
)}
Edit
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
className={`${active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<DuplicateActiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
) : (
<DuplicateInactiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
)}
Duplicate
</button>
)}
</Menu.Item>
</div>
<div className=px-1 py-1>
<Menu.Item>
{({ active }) => (
<button
className={`${active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<ArchiveActiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
) : (
<ArchiveInactiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
)}
Archive
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
className={`${active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<MoveActiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
) : (
<MoveInactiveIcon
className=w-5 h-5 mr-2
aria-hidden=true
/>
)}
Move
</button>
)}
</Menu.Item>
</div>
<div className=px-1 py-1>
<Menu.Item>
{({ active }) => (
<button
className={`${active ? 'bg-violet-500 text-white' : 'text-gray-900'
} group flex rounded-md items-center w-full px-2 py-2 text-sm`}
>
{active ? (
<DeleteActiveIcon
className=w-5 h-5 mr-2 text-violet-400
aria-hidden=true
/>
) : (
<DeleteInactiveIcon
className=w-5 h-5 mr-2 text-violet-400
aria-hidden=true
/>
)}
Delete
</button>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</Menu>
</div>


)
}

function EditInactiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<path
d=M4 13V16H7L16 7L13 4L4 13Z
fill=#EDE9FE
stroke=#A78BFA
strokeWidth=2
/>
</svg>
)
}

function EditActiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<path
d=M4 13V16H7L16 7L13 4L4 13Z
fill=#8B5CF6
stroke=#C4B5FD
strokeWidth=2
/>
</svg>
)
}

function DuplicateInactiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<path
d=M4 4H12V12H4V4Z
fill=#EDE9FE
stroke=#A78BFA
strokeWidth=2
/>
<path
d=M8 8H16V16H8V8Z
fill=#EDE9FE
stroke=#A78BFA
strokeWidth=2
/>
</svg>
)
}

function DuplicateActiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<path
d=M4 4H12V12H4V4Z
fill=#8B5CF6
stroke=#C4B5FD
strokeWidth=2
/>
<path
d=M8 8H16V16H8V8Z
fill=#8B5CF6
stroke=#C4B5FD
strokeWidth=2
/>
</svg>
)
}

function ArchiveInactiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<rect
x=5
y=8
width=10
height=8
fill=#EDE9FE
stroke=#A78BFA
strokeWidth=2
/>
<rect
x=4
y=4
width=12
height=4
fill=#EDE9FE
stroke=#A78BFA
strokeWidth=2
/>
<path d=M8 12H12 stroke=#A78BFA strokeWidth=2 />
</svg>
)
}

function ArchiveActiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<rect
x=5
y=8
width=10
height=8
fill=#8B5CF6
stroke=#C4B5FD
strokeWidth=2
/>
<rect
x=4
y=4
width=12
height=4
fill=#8B5CF6
stroke=#C4B5FD
strokeWidth=2
/>
<path d=M8 12H12 stroke=#A78BFA strokeWidth=2 />
</svg>
)
}

function MoveInactiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<path d=M10 4H16V10 stroke=#A78BFA strokeWidth=2 />
<path d=M16 4L8 12 stroke=#A78BFA strokeWidth=2 />
<path d=M8 6H4V16H14V12 stroke=#A78BFA strokeWidth=2 />
</svg>
)
}

function MoveActiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<path d=M10 4H16V10 stroke=#C4B5FD strokeWidth=2 />
<path d=M16 4L8 12 stroke=#C4B5FD strokeWidth=2 />
<path d=M8 6H4V16H14V12 stroke=#C4B5FD strokeWidth=2 />
</svg>
)
}

function DeleteInactiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<rect
x=5
y=6
width=10
height=10
fill=#EDE9FE
stroke=#A78BFA
strokeWidth=2
/>
<path d=M3 6H17 stroke=#A78BFA strokeWidth=2 />
<path d=M8 6V4H12V6 stroke=#A78BFA strokeWidth=2 />
</svg>
)
}

function DeleteActiveIcon(props) {
return (
<svg
{...props}
viewBox=0 0 20 20
fill=none
xmlns=http://www.w3.org/2000/svg
>
<rect
x=5
y=6
width=10
height=10
fill=#8B5CF6
stroke=#C4B5FD
strokeWidth=2
/>
<path d=M3 6H17 stroke=#C4B5FD strokeWidth=2 />
<path d=M8 6V4H12V6 stroke=#C4B5FD strokeWidth=2 />
</svg>
)
}




What I changed was <Menu.Items className="-top-2 transform -translate-y-full absolute right-0 w-56 origin-top-right bg-white divide-y divide-gray-100 rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">


please checkout if it works as you prefer.


[#397] Sunday, January 30, 2022, 2 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
monicag

Total Points: 651
Total Questions: 106
Total Answers: 104

Location: Grenada
Member since Sun, Dec 20, 2020
4 Years ago
monicag questions
;