fix(ui): move onMouseDown prevention to individual toolbar buttons and default linkNewTab to false

- move `e.preventDefault()` from toolbar container to each individual button to avoid broad focus prevention
- default `linkNewTab` state to `false` instead of `true` for new links
- add `onMouseDown` prevention to color grid buttons
This commit is contained in:
2026-04-25 18:35:11 -04:00
parent 2666d1a7fd
commit 9893ade233
@@ -27,7 +27,7 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
const [pos, setPos] = useState({ top: 0, left: 0, flipped: false }); const [pos, setPos] = useState({ top: 0, left: 0, flipped: false });
const [popover, setPopover] = useState(null); // 'color' | 'highlight' | 'link' | null const [popover, setPopover] = useState(null); // 'color' | 'highlight' | 'link' | null
const [linkUrl, setLinkUrl] = useState(''); const [linkUrl, setLinkUrl] = useState('');
const [linkNewTab, setLinkNewTab] = useState(true); const [linkNewTab, setLinkNewTab] = useState(false);
useEffect(() => { useEffect(() => {
onPinChange?.(popover !== null); onPinChange?.(popover !== null);
@@ -91,7 +91,7 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
function openLinkPopover() { function openLinkPopover() {
const link = activeMarks.find(m => m.type === 'link'); const link = activeMarks.find(m => m.type === 'link');
setLinkUrl(link?.href ?? ''); setLinkUrl(link?.href ?? '');
setLinkNewTab(link ? !!link.newTab : true); setLinkNewTab(link ? !!link.newTab : false);
setPopover(p => (p === 'link' ? null : 'link')); setPopover(p => (p === 'link' ? null : 'link'));
} }
@@ -101,13 +101,13 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
data-inline-toolbar data-inline-toolbar
className="fixed z-50 flex items-center gap-0.5 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md px-1 py-1" className="fixed z-50 flex items-center gap-0.5 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md px-1 py-1"
style={{ top: pos.top, left: pos.left }} style={{ top: pos.top, left: pos.left }}
onMouseDown={(e) => e.preventDefault()}
> >
{SIMPLE_BUTTONS.map(btn => ( {SIMPLE_BUTTONS.map(btn => (
<button <button
key={btn.type} key={btn.type}
type="button" type="button"
title={btn.title} title={btn.title}
onMouseDown={(e) => e.preventDefault()}
onClick={() => handleSimple(btn.type)} onClick={() => handleSimple(btn.type)}
className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${btn.className} ${isActive(btn.type) ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`} className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${btn.className} ${isActive(btn.type) ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
> >
@@ -120,6 +120,7 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
<button <button
type="button" type="button"
title="Couleur du texte" title="Couleur du texte"
onMouseDown={(e) => e.preventDefault()}
onClick={() => setPopover(p => (p === 'color' ? null : 'color'))} onClick={() => setPopover(p => (p === 'color' ? null : 'color'))}
className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('color') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`} className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('color') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
> >
@@ -128,6 +129,7 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
<button <button
type="button" type="button"
title="Surlignage" title="Surlignage"
onMouseDown={(e) => e.preventDefault()}
onClick={() => setPopover(p => (p === 'highlight' ? null : 'highlight'))} onClick={() => setPopover(p => (p === 'highlight' ? null : 'highlight'))}
className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('highlight') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`} className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('highlight') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
> >
@@ -136,6 +138,7 @@ export default function InlineToolbar({ rect, activeMarks, onToggleMark, onPinCh
<button <button
type="button" type="button"
title="Lien (Ctrl+K)" title="Lien (Ctrl+K)"
onMouseDown={(e) => e.preventDefault()}
onClick={openLinkPopover} onClick={openLinkPopover}
className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('link') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`} className={`w-7 h-7 flex items-center justify-center rounded text-sm text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 ${isActive('link') ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
> >
@@ -213,6 +216,7 @@ function ColorGrid({ mode, activeKey, onPick }) {
key={key} key={key}
type="button" type="button"
title={key} title={key}
onMouseDown={(e) => e.preventDefault()}
onClick={() => onPick(key)} onClick={() => onPick(key)}
className={`w-6 h-6 flex items-center justify-center rounded ${tw} ${activeKey === key ? 'ring-2 ring-blue-500' : ''}`} className={`w-6 h-6 flex items-center justify-center rounded ${tw} ${activeKey === key ? 'ring-2 ring-blue-500' : ''}`}
> >