-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[table] feat: add default implementation for getCellClipboardData #5127
[table] feat: add default implementation for getCellClipboardData #5127
Conversation
…e-default-copy-cell
…eprint into tb/table-default-copy-cell
….cellRenderer if it is undefined,
It seems like there is only one test for blueprint/packages/table/test/selectionTests.tsx Lines 58 to 70 in 92db539
|
packages/table/src/tableProps.ts
Outdated
@@ -145,7 +146,7 @@ export interface ITableProps extends Props, Partial<IRowHeights>, Partial<IColum | |||
* The data will be invisibly added as `textContent` into the DOM before | |||
* copying. If not defined, keyboard copying via `mod+c` will be disabled. | |||
*/ | |||
getCellClipboardData?: (row: number, col: number) => any; | |||
getCellClipboardData?: (row: number, col: number, tableState: TableState) => any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a breaking change; we'll have to make the new prop argument optional if we want to add this to the API.
Also I think we should limit the scope of the new information required here. It would be better with just a cellRenderer argument rather than the whole table state.
getCellClipboardData?: (row: number, col: number, tableState: TableState) => any; | |
getCellClipboardData?: (row: number, col: number, cellRenderer?: CellRenderer) => any; |
Lastly, I think we should add a note about the default implementation to the documentation for this prop, right above in the JSDoc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tableState is not optional - since it is always defined/always passed by the caller. This happens here:
blueprint/packages/table/src/tableHotkeys.ts
Line 419 in 1f8ead7
const sparse = Regions.sparseMapCells(cells, (row, col) => getCellClipboardData(row, col, this.state)); |
It is not a breaking change to the API - since you don't need to use all the arguments when creating a callback function. Examples:
<>
{/* Still possible after API change */}
<Table getCellClipboardData={() => 'hello world'} ... />
{/* Still possible after API change */}
<Table getCellClipboardData={(row) => `row=${row}`} ... />
{/* Still possible after API change */}
<Table getCellClipboardData={(row, col) => `row=${row}, col=${col}`} ... />
{/* Only possible after API change */}
<Table getCellClipboardData={(row, col, tableState) => {
return tableState.childrenArray[col].props.cellRenderer?.(row, col)
// If tableState was optional - we would be forced to check if it is undefined in this callback:
// return tableState?.childrenArray[col].props.cellRenderer?.(row, col)
}} ... />
</>
Passing the entire tableState means the user of the Table-component will have a lot of flexibility when writing a custom getCellClipboardData-function. I see this as a bit analogous to how you have access to the entire array in the .map callback on arrays:
> [1,2,3,4].map((value, index, array) => array)
// Output:
[ [ 1, 2, 3, 4 ], [ 1, 2, 3, 4 ], [ 1, 2, 3, 4 ], [ 1, 2, 3, 4 ] ]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the docstring now to mention the default implementation.
In terms of CellRenderer
vs TableState
, I guess this depends on whether TableState
is likely to change in backwards-incompatible ways in the future or not. CellRenderer
certainly exposes less surface area - at the cost of some flexibility (which might not be useful in practice). But is CellRenderer
maybe too specific to the default implementation?
If we find out we need something else from TableState
in the getCellClipboardData
callback in the future, this would then have to be added as yet another argument to not break backwards compatibility - which could cause a very messy callback signature for getCellClipboardData
over time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I tested out the new argument and came to the same conclusion. It's not a breaking change like I imagined it would be with tsc --strict
, so that's good 👍
As for API surface area... I generally try to be conservative about adding to the API surface of Blueprint, as it's already quite large. TableState
is a type which I don't necessarily want to export as public API (you'll notice it's not even exported from the package root right now). It may have breaking changes in the future which I don't want to be constrained by.
So, yes, I would like to limit the scope of the data in the new argument here. Please change it to CellRenderer
, and pass along the specific cell renderer for that row/col coordinate.
getCellClipboardData?: (row: number, col: number, tableState: TableState) => any; | |
getCellClipboardData?: (row: number, col: number, cellRenderer: CellRenderer) => any; |
If we find out we need something else from TableState in the getCellClipboardData callback in the future, this would then have to be added as yet another argument to not break backwards compatibility - which could cause a very messy callback signature for getCellClipboardData over time.
I hear your concern here, and I also don't want to end up with an unwieldy callback signature over time. But at this point we only have 2 arguments, and I'm OK with adding a third one. I'll consider refactoring the next time we need to add more information here, if there is a next time.
packages/table/src/tableProps.ts
Outdated
@@ -145,7 +146,7 @@ export interface ITableProps extends Props, Partial<IRowHeights>, Partial<IColum | |||
* The data will be invisibly added as `textContent` into the DOM before | |||
* copying. If not defined, keyboard copying via `mod+c` will be disabled. | |||
*/ | |||
getCellClipboardData?: (row: number, col: number) => any; | |||
getCellClipboardData?: (row: number, col: number, tableState: TableState) => any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I tested out the new argument and came to the same conclusion. It's not a breaking change like I imagined it would be with tsc --strict
, so that's good 👍
As for API surface area... I generally try to be conservative about adding to the API surface of Blueprint, as it's already quite large. TableState
is a type which I don't necessarily want to export as public API (you'll notice it's not even exported from the package root right now). It may have breaking changes in the future which I don't want to be constrained by.
So, yes, I would like to limit the scope of the data in the new argument here. Please change it to CellRenderer
, and pass along the specific cell renderer for that row/col coordinate.
getCellClipboardData?: (row: number, col: number, tableState: TableState) => any; | |
getCellClipboardData?: (row: number, col: number, cellRenderer: CellRenderer) => any; |
If we find out we need something else from TableState in the getCellClipboardData callback in the future, this would then have to be added as yet another argument to not break backwards compatibility - which could cause a very messy callback signature for getCellClipboardData over time.
I hear your concern here, and I also don't want to end up with an unwieldy callback signature over time. But at this point we only have 2 arguments, and I'm OK with adding a third one. I'll consider refactoring the next time we need to add more information here, if there is a next time.
@bergkvist I'd like to merge this in this week, so if you don't mind, I will apply my suggestions myself to this PR |
Fixes #4566
Checklist
Changes proposed in this pull request:
Add default implementation of getCellClipboardData for Table and Table2, which uses the package
react-innertext
to extract the default value of each cell.Change signature of getCellClipboardData: