66 lines
2.7 KiB
TypeScript
66 lines
2.7 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
Heading1,
|
|
Heading2,
|
|
List,
|
|
Quote,
|
|
Code,
|
|
Image as ImageIcon,
|
|
Type,
|
|
Sparkles
|
|
} from 'lucide-react';
|
|
import { motion, AnimatePresence } from 'motion/react';
|
|
|
|
interface SlashMenuProps {
|
|
position: { top: number; left: number };
|
|
onSelect: (type: string) => void;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export const SlashMenu: React.FC<SlashMenuProps> = ({ position, onSelect, onClose }) => {
|
|
const commands = [
|
|
{ id: 'h1', label: 'Titre Principal', icon: <Heading1 size={14} />, desc: 'Grand titre de section' },
|
|
{ id: 'h2', label: 'Sous-titre', icon: <Heading2 size={14} />, desc: 'Titre de niveau 2' },
|
|
{ id: 'bullet', label: 'Liste à puces', icon: <List size={14} />, desc: 'Liste simple' },
|
|
{ id: 'quote', label: 'Citation', icon: <Quote size={14} />, desc: 'Bloc de texte mis en avant' },
|
|
{ id: 'code', label: 'Bloc de Code', icon: <Code size={14} />, desc: 'Code ou texte technique' },
|
|
{ id: 'image', label: 'Image', icon: <ImageIcon size={14} />, desc: 'Insérer un visuel' },
|
|
{ id: 'ai-summary', label: 'Résumé IA', icon: <Sparkles size={14} />, desc: 'Générer un résumé court', special: true },
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<div className="fixed inset-0 z-[60]" onClick={onClose} />
|
|
<motion.div
|
|
initial={{ opacity: 0, scale: 0.95, y: 10 }}
|
|
animate={{ opacity: 1, scale: 1, y: 0 }}
|
|
exit={{ opacity: 0, scale: 0.95, y: 10 }}
|
|
className="fixed z-[70] w-64 bg-white dark:bg-[#1A1A1A] border border-border shadow-2xl rounded-xl overflow-hidden py-2"
|
|
style={{ top: position.top, left: position.left }}
|
|
>
|
|
<div className="px-3 py-2 text-[10px] font-bold text-concrete uppercase tracking-widest border-b border-border/40 mb-1">
|
|
Commandes rapides
|
|
</div>
|
|
<div className="max-h-80 overflow-y-auto custom-scrollbar">
|
|
{commands.map((cmd) => (
|
|
<button
|
|
key={cmd.id}
|
|
onClick={() => onSelect(cmd.id)}
|
|
className="w-full flex items-start gap-3 px-3 py-2 hover:bg-paper dark:hover:bg-white/5 transition-colors group text-left"
|
|
>
|
|
<div className={`p-2 rounded-lg border border-border transition-colors group-hover:border-ink/20
|
|
${cmd.special ? 'bg-blueprint/10 text-blueprint border-blueprint/20' : 'bg-white/50 dark:bg-white/5 text-ink'}`}>
|
|
{cmd.icon}
|
|
</div>
|
|
<div className="space-y-0.5">
|
|
<p className="text-xs font-bold text-ink">{cmd.label}</p>
|
|
<p className="text-[10px] text-muted-ink leading-tight">{cmd.desc}</p>
|
|
</div>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
</>
|
|
);
|
|
};
|