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
7 changes: 5 additions & 2 deletions src/features/notifications/components/notification-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ function NotificationCard({ n }: { n: AppNotification }) {
<div className="flex items-center gap-2">
{!n.read && <span className="h-1.5 w-1.5 shrink-0 rounded-full bg-[var(--primary)]" />}
<span className="truncate text-sm font-medium text-foreground">{n.title}</span>
<span className="ml-auto shrink-0 text-3xs text-muted-foreground tabular-nums">
{/* Gives way to the Dismiss button, which takes its place on hover. */}
<span className="ml-auto shrink-0 text-3xs text-muted-foreground tabular-nums transition-opacity group-hover:opacity-0 group-has-[[data-dismiss]:focus-visible]:opacity-0">
{timeAgo(n.timestamp, { suffix: true })}
</span>
</div>
Expand All @@ -160,11 +161,13 @@ function NotificationCard({ n }: { n: AppNotification }) {
<Hint label="Dismiss">
<button
type="button"
data-dismiss
aria-label="Dismiss"
onClick={(e) => {
e.stopPropagation();
dismiss(n.id);
}}
className="absolute right-1.5 top-1.5 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 grid h-5 w-5 place-items-center rounded-md text-muted-foreground hover:text-foreground hover:bg-element-active transition-opacity"
className="absolute right-2 top-2.5 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 grid h-5 w-5 place-items-center rounded-md text-muted-foreground hover:text-foreground hover:bg-element-active transition-opacity"
>
<X size={11} />
</button>
Expand Down
21 changes: 21 additions & 0 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -2612,3 +2612,24 @@
white-space: pre-wrap;
overflow-wrap: anywhere;
}

/* Two-button toasts (a notification's actions ride sonner's `action` and
`cancel` slots) put the buttons on their own row. Sonner lays the icon,
text and buttons out in one flex row, so two buttons took ~150px and left
the title and body a narrow column that wrapped every few words. Here the
text claims the whole first row beside the icon and the buttons wrap below
it, right-aligned: sonner gives every button an auto start margin
(`--toast-button-margin-start`), which on a row of their own splits the
free space between them, so only the first (`cancel`) keeps it. One button
is narrow enough to stay inline. Same (0,4,0)+ prefix as the description
rule above, for the same import-order reason. */
[data-sonner-toaster] [data-sonner-toast][data-styled="true"]:has([data-cancel]) {
flex-wrap: wrap;
row-gap: 10px;
}
[data-sonner-toaster] [data-sonner-toast][data-styled="true"]:has([data-cancel]) [data-content] {
flex-basis: calc(100% - 32px);
}
[data-sonner-toaster] [data-sonner-toast][data-styled="true"]:has([data-cancel]) [data-action] {
margin-left: 0;
}
Loading