UNPKG

@mui/x-data-grid

Version:

The community edition of the data grid component (MUI X).

92 lines (89 loc) 3.59 kB
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); };