R: Apply withPreventDefault utility

This commit is contained in:
Ivan 2025-07-08 12:37:08 +03:00
parent 022041881b
commit b62797205b
7 changed files with 84 additions and 107 deletions

View File

@ -5,6 +5,8 @@ import { Background, ReactFlow, type ReactFlowProps } from 'reactflow';
export { useReactFlow, useStoreApi } from 'reactflow'; export { useReactFlow, useStoreApi } from 'reactflow';
import { withPreventDefault } from '@/utils/utils';
import { cn } from '../utils'; import { cn } from '../utils';
type DiagramFlowProps = { type DiagramFlowProps = {
@ -48,9 +50,7 @@ export function DiagramFlow({
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) { function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
if (event.code === 'Space') { if (event.code === 'Space') {
event.preventDefault(); withPreventDefault(() => setSpaceMode(true))(event);
event.stopPropagation();
setSpaceMode(true);
} }
onKeyDown?.(event); onKeyDown?.(event);
} }

View File

@ -9,6 +9,7 @@ import { useDialogsStore } from '@/stores/dialogs';
import { usePreferencesStore } from '@/stores/preferences'; import { usePreferencesStore } from '@/stores/preferences';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { promptText } from '@/utils/labels'; import { promptText } from '@/utils/labels';
import { withPreventDefault } from '@/utils/utils';
import { useDeleteBlock } from '../../../backend/use-delete-block'; import { useDeleteBlock } from '../../../backend/use-delete-block';
import { useMutatingOss } from '../../../backend/use-mutating-oss'; import { useMutatingOss } from '../../../backend/use-mutating-oss';
@ -149,36 +150,26 @@ export function OssFlow() {
return; return;
} }
if (event.key === 'Escape') { if (event.key === 'Escape') {
event.preventDefault(); withPreventDefault(resetSelectedElements)(event);
event.stopPropagation();
resetSelectedElements();
return; return;
} }
if (!isMutable) { if (!isMutable) {
return; return;
} }
if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') { if ((event.ctrlKey || event.metaKey) && event.code === 'KeyS') {
event.preventDefault(); withPreventDefault(handleSavePositions)(event);
event.stopPropagation();
handleSavePositions();
return; return;
} }
if (event.altKey && event.code === 'Key1') { if (event.altKey && event.code === 'Key1') {
event.preventDefault(); withPreventDefault(handleCreateBlock)(event);
event.stopPropagation();
handleCreateBlock();
return; return;
} }
if (event.altKey && event.code === 'Key2') { if (event.altKey && event.code === 'Key2') {
event.preventDefault(); withPreventDefault(handleCreateOperation)(event);
event.stopPropagation();
handleCreateOperation();
return; return;
} }
if (event.key === 'Delete') { if (event.key === 'Delete') {
event.preventDefault(); withPreventDefault(handleDeleteSelected)(event);
event.stopPropagation();
handleDeleteSelected();
return; return;
} }
} }

View File

@ -18,6 +18,7 @@ import { usePreferencesStore } from '@/stores/preferences';
import { APP_COLORS } from '@/styling/colors'; import { APP_COLORS } from '@/styling/colors';
import { CodeMirrorWrapper } from '@/utils/codemirror'; import { CodeMirrorWrapper } from '@/utils/codemirror';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { withPreventDefault } from '@/utils/utils';
import { type IReferenceInputState } from '../../dialogs/dlg-edit-reference/dlg-edit-reference'; import { type IReferenceInputState } from '../../dialogs/dlg-edit-reference/dlg-edit-reference';
import { ReferenceType } from '../../models/language'; import { ReferenceType } from '../../models/language';
@ -117,6 +118,53 @@ export const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
if (onBlur) onBlur(event); if (onBlur) onBlur(event);
} }
function onEditRef() {
const wrap = new CodeMirrorWrapper(thisRef.current as Required<ReactCodeMirrorRef>);
wrap.fixSelection(ReferenceTokens);
const nodes = wrap.getEnvelopingNodes(ReferenceTokens);
const data: IReferenceInputState = {
type: ReferenceType.ENTITY,
refRaw: '',
text: '',
mainRefs: [],
basePosition: 0
};
if (nodes.length !== 1) {
data.text = wrap.getSelectionText();
} else {
data.type = nodes[0].type.id === RefEntity ? ReferenceType.ENTITY : ReferenceType.SYNTACTIC;
data.refRaw = wrap.getSelectionText();
}
const selection = wrap.getSelection();
const mainNodes = wrap
.getAllNodes([RefEntity])
.filter(node => node.from >= selection.to || node.to <= selection.from);
data.mainRefs = mainNodes.map(node => wrap.getText(node.from, node.to));
data.basePosition = mainNodes.filter(node => node.to <= selection.from).length;
setIsEditing(true);
showEditReference({
schema: schema,
initial: data,
onCancel: () => {
setIsEditing(false);
setTimeout(() => {
thisRef.current?.view?.focus();
}, PARAMETER.minimalTimeout);
},
onSave: ref => {
wrap.replaceWith(referenceToString(ref));
setIsEditing(false);
setTimeout(() => {
thisRef.current?.view?.focus();
}, PARAMETER.minimalTimeout);
}
});
}
function handleInput(event: React.KeyboardEvent<HTMLDivElement>) { function handleInput(event: React.KeyboardEvent<HTMLDivElement>) {
if (!thisRef.current?.view) { if (!thisRef.current?.view) {
event.preventDefault(); event.preventDefault();
@ -124,53 +172,8 @@ export const RefsInput = forwardRef<ReactCodeMirrorRef, RefsInputInputProps>(
return; return;
} }
if ((event.ctrlKey || event.metaKey) && event.code === 'Space') { if ((event.ctrlKey || event.metaKey) && event.code === 'Space') {
event.preventDefault(); withPreventDefault(onEditRef)(event);
event.stopPropagation(); return;
const wrap = new CodeMirrorWrapper(thisRef.current as Required<ReactCodeMirrorRef>);
wrap.fixSelection(ReferenceTokens);
const nodes = wrap.getEnvelopingNodes(ReferenceTokens);
const data: IReferenceInputState = {
type: ReferenceType.ENTITY,
refRaw: '',
text: '',
mainRefs: [],
basePosition: 0
};
if (nodes.length !== 1) {
data.text = wrap.getSelectionText();
} else {
data.type = nodes[0].type.id === RefEntity ? ReferenceType.ENTITY : ReferenceType.SYNTACTIC;
data.refRaw = wrap.getSelectionText();
}
const selection = wrap.getSelection();
const mainNodes = wrap
.getAllNodes([RefEntity])
.filter(node => node.from >= selection.to || node.to <= selection.from);
data.mainRefs = mainNodes.map(node => wrap.getText(node.from, node.to));
data.basePosition = mainNodes.filter(node => node.to <= selection.from).length;
setIsEditing(true);
showEditReference({
schema: schema,
initial: data,
onCancel: () => {
setIsEditing(false);
setTimeout(() => {
thisRef.current?.view?.focus();
}, PARAMETER.minimalTimeout);
},
onSave: ref => {
wrap.replaceWith(referenceToString(ref));
setIsEditing(false);
setTimeout(() => {
thisRef.current?.view?.focus();
}, PARAMETER.minimalTimeout);
}
});
} }
} }

View File

@ -10,7 +10,7 @@ import { IconCSV } from '@/components/icons';
import { SearchBar } from '@/components/input'; import { SearchBar } from '@/components/input';
import { useFitHeight } from '@/stores/app-layout'; import { useFitHeight } from '@/stores/app-layout';
import { infoMsg } from '@/utils/labels'; import { infoMsg } from '@/utils/labels';
import { convertToCSV } from '@/utils/utils'; import { convertToCSV, withPreventDefault } from '@/utils/utils';
import { CstType } from '../../../backend/types'; import { CstType } from '../../../backend/types';
import { useMutatingRSForm } from '../../../backend/use-mutating-rsform'; import { useMutatingRSForm } from '../../../backend/use-mutating-rsform';
@ -34,7 +34,6 @@ export function EditorRSList() {
moveUp, moveUp,
moveDown, moveDown,
cloneCst, cloneCst,
canDeleteSelected,
promptDeleteCst, promptDeleteCst,
navigateCst navigateCst
} = useRSEdit(); } = useRSEdit();
@ -74,27 +73,22 @@ export function EditorRSList() {
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) { function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
if (event.key === 'Escape') { if (event.key === 'Escape') {
event.preventDefault(); withPreventDefault(deselectAll)(event);
event.stopPropagation();
deselectAll();
return; return;
} }
if (!isContentEditable || isProcessing) { if (!isContentEditable || isProcessing) {
return; return;
} }
if (event.key === 'Delete' && canDeleteSelected) { if (event.key === 'Delete') {
event.preventDefault(); withPreventDefault(promptDeleteCst)(event);
event.stopPropagation();
promptDeleteCst();
return; return;
} }
if (!event.altKey || event.shiftKey) { if (event.altKey && !event.shiftKey) {
return; if (processAltKey(event.code)) {
} event.preventDefault();
if (processAltKey(event.code)) { event.stopPropagation();
event.preventDefault(); return;
event.stopPropagation(); }
return;
} }
} }

View File

@ -6,6 +6,7 @@ import { type Edge, MarkerType, type Node, useEdgesState, useNodesState, useOnSe
import { DiagramFlow, useReactFlow, useStoreApi } from '@/components/flow/diagram-flow'; import { DiagramFlow, useReactFlow, useStoreApi } from '@/components/flow/diagram-flow';
import { useMainHeight } from '@/stores/app-layout'; import { useMainHeight } from '@/stores/app-layout';
import { PARAMETER } from '@/utils/constants'; import { PARAMETER } from '@/utils/constants';
import { withPreventDefault } from '@/utils/utils';
import { useMutatingRSForm } from '../../../backend/use-mutating-rsform'; import { useMutatingRSForm } from '../../../backend/use-mutating-rsform';
import { ToolbarGraphSelection } from '../../../components/toolbar-graph-selection'; import { ToolbarGraphSelection } from '../../../components/toolbar-graph-selection';
@ -39,17 +40,8 @@ export function TGFlow() {
const store = useStoreApi(); const store = useStoreApi();
const { addSelectedNodes } = store.getState(); const { addSelectedNodes } = store.getState();
const isProcessing = useMutatingRSForm(); const isProcessing = useMutatingRSForm();
const { const { isContentEditable, schema, selected, setSelected, promptDeleteCst, focusCst, setFocus, deselectAll } =
isContentEditable, useRSEdit();
schema,
selected,
setSelected,
canDeleteSelected,
promptDeleteCst,
focusCst,
setFocus,
deselectAll
} = useRSEdit();
const [nodes, setNodes, onNodesChange] = useNodesState([]); const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [edges, setEdges] = useEdgesState([]); const [edges, setEdges] = useEdgesState([]);
@ -140,20 +132,14 @@ export function TGFlow() {
return; return;
} }
if (event.key === 'Escape') { if (event.key === 'Escape') {
event.preventDefault(); withPreventDefault(() => setFocus(null))(event);
event.stopPropagation();
setFocus(null);
return; return;
} }
if (!isContentEditable) { if (!isContentEditable) {
return; return;
} }
if (event.key === 'Delete') { if (event.key === 'Delete') {
event.preventDefault(); withPreventDefault(promptDeleteCst)(event);
event.stopPropagation();
if (canDeleteSelected) {
promptDeleteCst();
}
return; return;
} }
} }

View File

@ -2,6 +2,7 @@ import { useReactFlow } from 'reactflow';
import { HelpTopic } from '@/features/help'; import { HelpTopic } from '@/features/help';
import { BadgeHelp } from '@/features/help/components/badge-help'; import { BadgeHelp } from '@/features/help/components/badge-help';
import { type ILibraryItemReference } from '@/features/library';
import { MiniSelectorOSS } from '@/features/library/components/mini-selector-oss'; import { MiniSelectorOSS } from '@/features/library/components/mini-selector-oss';
import { MiniButton } from '@/components/control'; import { MiniButton } from '@/components/control';
@ -61,7 +62,7 @@ export function ToolbarTermGraph() {
} }
function handleDeleteCst() { function handleDeleteCst() {
if (!canDeleteSelected || isProcessing) { if (isProcessing) {
return; return;
} }
promptDeleteCst(); promptDeleteCst();
@ -94,14 +95,13 @@ export function ToolbarTermGraph() {
}); });
} }
function handleSelectOss(event: React.MouseEvent<HTMLElement>, newValue: ILibraryItemReference) {
navigateOss(newValue.id, event.ctrlKey || event.metaKey);
}
return ( return (
<div className='cc-icons'> <div className='cc-icons'>
{schema.oss.length > 0 ? ( {schema.oss.length > 0 ? <MiniSelectorOSS items={schema.oss} onSelect={handleSelectOss} /> : null}
<MiniSelectorOSS
items={schema.oss}
onSelect={(event, value) => navigateOss(value.id, event.ctrlKey || event.metaKey)}
/>
) : null}
<MiniButton <MiniButton
title='Настройки фильтрации узлов и связей' title='Настройки фильтрации узлов и связей'
icon={<IconFilter size='1.25rem' className='icon-primary' />} icon={<IconFilter size='1.25rem' className='icon-primary' />}

View File

@ -241,6 +241,9 @@ export const RSEditState = ({
} }
function promptDeleteCst() { function promptDeleteCst() {
if (!canDeleteSelected) {
return;
}
showDeleteCst({ showDeleteCst({
schema: schema, schema: schema,
selected: selected, selected: selected,