Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions docs/src/app/(docs)/react/components/popover/demos/_index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@

.Title {
margin: 0;
padding-right: 2rem;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 700;
Expand All @@ -103,6 +104,83 @@
}
}

.Link {
align-self: flex-start;
font-size: 0.875rem;
line-height: 1.25rem;
color: oklch(14.5% 0 0deg);
text-decoration: underline;
text-decoration-thickness: 1px;
text-underline-offset: 0.16em;

@media (prefers-color-scheme: dark) {
color: white;
}

@media (hover: hover) {
&:hover {
text-decoration: none;
}
}

&:focus-visible {
outline: 2px solid oklch(14.5% 0 0deg);
outline-offset: 2px;

@media (prefers-color-scheme: dark) {
outline-color: white;
}
}
}

.Close {
box-sizing: border-box;
position: absolute;
top: 0.5rem;
right: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
width: 1.75rem;
height: 1.75rem;
padding: 0;
margin: 0;
border: none;
background: none;
color: oklch(14.5% 0 0deg);

@media (prefers-color-scheme: dark) {
color: white;
}

@media (hover: hover) {
&:hover {
background-color: oklch(97% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(26.9% 0 0deg);
}
}
}

&:active {
background-color: oklch(92.2% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(37.1% 0 0deg);
}
}

&:focus-visible {
outline: 2px solid oklch(14.5% 0 0deg);
outline-offset: -1px;

@media (prefers-color-scheme: dark) {
outline-color: white;
}
}
}

.Container {
display: flex;
gap: 8px;
Expand Down Expand Up @@ -182,3 +260,72 @@
}
}
}

.IconButton {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
padding: 0;
margin: 0;
outline: 0;
border: 1px solid oklch(14.5% 0 0deg);
border-radius: 0;
background-color: white;
color: oklch(14.5% 0 0deg);
-webkit-user-select: none;
user-select: none;

@media (prefers-color-scheme: dark) {
border: 1px solid white;
background-color: oklch(14.5% 0 0deg);
color: white;
}

@media (hover: hover) {
&:hover:not([data-disabled]) {
background-color: oklch(97% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(26.9% 0 0deg);
}
}
}

&:active:not([data-disabled]) {
background-color: oklch(92.2% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(37.1% 0 0deg);
}
}

&[data-pressed] {
background-color: oklch(97% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(26.9% 0 0deg);
}
}

&[data-disabled] {
color: oklch(55.6% 0 0deg);
border-color: oklch(55.6% 0 0deg);

@media (prefers-color-scheme: dark) {
color: oklch(70.8% 0 0deg);
border-color: oklch(70.8% 0 0deg);
}
}

&:focus-visible {
outline: 2px solid oklch(14.5% 0 0deg);
outline-offset: -1px;

@media (prefers-color-scheme: dark) {
outline-color: white;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,38 @@ export default function PopoverDetachedTriggersControlledDemo() {
<Popover.Positioner className={styles.Positioner} sideOffset={8}>
<Popover.Popup className={styles.Popup}>
<Popover.Arrow className={styles.Arrow} />
<Popover.Title className={styles.Title}>Notifications</Popover.Title>
<Popover.Title className={styles.Title}>Free shipping</Popover.Title>
<Popover.Description className={styles.Description}>
You are all caught up. Good job!
Orders over $50 arrive in 3–5 business days at no extra cost.
</Popover.Description>
<a href="#" className={styles.Link}>
View shipping policy
</a>
<Popover.Close aria-label="Close" className={styles.Close}>
<XIcon />
</Popover.Close>
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
</React.Fragment>
);
}

function XIcon(props: React.ComponentProps<'svg'>) {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeLinecap="square"
strokeLinejoin="round"
{...props}
style={{ display: 'block', ...props.style }}
>
<path d="m4.5 4.5 7 7m-7 0 7-7" />
</svg>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,44 @@ export default function PopoverDetachedTriggersControlledDemo() {
>
<Popover.Popup className="relative flex h-[var(--popup-height,auto)] w-[var(--popup-width,auto)] max-w-[500px] flex-col gap-1 origin-[var(--transform-origin)] bg-white dark:bg-neutral-950 p-3 text-neutral-950 dark:text-white outline-none border border-neutral-950 dark:border-white shadow-[0.25rem_0.25rem_0] shadow-black/12 dark:shadow-none transition-[scale,opacity] duration-100 ease-out data-ending-style:scale-[0.98] data-ending-style:opacity-0 data-starting-style:scale-[0.98] data-starting-style:opacity-0">
<Popover.Arrow className="relative block w-3 h-1.5 overflow-clip data-[side=bottom]:top-[-6px] data-[side=left]:right-[-9px] data-[side=left]:rotate-90 data-[side=right]:left-[-9px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-6px] data-[side=top]:rotate-180 before:content-[''] before:absolute before:bottom-0 before:left-1/2 before:w-[calc(6px*sqrt(2))] before:h-[calc(6px*sqrt(2))] before:bg-white dark:before:bg-neutral-950 before:border before:border-neutral-950 dark:before:border-white before:[transform:translate(-50%,50%)_rotate(45deg)]" />
<Popover.Title className="text-sm font-bold">Notifications</Popover.Title>
<Popover.Title className="pr-8 text-sm font-bold">Free shipping</Popover.Title>
<Popover.Description className="text-sm text-neutral-600 dark:text-neutral-400">
You are all caught up. Good job!
Orders over $50 arrive in 3–5 business days at no extra cost.
</Popover.Description>
<a
href="#"
className="self-start text-sm text-neutral-950 dark:text-white underline underline-offset-[0.16em] decoration-[1px] hover:no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-neutral-950 dark:focus-visible:outline-white"
>
View shipping policy
</a>
<Popover.Close
aria-label="Close"
className="absolute top-2 right-2 flex size-7 items-center justify-center border-0 bg-transparent p-0 text-neutral-950 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 active:bg-neutral-200 dark:active:bg-neutral-700 focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-neutral-950 dark:focus-visible:outline-white"
>
<XIcon />
</Popover.Close>
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
</Popover.Root>
</React.Fragment>
);
}

function XIcon(props: React.ComponentProps<'svg'>) {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeLinecap="square"
strokeLinejoin="round"
{...props}
style={{ display: 'block', ...props.style }}
>
<path d="m4.5 4.5 7 7m-7 0 7-7" />
</svg>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@

.Title {
margin: 0;
padding-right: 2rem;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 700;
Expand All @@ -172,6 +173,54 @@
}
}

.Close {
box-sizing: border-box;
position: absolute;
top: 0.25rem;
right: 0.25rem;
display: flex;
align-items: center;
justify-content: center;
width: 1.75rem;
height: 1.75rem;
padding: 0;
margin: 0;
border: none;
background: none;
color: oklch(14.5% 0 0deg);

@media (prefers-color-scheme: dark) {
color: white;
}

@media (hover: hover) {
&:hover {
background-color: oklch(97% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(26.9% 0 0deg);
}
}
}

&:active {
background-color: oklch(92.2% 0 0deg);

@media (prefers-color-scheme: dark) {
background-color: oklch(37.1% 0 0deg);
}
}

&:focus-visible {
outline: 2px solid oklch(14.5% 0 0deg);
outline-offset: -1px;

@media (prefers-color-scheme: dark) {
outline-color: white;
}
}
}

.Container {
display: flex;
gap: 0.5rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@ const demoPopover = Popover.createHandle<React.ComponentType>();
export default function PopoverDetachedTriggersFullDemo() {
return (
<div className={styles.Container}>
<Popover.Trigger
className={baseStyles.Button}
handle={demoPopover}
payload={NotificationsPanel}
>
Notifications
<Popover.Trigger className={baseStyles.Button} handle={demoPopover} payload={ShippingPanel}>
Shipping
</Popover.Trigger>

<Popover.Trigger className={baseStyles.Button} handle={demoPopover} payload={ActivityPanel}>
Activity
<Popover.Trigger className={baseStyles.Button} handle={demoPopover} payload={ReturnsPanel}>
Returns
</Popover.Trigger>

<Popover.Trigger className={baseStyles.Button} handle={demoPopover} payload={ProfilePanel}>
Expand All @@ -35,6 +31,10 @@ export default function PopoverDetachedTriggersFullDemo() {
<Popover.Viewport className={styles.Viewport}>
{Payload !== undefined && <Payload />}
</Popover.Viewport>

<Popover.Close aria-label="Close" className={styles.Close}>
<XIcon />
</Popover.Close>
</Popover.Popup>
</Popover.Positioner>
</Popover.Portal>
Expand All @@ -44,12 +44,12 @@ export default function PopoverDetachedTriggersFullDemo() {
);
}

function NotificationsPanel() {
function ShippingPanel() {
return (
<div className={styles.Stack}>
<Popover.Title className={styles.Title}>Notifications</Popover.Title>
<Popover.Title className={styles.Title}>Free shipping</Popover.Title>
<Popover.Description className={styles.Description}>
You are all caught up. Good job!
Orders over $50 arrive in 3–5 business days at no extra cost.
</Popover.Description>
</div>
);
Expand All @@ -75,13 +75,31 @@ function ProfilePanel() {
);
}

function ActivityPanel() {
function ReturnsPanel() {
return (
<div className={styles.Stack}>
<Popover.Title className={styles.Title}>Activity</Popover.Title>
<Popover.Title className={styles.Title}>Free returns</Popover.Title>
<Popover.Description className={styles.Description}>
Nothing interesting happened recently.
Return any item within 30 days for a full refund.
</Popover.Description>
</div>
);
}

function XIcon(props: React.ComponentProps<'svg'>) {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeLinecap="square"
strokeLinejoin="round"
{...props}
style={{ display: 'block', ...props.style }}
>
<path d="m4.5 4.5 7 7m-7 0 7-7" />
</svg>
);
}
Loading
Loading