mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(site): add bouncy pop animation to inbox notification badge (#26057)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell. Replaces the basic `animate-in fade-in zoom-in duration-200` on the inbox unread badge with a bouncier pop using an overshoot easing. The badge now pops in from `scale(0)` with `cubic-bezier(0.34, 1.36, 0.64, 1)` over 500ms, giving it an elastic overshoot that makes it feel alive. Uses `tailwindcss-animate` utilities (`animate-in zoom-in-0 fade-in-0`) with just one arbitrary property for the easing. Conditional rendering is preserved as before. Also adds a `BadgeTransition` story with toggle buttons for easy visual verification. <img width="150" height="150" alt="preview-notification-animation" src="https://github.com/user-attachments/assets/70331cd2-c2e2-4fd7-8f9e-edfe876e2bab" />
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { useState } from "react";
|
||||
import { InboxButton } from "./InboxButton";
|
||||
|
||||
const meta: Meta<typeof InboxButton> = {
|
||||
@@ -16,3 +17,32 @@ export const Unread: Story = {
|
||||
unreadCount: 3,
|
||||
},
|
||||
};
|
||||
|
||||
export const BadgeTransition: Story = {
|
||||
render: function BadgeTransitionStory() {
|
||||
const [count, setCount] = useState(0);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-4">
|
||||
<InboxButton unreadCount={count} />
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
className="rounded border border-solid border-border px-3 py-1 text-sm bg-surface-primary text-content-primary"
|
||||
onClick={() => setCount((c) => c + 1)}
|
||||
>
|
||||
Add notification
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded border border-solid border-border px-3 py-1 text-sm bg-surface-primary text-content-primary"
|
||||
onClick={() => setCount(0)}
|
||||
>
|
||||
Clear all
|
||||
</button>
|
||||
</div>
|
||||
<span className="text-sm text-content-secondary">Count: {count}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -17,11 +17,12 @@ export const InboxButton: React.FC<InboxButtonProps> = ({
|
||||
{unreadCount > 0 && (
|
||||
<UnreadBadge
|
||||
count={unreadCount}
|
||||
className={cn([
|
||||
className={cn(
|
||||
"[--offset:calc(var(--unread-badge-size)/2)]",
|
||||
"absolute top-0 right-0 -mr-[--offset] -mt-[--offset]",
|
||||
"animate-in fade-in zoom-in duration-200",
|
||||
])}
|
||||
"origin-center animate-in zoom-in-0 fade-in-0 duration-500",
|
||||
"[animation-timing-function:cubic-bezier(0.34,1.36,0.64,1)]",
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user