/** * Copyright (c) 2023-present Plane Software, Inc. and contributors * SPDX-License-Identifier: AGPL-3.0-only * See the LICENSE file for details. */ import { useState } from "react"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { SmilePlus } from "lucide-react"; import { stringToEmoji } from "../emoji-icon-picker"; import type { EmojiReactionType } from "./emoji-reaction"; import { EmojiReactionGroup } from "./emoji-reaction"; import { EmojiReactionPicker } from "./emoji-reaction-picker"; const meta = { title: "Components/Emoji/EmojiReactionPicker", component: EmojiReactionPicker, parameters: { layout: "centered", }, tags: ["autodocs"], } satisfies Meta; export default meta; type Story = StoryObj; export const Default: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Pick Emoji", }, render() { const [isOpen, setIsOpen] = useState(false); const [selectedEmoji, setSelectedEmoji] = useState(null); return (
{selectedEmoji ? stringToEmoji(selectedEmoji) : } } /> {selectedEmoji && (
Selected: {selectedEmoji}
)}
); }, }; export const WithCustomLabel: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Add Reaction", }, render() { const [isOpen, setIsOpen] = useState(false); const [selectedEmoji, setSelectedEmoji] = useState(null); return (
{selectedEmoji ? stringToEmoji(selectedEmoji) : } Add Reaction } /> {selectedEmoji &&
Selected: {selectedEmoji}
}
); }, }; export const InlineReactions: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Add", }, render() { const [isOpen, setIsOpen] = useState(false); const [reactions, setReactions] = useState([ { emoji: "👍", count: 3, reacted: false, users: ["Alice", "Bob", "Charlie"] }, { emoji: "❤️", count: 2, reacted: true, users: ["You", "David"] }, ]); const handleReactionAdd = (emoji: string) => { setReactions((prev) => { const existing = prev.find((r) => r.emoji === emoji); if (existing) { return prev.map((r) => (r.emoji === emoji ? { ...r, count: r.count + 1, reacted: true } : r)); } return [...prev, { emoji, count: 1, reacted: true, users: ["You"] }]; }); }; const handleReactionClick = (emoji: string) => { setReactions((prev) => prev.map((r) => { if (r.emoji === emoji) { return { ...r, reacted: !r.reacted, count: r.reacted ? r.count - 1 : r.count + 1, }; } return r; }) ); }; return (
setIsOpen(true)} showAddButton={false} /> } />
); }, }; export const DifferentPlacements: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Placements", }, render() { const [isOpen1, setIsOpen1] = useState(false); const [isOpen2, setIsOpen2] = useState(false); const [isOpen3, setIsOpen3] = useState(false); const [isOpen4, setIsOpen4] = useState(false); return (
Bottom Start: {}} placement="bottom-start" label={} />
Bottom End: {}} placement="bottom-end" label={} />
Top Start: {}} placement="top-start" label={} />
Top End: {}} placement="top-end" label={} />
); }, }; export const SearchDisabled: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "No Search", }, render() { const [isOpen, setIsOpen] = useState(false); const [selectedEmoji, setSelectedEmoji] = useState(null); return (
No Search } /> {selectedEmoji &&
Selected: {selectedEmoji}
}
); }, }; export const CustomSearchPlaceholder: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Custom Search", }, render() { const [isOpen, setIsOpen] = useState(false); const [selectedEmoji, setSelectedEmoji] = useState(null); return (
Custom Search } /> {selectedEmoji &&
Selected: {selectedEmoji}
}
); }, }; export const CloseOnSelectDisabled: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Select Multiple", }, render() { const [isOpen, setIsOpen] = useState(false); const [selectedEmojis, setSelectedEmojis] = useState([]); const handleChange = (emoji: string) => { setSelectedEmojis((prev) => [...prev, emoji]); }; return (
Select Multiple (Stays Open) } />
{selectedEmojis.length > 0 && (
Selected ({selectedEmojis.length}):
{selectedEmojis.map((emoji, idx) => ( {emoji} ))}
)}
); }, }; export const InMessageContext: Story = { args: { isOpen: false, handleToggle: () => {}, onChange: () => {}, label: "Message", }, render() { const [isOpen, setIsOpen] = useState(false); const [reactions, setReactions] = useState([ { emoji: "👍", count: 5, reacted: false, users: ["Alice", "Bob", "Charlie"] }, ]); const handleReactionAdd = (emoji: string) => { setReactions((prev) => { const existing = prev.find((r) => r.emoji === emoji); if (existing) { return prev.map((r) => (r.emoji === emoji ? { ...r, count: r.count + 1, reacted: true } : r)); } return [...prev, { emoji, count: 1, reacted: true, users: ["You"] }]; }); }; const handleReactionClick = (emoji: string) => { setReactions((prev) => prev.map((r) => { if (r.emoji === emoji) { return { ...r, reacted: !r.reacted, count: r.reacted ? r.count - 1 : r.count + 1, }; } return r; }) ); }; return (
AB
Alice Brown
Just finished the design for the new dashboard! Would love to hear your thoughts.
} />
); }, };