UNPKG

ember-sortable

Version:
346 lines (345 loc) 9.54 kB
import Modifier from 'ember-modifier'; import type { ArgsFor, PositionalArgs, NamedArgs } from 'ember-modifier'; import type EmberSortableService from '../services/ember-sortable-internal-state.ts'; import type Owner from '@ember/owner'; import type { Group } from '../services/ember-sortable-internal-state.ts'; import type SortableGroupModifier from './sortable-group.ts'; import type { TDirection } from './sortable-group.ts'; export interface MoveDirection { left: boolean; right: boolean; top: boolean; bottom: boolean; } export interface FakeEvent { pageX: number; pageY: number; clientX: number; clientY: number; } export interface SortableItemModifierSignature<T> { Args: { Named: { model: T; groupName?: string; disabled?: boolean; updateInterval?: number; spacing?: number; isDraggingDisabled?: boolean; handle?: string; distance?: number; disableCheckScrollBounds?: boolean; onDragStart?: (item: T) => void; onDragStop?: (item: T) => void; }; }; Element: HTMLElement; } /** * Modifier to mark an element as an item to be reordered * * @param {Object} model The model that this item will represent * @param {boolean} [disabled=false] Set to true to make this item not sortable * @param {Function} [onDragStart] An optional callback for when dragging starts. * @param {Function} [onDragStop] An optional callback for when dragging stops. * * @module drag-drop/draggable-group * @example * <ol {{sortable-group onChange=this.update a11yAnnouncementConfig=this.myA11yConfig}}> * {{#each model.items as |item|}} * <li {{sortable-item model=item}}> * {{item.name}} * <span class="handle" {{sortable-handle}}>&varr;</span> * </li> * {{/each}} * </ol> */ export default class SortableItemModifier<T> extends Modifier<SortableItemModifierSignature<T>> { className: string; sortableService: EmberSortableService<T>; startEvent?: FakeEvent | Event; _sortableGroup?: Group<T>; _x?: number; _y?: number; _dragOriginX?: number; _dragOriginY?: number; _pageX?: number; _pageY?: number; /** * The SortableGroupModifier this item belongs to. Assigned by the group * when it inspects all the items in the list * * @type SortableGroupModifier */ get sortableGroup(): SortableGroupModifier<T>; get model(): T; get direction(): TDirection; get groupDisabled(): boolean; /** * This is the group name used to keep groups separate if there are more than one on the screen at a time. * If no group is assigned a default is used * * @default "_EmberSortableGroup" * @returns {string} */ get groupName(): string; /** The frequency with which the group is informed that an update is required. @property updateInterval @type Number @default 125 */ get updateInterval(): number; /** Additional spacing between active item and the rest of the elements. @property spacing @type Number @default 0[px] */ get spacing(): number; /** Removes the ability for the current item to be sorted @property disabled @type boolean @default false */ get isDisabled(): boolean; /** Selector for the element to use as handle. 1. By default, we will hook it the yielded sortable-handle. 2. If you don't use the sortable-handle, the entire element will be used as the handle. 3. In very rare situations, if you want to use a handle, but not the sortable-handle, you can override this class with your own handle's selector. This behavior will be synonymous with v1 @property handle @type String @default "[data-sortable-handle]" */ get handle(): string; handleElement?: HTMLElement | null; /** * Tolerance, in pixels, for when sorting should start. * If specified, sorting will not start until after mouse * is dragged beyond distance. Can be used to allow for clicks * on elements within a handle. * * @property distance * @type Integer * @default 0 */ get distance(): number; /** * True if the item is currently being dragged. * * @property isDragging * @type boolean * @default false * @protected */ _isDragging: boolean; get isDragging(): boolean; set isDragging(value: boolean); /** * Gives info in which direction the element will be moved * * @property moveDirection * @type Object */ get moveDirection(): MoveDirection; /** Action that fires when the item starts being dragged. @property onDragStart @type Function @param {Object} item model @default null */ get onDragStart(): (item: T) => void; /** Action that fires when the item stops being dragged. @property onDragStop @type Function @param {Object} item model @default null */ get onDragStop(): (item: T) => void; /** True if the item is currently dropping. @property isDropping @type Boolean @default false */ _isDropping: boolean; get isDropping(): boolean; set isDropping(value: boolean); /** True if the item was dropped during the interaction @property wasDropped @type Boolean @default false */ wasDropped: boolean; /** @property isBusy @type Boolean */ get isBusy(): boolean; /** @property disableCheckScrollBounds */ get disableCheckScrollBounds(): boolean; /** @method mouseDown */ mouseDown(event: MouseEvent): void; keyDown(event: Event): void; /** @method touchStart */ touchStart(event: TouchEvent): void; /** @method freeze */ freeze(): void; /** @method reset */ reset(): void; /** @method thaw */ thaw(): void; _prepareDragListener: () => void; _cancelStartDragListener: () => void; /** * Setup event listeners for drag and drop * * @method _primeDrag * @param {Event} startEvent JS Event object * @private */ _primeDrag(startEvent: Event): void; /** * Prepares for the drag event * * @method _prepareDrag * @param {Event} startEvent JS Event object * @param {Event} event JS Event object * @private */ _prepareDrag(startEvent: MouseEvent, event: MouseEvent): void; /** * Start dragging & setup more event listeners * * @method _startDrag * @param {Event} event JS Event object * @private */ _startDrag(event: MouseEvent | TouchEvent): void; /** The maximum scroll speed when dragging element. @property maxScrollSpeed @default 20 */ maxScrollSpeed: number; _scrollOnEdges(drag: (event: FakeEvent | Event) => void): void; /** @method _makeDragHandler @param {Event} startEvent @return {Function} @private */ _makeDragHandler(startEvent: FakeEvent | Event): (event: FakeEvent | Event) => void; /** @method _scheduleApplyPosition @private */ _scheduleApplyPosition(): void; /** @method _applyPosition @private */ _applyPosition(): void; /** @method _drag @private */ _drag(dimensionX: number, dimensionY: number): void; /** @method _drop @private */ _drop(): void; /** @method _preventClick @private */ _preventClick(): void; /** @method _preventClickHandler @private */ _preventClickHandler(e: Event): void; /** @method _waitForTransition @private @return Promise */ _waitForTransition(): Promise<unknown>; /** @method _waitForTransitions @private @return Promise */ _waitForAllTransitions(): Promise<unknown>; /** @method _complete @private */ _complete(): void; get isAnimated(): boolean | undefined; /** The current transition duration in milliseconds. @property transitionDuration @type Number */ get transitionDuration(): number; /** Horizontal position of the item. @property x @type Number */ get x(): number; set x(value: number); /** Vertical position of the item relative to its offset parent. @property y @type Number */ get y(): number; set y(value: number); /** Width of the item. @property height @type Number */ get width(): number; /** Height of the item including margins. @property height @type Number */ get height(): number; addEventListener(): void; removeEventListener(): void; setupHandleElement(disabled?: boolean): void; element: HTMLElement; didSetup: boolean; named: NamedArgs<SortableItemModifierSignature<T>>; /** * tracks if event listeners have been registered. Registering event handlers is unnecessary if item is disabled. */ listenersRegistered: boolean; constructor(owner: Owner, args: ArgsFor<SortableItemModifierSignature<T>>); modify(element: HTMLElement, _positional: PositionalArgs<SortableItemModifierSignature<T>>, named: NamedArgs<SortableItemModifierSignature<T>>): void; }