react-arborist icon indicating copy to clipboard operation
react-arborist copied to clipboard

API to prevent nodes from being selectable

Open boriskor opened this issue 11 months ago • 5 comments

Added a tree prop disableSelect, in the spirit of disableEdit and disableDrag, closes #56

boriskor avatar Jul 31 '23 11:07 boriskor

Thank you @boriskor ! This looks really good. I am testing it out now.

jameskerr avatar Jul 31 '23 16:07 jameskerr

I am noticing some bugs when using shift + up/down to expand the selection with the keyboard.

jameskerr avatar Jul 31 '23 17:07 jameskerr

It looks like you may need to keep the the anchor and the most recent the same, even if some of the items are not selected.

Maybe this means you could make a function called tree.filterSelected(nodes/ids) that would take an array of ids or nodes and filter out only the ones that are selectable. Just like you have in the selectAll function. Then just use that function before setting the selection anywhere.

This would allow you to remove the if statements. In that function, if there is no disableSelection prop, just return everything. If there is, run the function on it.

Then make sure to test the shift+up, shift+down behavior and see if it feels right.

Add these lines to the bottom of the gmail-spec.cy.ts file as well:

  it("can select inbox but not categories", () => {
    cy.get("@item").contains("Inbox").click();
    cy.focused().should("have.attr", "aria-selected", "true");
    cy.get("@item").contains("Categories").click();
    cy.focused().should("have.attr", "aria-selected", "false");
  });

  it("select all does not select categories or spam", () => {
    cy.get("@item").contains("Inbox").click();
    cy.focused().type("{meta}a");
    cy.get("[aria-selected='true']")
      .should("not.contain.text", "Categories")
      .should("not.contain.text", "Spam")
      .should("contain.text", "Inbox")
      .should("have.length", 15);
  });

jameskerr avatar Jul 31 '23 17:07 jameskerr

Hi, @jameskerr, thank you for a quick response and sorry for the delay!

I've added the tests you've suggested to Cypress.

Can you explain please what are the bugs you noticed with shift + up/down and how can I reproduce them, step by step? Not sure I understand. Do you mean that shift + up/down should "skip" non-selectable nodes and move the focus right to the next selectable node? Or something else?

boriskor avatar Aug 19 '23 14:08 boriskor

Here are some videos of the behavior I am seeing on your branch.

Shift+Up/Down with selectable nodes (base behavior)

https://github.com/brimdata/react-arborist/assets/3460638/d0b10331-3460-446c-8a86-9a8130d481ae

Shift+Up/Down Encountering a non-selectable node (bug)

https://github.com/brimdata/react-arborist/assets/3460638/ec508519-fa69-445f-bb8a-f173db36752b

To me, it's strange that the first time pressing shift+down, it appears nothing happens because it tries to select "spam", but fails because it's not selectable. Shift+down again selects "Important". Then shift+up does not deselect "Important" which I think it should.

What I think should happen:

When changing the selection with "shift+up/down", pretend like the non-selectable nodes don't exist. If you encounter one as the next node, skip it and select the next selectable node.

In the video above starting with the node "Draft" selected...

  1. Pressing shift+down should skip "spam" (not-selectable) and select "Important"
  2. Pressing shift+up should then deselect "important" and move the focus back to "drafts"

Implementation

Multi-selection relies on the concept of an "anchor node" and a "most-recently selected node". When you expand the selection with the "shift+up/down" keys, the anchor node stays the same and the most recently selected changes. The new selection ends up being all the nodes between the anchor and the most recent node.

It appears that we need to account for non-selectable nodes when expanding/collapsing the selection. We need to add a check to "select next node" that skips non-selectable nodes and jumps to the next one we can select.

Did I write the words "selectable" and "nodes" enough times? 😂 Hopefully that makes sense.

jameskerr avatar Aug 28 '23 17:08 jameskerr