Skip to content
This repository has been archived by the owner on Dec 1, 2024. It is now read-only.

Commit

Permalink
Make the emoji picker only render when used
Browse files Browse the repository at this point in the history
  • Loading branch information
mybearworld committed Jul 28, 2024
1 parent 3928e3d commit 85b0f02
Showing 1 changed file with 95 additions and 100 deletions.
195 changes: 95 additions & 100 deletions src/components/EmojiPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ReactNode, useEffect, useState } from "react";
import * as Popover from "@radix-ui/react-popover";
import * as Tabs from "@radix-ui/react-tabs";
import { Menu, MenuItem } from "./Menu";
import { DiscordEmoji, discordEmoji } from "../lib/discordEmoji";
Expand All @@ -15,6 +14,18 @@ export type EmojiPickerProps = {
trigger: ReactNode;
};
export const EmojiPicker = (props: EmojiPickerProps) => {
return (
<Menu
trigger={props.trigger}
contextMenu={false}
contentProps={{ className: "w-80" }}
>
<EmojiPickerBase {...props} />
</Menu>
);
};

const EmojiPickerBase = (props: EmojiPickerProps) => {
const storageSkinTone = localStorage.getItem(SKIN_TONE_STORAGE_KEY);
const numberStorageSkinTone = Number(storageSkinTone);
const [skinTone, setSkinTone] = useState(
Expand All @@ -26,6 +37,7 @@ export const EmojiPicker = (props: EmojiPickerProps) => {
const allowDiscordEmoji = props.discordEmoji ?? true;

useEffect(() => {
console.log("running");
localStorage.setItem(SKIN_TONE_STORAGE_KEY, skinTone.toString());
}, [skinTone]);

Expand All @@ -37,106 +49,89 @@ export const EmojiPicker = (props: EmojiPickerProps) => {
}

return (
<Popover.Root>
<Popover.Trigger asChild>{props.trigger}</Popover.Trigger>
<Popover.Anchor />
<Popover.Portal>
<Popover.Content align="end" asChild sideOffset={4}>
<div className="z-[--z-above-sidebar] w-80 rounded-lg border border-gray-200 bg-white px-2 py-1 dark:border-gray-800 dark:bg-gray-950">
<Tabs.Root defaultValue={allowDiscordEmoji ? "meower" : "people"}>
<Tabs.List className="mb-2 flex justify-center gap-2">
{emojiCategories.map((category) => (
<Tabs.Trigger asChild value={category.id} key={category.id}>
<button
type="button"
aria-label={category.id}
className="border-b-2 border-transparent text-xl aria-selected:border-lime-500 aria-selected:dark:border-lime-600"
>
{category.categoryEmoji}
</button>
</Tabs.Trigger>
<Tabs.Root defaultValue={allowDiscordEmoji ? "meower" : "people"}>
<Tabs.List className="mb-2 flex justify-center gap-2">
{emojiCategories.map((category) => (
<Tabs.Trigger asChild value={category.id} key={category.id}>
<button
type="button"
aria-label={category.id}
className="border-b-2 border-transparent text-xl aria-selected:border-lime-500 aria-selected:dark:border-lime-600"
>
{category.categoryEmoji}
</button>
</Tabs.Trigger>
))}
{allowDiscordEmoji ?
<Tabs.Trigger asChild value="meower">
<button
aria-label="Meower"
className="border-b-2 border-transparent text-xl aria-selected:border-lime-500 aria-selected:dark:border-lime-600"
>
</button>
</Tabs.Trigger>
: undefined}
</Tabs.List>
{emojiCategories.map((category) => (
<Tabs.Content value={category.id} key={category.id}>
<div className="grid max-h-80 grid-cols-7 flex-wrap justify-center gap-0 overflow-auto px-2">
{category.emoji.map((emoji) => {
const firstEmoji = emoji[0];
if (!firstEmoji) {
return undefined;
}
return (
<button
className="p-1 text-xl"
key={emoji.toString()}
onClick={() => props.onEmoji(emoji[skinTone] ?? firstEmoji)}
>
{emoji[skinTone] ?? firstEmoji}
</button>
);
})}
</div>
{category.id === "people" ?
<div className="flex justify-end">
<Menu
trigger={
<button className="flex items-center gap-1 p-1 text-xl">
<span>{skinToneEmoji[skinTone] ?? skinToneEmoji[0]}</span>
<ChevronDown className="h-5 w-5" />
</button>
}
>
{skinToneEmoji.map((emoji, i) => (
<MenuItem
key={emoji}
aria-label={`Skin tone ${i}`}
onClick={() => setSkinTone(i)}
>
{emoji}
</MenuItem>
))}
{allowDiscordEmoji ?
<Tabs.Trigger asChild value="meower">
<button
aria-label="Meower"
className="border-b-2 border-transparent text-xl aria-selected:border-lime-500 aria-selected:dark:border-lime-600"
>
</button>
</Tabs.Trigger>
: undefined}
</Tabs.List>
{emojiCategories.map((category) => (
<Tabs.Content value={category.id} key={category.id}>
<div className="grid max-h-80 grid-cols-7 flex-wrap justify-center gap-0 overflow-auto px-2">
{category.emoji.map((emoji) => {
const firstEmoji = emoji[0];
if (!firstEmoji) {
return undefined;
}
return (
<button
className="p-1 text-xl"
key={emoji.toString()}
onClick={() =>
props.onEmoji(emoji[skinTone] ?? firstEmoji)
}
>
{emoji[skinTone] ?? firstEmoji}
</button>
);
})}
</div>
{category.id === "people" ?
<div className="flex justify-end">
<Menu
trigger={
<button className="flex items-center gap-1 p-1 text-xl">
<span>
{skinToneEmoji[skinTone] ?? skinToneEmoji[0]}
</span>
<ChevronDown className="h-5 w-5" />
</button>
}
>
{skinToneEmoji.map((emoji, i) => (
<MenuItem
key={emoji}
aria-label={`Skin tone ${i}`}
onClick={() => setSkinTone(i)}
>
{emoji}
</MenuItem>
))}
</Menu>
</div>
: undefined}
</Tabs.Content>
))}
{allowDiscordEmoji ?
<Tabs.Content value="meower">
<div className="grid max-h-80 grid-cols-7 flex-wrap justify-center gap-0 overflow-auto px-2">
{discordEmoji.map((emoji) => (
<button
key={emoji.id}
className="box-content h-6 w-6 p-1"
title={`:${emoji.name}:`}
onClick={() => props.onEmoji(emoji)}
>
<img
src={urlFromDiscordEmoji(emoji)}
alt={emoji.name}
/>
</button>
))}
</div>
</Tabs.Content>
: undefined}
</Tabs.Root>
</Menu>
</div>
: undefined}
</Tabs.Content>
))}
{allowDiscordEmoji ?
<Tabs.Content value="meower">
<div className="grid max-h-80 grid-cols-7 flex-wrap justify-center gap-0 overflow-auto px-2">
{discordEmoji.map((emoji) => (
<button
key={emoji.id}
className="box-content h-6 w-6 p-1"
title={`:${emoji.name}:`}
onClick={() => props.onEmoji(emoji)}
>
<img src={urlFromDiscordEmoji(emoji)} alt={emoji.name} />
</button>
))}
</div>
</Popover.Content>
</Popover.Portal>
</Popover.Root>
</Tabs.Content>
: undefined}
</Tabs.Root>
);
};

0 comments on commit 85b0f02

Please sign in to comment.