@mui/x-data-grid
Version:
The community edition of the data grid component (MUI X).
92 lines (89 loc) • 3.59 kB
JavaScript
import _typeof from "@babel/runtime/helpers/esm/typeof";
import * as React from 'react';
import { useGridApiOptionHandler, useGridNativeEventListener } from '../../utils';
import { gridFocusCellSelector } from '../focus/gridFocusStateSelector';
import { serializeCellValue } from '../export/serializers/csvSerializer';
function writeToClipboardPolyfill(data) {
var span = document.createElement('span');
span.style.whiteSpace = 'pre';
span.style.userSelect = 'all';
span.style.opacity = '0px';
span.textContent = data;
document.body.appendChild(span);
var range = document.createRange();
range.selectNode(span);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
try {
document.execCommand('copy');
} finally {
document.body.removeChild(span);
}
}
function copyToClipboard(data) {
if (navigator.clipboard) {
navigator.clipboard.writeText(data).catch(function () {
writeToClipboardPolyfill(data);
});
} else {
writeToClipboardPolyfill(data);
}
}
function hasNativeSelection(element) {
var _window$getSelection;
// When getSelection is called on an <iframe> that is not displayed Firefox will return null.
if ((_window$getSelection = window.getSelection()) != null && _window$getSelection.toString()) {
return true;
}
// window.getSelection() returns an empty string in Firefox for selections inside a form element.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=85686.
// Instead, we can use element.selectionStart that is only defined on form elements.
if (element && (element.selectionEnd || 0) - (element.selectionStart || 0) > 0) {
return true;
}
return false;
}
/**
* @requires useGridCsvExport (method)
* @requires useGridSelection (method)
*/
export var useGridClipboard = function useGridClipboard(apiRef, props) {
var ignoreValueFormatterProp = props.unstable_ignoreValueFormatterDuringExport;
var ignoreValueFormatter = (_typeof(ignoreValueFormatterProp) === 'object' ? ignoreValueFormatterProp == null ? void 0 : ignoreValueFormatterProp.clipboardExport : ignoreValueFormatterProp) || false;
var clipboardCopyCellDelimiter = props.clipboardCopyCellDelimiter;
var handleCopy = React.useCallback(function (event) {
if (!((event.ctrlKey || event.metaKey) && event.key === 'c')) {
return;
}
// Do nothing if there's a native selection
if (hasNativeSelection(event.target)) {
return;
}
var textToCopy = '';
var selectedRows = apiRef.current.getSelectedRows();
if (selectedRows.size > 0) {
textToCopy = apiRef.current.getDataAsCsv({
includeHeaders: false,
// TODO: make it configurable
delimiter: clipboardCopyCellDelimiter
});
} else {
var focusedCell = gridFocusCellSelector(apiRef);
if (focusedCell) {
var cellParams = apiRef.current.getCellParams(focusedCell.id, focusedCell.field);
textToCopy = serializeCellValue(cellParams, {
delimiterCharacter: clipboardCopyCellDelimiter,
ignoreValueFormatter: ignoreValueFormatter
});
}
}
textToCopy = apiRef.current.unstable_applyPipeProcessors('clipboardCopy', textToCopy);
if (textToCopy) {
copyToClipboard(textToCopy);
apiRef.current.publishEvent('clipboardCopy', textToCopy);
}
}, [apiRef, ignoreValueFormatter, clipboardCopyCellDelimiter]);
useGridNativeEventListener(apiRef, apiRef.current.rootElementRef, 'keydown', handleCopy);
useGridApiOptionHandler(apiRef, 'clipboardCopy', props.onClipboardCopy);
};