import React, { useCallback } from 'react' import type { Meta, StoryFn } from '@storybook/react-webpack5' import type { Column, GridRangeSelection } from '../../types' import { GridCellChips, GridCellDefault } from '../../components' import { useIntl } from 'react-intl' import { SpreadsheetGrid } from '.' import { Radio, RadioGroup } from '@planview/pv-form' import type { SpreadsheetGridApi } from '../../api' export default { title: 'pv-grid/Grids/SpreadsheetGrid/onRangeCopy', tags: ['hidden'], } satisfies Meta type User = { id: string name: string email: string subscription: number tags: string[] } const rows: User[] = [ { id: '1', name: 'Jane Doe', email: 'jdoe@example.com', subscription: 25, tags: ['beta', 'admin'], }, { id: '2', name: 'John Smith', email: 'jsmith@example.com', subscription: 14, tags: ['new', 'editor'], }, { id: '3', name: 'Alice Johnson', email: 'ajohnson@example.com', subscription: 14, tags: ['editor'], }, ] export const OnRangeCopy: StoryFn = () => { const [useValues, setUseValues] = React.useState(false) const intl = useIntl() const columns: Column[] = [ { id: 'name', label: 'Name', }, { id: 'email', label: 'Email', cell: { Renderer({ label, value, tabIndex }) { return ( ) }, }, }, { id: 'subscription', label: 'Subscription', cell: { label({ value }) { return intl.formatNumber(value, { style: 'currency', currency: 'USD', }) }, }, }, { id: 'tags', label: 'Tags', cell: { label({ value }) { return value.join(', ') }, Renderer({ value, tabIndex }) { return }, }, }, ] return ( <> setUseValues(value === 'values')} orientation="horizontal" > ) } export const CustomOnRangeCopy: StoryFn = () => { const intl = useIntl() const apiRef = React.useRef(null) const columns: Column[] = [ { id: 'name', label: 'Name', }, { id: 'email', label: 'Email', cell: { Renderer({ label, value, tabIndex }) { return ( ) }, }, }, { id: 'subscription', label: 'Subscription', cell: { label({ value }) { return intl.formatNumber(value, { style: 'currency', currency: 'USD', }) }, }, }, { id: 'tags', label: 'Tags', cell: { label({ value }) { return value.join(', ') }, Renderer({ value, tabIndex }) { return }, }, }, ] const onRangeCopy = useCallback( ( _rangeSelection: GridRangeSelection, data: { rowIds: User['id'][] columnIds: string[] }, e: React.ClipboardEvent ) => { const gridApi = apiRef.current if (!gridApi) { return } const doc = document.implementation.createHTMLDocument() const rows = doc.createElement('tbody') const rowsPlain: string[] = [] const headerRows = doc.createElement('thead') const headerCellsPlain: string[] = [] const headerRow = doc.createElement('tr') for (const columnId of data.columnIds) { const headerCell = doc.createElement('th') const headerContent = gridApi.content.getColumnLabel(columnId) headerCell.textContent = headerContent ?? '' headerRow.appendChild(headerCell) headerCellsPlain.push(headerContent) } rowsPlain.push(headerCellsPlain.join('\t')) headerRows.appendChild(headerRow) for (const rowId of data.rowIds) { const cells = doc.createElement('tr') const cellsPlain: string[] = [] for (const columnId of data.columnIds) { const cellContent = gridApi.content.getLabel({ rowId, columnId, }) const cell = doc.createElement('td') cell.textContent = cellContent ?? '' cells.appendChild(cell) cellsPlain.push(cellContent) } rows.appendChild(cells) rowsPlain.push(cellsPlain.join('\t')) } const table = doc.createElement('table') table.appendChild(headerRows) table.appendChild(rows) doc.body.appendChild(table) e.clipboardData?.setData('text/plain', rowsPlain.join('\n')) e.clipboardData?.setData('text/html', doc.documentElement.outerHTML) }, [] ) return ( ) }