Skip to content

Commit 06965a4

Browse files
committed
process plain text as fallback
1 parent 641e735 commit 06965a4

1 file changed

Lines changed: 29 additions & 8 deletions

File tree

packages/grid/src/key-handlers/PasteKeyHandler.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ export function parseValueFromNodes(nodes: NodeListOf<ChildNode>): string[][] {
4545
return result;
4646
}
4747

48+
export function parseValueFromText(text: string): string[][] {
49+
return text
50+
.trim()
51+
.split('\n')
52+
.map(row => row.split('\t'));
53+
}
54+
4855
export function parseValueFromElement(
4956
element: HTMLElement
5057
): string | string[][] | null {
@@ -104,21 +111,35 @@ class PasteKeyHandler extends KeyHandler {
104111
'clip-path: "inset(50%)"; height: 1px; width: 1px; margin: -1px; overflow: hidden; padding 0; position: absolute;'
105112
);
106113

107-
const listener = (): void => {
108-
dummyInput.removeEventListener('input', listener);
114+
const cleanup = (): void => {
115+
dummyInput.removeEventListener('paste', pasteListener);
116+
dummyInput.removeEventListener('input', inputListener);
109117
dummyInput.remove();
110-
111118
grid.focus();
112-
const value = parseValueFromElement(dummyInput);
119+
};
120+
121+
let plainText = '';
122+
123+
// Capture text/plain from the clipboard during the paste event.
124+
// This is used as a fallback if HTML parsing fails, for cases like pasting from Excel
125+
const pasteListener = (e: Event): void => {
126+
const clipboardEvent = e as ClipboardEvent;
127+
plainText =
128+
clipboardEvent.clipboardData?.getData('text/plain') ?? '';
129+
};
130+
131+
const inputListener = (): void => {
132+
cleanup();
133+
const value =
134+
parseValueFromElement(dummyInput) ??
135+
(plainText.length > 0 ? parseValueFromText(plainText) : null);
113136
if (value != null) {
114137
grid.pasteValue(value);
115138
}
116139
};
117140

118-
// Listen for the `input` event, when there's a change to the HTML
119-
// We could also listen to the `paste` event to get the clipboard data, but that's just text data
120-
// By listening to `input`, we can get a table that's already parsed in HTML, which is easier to consume
121-
dummyInput.addEventListener('input', listener);
141+
dummyInput.addEventListener('paste', pasteListener);
142+
dummyInput.addEventListener('input', inputListener);
122143

123144
// Focus the element so it receives the paste event
124145
dummyInput.focus();

0 commit comments

Comments
 (0)