This commit is contained in:
Jamie Brunton committed 2025-12-30 18:44:37 +00:00
1 parent c902763f9c
commit 25ab750c7d
5 files changed
+94 -12

No files matched your search

+2
View File
@@ -10,6 +10,8 @@
"preview": "vite preview"
},
"dependencies": {
"@emoji-mart/data": "^1.2.1",
"@emoji-mart/react": "^1.1.1",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
@@ -0,0 +1,59 @@
import { useState, useRef, useEffect } from 'react';
import data from '@emoji-mart/data';
import Picker from '@emoji-mart/react';
import { Button } from './button';
interface EmojiPickerProps {
value: string;
onChange: (emoji: string) => void;
}
export function EmojiPicker({ value, onChange }: EmojiPickerProps) {
const [open, setOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
setOpen(false);
}
}
if (open) {
document.addEventListener('mousedown', handleClickOutside);
}
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [open]);
const handleEmojiSelect = (emoji: any) => {
onChange(emoji.native);
setOpen(false);
};
return (
<div className="relative" ref={containerRef}>
<Button
type="button"
variant="outline"
className="w-16 h-16 text-3xl"
onClick={() => setOpen(!open)}
>
{value || '📚'}
</Button>
{open && (
<div className="absolute top-full left-0 mt-2 z-50">
<Picker
data={data}
onEmojiSelect={handleEmojiSelect}
theme="light"
previewPosition="none"
skinTonePosition="none"
/>
</div>
)}
</div>
);
}
@@ -7,6 +7,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { EmojiPicker } from '@/components/ui/emoji-picker';
import { Skeleton } from '@/components/ui/skeleton';
import {
Dialog,
@@ -225,13 +226,10 @@ export function CategoriesPage() {
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label htmlFor="icon">Icon (emoji)</Label>
<Input
id="icon"
<Label>Icon</Label>
<EmojiPicker
value={formData.icon}
onChange={(e) => setFormData(d => ({ ...d, icon: e.target.value }))}
placeholder="📚"
className="w-20 text-center text-2xl"
onChange={(emoji) => setFormData(d => ({ ...d, icon: emoji }))}
/>
</div>
+4 -6
View File
@@ -8,6 +8,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Switch } from '@/components/ui/switch';
import { EmojiPicker } from '@/components/ui/emoji-picker';
import { Badge } from '@/components/ui/badge';
import { Skeleton } from '@/components/ui/skeleton';
import {
@@ -286,13 +287,10 @@ export function PacksPage() {
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label htmlFor="icon">Icon (emoji)</Label>
<Input
id="icon"
<Label>Icon</Label>
<EmojiPicker
value={formData.icon}
onChange={(e) => setFormData(d => ({ ...d, icon: e.target.value }))}
placeholder="💕"
className="w-20 text-center text-2xl"
onChange={(emoji) => setFormData(d => ({ ...d, icon: emoji }))}
/>
</div>