Skip to content
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

TSX types missing #68

Open
delaneyj opened this issue Nov 21, 2022 · 8 comments
Open

TSX types missing #68

delaneyj opened this issue Nov 21, 2022 · 8 comments

Comments

@delaneyj
Copy link

Ran into problems and looked at #60 but this example fails to run with typescript strict mode.

image

With unhealthy amount of any I can compile

import {
  closestCenter,
  createSortable,
  DragDropProvider,
  DragDropSensors,
  DragOverlay,
  SortableProvider,
  useDragDropContext,
} from '@thisbeyond/solid-dnd'
import { Component, createSignal, For } from 'solid-js'

const Sortable: Component<{ item: any }> = (props) => {
  const sortable = createSortable(props.item)
  const ctx = useDragDropContext()
  return (
    <div
      use:sortable
      class="sortable"
      classList={{
        'opacity-25': sortable.isActiveDraggable,
        'transition-transform': !!ctx?.[0].active.draggable,
      }}
    >
      {props.item}
    </div>
  )
}

export const SortableVerticalListExample = () => {
  const [items, setItems] = createSignal([1, 2, 3])
  const [activeItem, setActiveItem] = createSignal(null)
  const ids = () => items()

  const onDragStart = (obj: any) => setActiveItem(obj.draggable.id)

  const onDragEnd = (obj: any) => {
    if (obj.draggable && obj.droppable) {
      const currentItems = ids()
      const fromIndex = currentItems.indexOf(obj.draggable.id)
      const toIndex = currentItems.indexOf(obj.droppable.id)
      if (fromIndex !== toIndex) {
        const updatedItems = currentItems.slice()
        updatedItems.splice(toIndex, 0, ...updatedItems.splice(fromIndex, 1))
        setItems(updatedItems)
      }
    }
  }

  return (
    <DragDropProvider
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      collisionDetector={closestCenter}
    >
      <DragDropSensors />
      <div class="column self-stretch">
        <SortableProvider ids={ids()}>
          <For each={items()}>{(item) => <Sortable item={item} />}</For>
        </SortableProvider>
      </div>
      <DragOverlay>
        <div class="sortable">{activeItem()}</div>
      </DragOverlay>
    </DragDropProvider>
  )
}

However at runtime I'm getting useDragDropContext is not a function or its return value is not iterable error and not sure what to do. I know the lib is written in TS show I'd think the .tsx would be straight forward. Could someone ELI5 what I'm missing?

@mohamed-adly
Copy link

checkout #63

@jyasskin
Copy link

I filed the parallel issue thisbeyond/solid-dnd-site#4 in the repository that holds the under-typed examples. It's not necessarily straightforward to fix this just because the library is in TS: giving users the types they expect is a whole extra development task compared to writing a library that's internally type-safe.

@MikaelPorttila
Copy link

Running into the same issue here, but I also get a bunch of warning about the "use:" attributes

Type '{ children: string; "use:draggable": true; }' is not assignable to type 'HTMLAttributes<HTMLDivElement>'.
  Property 'use:draggable' does not exist on type 'HTMLAttributes<HTMLDivElement>'. Did you mean 'draggable'?ts(2322)

@ShivamJoker
Copy link

I am also unable to use it with TS, any possible fixes?

image

@ShivamJoker
Copy link

@martinpengellyphillips any way to get around with this?

@martinpengellyphillips
Copy link
Contributor

martinpengellyphillips commented May 8, 2023

Have you looked at #60 yet?

I'm general, you should be able to use the exported types from solid-dnd to get what you need (as well as the types from solidjs for things like components).

Where specifically are the types not working for you (the screenshot you share is completely untyped)?

@Kapelianovych
Copy link

If you don't want to declare directives for draggable, droppable and sortable functions, you can pass them directly into the ref attribute, since directives are just a convenient way to obtain a reference to underlying node:

<div ref={draggable}></div>

Of course, if you need the reference in another place too, the syntax becomes less plausible:

let ref

<div ref={(element) => {
  ref = element;
  draggable(element);
}}></div>

But this should still work. Perhaps it is worth to add the definitions of those directives to the package itself, because it is a common feature that potentially is and will be used in most projects with DnD?

@ikemo3
Copy link

ikemo3 commented Feb 11, 2024

Here's how I fixed errors in strict mode: Specifically, the useDragDropContext is not a function or its return value is not iterable error was addressed by implementing const state = context && context[0];

import {
  closestCenter,
  createSortable,
  DragDropProvider,
  DragDropSensors,
  DragEventHandler,
  DragOverlay,
  Id,
  SortableProvider,
  useDragDropContext,
} from "@thisbeyond/solid-dnd";
import { createSignal, For } from "solid-js";

const Sortable = (props: { item: Id }) => {
  const sortable = createSortable(props.item);
  const context = useDragDropContext();
  const state = context && context[0];  // <-- this

  return (
    <div
      ref={sortable}
      class="sortable"
      classList={{
        "opacity-25": sortable.isActiveDraggable,
        "transition-transform": !!state?.active.draggable,
      }}
    >
      {props.item}
    </div>
  );
};

export const SortableVerticalListExample = () => {
  const [items, setItems] = createSignal<Id[]>([1, 2, 3]);
  const [activeItem, setActiveItem] = createSignal<Id | null>(null);
  const ids = () => items();

  const onDragStart: DragEventHandler = ({ draggable }) =>
    setActiveItem(draggable.id);

  const onDragEnd: DragEventHandler = ({ draggable, droppable }) => {
    if (draggable && droppable) {
      const currentItems = ids();
      const fromIndex = currentItems.indexOf(draggable.id);
      const toIndex = currentItems.indexOf(droppable.id);
      if (fromIndex !== toIndex) {
        const updatedItems = currentItems.slice();
        updatedItems.splice(toIndex, 0, ...updatedItems.splice(fromIndex, 1));
        setItems(updatedItems);
      }
    }
  };

  return (
    <DragDropProvider
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      collisionDetector={closestCenter}
    >
      <DragDropSensors />
      <div class="column self-stretch">
        <SortableProvider ids={ids()}>
          <For each={items()}>{(item) => <Sortable item={item} />}</For>
        </SortableProvider>
      </div>
      <DragOverlay>
        <div class="sortable">{activeItem()}</div>
      </DragOverlay>
    </DragDropProvider>
  );
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants