mac multi select
This commit is contained in:
@@ -11,8 +11,7 @@ export const InstructionsPanel: React.FC = () => {
|
||||
<ul className="space-y-1 text-blue-700">
|
||||
<li>• Survolez les mots pour les mettre en évidence</li>
|
||||
<li>
|
||||
• Cliquez pour sélectionner un mot, Crtl + clic pour plusieurs
|
||||
mots
|
||||
• Cliquez pour sélectionner un mot, Ctrl/CMD (ou Shift) + clic.
|
||||
</li>
|
||||
<li>• Faites clic droit pour ouvrir le menu contextuel</li>
|
||||
<li>• Modifiez les labels et couleurs selon vos besoins</li>
|
||||
|
||||
@@ -52,8 +52,11 @@ export const InteractiveTextEditor: React.FC<InteractiveTextEditorProps> = ({
|
||||
(index: number, event: React.MouseEvent) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
|
||||
// Support multi-sélection avec Ctrl, Cmd et Shift
|
||||
const isMultiSelect = event.ctrlKey || event.metaKey || event.shiftKey;
|
||||
|
||||
if (isMultiSelect) {
|
||||
setSelectedWords((prev) => {
|
||||
const newSet = new Set(prev);
|
||||
if (newSet.has(index)) {
|
||||
|
||||
@@ -70,11 +70,24 @@ export const TextDisplay: React.FC<TextDisplayProps> = ({
|
||||
className={className}
|
||||
style={{
|
||||
backgroundColor: backgroundColor,
|
||||
userSelect: "none",
|
||||
WebkitUserSelect: "none",
|
||||
}}
|
||||
onMouseEnter={() => onWordHover(index)}
|
||||
onMouseLeave={() => onWordHover(null)}
|
||||
onClick={(e) => onWordClick(index, e)}
|
||||
onClick={(e) => {
|
||||
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
onWordClick(index, e);
|
||||
}}
|
||||
onContextMenu={onContextMenu}
|
||||
onMouseDown={(e) => {
|
||||
if (e.metaKey || e.ctrlKey || e.shiftKey) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
title={
|
||||
word.isEntity
|
||||
? `Entité: ${word.entityType} (Original: ${word.text})`
|
||||
|
||||
@@ -162,11 +162,15 @@ export const useContextMenu = ({
|
||||
if (!contextMenu.selectedText) return;
|
||||
|
||||
const originalText = contextMenu.selectedText;
|
||||
const firstWordIndex = contextMenu.wordIndices[0];
|
||||
const selectedIndices = contextMenu.wordIndices;
|
||||
|
||||
const clickedWord = words[firstWordIndex];
|
||||
const wordStart = clickedWord?.start;
|
||||
const wordEnd = clickedWord?.end;
|
||||
// Calculer les positions de début et fin pour tous les mots sélectionnés
|
||||
const sortedIndices = selectedIndices.sort((a, b) => a - b);
|
||||
const firstWord = words[sortedIndices[0]];
|
||||
const lastWord = words[sortedIndices[sortedIndices.length - 1]];
|
||||
|
||||
const wordStart = firstWord?.start;
|
||||
const wordEnd = lastWord?.end;
|
||||
|
||||
const existingMapping = entityMappings.find(
|
||||
(m) => m.text === originalText
|
||||
@@ -179,7 +183,9 @@ export const useContextMenu = ({
|
||||
text: originalText,
|
||||
label: displayName,
|
||||
entityType,
|
||||
applyToAll
|
||||
applyToAll,
|
||||
wordIndices: selectedIndices,
|
||||
positions: { start: wordStart, end: wordEnd }
|
||||
});
|
||||
|
||||
onUpdateMapping(
|
||||
|
||||
Reference in New Issue
Block a user