diff --git a/packages/boxel-ui/addon/src/components/drag-and-drop/index.gts b/packages/boxel-ui/addon/src/components/drag-and-drop/index.gts index f8f8ea7da7..c5fc5511c8 100644 --- a/packages/boxel-ui/addon/src/components/drag-and-drop/index.gts +++ b/packages/boxel-ui/addon/src/components/drag-and-drop/index.gts @@ -6,6 +6,11 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { and, eq } from '../../helpers/truth-helpers.ts'; +import type { + DndDraggableItemModifier, + DndDropTargetModifier, + DndSortableItemModifier, +} from '../../types/drag-and-drop.ts'; const isFastBoot = typeof (globalThis as any).FastBoot !== 'undefined'; @@ -48,13 +53,16 @@ export default class DndKanbanBoard extends Component< DndKanbanBoardSignature > { @tracked areModifiersLoaded = false; - @tracked DndDraggableItemModifier: any = null; - @tracked DndDropTargetModifier: any = null; - @tracked DndSortableItemModifier: any = null; - @tracked insertAfter: any; - @tracked insertAt: any; - @tracked insertBefore: any; - @tracked removeItem: any; + @tracked DndDraggableItemModifier: DndDraggableItemModifier | undefined; + @tracked DndDropTargetModifier: DndDropTargetModifier | undefined; + @tracked DndSortableItemModifier: DndSortableItemModifier | undefined; + @tracked insertAfter: (array: T[], index: number, element: T) => T[] = + undefined as any; + @tracked insertAt: (array: T[], index: number, element: T) => T[] = + undefined as any; + @tracked insertBefore: (array: T[], index: number, element: T) => T[] = + undefined as any; + @tracked removeItem: (array: T[], item: T) => T[] = undefined as any; @tracked draggedCard: DndItem | null = null; constructor(owner: unknown, args: DndKanbanBoardArgs) { @@ -70,25 +78,22 @@ export default class DndKanbanBoard extends Component< // See: https://github.com/alvarocastro/ember-draggable-modifiers/issues/1 and https://github.com/cardstack/boxel/pull/1683#discussion_r1803979937 async loadModifiers() { // @ts-expect-error Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', or 'nodenext' - const DndDraggableItemModifier = await import( + const DndDraggableItemModifier: DndDraggableItemModifier = await import( 'ember-draggable-modifiers/modifiers/draggable-item' ); // @ts-expect-error Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', or 'nodenext' - const DndDropTargetModifier = await import( + const DndDropTargetModifier: DndDropTargetModifier = await import( 'ember-draggable-modifiers/modifiers/drop-target' ); // @ts-expect-error Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', or 'nodenext' - const DndSortableItemModifier = await import( + const DndSortableItemModifier: DndSortableItemModifier = await import( 'ember-draggable-modifiers/modifiers/sortable-item' ); // @ts-expect-error Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', or 'nodenext' const arrayUtils = await import('ember-draggable-modifiers/utils/array'); - this.DndDraggableItemModifier = DndDraggableItemModifier.default; - this.DndDropTargetModifier = DndDropTargetModifier.default; - this.DndSortableItemModifier = DndSortableItemModifier.default; this.insertAfter = arrayUtils.insertAfter; this.insertAt = arrayUtils.insertAt; this.insertBefore = arrayUtils.insertBefore; diff --git a/packages/boxel-ui/addon/src/types/drag-and-drop.ts b/packages/boxel-ui/addon/src/types/drag-and-drop.ts new file mode 100644 index 0000000000..0fc10e3ee2 --- /dev/null +++ b/packages/boxel-ui/addon/src/types/drag-and-drop.ts @@ -0,0 +1,71 @@ +import Modifier from 'ember-modifier'; + +export interface DndDraggableItemSignature { + Args: { + Named: { + data?: any; + disabled?: boolean; + dragHandleElement?: string; + group?: string; + isDraggingClass?: string; + onDragEnd?: (event: DragEvent) => void; + onDragStart?: (event: DragEvent) => void; + onDrop?: (event: { destination: unknown; source: unknown }) => void; + }; + Positional: []; + }; +} + +export interface DndDropTargetSignature { + Args: { + Named: { + accepts?: string[]; + allowDropOnChildren?: boolean; + allowDropOnItself?: boolean; + allowedEdges?: ('top' | 'bottom' | 'left' | 'right')[]; + canDrop?: (event: DragEvent) => boolean; + data?: any; + direction?: 'horizontal' | 'vertical'; + disabled?: boolean; + group?: string; + isOnTargetClass?: string; + onDragEnter?: (event: DragEvent) => void; + onDragLeave?: (event: DragEvent) => void; + onDrop?: (event: DragEvent, item: any) => void; + onHover?: (event: DragEvent) => void; + }; + Positional: []; + }; +} + +export interface DndSortableItemSignature { + Args: { + Named: { + accepts?: string[]; + allowDropOnChildren?: boolean; + allowDropOnItself?: boolean; + allowedEdges?: ('top' | 'bottom' | 'left' | 'right')[]; + canDrop?: (event: DragEvent) => boolean; + data?: any; + direction?: 'horizontal' | 'vertical'; + disabled?: boolean; + disabledDrag?: boolean; + disabledDrop?: boolean; + dragHandleElement?: string; + group?: string; + isDraggingClass?: string; + isOnTargetClass?: string; + onDragEnd?: (event: DragEvent) => void; + onDragEnter?: (event: DragEvent) => void; + onDragLeave?: (event: DragEvent) => void; + onDragStart?: (event: DragEvent) => void; + onDrop?: (event: DragEvent, item: any) => void; + onHover?: (event: DragEvent) => void; + }; + Positional: []; + }; +} + +export type DndDraggableItemModifier = Modifier; +export type DndDropTargetModifier = Modifier; +export type DndSortableItemModifier = Modifier; diff --git a/packages/experiments-realm/todo-app.gts b/packages/experiments-realm/todo-app.gts new file mode 100644 index 0000000000..65b237258f --- /dev/null +++ b/packages/experiments-realm/todo-app.gts @@ -0,0 +1,11 @@ +import { + field, + CardDef, + linksToMany, +} from 'https://cardstack.com/base/card-api'; +import { Todo } from './todo'; + +export class TodoApp extends CardDef { + static displayName = 'Todo App'; + @field todos = linksToMany(() => Todo); +}