app-ui / lists / stacked-lists
With Inline Links And Actions Menu
05-with-inline-links-and-actions-menu.jsx
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react'
import { EllipsisVerticalIcon } from '@heroicons/react/20/solid'
const people = [
{
name: 'Leslie Alexander',
email: 'leslie.alexander@example.com',
role: 'Co-Founder / CEO',
imageUrl:
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
href: '#',
lastSeen: '3h ago',
lastSeenDateTime: '2023-01-23T13:23Z',
},
{
name: 'Michael Foster',
email: 'michael.foster@example.com',
role: 'Co-Founder / CTO',
imageUrl:
'https://images.unsplash.com/photo-1519244703995-f4e0f30006d5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
href: '#',
lastSeen: '3h ago',
lastSeenDateTime: '2023-01-23T13:23Z',
},
{
name: 'Dries Vincent',
email: 'dries.vincent@example.com',
role: 'Business Relations',
imageUrl:
'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
href: '#',
lastSeen: null,
},
{
name: 'Lindsay Walton',
email: 'lindsay.walton@example.com',
role: 'Front-end Developer',
imageUrl:
'https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
href: '#',
lastSeen: '3h ago',
lastSeenDateTime: '2023-01-23T13:23Z',
},
{
name: 'Courtney Henry',
email: 'courtney.henry@example.com',
role: 'Designer',
imageUrl:
'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
href: '#',
lastSeen: '3h ago',
lastSeenDateTime: '2023-01-23T13:23Z',
},
{
name: 'Tom Cook',
email: 'tom.cook@example.com',
role: 'Director of Product',
imageUrl:
'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',
href: '#',
lastSeen: null,
},
]
export default function Example() {
return (
<ul role="list" className="divide-y divide-gray-100 dark:divide-white/5">
{people.map((person) => (
<li key={person.email} className="flex justify-between gap-x-6 py-5">
<div className="flex min-w-0 gap-x-4">
<img
alt=""
src={person.imageUrl}
className="size-12 flex-none rounded-full bg-gray-50 dark:bg-gray-800 dark:outline dark:-outline-offset-1 dark:outline-white/10"
/>
<div className="min-w-0 flex-auto">
<p className="text-sm/6 font-semibold text-gray-900 dark:text-white">
<a href={person.href} className="hover:underline">
{person.name}
</a>
</p>
<p className="mt-1 flex text-xs/5 text-gray-500 dark:text-gray-400">
<a href={`mailto:${person.email}`} className="truncate hover:underline">
{person.email}
</a>
</p>
</div>
</div>
<div className="flex shrink-0 items-center gap-x-6">
<div className="hidden sm:flex sm:flex-col sm:items-end">
<p className="text-sm/6 text-gray-900 dark:text-white">{person.role}</p>
{person.lastSeen ? (
<p className="mt-1 text-xs/5 text-gray-500 dark:text-gray-400">
Last seen <time dateTime={person.lastSeenDateTime}>{person.lastSeen}</time>
</p>
) : (
<div className="mt-1 flex items-center gap-x-1.5">
<div className="flex-none rounded-full bg-emerald-500/20 p-1 dark:bg-emerald-500/30">
<div className="size-1.5 rounded-full bg-emerald-500" />
</div>
<p className="text-xs/5 text-gray-500 dark:text-gray-400">Online</p>
</div>
)}
</div>
<Menu as="div" className="relative flex-none">
<MenuButton className="relative block text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white">
<span className="absolute -inset-2.5" />
<span className="sr-only">Open options</span>
<EllipsisVerticalIcon aria-hidden="true" className="size-5" />
</MenuButton>
<MenuItems
transition
className="absolute right-0 z-10 mt-2 w-32 origin-top-right rounded-md bg-white py-2 shadow-lg outline outline-gray-900/5 transition data-closed:scale-95 data-closed:transform data-closed:opacity-0 data-enter:duration-100 data-enter:ease-out data-leave:duration-75 data-leave:ease-in dark:bg-gray-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10"
>
<MenuItem>
<a
href="#"
className="block px-3 py-1 text-sm/6 text-gray-900 data-focus:bg-gray-50 data-focus:outline-hidden dark:text-white dark:data-focus:bg-white/5"
>
View profile<span className="sr-only">, {person.name}</span>
</a>
</MenuItem>
<MenuItem>
<a
href="#"
className="block px-3 py-1 text-sm/6 text-gray-900 data-focus:bg-gray-50 data-focus:outline-hidden dark:text-white dark:data-focus:bg-white/5"
>
Message<span className="sr-only">, {person.name}</span>
</a>
</MenuItem>
</MenuItems>
</Menu>
</div>
</li>
))}
</ul>
)
}