daybrush / selecto

Selecto.js is a component that allows you to select elements in the drag area using the mouse or touch.
https://daybrush.com/selecto
MIT License
2.04k stars 82 forks source link

How to implement CTRL-held selection toggling? #80

Open caleidon opened 2 years ago

caleidon commented 2 years ago

Environments

Description

I am very happy with how Selecto has the continueSelectWithoutDeselect option, where I can hold SHIFT and have it continuously select without deselecting. However, I am having huge trouble implementing CTRL-held selection, where (on most operating systems for example), holding CTRL and clicking an item would simply invert that selection and not touch anything else. Right now these two options seem mutually exclusive, you can only really have one, unless I am missing something.

Do you have any suggestions on how I could implement this, or would you please consider adding this to Selecto as a native feature?

Thank you for this amazing plugin, saved me dozens of hours of work and I love it! <3

fanterxissss commented 2 years ago

continueSelect={false} continueSelectWithoutDeselect={true} toggleContinueSelect={[["shift"],["ctrl"]]}

The preceding attributes are added in the new version.

caleidon commented 2 years ago

I think you misunderstood me. The desired outcome is that when CTRL is held, you can INVERT your selection, so deselect when it's selected and select when it's not selected. With the code you provide, no matter if ctrl or shift is held, it's always adding to the selection which isn't what I want.

fanterxissss commented 2 years ago

ok,try continueSelectWithoutDeselect={false}:

continueSelect={false} continueSelectWithoutDeselect={false} toggleContinueSelect={[["shift"],["ctrl"]]}

and, setting Moveable prop: onClickGroup={(e:any)=>{ selectoRef.current!.clickTarget(e.inputEvent, e.inputTarget); }}

caleidon commented 2 years ago

Hey! Thanks for the answer. I'm not sure where to put this last part. I don't use Moveable with selecto. Here's what my setup looks like:

<Selecto
    bind:this={selecto}
    dragContainer={".selectable-area"}
    hitRate="1"
    {scrollOptions}
    selectByClick={true}
    selectFromInside={true}
    selectableTargets={[".selectable"]}
    toggleContinueSelect={["shift"]}
    continueSelectWithoutDeselect={true}
    ratio={0}
    on:scroll={({ detail: e }) => {
      scroller.scrollBy(e.direction[0] * 15, e.direction[1] * 15);
    }}
    on:selectStart={({ detail: e }) => {
      if (rmbSelectedMetadata != null) {
        if (!e.selected.includes(rmbSelectedMetadata.hash)) {
          removeFromSelection([rmbSelectedMetadata.hash]);
        }

        rmbSelectedMetadata = null;
      }
    }}
    on:select={({ detail: e }) => {
      e.removed.forEach((element) => {
        element.classList.remove("selected");
      });
      e.added.forEach((element) => {
        element.classList.add("selected");
      });
    }}
    on:selectEnd={({ detail: e }) => {
      removeFromSelection(e.removed.map((element) => element.id));
      addToSelection(e.selected.map((element) => element.id));
    }}
  />

Where do I put the code that you wrote?

daybrush commented 2 years ago

@caleidon

Is it correct that you want to use different keys for continueSelect and continueSelectWithoutDeselect ?

caleidon commented 2 years ago

I'm not sure how to answer that question. Currently we only have toggleContinueSelect. I think a feature should be added where you can have both toggleContinueSelect (holding SHIFT to keep selecting all additional items) AND toggleInvertSelection, and to this we can bind CTRL (inverting selection instead of selecting).

Can this be added as a feature to Selecto? It seems very simple and very essential.

daybrush commented 2 years ago

@caleidon

I thought it was similar to the behavior on the window desktop.

When used with shift key, there is no deselection. continueSelect: true, continueSelectWithoutDeselect: true

There is deselection by using the ctrl key. continueSselect: true, continueSelectWithoutDeselect: false

I'll add this feature at next release.

caleidon commented 2 years ago

Yes, exactly! Just keep in mind that when using CTRL, there isn't deselection, it's inversion. So you can still select by using CTRL if it's not selected.

Thank you, and please let me know when this feature is implemented! <3

daybrush commented 2 years ago

Set this props:

                continueSelect={false}
                continueSelectWithoutDeselect={true}
                toggleContinueSelect={"shift"}
                toggleContinueSelectWithoutDeselect={"ctrl"}
caleidon commented 2 years ago

Hi. Thank you for the update and attempting to solve the problem. However, it isn't as I hoped it would be.

I tried your code that you posted and the behavior isn't what I expected. With your code, when I hold CTRL and keep clicking on a certain tile, I expect it to get selected, then deselected, then selected, and so on and on. Holding CTRL while selecting should TOGGLE the current selected state of that tile.

I'm not sure if there is a miscommunication or maybe I just implemented your feature wrong, please let me know! :)