import Modifier from 'ember-modifier';
import { type A11yAnnouncementConfig } from '../utils/defaults.ts';
import type { ArgsFor, PositionalArgs, NamedArgs } from 'ember-modifier';
import type Owner from '@ember/owner';
import type EmberSortableService from '../services/ember-sortable-internal-state.ts';
import type { Group } from '../services/ember-sortable-internal-state.ts';
import type SortableItemModifier from './sortable-item.ts';
import type { MoveDirection } from './sortable-item.ts';
export interface HandleVisualClass {
    UP?: string;
    DOWN?: string;
    LEFT?: string;
    RIGHT?: string;
}
interface Position {
    x: number;
    y: number;
}
export type TDirection = 'x' | 'y' | 'grid';
interface SortableGroupModifierSignature<T> {
    Args: {
        Named: {
            direction?: TDirection;
            groupName?: string;
            disabled?: boolean;
            handleVisualClass?: HandleVisualClass;
            a11yAnnouncementConfig?: A11yAnnouncementConfig;
            itemVisualClass?: string;
            a11yItemName?: string;
            onChange: (itemModels: T[], draggedModel: T | undefined) => void;
        };
        Positional: unknown[];
    };
    Element: HTMLElement;
}
/**
 * Modifier to apply a11y support to a group container for the Sortable component
 *
 * @param {String} [a11yItemName] A name for each model, used for creating more meaningful a11y announcements.
 * @param {Object} [a11yAnnouncementConfig] A map of action to function to build meaningful a11y announcements.
 * @param {String} [itemVisualClass] A class for styling visual indicators on the yielded `sortable-item`.
 * @param {Object} [handleVisualClass] An object for styling visual indicators on the yielded `sortable-handle` on different `move`.
 * @param {Function} [onChange] An optional callback for when position rearrangements are confirmed.
 *
 * @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 SortableGroupModifier<T> extends Modifier<SortableGroupModifierSignature<T>> {
    /** Primary keyboard utils */
    _selectedItem: SortableItemModifier<T> | null;
    _group: SortableGroupModifier<T> | null;
    _firstItemPosition?: Position;
    _groupDef: Group<T>;
    move: null;
    moves: [number, number][];
    isKeyboardReorderModeEnabled: boolean;
    isKeyDownEnabled: boolean;
    isRetainingFocus: boolean;
    /** End of keyboard utils */
    get disabled(): boolean;
    /** Start of a11y properties */
    /**
     * @property an object containing different classes for visual indicators
     * @type {Object}
     * @default null
     * @example
     * {
     *  UP: 'up'
     *  DOWN: 'down',
     *  LEFT: 'left',
     *  RIGHT: 'right',
     * }
     */
    get handleVisualClass(): HandleVisualClass;
    /**
     * @property an object containing functions for producing screen reader announcements
     * @type {Object}
     * @example
     * {
     *  MOVE: function() {},
     *  ACTIVATE: function() {},
     *  CONFIRM: function() {},
     *  CANCEL: function() {},
     * }
     */
    get a11yAnnouncementConfig(): A11yAnnouncementConfig;
    get itemVisualClass(): string;
    get a11yItemName(): string;
    /** End of a11y properties */
    /**
     * Make sure that we cancel any ongoing keyboard operation when the focus is lost from the handle.
     * Because this can be fired pre-maturely, effectively cancelling before other keyboard operations,
     * we need to wait until other operations are completed, so this will cancel properly.
     *
     * @param {Event} event a DOM event.
     */
    focusOut(): void;
    /**
     * Explanation
     * 1. `KeyboardReorderMode` is disabled: users can activate it via ENTER or SPACE.
     * 2. `KeyboardReorderMode` is enabled: users can reorder via UP or DOWN arrow keys. TODO: Expand to more keys, e.g LEFT, RIGHT
     * 3. `KeyboardReorderMode` is enabled: users can finalize/save the reordering via ENTER or SPACE.
     * 4. `KeyboardReorderMode` is enabled: users can discard the reordering via ESC.
     *
     * @param {Event} event a DOM event
     */
    keyDown(event: KeyboardEvent): void;
    /**
     * Checks if the given element is a child of a handle.
     *
     * @param {Element} element a DOM element.
     */
    _isElementWithinHandle(element: Element | null): boolean;
    /**
     * Moves an sortedItem from one index to another index, effectively performing an reorder.
     *
     * @param {Integer} fromIndex the original index
     * @param {Integer} toIndex the new index
     */
    _move(fromIndex: number, toIndex: number): void;
    /**
     * Handles all of the keyboard operations, such as
     * 1. Keyboard navigation for UP, DOWN, LEFT, RIGHT
     * 2. Confirming reorder
     * 3. Discard reorder
     * 4. Also handles refocusing the element that triggered the interaction.
     *
     * @param {Event} event a DOM event.
     */
    _handleKeyboardReorder(event: KeyboardEvent): void;
    /**
     * Moves the item to its new position and adds the move to our history.
     *
     * @param {SortableItemModifier} item the item to be moved.
     * @param {Integer} delta how much to move index-wise.
     */
    moveItem(item: SortableItemModifier<T>, delta: number): void;
    /**
     * Handles all the necessary operations needed for cancelling the current keyboard selection.
     * 1. Disables keyboard reorder mode.
     * 2. Undo all of the tracked moves.
     * 3. Tears down the application container, so we are not focus locked within the application.
     * 4. Resets the current selected item.
     */
    cancelKeyboardSelection(): void;
    /**
     * Handles all th necessary operations needed for confirming the current keyboard selection.
     * 1. Disables keyboard reorder mode.
     * 2. Tears down the application container, so we are not focus locked within the container.
     * 3. Make sure to update and sync all the internal items and UI.
     * 4. Triggers the `onChange` action if provided.
     * 5. Resets the currently selected item.
     */
    confirmKeyboardSelection(): void;
    /**
     * Announces the message constructed from `a11yAnnouncementConfig`.
     *
     * @param {String} type the action type.
     * @param {Number} delta how much distance (item-wise) is being moved.
     */
    _announceAction(type: keyof A11yAnnouncementConfig, delta?: number): void;
    /**
     * Reset the selected item.
     */
    _resetItemSelection(): void;
    /**
     * Updates the selected item's visual indicators.
     *
     * @param {SortableItemModifier} item the selected item.
     * @param {Boolean} isActive to activate or deactivate the class.
     */
    _updateItemVisualIndicators(item: SortableItemModifier<T>, isActive: boolean): void;
    /**
     * Updates the selected item's handle's visual indicators
     *
     * @param {SortableItemModifier} item the selected item.
     * @param {boolean} isUpdate to update or not update.
     */
    _updateHandleVisualIndicators(item: SortableItemModifier<T>, isUpdate: boolean): void;
    /**
     * Sets focus on the current item or its handle.
     *
     * @param {Element} itemElement an DOM element representing an sortable-item.
     */
    _focusItem(itemElement: HTMLElement): void;
    /**
     * Enables keyboard reorder mode.
     */
    _enableKeyboardReorderMode(): void;
    /**
     * Disables keyboard reorder mode
     */
    _disableKeyboardReorderMode(): void;
    /**
     * Sets up the group as an application and make it programmatically focusable.
     */
    _setupA11yApplicationContainer(): void;
    /**
     * Tears down the `role=application` container.
     */
    _tearDownA11yApplicationContainer(): void;
    _prepareKeyboardReorderMode(): void;
    /**
     @property direction
     @type string
     @default y
     */
    get direction(): TDirection;
    /**
     Called when order of items has been changed
     @property onChange
     @type Function
     @param {Object} groupModel group model (omitted if not set)
     @param {Object[]} newModel models in their new order
     @param {Object} itemModel model just dragged
     @default null
     */
    get onChange(): (itemModels: T[], draggedModel: T | undefined) => void;
    sortableService: EmberSortableService<T>;
    /**
     * 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;
    /**
     This is an array of SortableItemModifiers
  
     @property items
     @type SortableItemModifier[]
     */
    get items(): SortableItemModifier<T>[];
    set(items: SortableItemModifier<T>[]): void;
    /**
     * Announcer element
     *
     * @type {Element}
     */
    announcer: Element | null;
    /**
     Position for the first item.
     If spacing is present, first item's position will have to change as well.
     @property firstItemPosition
     @type Number
     */
    get firstItemPosition(): Position;
    /**
     An array of DOM elements.
     @property sortedItems
     @type SortableItemModifier[]
     */
    get sortedItems(): SortableItemModifier<T>[];
    /**
     * Enables keyboard navigation
     */
    activateKeyDown(selectedItem: SortableItemModifier<T>): void;
    /**
     * Disables keyboard navigation
     * Currently used to handle keydown events bubbling up from
     * elements that aren't meant to invoke keyboard navigation
     * by ignoring them.
     */
    deactivateKeyDown(): void;
    /**
     Register the group with this Sortable.
     @method registerGroup
     @param {SortableGroupModifier} group
     */
    registerGroup(group: SortableGroupModifier<T>): void;
    /**
     De-register the group with this Sortable.
     @method deregisterGroup
     @param {SortableGroupModifier} group
     */
    deregisterGroup(group: SortableGroupModifier<T>): void;
    /**
     Prepare for sorting.
     Main purpose is to stash the current firstItemPosition so
     we don’t incur expensive re-layouts.
     @method _prepare
     */
    prepare(): void;
    /**
     Update item positions (relatively to the first element position).
     @method update
     @param {SortableItemModifier[]} sortedItems
     */
    update(sortedItems: SortableItemModifier<T>[]): void;
    /**
     @method _commit
     */
    commit(): void;
    _onChange(itemModels: T[], draggedModel: T | undefined): void;
    /**
     * Keeps the UI in sync with actual changes.
     * Needed for drag and keyboard operations.
     */
    _updateItems(): void;
    _createAnnouncer(): HTMLSpanElement;
    _calculateGridPosition(a: SortableItemModifier<T>, b: SortableItemModifier<T>, groupWidth: number): {
        ax: number;
        ay: number;
        bx: number;
        by: number;
    };
    _calculateGridDragItemPos(x: number, y: number, otherX: number, otherY: number, width: number, height: number, moveDirection: MoveDirection, groupTopPos: number, groupLeftPos: number, groupWidth: number): Position;
    addEventListener(): void;
    removeEventListener(): void;
    element: HTMLElement;
    didSetup: boolean;
    named: NamedArgs<SortableGroupModifierSignature<T>>;
    constructor(owner: Owner, args: ArgsFor<SortableGroupModifierSignature<T>>);
    modify(element: HTMLElement, _positional: PositionalArgs<SortableGroupModifierSignature<T>>, named: NamedArgs<SortableGroupModifierSignature<T>>): void;
}
export {};
