88 TooltipTrigger ,
99} from '@/components/ui/tooltip' ;
1010import { Compartment , EditorState , StateEffect , StateField , RangeSetBuilder } from '@codemirror/state' ;
11- import { EditorView , keymap , lineNumbers , highlightActiveLine , Decoration , type DecorationSet , ViewPlugin } from '@codemirror/view' ;
11+ import { EditorView , keymap , lineNumbers , highlightActiveLine , Decoration , type DecorationSet } from '@codemirror/view' ;
1212import { defaultKeymap , history , historyKeymap , indentWithTab , undo , redo } from '@codemirror/commands' ;
1313import { syntaxHighlighting , HighlightStyle , bracketMatching } from '@codemirror/language' ;
1414import { search , highlightSelectionMatches } from '@codemirror/search' ;
@@ -94,8 +94,8 @@ const errorBaseTheme = EditorView.baseTheme({
9494 } ,
9595} ) ;
9696
97- const pastePlugin = ViewPlugin . define ( ( view ) => {
98- const handlePaste = ( event : ClipboardEvent ) => {
97+ const pasteHandler = EditorView . domEventHandlers ( {
98+ paste ( event , view ) {
9999 const text = event . clipboardData ?. getData ( 'text/plain' ) ;
100100 if ( text ) {
101101 const { state } = view ;
@@ -105,17 +105,10 @@ const pastePlugin = ViewPlugin.define((view) => {
105105 selection : { anchor : from + text . length } ,
106106 } ) ;
107107 event . preventDefault ( ) ;
108+ return true ;
108109 }
109- } ;
110-
111- const dom = view . dom ;
112- dom . addEventListener ( 'paste' , handlePaste , { passive : false } ) ;
113-
114- return {
115- destroy ( ) {
116- dom . removeEventListener ( 'paste' , handlePaste ) ;
117- } ,
118- } ;
110+ return false ;
111+ } ,
119112} ) ;
120113
121114
@@ -377,7 +370,7 @@ export const DaxEditor = forwardRef<DaxEditorHandle, DaxEditorProps>(function Da
377370 colorPickerExtension ( swatchCallbackRef ) ,
378371 errorField ,
379372 errorBaseTheme ,
380- pastePlugin ,
373+ pasteHandler ,
381374 highlightCompartmentRef . current . of ( syntaxHighlighting ( buildHighlight ( daxEditorTheme , theme ) ) ) ,
382375 themeCompartmentRef . current . of ( buildTheme ( daxEditorTheme , theme ) ) ,
383376 fontCompartmentRef . current . of ( buildFontSizeTheme ( fontSize ) ) ,
@@ -412,8 +405,25 @@ export const DaxEditor = forwardRef<DaxEditorHandle, DaxEditorProps>(function Da
412405 const handleScroll = ( ) => setShowScrollTop ( scroller . scrollTop > 300 ) ;
413406 scroller . addEventListener ( 'scroll' , handleScroll , { passive : true } ) ;
414407
408+ // Add global paste handler to ensure paste works even if editor loses focus
409+ const handleGlobalPaste = ( event : ClipboardEvent ) => {
410+ const text = event . clipboardData ?. getData ( 'text/plain' ) ;
411+ if ( text && containerRef . current ?. contains ( document . activeElement ) ) {
412+ const { state } = view ;
413+ const { from, to } = state . selection . main ;
414+ view . dispatch ( {
415+ changes : { from, to, insert : text } ,
416+ selection : { anchor : from + text . length } ,
417+ } ) ;
418+ event . preventDefault ( ) ;
419+ }
420+ } ;
421+
422+ document . addEventListener ( 'paste' , handleGlobalPaste , { capture : true } ) ;
423+
415424 return ( ) => {
416425 scroller . removeEventListener ( 'scroll' , handleScroll ) ;
426+ document . removeEventListener ( 'paste' , handleGlobalPaste , true ) ;
417427 view . destroy ( ) ;
418428 viewRef . current = null ;
419429 } ;
0 commit comments