packages/react-aria-components/docs/examples/notifications-popover.mdx
{/* Copyright 2023 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}
import {ExampleLayout} from '@react-spectrum/docs'; export default ExampleLayout;
import docs from 'docs:react-aria-components'; import {TypeLink} from '@react-spectrum/docs'; import styles from '@react-spectrum/docs/src/docs.css'; import Popover from '@react-spectrum/docs/pages/assets/component-illustrations/Popover.svg'; import Button from '@react-spectrum/docs/pages/assets/component-illustrations/ActionButton.svg'; import Dialog from '@react-spectrum/docs/pages/assets/component-illustrations/Dialog.svg'; import Link from '@react-spectrum/docs/pages/assets/component-illustrations/Link.svg'; import {ExampleCard} from '@react-spectrum/docs/src/ExampleCard'; import ChevronRight from '@spectrum-icons/workflow/ChevronRight';
A notifications Popover styled with Tailwind CSS.
import './tailwind.global.css';
import {DialogTrigger, Button, Popover, OverlayArrow, Dialog, Link} from 'react-aria-components';
import type {PopoverProps} from 'react-aria-components';
import {Bell, MessageSquare} from 'lucide-react';
function PopoverExample() {
return (
<div className="bg-linear-to-r from-orange-400 to-pink-600 p-8 rounded-lg sm:h-[300px] flex items-start justify-center">
<DialogTrigger>
<Button aria-label="Notifications" className="inline-flex items-center justify-center rounded-md bg-black/20 bg-clip-padding border border-white/20 px-3.5 py-2 font-medium text-white hover:bg-black/30 pressed:bg-black/40 transition-colors cursor-default outline-hidden focus-visible:ring-2 focus-visible:ring-white/75">
<Bell className="w-6 h-6" />
</Button>
<MyPopover>
<OverlayArrow>
<svg viewBox="0 0 12 12" className="block fill-white group-placement-bottom:rotate-180 w-4 h-4">
<path d="M0 0L6 6L12 0" />
</svg>
</OverlayArrow>
<Dialog className="p-2 outline-hidden text-gray-700">
<div className="flex flex-col">
<Notification avatar="https://images.unsplash.com/photo-1569913486515-b74bf7751574?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" name="Sonja Balmann" time="2h" text="This looks great! Let's ship it." />
<Notification avatar="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" name="Maia Pettegree" time="4h" text="Can you add a bit more pizzazz?" />
<Notification avatar="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80" name="Charles Webb" time="1d" text="Here's a first pass. What do you think?" />
</div>
</Dialog>
</MyPopover>
</DialogTrigger>
</div>
);
}
function MyPopover(props: PopoverProps) {
return (
<Popover
{...props}
className={({isEntering, isExiting}) => `
w-[280px] placement-bottom:mt-2 placement-top:mb-2 group rounded-lg drop-shadow-lg ring-1 ring-black/10 bg-white
${isEntering ? 'animate-in fade-in placement-bottom:slide-in-from-top-1 placement-top:slide-in-from-bottom-1 ease-out duration-200' : ''}
${isExiting ? 'animate-out fade-out placement-bottom:slide-out-to-top-1 placement-top:slide-out-to-bottom-1 ease-in duration-150' : ''}
`} />
);
}
function Notification({avatar, name, time, text}) {
return (
<Link href="#" className="p-2 rounded-lg hover:bg-gray-100 grid grid-cols-[theme(width.5)_1fr_theme(width.4)] gap-x-2 text-[inherit] no-underline outline-hidden focus-visible:ring-2 ring-pink-800">
<div className="text-gray-800 font-semibold leading-5">{name}</div>
<div className="text-gray-400"><MessageSquare className="w-4 h-4" /></div>
<div className="text-sm text-gray-500 col-span-2">Commented {time} ago</div>
<p className="text-sm overflow-hidden text-ellipsis line-clamp-2 mt-1 mb-0 col-span-2">{text}</p>
</Link>
);
}
This example uses the following plugins:
When using Tailwind v4, add them to your CSS:
@import "tailwindcss";
@plugin "tailwindcss-react-aria-components";
@plugin "tailwindcss-animate";
When using Tailwind v3, add the plugins to your tailwind.config.js instead:
module.exports = {
// ...
plugins: [
require('tailwindcss-react-aria-components'),
require('tailwindcss-animate')
]
};
Note: When using Tailwind v3, install tailwindcss-react-aria-components version 1.x instead of 2.x.
<ExampleCard url="../Popover.html" title="Popover" description="A popover displays content in context with a trigger element."> <Popover /> </ExampleCard>
<ExampleCard url="../Dialog.html" title="Dialog" description="A dialog is an overlay shown above other content in an application.">
<Dialog /> </ExampleCard><ExampleCard url="../Button.html" title="Button" description="A button allows a user to perform an action."> <Button /> </ExampleCard>
<ExampleCard url="../Link.html" title="Link" description="A link allows a user to navigate to another page.">
<Link /> </ExampleCard> </section>