adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.97k stars 1.13k forks source link

Table: Allow text selection #2585

Open datagutt opened 2 years ago

datagutt commented 2 years ago

๐Ÿ™‹ Feature Request

There is currently no way to enable selection of text in a component that is using react-aria table hooks.

๐Ÿค” Expected Behavior

A prop to allow text selection in a table (might make sense to only allow this if selectionMode is none)

๐Ÿ˜ฏ Current Behavior

Currently, there is no way to enable text selection in a table.

๐Ÿ’ Possible Solution

I have tried to use the new enableTextSelection in usePress, and applying that to a TableRow, without any luck. There are probably some event handlers preventing this from being a workaround.

I am not sure how the logic for enabling selection of rows works, but there should be a prop to allow text selection in "regular" tables that do not have selectionMode.

๐Ÿ”ฆ Context

I am currently working on a UI library using react-arias useTable, and we want the user to have the ability to select, copy and paste text in a table with selectionMode "none".

๐Ÿ’ป Examples

I have a comparison table containing rows of products, and i wish to let the users copy and paste text (product details, prices etc). This table does not require selectionMode (highlight/checkbox functionality), but it does use the sorting and other functionality of react-aria table hooks.

๐Ÿงข Your Company/Team

๐ŸŽ Tracking Ticket (optional)

snowystinger commented 2 years ago

Thanks for bringing this up. I'll bring it up with the team. Thanks for the detailed use case, it helps a lot. In the meantime, our suggestions have been to add a "copy" button to rows or to enable selection and put a copy button outside the table. This allows you greater flexibility in the way content is copied (plain text, json, csv) and the order it's in (sorted? not? by column or by row) It can also be easier to copy text this way for keyboard, voice over, and touch users. I'm not sure if you're using any sort of virtualizer for your table, but text selection when the dom nodes are reused after they scroll out of view can be tricky since the DOM no longer has that text it's no longer part of the selection. The above mentioned copy button and selection mode can also help with that.

datagutt commented 2 years ago

While a copy button might work in certain situations (dashboards, people used to working with tabular data etc), i do think "regular" users browsing our website would expect to be able to copy using regular native methods.

penspinner commented 2 years ago

Ran into this issue recently as well and would be nice if text selection worked on table cells.

snowystinger commented 2 years ago

Hey, sorry for the delay. I discussed this with the team. Things start to get tricky when you introduce drag/drop, selection, virtualizers, non-text components inside cells.

We think the best way to approach this problem is to use the methods outlined above. Make use of selection and provide ways to write the selection to the clipboard (as CSV or JSON for example). Our selection hooks already handle select all, so something like CMD + A, CMD + C should be trivial to implement. This could also solve the issue of not being able to copy out the swatch value since the display representation of the data could be different than what you write to the clipboard.

I think if you have a data only table and are ok with some of the possible interaction issues outlined above, you could do something like this: https://codesandbox.io/s/brave-glade-h78ge?file=/src/App.js or apply the style/events directly to the cell in aria if you're using our hooks.

devongovett commented 2 years ago

We have some hooks for dealing with clipboard events too if you decide to go that way: https://github.com/adobe/react-spectrum/blob/main/packages/@react-aria/dnd/src/useClipboard.ts No docs just yet, but there are some examples if you search the repo.